Skip to content

Commit d2fd719

Browse files
natesullydavem330
authored andcommitted
net/phy: micrel: Add workaround for bad autoneg
Very rarely, the KSZ9031 will appear to complete autonegotiation, but will drop all traffic afterwards. When this happens, the idle error count will read 0xFF after autonegotiation completes. Reset the PHY when in that state. Signed-off-by: Nathan Sullivan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ec3661b commit d2fd719

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

drivers/net/phy/micrel.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,27 @@ static int ksz8873mll_read_status(struct phy_device *phydev)
514514
return 0;
515515
}
516516

517+
static int ksz9031_read_status(struct phy_device *phydev)
518+
{
519+
int err;
520+
int regval;
521+
522+
err = genphy_read_status(phydev);
523+
if (err)
524+
return err;
525+
526+
/* Make sure the PHY is not broken. Read idle error count,
527+
* and reset the PHY if it is maxed out.
528+
*/
529+
regval = phy_read(phydev, MII_STAT1000);
530+
if ((regval & 0xFF) == 0xFF) {
531+
phy_init_hw(phydev);
532+
phydev->link = 0;
533+
}
534+
535+
return 0;
536+
}
537+
517538
static int ksz8873mll_config_aneg(struct phy_device *phydev)
518539
{
519540
return 0;
@@ -772,7 +793,7 @@ static struct phy_driver ksphy_driver[] = {
772793
.driver_data = &ksz9021_type,
773794
.config_init = ksz9031_config_init,
774795
.config_aneg = genphy_config_aneg,
775-
.read_status = genphy_read_status,
796+
.read_status = ksz9031_read_status,
776797
.ack_interrupt = kszphy_ack_interrupt,
777798
.config_intr = kszphy_config_intr,
778799
.suspend = genphy_suspend,

0 commit comments

Comments
 (0)