When a network interface is brought down, the associated PHY is stopped. However, several link-specific parameters within the phy_device struct are not cleared. This leads to userspace tools like ethtool reporting stale information from the last active connection, which is misleading as the link is no longer active. For example, after running `ip link set dev lan2 down`, ethtool might show the following outdated information, indicating a 1000Mb/s Full duplex link with a link partner, even though the link is detected as down: # ethtool lan2 Settings for lan2: Supported ports: [ TP MII ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full ... Link partner advertised link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full ... Speed: 1000Mb/s Duplex: Full Auto-negotiation: on master-slave cfg: preferred master master-slave status: slave ... Link detected: no This patch fixes the issue by clearing all outdated link parameters within the `phy_link_down()` function. This seems to be the correct place to reset this data, as it is called whenever the link transitions to a down state. The following parameters are now reset: - Speed and duplex are set to UNKNOWN. - Link partner advertising information is zeroed out. - Master/slave state is set to UNKNOWN. - MDI-X status is set to INVALID. - EEE active status is set to false. Signed-off-by: Oleksij Rempel --- changes v2: - rebase and resned against net-next drivers/net/phy/phy.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 13df28445f02..6bdd49d93740 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -83,6 +83,16 @@ static void phy_link_down(struct phy_device *phydev) { phydev->phy_link_change(phydev, false); phy_led_trigger_change_speed(phydev); + + /* Clear the outdated link parameters */ + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + if (phydev->master_slave_state != MASTER_SLAVE_STATE_UNSUPPORTED) + phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN; + phydev->mdix = ETH_TP_MDI_INVALID; + linkmode_zero(phydev->lp_advertising); + phydev->eee_active = false; + WRITE_ONCE(phydev->link_down_events, phydev->link_down_events + 1); } -- 2.39.5