From 621a26e5dd385e1fd89b2e41f582ccfa1db565cf Mon Sep 17 00:00:00 2001 From: Jan Sondhauss Date: Thu, 23 Oct 2025 12:55:00 +0200 Subject: [PATCH] net: phy: phy_device: repeat reading of the phy-state when state is down This attempts to work around an issue where there is a spurious link down detected Signed-off-by: Jan Sondhauss --- drivers/net/phy/phy_device.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 92c62864b07d..707cd28202a3 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -2343,12 +2343,13 @@ EXPORT_SYMBOL(genphy_aneg_done); */ int genphy_update_link(struct phy_device *phydev) { - int status = 0, bmcr; + int status = 0, bmcr, i; bmcr = phy_read(phydev, MII_BMCR); if (bmcr < 0) return bmcr; + /* Autoneg is being started, therefore disregard BMSR value and * report link as down. */ @@ -2369,9 +2370,19 @@ int genphy_update_link(struct phy_device *phydev) } /* Read link and autonegotiation status */ - status = phy_read(phydev, MII_BMSR); - if (status < 0) - return status; + for (i = 0; i < 20; i++) { + status = phy_read(phydev, MII_BMSR); + if (status < 0) + return status; + + if (status & BMSR_LSTATUS) + break; + + cpu_relax(); + } + if (status & BMSR_LSTATUS) + if (i >= 1) + phydev_info(phydev, "link up after multiple reads: %di\n", i); done: phydev->link = status & BMSR_LSTATUS ? 1 : 0; phydev->autoneg_complete = status & BMSR_ANEGCOMPLETE ? 1 : 0;