Merge tag 'cxl-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
[platform/kernel/linux-starfive.git] / drivers / net / phy / marvell.c
index 2702faf..d777c88 100644 (file)
@@ -961,7 +961,21 @@ static int m88e1111_config_init(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       return genphy_soft_reset(phydev);
+       err = genphy_soft_reset(phydev);
+       if (err < 0)
+               return err;
+
+       if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
+               /* If the HWCFG_MODE was changed from another mode (such as
+                * 1000BaseX) to SGMII, the state of the support bits may have
+                * also changed now that the PHY has been reset.
+                * Update the PHY abilities accordingly.
+                */
+               err = genphy_read_abilities(phydev);
+               linkmode_or(phydev->advertising, phydev->advertising,
+                           phydev->supported);
+       }
+       return err;
 }
 
 static int m88e1111_get_downshift(struct phy_device *phydev, u8 *data)
@@ -1177,7 +1191,44 @@ static int m88e1318_config_init(struct phy_device *phydev)
 
 static int m88e1510_config_init(struct phy_device *phydev)
 {
+       static const struct {
+               u16 reg17, reg16;
+       } errata_vals[] = {
+               { 0x214b, 0x2144 },
+               { 0x0c28, 0x2146 },
+               { 0xb233, 0x214d },
+               { 0xcc0c, 0x2159 },
+       };
        int err;
+       int i;
+
+       /* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512/
+        * 88E1514 Rev A0, Errata Section 5.1:
+        * If EEE is intended to be used, the following register writes
+        * must be done once after every hardware reset.
+        */
+       err = marvell_set_page(phydev, 0x00FF);
+       if (err < 0)
+               return err;
+
+       for (i = 0; i < ARRAY_SIZE(errata_vals); ++i) {
+               err = phy_write(phydev, 17, errata_vals[i].reg17);
+               if (err)
+                       return err;
+               err = phy_write(phydev, 16, errata_vals[i].reg16);
+               if (err)
+                       return err;
+       }
+
+       err = marvell_set_page(phydev, 0x00FB);
+       if (err < 0)
+               return err;
+       err = phy_write(phydev, 07, 0xC00D);
+       if (err < 0)
+               return err;
+       err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
+       if (err < 0)
+               return err;
 
        /* SGMII-to-Copper mode initialization */
        if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {