net: phy: add support for disabling PHY-autonomous EEE

Some PHYs (e.g. Broadcom BCM54xx, Realtek RTL8211F) implement
autonomous EEE where the PHY manages LPI signaling without forwarding
it to the MAC. This conflicts with MAC drivers that implement their own
LPI control.

Add a .disable_autonomous_eee callback to struct phy_driver and call it
from phy_support_eee(). When a MAC driver indicates it supports EEE via
phy_support_eee(), the PHY's autonomous EEE is automatically disabled so
the MAC can manage LPI entry/exit.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260406-devel-autonomous-eee-v1-1-b335e7143711@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Nicolai Buchwitz
2026-04-06 09:13:07 +02:00
committed by Jakub Kicinski
parent 200df94709
commit 7ef629b458
2 changed files with 36 additions and 0 deletions

View File

@@ -1375,6 +1375,14 @@ int phy_init_hw(struct phy_device *phydev)
return ret;
}
/* Re-apply autonomous EEE disable after soft reset */
if (phydev->autonomous_eee_disabled &&
phydev->drv->disable_autonomous_eee) {
ret = phydev->drv->disable_autonomous_eee(phydev);
if (ret)
return ret;
}
return 0;
}
EXPORT_SYMBOL(phy_init_hw);
@@ -2898,6 +2906,20 @@ void phy_support_eee(struct phy_device *phydev)
linkmode_copy(phydev->advertising_eee, phydev->supported_eee);
phydev->eee_cfg.tx_lpi_enabled = true;
phydev->eee_cfg.eee_enabled = true;
/* If the PHY supports autonomous EEE, disable it so the MAC can
* manage LPI signaling instead. The flag is stored so it can be
* re-applied after a PHY soft reset (e.g. suspend/resume).
*/
if (phydev->drv && phydev->drv->disable_autonomous_eee) {
int ret = phydev->drv->disable_autonomous_eee(phydev);
if (ret)
phydev_warn(phydev, "Failed to disable autonomous EEE: %pe\n",
ERR_PTR(ret));
else
phydev->autonomous_eee_disabled = true;
}
}
EXPORT_SYMBOL(phy_support_eee);

View File

@@ -612,6 +612,8 @@ struct phy_oatc14_sqi_capability {
* @advertising_eee: Currently advertised EEE linkmodes
* @enable_tx_lpi: When True, MAC should transmit LPI to PHY
* @eee_active: phylib private state, indicating that EEE has been negotiated
* @autonomous_eee_disabled: Set when autonomous EEE has been disabled,
* used to re-apply after PHY soft reset
* @eee_cfg: User configuration of EEE
* @lp_advertising: Current link partner advertised linkmodes
* @host_interfaces: PHY interface modes supported by host
@@ -739,6 +741,7 @@ struct phy_device {
__ETHTOOL_DECLARE_LINK_MODE_MASK(eee_disabled_modes);
bool enable_tx_lpi;
bool eee_active;
bool autonomous_eee_disabled;
struct eee_config eee_cfg;
/* Host supported PHY interface types. Should be ignored if empty. */
@@ -1359,6 +1362,17 @@ struct phy_driver {
void (*get_stats)(struct phy_device *dev,
struct ethtool_stats *stats, u64 *data);
/**
* @disable_autonomous_eee: Disable PHY-autonomous EEE
*
* Some PHYs manage EEE autonomously, preventing the MAC from
* controlling LPI signaling. This callback disables autonomous
* EEE at the PHY.
*
* Return: 0 on success, negative errno on failure.
*/
int (*disable_autonomous_eee)(struct phy_device *dev);
/* Get and Set PHY tunables */
/** @get_tunable: Return the value of a tunable */
int (*get_tunable)(struct phy_device *dev,