summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2022-01-11 12:07:23 +0000
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2022-01-18 10:17:09 +0000
commitdac82e4b99b6e496e44709945e280af792b918e9 (patch)
tree216d34bed0a0ae1365aa4666729c200f8da3090c /drivers
parent94876bfc95688ce7f9197eda96350902b7d40c22 (diff)
net: dsa: mv88e6xxx: update 88e6390 workaround
Add a modify() helper, and use this to deal with the work around for the 88e6390, including powering the Serdes PHY down. This is necessary as we will be removing the serdes_power implementation in a later patch. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index 2c1707af082a..1f6ce4cc5520 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -49,6 +49,22 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
}
+static int mv88e6390_serdes_modify(struct mv88e6xxx_chip *chip, int lane,
+ int device, int reg, u16 mask, u16 set)
+{
+ int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
+ int err;
+ u16 val;
+
+ err = mv88e6xxx_phy_read(chip, lane, reg_c45, &val);
+ if (err)
+ return err;
+
+ val = (val & ~mask) | set;
+
+ return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
+}
+
static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
u16 bmsr, u16 lpa, u16 status,
struct phylink_link_state *state)
@@ -1340,7 +1356,6 @@ static int mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip *chip, int lane,
static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane)
{
- u16 reg;
int err;
/* mv88e6393x family errata 4.6:
@@ -1351,20 +1366,17 @@ static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane)
* It seems that after this workaround the SERDES is automatically
* powered up (the bit is cleared), so power it down.
*/
- err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
- MV88E6393X_SERDES_POC, &reg);
+ err = mv88e6390_serdes_modify(chip, lane, MDIO_MMD_PHYXS,
+ MV88E6393X_SERDES_POC,
+ MV88E6393X_SERDES_POC_PDOWN |
+ MV88E6393X_SERDES_POC_RESET,
+ MV88E6393X_SERDES_POC_RESET);
if (err)
return err;
- reg &= ~MV88E6393X_SERDES_POC_PDOWN;
- reg |= MV88E6393X_SERDES_POC_RESET;
-
- err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
- MV88E6393X_SERDES_POC, reg);
- if (err)
- return err;
-
- err = mv88e6390_serdes_power_sgmii(chip, lane, false);
+ err = mv88e6390_serdes_modify(chip, lane, MDIO_MMD_PHYXS,
+ MV88E6390_SGMII_BMCR,
+ BMCR_PDOWN, BMCR_PDOWN);
if (err)
return err;