diff mbox series

[RFC/RFT,03/23] net: phy: Add helper to set EEE Clock stop enable bit

Message ID 20230327170201.2036708-4-andrew@lunn.ch (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: ethernet: Rework EEE | expand

Checks

Context Check Description
netdev/series_format fail Series longer than 15 patches (and no cover letter)
netdev/tree_selection success Guessed tree name to be net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 425 this patch: 425
netdev/cc_maintainers warning 4 maintainers not CCed: pabeni@redhat.com kuba@kernel.org edumazet@google.com davem@davemloft.net
netdev/build_clang success Errors and warnings before: 299 this patch: 299
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 411 this patch: 411
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 33 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Andrew Lunn March 27, 2023, 5:01 p.m. UTC
The MAC driver can request that the PHY stops the clock during EEE
LPI. This has normally been does as part of phy_init_eee(), however
that function is overly complex and often wrongly used. Add a
standalone helper, to aid removing phy_init_eee().

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
v2: Add missing EXPORT_SYMBOL_GPL
---
 drivers/net/phy/phy.c | 20 ++++++++++++++++++++
 include/linux/phy.h   |  1 +
 2 files changed, 21 insertions(+)

Comments

Russell King (Oracle) March 27, 2023, 5:58 p.m. UTC | #1
On Mon, Mar 27, 2023 at 07:01:41PM +0200, Andrew Lunn wrote:
> The MAC driver can request that the PHY stops the clock during EEE
> LPI. This has normally been does as part of phy_init_eee(), however
> that function is overly complex and often wrongly used. Add a
> standalone helper, to aid removing phy_init_eee().
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Thanks!
Oleksij Rempel March 28, 2023, 5:03 a.m. UTC | #2
On Mon, Mar 27, 2023 at 07:01:41PM +0200, Andrew Lunn wrote:
> The MAC driver can request that the PHY stops the clock during EEE
> LPI. This has normally been does as part of phy_init_eee(), however
> that function is overly complex and often wrongly used. Add a
> standalone helper, to aid removing phy_init_eee().
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> v2: Add missing EXPORT_SYMBOL_GPL
> ---
>  drivers/net/phy/phy.c | 20 ++++++++++++++++++++
>  include/linux/phy.h   |  1 +
>  2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index 68e1ce942dd6..d3d6ff4ed488 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -1503,6 +1503,26 @@ void phy_mac_interrupt(struct phy_device *phydev)
>  }
>  EXPORT_SYMBOL(phy_mac_interrupt);
>  
> +/**
> + * phy_eee_clk_stop_enable - Clock should stop during LIP
> + * @phydev: target phy_device struct
> + *
> + * Description: Program the MMD register 3.0 setting the "Clock stop enable"
> + * bit.


> + */
> +int phy_eee_clk_stop_enable(struct phy_device *phydev)

this function should go to drivers/net/phy/phy-c45.c
and renamed to genphy_c45_eee_clk_stop_enable()
> +{
> +	int ret;
> +
> +	mutex_lock(&phydev->lock);

	/* IEEE 802.3-2018 45.2.3.1.4 Clock stop enable (3.0.10) */

> +	ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
> +			       MDIO_PCS_CTRL1_CLKSTOP_EN);

It would be better to write it conditionally. Only if EEE is supported
and only if this bit is supported as well. Support is indicated by the
IEEE 802.3:2018 - 45.2.3.2.6 Clock stop capable (3.1.6)

It looks like there are other registers for same functionality too but
other types of PHYs:
45.2.4.1.4 Clock stop enable (4.0.10)
45.2.4.2.6 Clock stop capable (4.1.6)
45.2.5.1.4 Clock stop enable (5.0.10)
45.2.5.2.6 Clock stop capable (5.1.6)

If I see it correctly, Clock-stop is possible only for GMII/RGMII.
Integrated PHYs or EEE capable PHYs with RMII do not support it.
For example KSZ8091RNA with RMII:
https://ww1.microchip.com/downloads/en/DeviceDoc/KSZ8091RNA-RND-10BASE-T-100BASE-TX-PHY-with-RMII-and-EEE-Support-DS00002298B.pdf
KSZ9477 switch with integrated PHYs:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/KSZ9477S-Data-Sheet-DS00002392C.pdf

> +	mutex_unlock(&phydev->lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(phy_eee_clk_stop_enable);
> +
>  /**
>   * phy_init_eee - init and check the EEE feature
>   * @phydev: target phy_device struct
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index 2508f1d99777..12addd1c29f2 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -1846,6 +1846,7 @@ int phy_unregister_fixup_for_id(const char *bus_id);
>  int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask);
>  
>  int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable);
> +int phy_eee_clk_stop_enable(struct phy_device *phydev);
>  int phy_get_eee_err(struct phy_device *phydev);
>  int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data);
>  int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data);
> -- 
> 2.39.2
> 
>
Oleksij Rempel March 28, 2023, 5:13 a.m. UTC | #3
On Tue, Mar 28, 2023 at 07:03:27AM +0200, Oleksij Rempel wrote:
> On Mon, Mar 27, 2023 at 07:01:41PM +0200, Andrew Lunn wrote:
> > The MAC driver can request that the PHY stops the clock during EEE
> > LPI. This has normally been does as part of phy_init_eee(), however
> > that function is overly complex and often wrongly used. Add a
> > standalone helper, to aid removing phy_init_eee().
> > 
> > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> > ---
> > v2: Add missing EXPORT_SYMBOL_GPL
> > ---
> >  drivers/net/phy/phy.c | 20 ++++++++++++++++++++
> >  include/linux/phy.h   |  1 +
> >  2 files changed, 21 insertions(+)
> > 
> > diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> > index 68e1ce942dd6..d3d6ff4ed488 100644
> > --- a/drivers/net/phy/phy.c
> > +++ b/drivers/net/phy/phy.c
> > @@ -1503,6 +1503,26 @@ void phy_mac_interrupt(struct phy_device *phydev)
> >  }
> >  EXPORT_SYMBOL(phy_mac_interrupt);
> >  
> > +/**
> > + * phy_eee_clk_stop_enable - Clock should stop during LIP
> > + * @phydev: target phy_device struct
> > + *
> > + * Description: Program the MMD register 3.0 setting the "Clock stop enable"
> > + * bit.
> 
> 
> > + */
> > +int phy_eee_clk_stop_enable(struct phy_device *phydev)
> 
> this function should go to drivers/net/phy/phy-c45.c
> and renamed to genphy_c45_eee_clk_stop_enable()
> > +{
> > +	int ret;
> > +
> > +	mutex_lock(&phydev->lock);
> 
> 	/* IEEE 802.3-2018 45.2.3.1.4 Clock stop enable (3.0.10) */
> 
> > +	ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
> > +			       MDIO_PCS_CTRL1_CLKSTOP_EN);
> 
> It would be better to write it conditionally. Only if EEE is supported
> and only if this bit is supported as well. Support is indicated by the
> IEEE 802.3:2018 - 45.2.3.2.6 Clock stop capable (3.1.6)
> 
> It looks like there are other registers for same functionality too but
> other types of PHYs:
> 45.2.4.1.4 Clock stop enable (4.0.10)
> 45.2.4.2.6 Clock stop capable (4.1.6)
> 45.2.5.1.4 Clock stop enable (5.0.10)
> 45.2.5.2.6 Clock stop capable (5.1.6)
> 
> If I see it correctly, Clock-stop is possible only for GMII/RGMII.
> Integrated PHYs or EEE capable PHYs with RMII do not support it.
> For example KSZ8091RNA with RMII:
> https://ww1.microchip.com/downloads/en/DeviceDoc/KSZ8091RNA-RND-10BASE-T-100BASE-TX-PHY-with-RMII-and-EEE-Support-DS00002298B.pdf
> KSZ9477 switch with integrated PHYs:
> https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/KSZ9477S-Data-Sheet-DS00002392C.pdf

One more PHY, with RGMII support, but without clock-stop, which is
probably indicated by 3.1.6 bit.
https://ww1.microchip.com/downloads/aemDocuments/documents/AERO/ProductDocuments/DataSheets/VSC8540ET_Extended_Temperature_Single_Port_Fast_Ethernet_Copper_PHY_DS60001648.pdf
Andrew Lunn March 28, 2023, 12:09 p.m. UTC | #4
> > + */
> > +int phy_eee_clk_stop_enable(struct phy_device *phydev)
> 
> this function should go to drivers/net/phy/phy-c45.c
> and renamed to genphy_c45_eee_clk_stop_enable()
> > +{
> > +	int ret;
> > +
> > +	mutex_lock(&phydev->lock);
> 
> 	/* IEEE 802.3-2018 45.2.3.1.4 Clock stop enable (3.0.10) */
> 
> > +	ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
> > +			       MDIO_PCS_CTRL1_CLKSTOP_EN);
> 
> It would be better to write it conditionally. Only if EEE is supported
> and only if this bit is supported as well. Support is indicated by the
> IEEE 802.3:2018 - 45.2.3.2.6 Clock stop capable (3.1.6)

O.K, i was too lazy. I just took the existing code in phy_eee_init()
and moved it here. I can rework it as requested.

> It looks like there are other registers for same functionality too but
> other types of PHYs:
> 45.2.4.1.4 Clock stop enable (4.0.10)
> 45.2.4.2.6 Clock stop capable (4.1.6)
> 45.2.5.1.4 Clock stop enable (5.0.10)
> 45.2.5.2.6 Clock stop capable (5.1.6)
> 
> If I see it correctly, Clock-stop is possible only for GMII/RGMII.
> Integrated PHYs or EEE capable PHYs with RMII do not support it.

For the existing code, it is up to the MAC to decide if the clock
should be stopped. It is not clear why, but we do see some MACs where
the DMA engine stops working when the clock is stopped. So i don't
want to be overly eager to stop clocks and introduce regressions.  So
i will keep with just one clock above. But make it conditional on the
capability.

	Andrew
diff mbox series

Patch

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 68e1ce942dd6..d3d6ff4ed488 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1503,6 +1503,26 @@  void phy_mac_interrupt(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_mac_interrupt);
 
+/**
+ * phy_eee_clk_stop_enable - Clock should stop during LIP
+ * @phydev: target phy_device struct
+ *
+ * Description: Program the MMD register 3.0 setting the "Clock stop enable"
+ * bit.
+ */
+int phy_eee_clk_stop_enable(struct phy_device *phydev)
+{
+	int ret;
+
+	mutex_lock(&phydev->lock);
+	ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
+			       MDIO_PCS_CTRL1_CLKSTOP_EN);
+	mutex_unlock(&phydev->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(phy_eee_clk_stop_enable);
+
 /**
  * phy_init_eee - init and check the EEE feature
  * @phydev: target phy_device struct
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 2508f1d99777..12addd1c29f2 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1846,6 +1846,7 @@  int phy_unregister_fixup_for_id(const char *bus_id);
 int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask);
 
 int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable);
+int phy_eee_clk_stop_enable(struct phy_device *phydev);
 int phy_get_eee_err(struct phy_device *phydev);
 int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data);
 int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data);