net: dsa: mv88e6xxx: use BMSR_ANEGCOMPLETE bit for filling an_complete
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>
This commit is contained in:
committed by
Jakub Kicinski
parent
11ec18b1d8
commit
47e96930d6
@ -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,
|
||||
|
Reference in New Issue
Block a user