net: dsa: mv88e6xxx: use BMSR_ANEGCOMPLETE bit for filling an_complete
authorMarek Behún <kabel@kernel.org>
Tue, 7 Jun 2022 11:28:42 +0000 (12:28 +0100)
committerJakub Kicinski <kuba@kernel.org>
Thu, 9 Jun 2022 03:58:30 +0000 (20:58 -0700)
Commit ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN
is bypassed") added the ability to link if AN was bypassed, and added
filling of state->an_complete field, but set it to true if AN was
enabled in BMCR, not when AN was reported complete in BMSR.

This was done because for some reason, when I wanted to use BMSR value
to infer an_complete, I was looking at BMSR_ANEGCAPABLE bit (which was
always 1), instead of BMSR_ANEGCOMPLETE bit.

Use BMSR_ANEGCOMPLETE for filling state->an_complete.

Fixes: ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed")
Signed-off-by: Marek Behún <kabel@kernel.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/dsa/mv88e6xxx/serdes.c

index 7b37d45bc9fb52c1f580b9efa7ce5b67fe149163..1a19c5284f2cb2e42c52a617835d1fda9e3efece 100644 (file)
@@ -50,22 +50,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
 }
 
 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
-                                         u16 ctrl, u16 status, u16 lpa,
+                                         u16 bmsr, u16 lpa, u16 status,
                                          struct phylink_link_state *state)
 {
        state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
+       state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
 
        if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
                /* The Spped and Duplex Resolved register is 1 if AN is enabled
                 * and complete, or if AN is disabled. So with disabled AN we
-                * still get here on link up. But we want to set an_complete
-                * only if AN was enabled, thus we look at BMCR_ANENABLE.
-                * (According to 802.3-2008 section 22.2.4.2.10, we should be
-                *  able to get this same value from BMSR_ANEGCAPABLE, but tests
-                *  show that these Marvell PHYs don't conform to this part of
-                *  the specificaion - BMSR_ANEGCAPABLE is simply always 1.)
+                * still get here on link up.
                 */
-               state->an_complete = !!(ctrl & BMCR_ANENABLE);
                state->duplex = status &
                                MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
                                                 DUPLEX_FULL : DUPLEX_HALF;
@@ -191,12 +186,12 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
                                   int lane, struct phylink_link_state *state)
 {
-       u16 lpa, status, ctrl;
+       u16 bmsr, lpa, status;
        int err;
 
-       err = mv88e6352_serdes_read(chip, MII_BMCR, &ctrl);
+       err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
        if (err) {
-               dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
+               dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
                return err;
        }
 
@@ -212,7 +207,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
                return err;
        }
 
-       return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
+       return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
 }
 
 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
@@ -918,13 +913,13 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
        int port, int lane, struct phylink_link_state *state)
 {
-       u16 lpa, status, ctrl;
+       u16 bmsr, lpa, status;
        int err;
 
        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
-                                   MV88E6390_SGMII_BMCR, &ctrl);
+                                   MV88E6390_SGMII_BMSR, &bmsr);
        if (err) {
-               dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
+               dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
                return err;
        }
 
@@ -942,7 +937,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
                return err;
        }
 
-       return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
+       return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
 }
 
 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,