Skip to content

Commit 7e0e624

Browse files
Russell Kingdavem330
authored andcommitted
net: dsa: mv88e6xxx: fix Serdes link changes
phylink_mac_change() is supposed to be called with a 'false' argument if the link has gone down since it was last reported up; this is to ensure that link events along with renegotiation events are always correctly reported to userspace. Read the BMSR once when we have an interrupt, and report the link latched status to phylink via phylink_mac_change(). phylink will deal automatically with re-reading the link state once it has processed the link-down event. Signed-off-by: Russell King <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a5a6858 commit 7e0e624

File tree

2 files changed

+13
-21
lines changed

2 files changed

+13
-21
lines changed

drivers/net/dsa/mv88e6xxx/serdes.c

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -340,26 +340,17 @@ int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
340340

341341
static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
342342
{
343-
struct dsa_switch *ds = chip->ds;
344-
u16 status;
345-
bool up;
343+
u16 bmsr;
346344
int err;
347345

348-
err = mv88e6352_serdes_read(chip, MII_BMSR, &status);
349-
if (err)
350-
return;
351-
352-
/* Status must be read twice in order to give the current link
353-
* status. Otherwise the change in link status since the last
354-
* read of the register is returned.
355-
*/
356-
err = mv88e6352_serdes_read(chip, MII_BMSR, &status);
357-
if (err)
346+
/* If the link has dropped, we want to know about it. */
347+
err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
348+
if (err) {
349+
dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
358350
return;
351+
}
359352

360-
up = status & BMSR_LSTATUS;
361-
362-
dsa_port_phylink_mac_change(ds, port, up);
353+
dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
363354
}
364355

365356
irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
@@ -833,18 +824,18 @@ int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
833824
static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
834825
int port, u8 lane)
835826
{
836-
u16 status;
827+
u16 bmsr;
837828
int err;
838829

830+
/* If the link has dropped, we want to know about it. */
839831
err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
840-
MV88E6390_SGMII_PHY_STATUS, &status);
832+
MV88E6390_SGMII_BMSR, &bmsr);
841833
if (err) {
842-
dev_err(chip->dev, "can't read SGMII PHY status: %d\n", err);
834+
dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
843835
return;
844836
}
845837

846-
dsa_port_phylink_mac_change(chip->ds, port,
847-
!!(status & MV88E6390_SGMII_PHY_STATUS_LINK));
838+
dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
848839
}
849840

850841
static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,

drivers/net/dsa/mv88e6xxx/serdes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
/* 1000BASE-X and SGMII */
5050
#define MV88E6390_SGMII_BMCR (0x2000 + MII_BMCR)
51+
#define MV88E6390_SGMII_BMSR (0x2000 + MII_BMSR)
5152
#define MV88E6390_SGMII_ADVERTISE (0x2000 + MII_ADVERTISE)
5253
#define MV88E6390_SGMII_LPA (0x2000 + MII_LPA)
5354
#define MV88E6390_SGMII_INT_ENABLE 0xa001

0 commit comments

Comments
 (0)