Re: [PATCH 3/3] net: dsa: microchip: implement KSZ87xx Module 3 low-loss cable errata

From: Marek Vasut

Date: Thu Mar 26 2026 - 08:39:37 EST


On 3/26/26 10:10 AM, Fidelio Lawson wrote:

+static int ksz8_handle_module3_errata(struct ksz_device *dev)
+{
+ int ret = 0;
+ const u16 *regs = dev->info->regs;
+ u16 indir_reg = 0x0000;
+ u8 indir_val = 0x00;
+
+ switch (dev->low_loss_wa_mode) {
+ case KSZ_LOW_LOSS_WA_1:
+ indir_reg = 0x3C;
+ indir_val = 0x15;
+ break;
+ case KSZ_LOW_LOSS_WA_2:
+ indir_reg = 0x4C;
+ indir_val = 0x40;
+ break;
+ default:
+ break;
+ }
+
+ mutex_lock(&dev->alu_mutex);
+
+ ret = ksz_write8(dev, regs[REG_IND_CTRL_0], 0xA0);
+
+ if (!ret)
+ ret = ksz_write8(dev, 0x6F, indir_reg);
+
+ if (!ret)
+ ret = ksz_write8(dev, regs[REG_IND_BYTE], indir_val);
+
+ mutex_unlock(&dev->alu_mutex);
+
+ return ret;
+}
Since this is configurable from DT, please adjust the bindings and make the low pass filter bandwidth actually configurable according to the values supported by the hardware, see this article:

https://microchip.my.site.com/s/article/Solution-for-Using-CAT-5E-or-CAT-6-Short-Cable-with-a-Link-Issue-for-the-KSZ8795-Family

The indirect register (0x4C) is an 8-bit register. The bits [7:6] are described in the table below.

Low pass filter bandwidth
00 = 90MHz
01 = 62MHz
10 = 55MHz
11 = 44MHz

...

I had this attached patch in my tree for a while, I just never got around to finishing it, because even with this in place, there was some packet loss with short cables at low temperatures. Maybe it can help:

From 937278ee6dc0aa46797cc4b2d53078f95b6557a9 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@xxxxxxxxxxxx>
Date: Mon, 2 Jun 2025 01:42:17 +0200
Subject: [PATCH] net: dsa: microchip: Fix KSZ87xx high quality cable errata
module 3

KSZ87xx may fail to establish link, or may take long time to
establish link, when using high quality > CAT-5 ethernet cables.
This is described in KSZ87xx Errata DS80000687C Module 3:

Module 3: Establishing a link through low loss connections.
The receiver of the embedded PHYs is tuned by default to
support long cable length applications. This was developed
using low quality, high loss cables. Because of this, the
equalizer in the PHY may amplify high amplitude receiver
signals to the point that the signal is distorted internally,
preventing a link from being established.

More detailed description and a more advanced fix is described in
"
Solution for Using CAT-5E or CAT-6 Short Cable with a Link Issue
for the KSZ8795 Family
"
https://microchip.my.site.com/s/article/Solution-for-Using-CAT-5E-or-CAT-6-Short-Cable-with-a-Link-Issue-for-the-KSZ8795-Family

The fix reduces low pass filter bandwidth from 90 MHz to 62 MHz
to block higher frequency components which make it through the
higher quality cables and saturate the receiver amplifier. In
case of even shorter cables, the link equalizer function has to
start from position 0 instead of the default position 0xf to
cater for those cables, configure the equalizer position as well.

Signed-off-by: Marek Vasut <marex@xxxxxxxxxxxx>
---
drivers/net/dsa/microchip/ksz8.c | 33 ++++++++++++++++++++++++++--
drivers/net/dsa/microchip/ksz8_reg.h | 2 +-
2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index 3309c2c172f02..f8716c8d0d375 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -1891,10 +1891,39 @@ static int ksz8_handle_global_errata(struct dsa_switch *ds)
* KSZ879x/KSZ877x/KSZ876x and some EEE link partners may result in
* the link dropping.
*/
- if (dev->info->ksz87xx_eee_link_erratum)
+ if (dev->info->ksz87xx_eee_link_erratum) {
ret = ksz8_ind_write8(dev, TABLE_EEE, REG_IND_EEE_GLOB2_HI, 0);
+ if (ret)
+ return ret;
+ }

- return ret;
+ /*
+ * Module 3: Establishing a link through low loss connections.
+ * The receiver of the embedded PHYs is tuned by default to
+ * support long cable length applications. This was developed
+ * using low quality, high loss cables. Because of this, the
+ * equalizer in the PHY may amplify high amplitude receiver
+ * signals to the point that the signal is distorted internally,
+ * preventing a link from being established.
+ *
+ * More detailed description and a more advanced fix is described in
+ * "
+ * Solution for Using CAT-5E or CAT-6 Short Cable with a Link Issue
+ * for the KSZ8795 Family
+ * "
+ * https://microchip.my.site.com/s/article/Solution-for-Using-CAT-5E-or-CAT-6-Short-Cable-with-a-Link-Issue-for-the-KSZ8795-Family
+ *
+ * The following two magic writes are the implementation of the
+ * aforementioned workaround.
+ */
+
+ /* Force low pass filter bandwidth from 90 MHz to 62 MHz */
+ ret = ksz8_ind_write8(dev, TABLE_LINK_MD, 0x4c, 0x40);
+ if (ret)
+ return ret;
+
+ /* Force DSP EQ initial value to 0 */
+ return ksz8_ind_write8(dev, TABLE_LINK_MD, 0x08, 0);
}

int ksz8_enable_stp_addr(struct ksz_device *dev)
diff --git a/drivers/net/dsa/microchip/ksz8_reg.h b/drivers/net/dsa/microchip/ksz8_reg.h
index 329688603a582..c4897f27c6d1c 100644
--- a/drivers/net/dsa/microchip/ksz8_reg.h
+++ b/drivers/net/dsa/microchip/ksz8_reg.h
@@ -342,7 +342,7 @@
#define TABLE_EEE (TABLE_EEE_V << TABLE_EXT_SELECT_S)
#define TABLE_ACL (TABLE_ACL_V << TABLE_EXT_SELECT_S)
#define TABLE_PME (TABLE_PME_V << TABLE_EXT_SELECT_S)
-#define TABLE_LINK_MD (TABLE_LINK_MD << TABLE_EXT_SELECT_S)
+#define TABLE_LINK_MD (TABLE_LINK_MD_V << TABLE_EXT_SELECT_S)
#define TABLE_READ BIT(4)
#define TABLE_SELECT_S 2
#define TABLE_STATIC_MAC_V 0
--
2.53.0
From 937278ee6dc0aa46797cc4b2d53078f95b6557a9 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@xxxxxxxxxxxx>
Date: Mon, 2 Jun 2025 01:42:17 +0200
Subject: [PATCH] net: dsa: microchip: Fix KSZ87xx high quality cable errata
module 3

KSZ87xx may fail to establish link, or may take long time to
establish link, when using high quality > CAT-5 ethernet cables.
This is described in KSZ87xx Errata DS80000687C Module 3:

Module 3: Establishing a link through low loss connections.
The receiver of the embedded PHYs is tuned by default to
support long cable length applications. This was developed
using low quality, high loss cables. Because of this, the
equalizer in the PHY may amplify high amplitude receiver
signals to the point that the signal is distorted internally,
preventing a link from being established.

More detailed description and a more advanced fix is described in
"
Solution for Using CAT-5E or CAT-6 Short Cable with a Link Issue
for the KSZ8795 Family
"
https://microchip.my.site.com/s/article/Solution-for-Using-CAT-5E-or-CAT-6-Short-Cable-with-a-Link-Issue-for-the-KSZ8795-Family

The fix reduces low pass filter bandwidth from 90 MHz to 62 MHz
to block higher frequency components which make it through the
higher quality cables and saturate the receiver amplifier. In
case of even shorter cables, the link equalizer function has to
start from position 0 instead of the default position 0xf to
cater for those cables, configure the equalizer position as well.

Signed-off-by: Marek Vasut <marex@xxxxxxxxxxxx>
---
drivers/net/dsa/microchip/ksz8.c | 33 ++++++++++++++++++++++++++--
drivers/net/dsa/microchip/ksz8_reg.h | 2 +-
2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index 3309c2c172f02..f8716c8d0d375 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -1891,10 +1891,39 @@ static int ksz8_handle_global_errata(struct dsa_switch *ds)
* KSZ879x/KSZ877x/KSZ876x and some EEE link partners may result in
* the link dropping.
*/
- if (dev->info->ksz87xx_eee_link_erratum)
+ if (dev->info->ksz87xx_eee_link_erratum) {
ret = ksz8_ind_write8(dev, TABLE_EEE, REG_IND_EEE_GLOB2_HI, 0);
+ if (ret)
+ return ret;
+ }

- return ret;
+ /*
+ * Module 3: Establishing a link through low loss connections.
+ * The receiver of the embedded PHYs is tuned by default to
+ * support long cable length applications. This was developed
+ * using low quality, high loss cables. Because of this, the
+ * equalizer in the PHY may amplify high amplitude receiver
+ * signals to the point that the signal is distorted internally,
+ * preventing a link from being established.
+ *
+ * More detailed description and a more advanced fix is described in
+ * "
+ * Solution for Using CAT-5E or CAT-6 Short Cable with a Link Issue
+ * for the KSZ8795 Family
+ * "
+ * https://microchip.my.site.com/s/article/Solution-for-Using-CAT-5E-or-CAT-6-Short-Cable-with-a-Link-Issue-for-the-KSZ8795-Family
+ *
+ * The following two magic writes are the implementation of the
+ * aforementioned workaround.
+ */
+
+ /* Force low pass filter bandwidth from 90 MHz to 62 MHz */
+ ret = ksz8_ind_write8(dev, TABLE_LINK_MD, 0x4c, 0x40);
+ if (ret)
+ return ret;
+
+ /* Force DSP EQ initial value to 0 */
+ return ksz8_ind_write8(dev, TABLE_LINK_MD, 0x08, 0);
}

int ksz8_enable_stp_addr(struct ksz_device *dev)
diff --git a/drivers/net/dsa/microchip/ksz8_reg.h b/drivers/net/dsa/microchip/ksz8_reg.h
index 329688603a582..c4897f27c6d1c 100644
--- a/drivers/net/dsa/microchip/ksz8_reg.h
+++ b/drivers/net/dsa/microchip/ksz8_reg.h
@@ -342,7 +342,7 @@
#define TABLE_EEE (TABLE_EEE_V << TABLE_EXT_SELECT_S)
#define TABLE_ACL (TABLE_ACL_V << TABLE_EXT_SELECT_S)
#define TABLE_PME (TABLE_PME_V << TABLE_EXT_SELECT_S)
-#define TABLE_LINK_MD (TABLE_LINK_MD << TABLE_EXT_SELECT_S)
+#define TABLE_LINK_MD (TABLE_LINK_MD_V << TABLE_EXT_SELECT_S)
#define TABLE_READ BIT(4)
#define TABLE_SELECT_S 2
#define TABLE_STATIC_MAC_V 0
--
2.53.0