Skip to content

Commit e6c4ace

Browse files
committed
net: phy: fix EEE advertisement not restored after eee off/on toggle
When EEE is disabled via 'ethtool --set-eee eth0 eee off' and then re-enabled with 'ethtool --set-eee eth0 eee on' (without explicitly specifying advertised modes), the advertised EEE link modes are lost, showing "Not reported" instead of being restored to the supported modes. The bug is a state ordering issue in phy_ethtool_set_eee(): genphy_c45_ethtool_set_eee(phydev, data); // uses OLD eee_cfg eee_to_eeecfg(&phydev->eee_cfg, data); // updates eee_cfg AFTER genphy_c45_ethtool_set_eee() correctly restores advertising_eee from supported_eee when re-enabling, but then calls genphy_c45_an_config_eee_aneg() which checks phydev->eee_cfg.eee_enabled -- still false from the previous 'eee off'. This causes it to write empty modes to the PHY, overriding the just-restored advertisement. Fix by updating eee_cfg.eee_enabled before calling genphy_c45_ethtool_set_eee(), and restoring it on error. Fixes: 49168d1 ("net: phy: Add phy_support_eee library function") Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
1 parent 294ebe6 commit e6c4ace

1 file changed

Lines changed: 13 additions & 0 deletions

File tree

drivers/net/phy/phy.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,17 +1763,30 @@ static void phy_ethtool_set_eee_noneg(struct phy_device *phydev,
17631763
*/
17641764
int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_keee *data)
17651765
{
1766+
bool old_eee_enabled;
17661767
int ret;
17671768

17681769
if (!phydev->drv)
17691770
return -EIO;
17701771

17711772
mutex_lock(&phydev->lock);
1773+
/* Update eee_enabled before calling genphy_c45_ethtool_set_eee(),
1774+
* because it calls genphy_c45_an_config_eee_aneg() which reads
1775+
* phydev->eee_cfg.eee_enabled to decide whether to write the
1776+
* advertisement to the PHY. Without this, toggling EEE off then
1777+
* on results in empty advertisement (the old eee_enabled=false
1778+
* causes it to write zero modes despite advertising_eee being
1779+
* correctly restored).
1780+
*/
1781+
old_eee_enabled = phydev->eee_cfg.eee_enabled;
1782+
phydev->eee_cfg.eee_enabled = data->eee_enabled;
17721783
ret = genphy_c45_ethtool_set_eee(phydev, data);
17731784
if (ret >= 0) {
17741785
if (ret == 0)
17751786
phy_ethtool_set_eee_noneg(phydev, data);
17761787
eee_to_eeecfg(&phydev->eee_cfg, data);
1788+
} else {
1789+
phydev->eee_cfg.eee_enabled = old_eee_enabled;
17771790
}
17781791
mutex_unlock(&phydev->lock);
17791792

0 commit comments

Comments
 (0)