Commit 3de5ae54 authored by Yonglong Liu's avatar Yonglong Liu Committed by David S. Miller

net: phy: Fix "link partner" information disappear issue

Some drivers just call phy_ethtool_ksettings_set() to set the
links, for those phy drivers that use genphy_read_status(), if
autoneg is on, and the link is up, than execute "ethtool -s
ethx autoneg on" will cause "link partner" information disappear.

The call trace is phy_ethtool_ksettings_set()->phy_start_aneg()
->linkmode_zero(phydev->lp_advertising)->genphy_read_status(),
the link didn't change, so genphy_read_status() just return, and
phydev->lp_advertising is zero now.

This patch moves the clear operation of lp_advertising from
phy_start_aneg() to genphy_read_lpa()/genphy_c45_read_lpa(), and
if autoneg on and autoneg not complete, just clear what the
generic functions care about.

Fixes: 88d6272a ("net: phy: avoid unneeded MDIO reads in genphy_read_status")
Signed-off-by: default avatarYonglong Liu <liuyonglong@huawei.com>
Reviewed-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2ca4f6ca
...@@ -323,6 +323,8 @@ int genphy_c45_read_pma(struct phy_device *phydev) ...@@ -323,6 +323,8 @@ int genphy_c45_read_pma(struct phy_device *phydev)
{ {
int val; int val;
linkmode_zero(phydev->lp_advertising);
val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1); val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
if (val < 0) if (val < 0)
return val; return val;
......
...@@ -572,9 +572,6 @@ int phy_start_aneg(struct phy_device *phydev) ...@@ -572,9 +572,6 @@ int phy_start_aneg(struct phy_device *phydev)
if (AUTONEG_DISABLE == phydev->autoneg) if (AUTONEG_DISABLE == phydev->autoneg)
phy_sanitize_settings(phydev); phy_sanitize_settings(phydev);
/* Invalidate LP advertising flags */
linkmode_zero(phydev->lp_advertising);
err = phy_config_aneg(phydev); err = phy_config_aneg(phydev);
if (err < 0) if (err < 0)
goto out_unlock; goto out_unlock;
......
...@@ -1787,7 +1787,14 @@ int genphy_read_lpa(struct phy_device *phydev) ...@@ -1787,7 +1787,14 @@ int genphy_read_lpa(struct phy_device *phydev)
{ {
int lpa, lpagb; int lpa, lpagb;
if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { if (phydev->autoneg == AUTONEG_ENABLE) {
if (!phydev->autoneg_complete) {
mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
0);
mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
return 0;
}
if (phydev->is_gigabit_capable) { if (phydev->is_gigabit_capable) {
lpagb = phy_read(phydev, MII_STAT1000); lpagb = phy_read(phydev, MII_STAT1000);
if (lpagb < 0) if (lpagb < 0)
...@@ -1815,6 +1822,8 @@ int genphy_read_lpa(struct phy_device *phydev) ...@@ -1815,6 +1822,8 @@ int genphy_read_lpa(struct phy_device *phydev)
return lpa; return lpa;
mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
} else {
linkmode_zero(phydev->lp_advertising);
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment