[RFC PATCH v1 9/9] net: phy: micrel: add patch for erratas on port1
From: Oleksij Rempel <o.rempel@pengutronix.de>
Date: 2021-05-05 09:22:46
Also in:
lkml
Subsystem:
ethernet phy library, microchip ksz series ethernet switch driver, networking drivers, networking [dsa], networking [general], sff/sfp/sfp+ module support, the rest · Maintainers:
Andrew Lunn, Heiner Kallweit, Woojung Huh, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Russell King, Linus Torvalds
From: Michael Grzeschik <redacted> The micrel switch ksz8873 has the following errata [1]: * Module 1: LinkMD does not work on Port 1 * Module 4: Port 1 does not respond to received flow control PAUSE frames This patch disables the support on the defective port. [1] http://ww1.microchip.com/downloads/en/DeviceDoc/KSZ8873-Errata-DS80000830A.pdf Signed-off-by: Michael Grzeschik <redacted> --- drivers/net/dsa/microchip/ksz8795.c | 13 +++++++++++++ drivers/net/phy/micrel.c | 3 +++ drivers/net/phy/phylink.c | 2 +- include/linux/micrel_phy.h | 1 + net/dsa/slave.c | 4 ++++ 5 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c
index fb47be0c2154..42b7ef36f24f 100644
--- a/drivers/net/dsa/microchip/ksz8795.c
+++ b/drivers/net/dsa/microchip/ksz8795.c@@ -966,6 +966,18 @@ static enum dsa_tag_protocol ksz8_get_tag_protocol(struct dsa_switch *ds, DSA_TAG_PROTO_KSZ9893 : DSA_TAG_PROTO_KSZ8795; } +static u32 ksz8_sw_get_phy_flags(struct dsa_switch *ds, int port) +{ + /* 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; + + return 0; +} + static void ksz8_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *buf) {
@@ -1516,6 +1528,7 @@ static void ksz_validate(struct dsa_switch *ds, int port, static const struct dsa_switch_ops ksz8_switch_ops = { .get_tag_protocol = ksz8_get_tag_protocol, + .get_phy_flags = ksz8_sw_get_phy_flags, .setup = ksz8_setup, .phy_read = ksz_phy_read16, .phy_write = ksz_phy_write16,
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index f0ca7b53bcf9..dbdc0926386e 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c@@ -1414,6 +1414,9 @@ static int kszphy_probe(struct phy_device *phydev) static int ksz886x_cable_test_start(struct phy_device *phydev) { + if (phydev->dev_flags & MICREL_KSZ8_P1_ERRATA) + return -ENOTSUPP; + /* If autoneg is enabled, we won't be able to test cross pair * short. In this case, the PHY will "detect" a link and * confuse the internal state machine - disable auto neg here.
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 96d8e88b4e46..167c2277814f 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c@@ -1029,7 +1029,7 @@ static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, if (pl->phydev) return -EBUSY; - return phy_attach_direct(pl->netdev, phy, 0, interface); + return phy_attach_direct(pl->netdev, phy, phy->dev_flags, interface); } /**
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index ee23acc4d551..0117a2c126eb 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h@@ -39,6 +39,7 @@ /* struct phy_device dev_flags definitions */ #define MICREL_PHY_50MHZ_CLK 0x00000001 #define MICREL_PHY_FXEN 0x00000002 +#define MICREL_KSZ8_P1_ERRATA 0x00000003 #define MICREL_KSZ9021_EXTREG_CTRL 0xB #define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 8c0f3c6ab365..7e208f16f006 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c@@ -1758,6 +1758,10 @@ static int dsa_slave_phy_connect(struct net_device *slave_dev, int addr) return -ENODEV; } + if (ds->ops->get_phy_flags) + slave_dev->phydev->dev_flags |= + ds->ops->get_phy_flags(ds, dp->index); + return phylink_connect_phy(dp->pl, slave_dev->phydev); }
--
2.29.2