diff mbox series

[v3] net: phy: Provide Module 4 KSZ9477 errata (DS80000754C)

Message ID 20230831072527.537839-1-lukma@denx.de (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [v3] net: phy: Provide Module 4 KSZ9477 errata (DS80000754C) | expand

Checks

Context Check Description
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
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: 1369 this patch: 1369
netdev/cc_maintainers success CCed 16 of 16 maintainers
netdev/build_clang success Errors and warnings before: 1353 this patch: 1353
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 fail Problems with Fixes tag: 3
netdev/build_allmodconfig_warn success Errors and warnings before: 1392 this patch: 1392
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 56 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Lukasz Majewski Aug. 31, 2023, 7:25 a.m. UTC
The KSZ9477 errata points out (in 'Module 4') the link up/down problems
when EEE (Energy Efficient Ethernet) is enabled in the device to which
the KSZ9477 tries to auto negotiate.

The suggested workaround is to clear advertisement of EEE for PHYs in
this chip driver.

To avoid regressions with other switch ICs the new MICREL_NO_EEE flag
has been introduced.

Moreover, the in-register disablement of MMD_DEVICE_ID_EEE_ADV.MMD_EEE_ADV
MMD register is removed, as this code is both; now executed too late
(after previous rework of the PHY and DSA for KSZ switches) and not
required as setting all members of eee_broken_modes bit field prevents
the KSZ9477 from advertising EEE.

Fixes: 69d3b36ca045 ("net: dsa: microchip: enable EEE support") (for KSZ9477).

Signed-off-by: Lukasz Majewski <lukma@denx.de>

---
Changes for v2:
- Move this fix from clearing directly
  MMD_DEVICE_ID_EEE_ADV.MMD_EEE_ADV MMD register in KSZ DSA switch
  initialization to more generic solution in the micrel.c PHY driver

Changes for v3:
- Drop the rename patch
- Use MICREL_NO_EEE flag as suggested by Oleksij
- Extend the ksz9477_config_init to avoid regression
- Do not use the direct write to MMD 7.60 register - instead the
  phydev->eee_broken_modes is used
---
 drivers/net/dsa/microchip/ksz_common.c | 16 +++++++++++++++-
 drivers/net/phy/micrel.c               |  9 ++++++---
 include/linux/micrel_phy.h             |  1 +
 3 files changed, 22 insertions(+), 4 deletions(-)

Comments

Oleksij Rempel Aug. 31, 2023, 7:51 a.m. UTC | #1
On Thu, Aug 31, 2023 at 09:25:27AM +0200, Lukasz Majewski wrote:
> The KSZ9477 errata points out (in 'Module 4') the link up/down problems
> when EEE (Energy Efficient Ethernet) is enabled in the device to which
> the KSZ9477 tries to auto negotiate.
> 
> The suggested workaround is to clear advertisement of EEE for PHYs in
> this chip driver.
> 
> To avoid regressions with other switch ICs the new MICREL_NO_EEE flag
> has been introduced.
> 
> Moreover, the in-register disablement of MMD_DEVICE_ID_EEE_ADV.MMD_EEE_ADV
> MMD register is removed, as this code is both; now executed too late
> (after previous rework of the PHY and DSA for KSZ switches) and not
> required as setting all members of eee_broken_modes bit field prevents
> the KSZ9477 from advertising EEE.
> 
> Fixes: 69d3b36ca045 ("net: dsa: microchip: enable EEE support") (for KSZ9477).
> 
> Signed-off-by: Lukasz Majewski <lukma@denx.de>
 
Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>

Confirmed disabled EEE with oscilloscope.

Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
Russell King (Oracle) Aug. 31, 2023, 10:28 a.m. UTC | #2
On Thu, Aug 31, 2023 at 09:25:27AM +0200, Lukasz Majewski wrote:
> diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
> index 8bef1ab62bba..eed474fc7308 100644
> --- a/include/linux/micrel_phy.h
> +++ b/include/linux/micrel_phy.h
> @@ -44,6 +44,7 @@
>  #define MICREL_PHY_50MHZ_CLK	0x00000001
>  #define MICREL_PHY_FXEN		0x00000002
>  #define MICREL_KSZ8_P1_ERRATA	0x00000003
> +#define MICREL_NO_EEE	0x00000004

Erm... Maybe someone should clarify this... we have in the code the
following tests for these "flags":

	/* Support legacy board-file configuration */
	if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) {
	        priv->rmii_ref_clk_sel = true;
	        priv->rmii_ref_clk_sel_val = true;
	}

	/* Skip auto-negotiation in fiber mode */
	if (phydev->dev_flags & MICREL_PHY_FXEN) {
	        phydev->speed = SPEED_100;
	        return 0;
	}

	if (phydev->dev_flags & MICREL_KSZ8_P1_ERRATA)
		return -EOPNOTSUPP;

	/* According to KSZ9477 Errata DS80000754C (Module 4) all EEE modes
	 * in this switch shall be regarded as broken.
	 */
	if (phydev->dev_flags & MICREL_NO_EEE)
	        phydev->eee_broken_modes = -1;

Is it intentional that setting MICREL_PHY_50MHZ_CLK on its own also
activates the MICREL_KSZ8_P1_ERRATA and vice versa? Is it intentional
that setting MICREL_PHY_FXEN also activates MICREL_KSZ8_P1_ERRATA and
vice versa?

To me, this looks horribly broken, and this patch just perpetuates the
brokenness (but at least 0x4 doesn't overlap with the other flags.)

If it is intentional, then MICREL_KSZ8_P1_ERRATA should be defined to
make it explicit - in other words, as
(MICREL_PHY_FXEN|MICREL_PHY_50MHZ_CLK). If not, all these flags should
be defined using (1 << n) or BIT() to make it explicit that they're a
bit, and not just a hex number that gets incremented when the next flag
is added.

Thanks.
Oleksij Rempel Aug. 31, 2023, 10:37 a.m. UTC | #3
On Thu, Aug 31, 2023 at 11:28:00AM +0100, Russell King (Oracle) wrote:
> On Thu, Aug 31, 2023 at 09:25:27AM +0200, Lukasz Majewski wrote:
> > diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
> > index 8bef1ab62bba..eed474fc7308 100644
> > --- a/include/linux/micrel_phy.h
> > +++ b/include/linux/micrel_phy.h
> > @@ -44,6 +44,7 @@
> >  #define MICREL_PHY_50MHZ_CLK	0x00000001
> >  #define MICREL_PHY_FXEN		0x00000002
> >  #define MICREL_KSZ8_P1_ERRATA	0x00000003
> > +#define MICREL_NO_EEE	0x00000004
> 
> Erm... Maybe someone should clarify this... we have in the code the
> following tests for these "flags":
> 
> 	/* Support legacy board-file configuration */
> 	if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) {
> 	        priv->rmii_ref_clk_sel = true;
> 	        priv->rmii_ref_clk_sel_val = true;
> 	}
> 
> 	/* Skip auto-negotiation in fiber mode */
> 	if (phydev->dev_flags & MICREL_PHY_FXEN) {
> 	        phydev->speed = SPEED_100;
> 	        return 0;
> 	}
> 
> 	if (phydev->dev_flags & MICREL_KSZ8_P1_ERRATA)
> 		return -EOPNOTSUPP;
> 
> 	/* According to KSZ9477 Errata DS80000754C (Module 4) all EEE modes
> 	 * in this switch shall be regarded as broken.
> 	 */
> 	if (phydev->dev_flags & MICREL_NO_EEE)
> 	        phydev->eee_broken_modes = -1;
> 
> Is it intentional that setting MICREL_PHY_50MHZ_CLK on its own also
> activates the MICREL_KSZ8_P1_ERRATA and vice versa? Is it intentional
> that setting MICREL_PHY_FXEN also activates MICREL_KSZ8_P1_ERRATA and
> vice versa?
> 
> To me, this looks horribly broken, and this patch just perpetuates the
> brokenness (but at least 0x4 doesn't overlap with the other flags.)
> 
> If it is intentional, then MICREL_KSZ8_P1_ERRATA should be defined to
> make it explicit - in other words, as
> (MICREL_PHY_FXEN|MICREL_PHY_50MHZ_CLK). If not, all these flags should
> be defined using (1 << n) or BIT() to make it explicit that they're a
> bit, and not just a hex number that gets incremented when the next flag
> is added.

Indeed, it is broken. I'll send a fix for this one.
MICREL_KSZ8_P1_ERRATA should be BIT(3)
and MICREL_NO_EEE BIT(4)

Thx!

Regards,
Oleksij
diff mbox series

Patch

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 6c0623f88654..d9d843efd111 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -2337,13 +2337,27 @@  static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port)
 {
 	struct ksz_device *dev = ds->priv;
 
-	if (dev->chip_id == KSZ8830_CHIP_ID) {
+	switch (dev->chip_id) {
+	case KSZ8830_CHIP_ID:
 		/* Silicon Errata Sheet (DS80000830A):
 		 * Port 1 does not work with LinkMD Cable-Testing.
 		 * Port 1 does not respond to received PAUSE control frames.
 		 */
 		if (!port)
 			return MICREL_KSZ8_P1_ERRATA;
+		break;
+	case KSZ9477_CHIP_ID:
+		/* KSZ9477 Errata DS80000754C
+		 *
+		 * Module 4: Energy Efficient Ethernet (EEE) feature select must
+		 * be manually disabled
+		 *   The EEE feature is enabled by default, but it is not fully
+		 *   operational. It must be manually disabled through register
+		 *   controls. If not disabled, the PHY ports can auto-negotiate
+		 *   to enable EEE, and this feature can cause link drops when
+		 *   linked to another device supporting EEE.
+		 */
+		return MICREL_NO_EEE;
 	}
 
 	return 0;
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index b6d7981b2d1e..927d3d54658e 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -1800,9 +1800,6 @@  static const struct ksz9477_errata_write ksz9477_errata_writes[] = {
 	/* Transmit waveform amplitude can be improved (1000BASE-T, 100BASE-TX, 10BASE-Te) */
 	{0x1c, 0x04, 0x00d0},
 
-	/* Energy Efficient Ethernet (EEE) feature select must be manually disabled */
-	{0x07, 0x3c, 0x0000},
-
 	/* Register settings are required to meet data sheet supply current specifications */
 	{0x1c, 0x13, 0x6eff},
 	{0x1c, 0x14, 0xe6ff},
@@ -1847,6 +1844,12 @@  static int ksz9477_config_init(struct phy_device *phydev)
 			return err;
 	}
 
+	/* According to KSZ9477 Errata DS80000754C (Module 4) all EEE modes
+	 * in this switch shall be regarded as broken.
+	 */
+	if (phydev->dev_flags & MICREL_NO_EEE)
+		phydev->eee_broken_modes = -1;
+
 	err = genphy_restart_aneg(phydev);
 	if (err)
 		return err;
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index 8bef1ab62bba..eed474fc7308 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -44,6 +44,7 @@ 
 #define MICREL_PHY_50MHZ_CLK	0x00000001
 #define MICREL_PHY_FXEN		0x00000002
 #define MICREL_KSZ8_P1_ERRATA	0x00000003
+#define MICREL_NO_EEE	0x00000004
 
 #define MICREL_KSZ9021_EXTREG_CTRL	0xB
 #define MICREL_KSZ9021_EXTREG_DATA_WRITE	0xC