]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
net: phy: micrel_ksz90x1: disable asymmetric pause for KSZ9031 and KSZ9021
authorMarkus Niebel <Markus.Niebel@ew.tq-group.com>
Tue, 2 Dec 2025 08:13:42 +0000 (09:13 +0100)
committerJerome Forissier <jerome.forissier@arm.com>
Thu, 15 Jan 2026 10:09:28 +0000 (11:09 +0100)
Disable the support due to chip errata and call genphy_config_aneg
instead of genphy_config. For a complete describtion look at the
KSZ9031 errata sheets: DS80000691D or DS80000692D.

Micrel KSZ9021 has no errata, but has the same issue with Asymmetric Pause.
This patch apply the same workaround as the one for KSZ9031.

This follows linux implementation in commits
3aed3e2a143c ("net: phy: micrel: add Asym Pause workaround")
407d8098cb1a ("net: phy: micrel: add Asym Pause workaround for KSZ9021")

Signed-off-by: Markus Niebel <Markus.Niebel@ew.tq-group.com>
Signed-off-by: Max Merchel <Max.Merchel@ew.tq-group.com>
drivers/net/phy/micrel_ksz90x1.c

index a02dbe900b89acf9b816844619ac198657108ec7..a669a5789b916e6e6be0796dee91843182826477 100644 (file)
@@ -217,6 +217,31 @@ static int ksz9031_center_flp_timing(struct phy_device *phydev)
        return ret;
 }
 
+static void ksz90x1_workaround_asymmetric_pause(struct phy_device *phydev)
+{
+       u32 features = phydev->drv->features;
+
+       /* Silicon Errata Sheet (DS80000691D or DS80000692D):
+        * Whenever the device's Asymmetric Pause capability is set to 1,
+        * link-up may fail after a link-up to link-down transition.
+        *
+        * The Errata Sheet is for ksz9031, but ksz9021 has the same issue
+        *
+        * Workaround:
+        * Do not enable the Asymmetric Pause capability bit.
+        */
+       features &= ~ADVERTISE_PAUSE_ASYM;
+
+       /* We force setting the Pause capability as the core will force the
+        * Asymmetric Pause capability to 1 otherwise.
+        */
+       features |= ADVERTISE_PAUSE_CAP;
+
+       /* update feature support and forward to advertised features */
+       phydev->supported = features;
+       phydev->advertising = phydev->supported;
+}
+
 /*
  * KSZ9021
  */
@@ -260,6 +285,8 @@ static int ksz9021_config(struct phy_device *phydev)
        if (ret)
                return ret;
 
+       ksz90x1_workaround_asymmetric_pause(phydev);
+
        if (env_get("disable_giga"))
                features &= ~(SUPPORTED_1000baseT_Half |
                SUPPORTED_1000baseT_Full);
@@ -345,6 +372,8 @@ static int ksz9031_config(struct phy_device *phydev)
        if (ret)
                return ret;
 
+       ksz90x1_workaround_asymmetric_pause(phydev);
+
        /* add an option to disable the gigabit feature of this PHY */
        if (env_get("disable_giga")) {
                unsigned features;