Message ID | 20240221062107.778661-6-o.rempel@pengutronix.de (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net: ethernet: Rework EEE | expand |
On 2/20/2024 10:21 PM, Oleksij Rempel wrote: > From: Andrew Lunn <andrew@lunn.ch> > > The MAC driver changes its EEE hardware configuration in its > adjust_link callback. This is called when auto-neg > completes. Disabling EEE via eee_enabled false will trigger an > autoneg, and as a result the adjust_link callback will be called with > phydev->enable_tx_lpi set to false. Similarly, eee_enabled set to true > and with a change of advertised link modes will result in a new > autoneg, and a call the adjust_link call. > > If set_eee is called with only a change to tx_lpi_enabled which does > not trigger an auto-neg, it is necessary to call the adjust_link > callback so that the MAC is reconfigured to take this change into > account. > > When setting phydev->enable_tx_lpi, take both eee_enabled and > tx_lpi_enabled into account, so the MAC drivers just needs to act on > phydev->enable_tx_lpi and not the whole EEE configuration. > > Signed-off-by: Andrew Lunn <andrew@lunn.ch> > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Definitively an improvement! Minor nits below > --- > drivers/net/phy/phy-c45.c | 11 ++++++++--- > drivers/net/phy/phy.c | 25 ++++++++++++++++++++++--- > 2 files changed, 30 insertions(+), 6 deletions(-) > > diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c > index c69568e7695e..217d4df59eb6 100644 > --- a/drivers/net/phy/phy-c45.c > +++ b/drivers/net/phy/phy-c45.c > @@ -1549,6 +1549,8 @@ EXPORT_SYMBOL(genphy_c45_ethtool_get_eee); > * advertised, but the previously advertised link modes are > * retained. This allows EEE to be enabled/disabled in a > * non-destructive way. > + * Returns either error code, 0 if there was no change, or positive > + * value if there was a change which triggered auto-neg. > */ > int genphy_c45_ethtool_set_eee(struct phy_device *phydev, > struct ethtool_keee *data) > @@ -1580,9 +1582,12 @@ int genphy_c45_ethtool_set_eee(struct phy_device *phydev, > ret = genphy_c45_an_config_eee_aneg(phydev); > if (ret < 0) > return ret; > - if (ret > 0) > - return phy_restart_aneg(phydev); > - > + if (ret > 0) { > + ret = phy_restart_aneg(phydev); > + if (ret < 0) > + return ret; > + return 1; > + } > return 0; > } > EXPORT_SYMBOL(genphy_c45_ethtool_set_eee); > diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c > index 7f3629d56503..dad827717ad9 100644 > --- a/drivers/net/phy/phy.c > +++ b/drivers/net/phy/phy.c > @@ -988,7 +988,8 @@ static int phy_check_link_status(struct phy_device *phydev) > if (err < 0) > phydev->enable_tx_lpi = false; > else > - phydev->enable_tx_lpi = err; > + phydev->enable_tx_lpi = (err & phydev->eee_cfg.tx_lpi_enabled); > + > phy_link_up(phydev); > } else if (!phydev->link && phydev->state != PHY_NOLINK) { > phydev->state = PHY_NOLINK; > @@ -1679,6 +1680,21 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_keee *data) > } > EXPORT_SYMBOL(phy_ethtool_get_eee); > > +/* auto-neg not triggered, directly inform the MAC if something > + * changed' Stray ' character at the end here. > + */ > +static void phy_ethtool_set_eee_noneg(struct phy_device *phydev, > + struct ethtool_keee *data) > +{ > + if (phydev->eee_cfg.tx_lpi_enabled != > + data->tx_lpi_enabled) { > + eee_to_eeecfg(data, &phydev->eee_cfg); > + phydev->enable_tx_lpi = eeecfg_mac_can_tx_lpi(&phydev->eee_cfg); > + if (phydev->link) > + phy_link_up(phydev); > + } > +} > + > /** > * phy_ethtool_set_eee - set EEE supported and status > * @phydev: target phy_device struct > @@ -1695,11 +1711,14 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_keee *data) > > mutex_lock(&phydev->lock); > ret = genphy_c45_ethtool_set_eee(phydev, data); > - if (!ret) > + if (ret >= 0) { > + if (ret == 0) > + phy_ethtool_set_eee_noneg(phydev, data); > eee_to_eeecfg(data, &phydev->eee_cfg); > + } > mutex_unlock(&phydev->lock); > > - return ret; > + return (ret < 0 ? ret : 0); Don't think the parenthesis are needed but does not hurt.
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index c69568e7695e..217d4df59eb6 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -1549,6 +1549,8 @@ EXPORT_SYMBOL(genphy_c45_ethtool_get_eee); * advertised, but the previously advertised link modes are * retained. This allows EEE to be enabled/disabled in a * non-destructive way. + * Returns either error code, 0 if there was no change, or positive + * value if there was a change which triggered auto-neg. */ int genphy_c45_ethtool_set_eee(struct phy_device *phydev, struct ethtool_keee *data) @@ -1580,9 +1582,12 @@ int genphy_c45_ethtool_set_eee(struct phy_device *phydev, ret = genphy_c45_an_config_eee_aneg(phydev); if (ret < 0) return ret; - if (ret > 0) - return phy_restart_aneg(phydev); - + if (ret > 0) { + ret = phy_restart_aneg(phydev); + if (ret < 0) + return ret; + return 1; + } return 0; } EXPORT_SYMBOL(genphy_c45_ethtool_set_eee); diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 7f3629d56503..dad827717ad9 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -988,7 +988,8 @@ static int phy_check_link_status(struct phy_device *phydev) if (err < 0) phydev->enable_tx_lpi = false; else - phydev->enable_tx_lpi = err; + phydev->enable_tx_lpi = (err & phydev->eee_cfg.tx_lpi_enabled); + phy_link_up(phydev); } else if (!phydev->link && phydev->state != PHY_NOLINK) { phydev->state = PHY_NOLINK; @@ -1679,6 +1680,21 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_keee *data) } EXPORT_SYMBOL(phy_ethtool_get_eee); +/* auto-neg not triggered, directly inform the MAC if something + * changed' + */ +static void phy_ethtool_set_eee_noneg(struct phy_device *phydev, + struct ethtool_keee *data) +{ + if (phydev->eee_cfg.tx_lpi_enabled != + data->tx_lpi_enabled) { + eee_to_eeecfg(data, &phydev->eee_cfg); + phydev->enable_tx_lpi = eeecfg_mac_can_tx_lpi(&phydev->eee_cfg); + if (phydev->link) + phy_link_up(phydev); + } +} + /** * phy_ethtool_set_eee - set EEE supported and status * @phydev: target phy_device struct @@ -1695,11 +1711,14 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_keee *data) mutex_lock(&phydev->lock); ret = genphy_c45_ethtool_set_eee(phydev, data); - if (!ret) + if (ret >= 0) { + if (ret == 0) + phy_ethtool_set_eee_noneg(phydev, data); eee_to_eeecfg(data, &phydev->eee_cfg); + } mutex_unlock(&phydev->lock); - return ret; + return (ret < 0 ? ret : 0); } EXPORT_SYMBOL(phy_ethtool_set_eee);