Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Nicolai Buchwitz and committed by
Jakub Kicinski
7ef629b4 200df947

+36
+22
drivers/net/phy/phy_device.c
··· 1375 1375 return ret; 1376 1376 } 1377 1377 1378 + /* Re-apply autonomous EEE disable after soft reset */ 1379 + if (phydev->autonomous_eee_disabled && 1380 + phydev->drv->disable_autonomous_eee) { 1381 + ret = phydev->drv->disable_autonomous_eee(phydev); 1382 + if (ret) 1383 + return ret; 1384 + } 1385 + 1378 1386 return 0; 1379 1387 } 1380 1388 EXPORT_SYMBOL(phy_init_hw); ··· 2906 2898 linkmode_copy(phydev->advertising_eee, phydev->supported_eee); 2907 2899 phydev->eee_cfg.tx_lpi_enabled = true; 2908 2900 phydev->eee_cfg.eee_enabled = true; 2901 + 2902 + /* If the PHY supports autonomous EEE, disable it so the MAC can 2903 + * manage LPI signaling instead. The flag is stored so it can be 2904 + * re-applied after a PHY soft reset (e.g. suspend/resume). 2905 + */ 2906 + if (phydev->drv && phydev->drv->disable_autonomous_eee) { 2907 + int ret = phydev->drv->disable_autonomous_eee(phydev); 2908 + 2909 + if (ret) 2910 + phydev_warn(phydev, "Failed to disable autonomous EEE: %pe\n", 2911 + ERR_PTR(ret)); 2912 + else 2913 + phydev->autonomous_eee_disabled = true; 2914 + } 2909 2915 } 2910 2916 EXPORT_SYMBOL(phy_support_eee); 2911 2917
+14
include/linux/phy.h
··· 612 612 * @advertising_eee: Currently advertised EEE linkmodes 613 613 * @enable_tx_lpi: When True, MAC should transmit LPI to PHY 614 614 * @eee_active: phylib private state, indicating that EEE has been negotiated 615 + * @autonomous_eee_disabled: Set when autonomous EEE has been disabled, 616 + * used to re-apply after PHY soft reset 615 617 * @eee_cfg: User configuration of EEE 616 618 * @lp_advertising: Current link partner advertised linkmodes 617 619 * @host_interfaces: PHY interface modes supported by host ··· 741 739 __ETHTOOL_DECLARE_LINK_MODE_MASK(eee_disabled_modes); 742 740 bool enable_tx_lpi; 743 741 bool eee_active; 742 + bool autonomous_eee_disabled; 744 743 struct eee_config eee_cfg; 745 744 746 745 /* Host supported PHY interface types. Should be ignored if empty. */ ··· 1361 1358 /** @get_stats: Return the statistic counter values */ 1362 1359 void (*get_stats)(struct phy_device *dev, 1363 1360 struct ethtool_stats *stats, u64 *data); 1361 + 1362 + /** 1363 + * @disable_autonomous_eee: Disable PHY-autonomous EEE 1364 + * 1365 + * Some PHYs manage EEE autonomously, preventing the MAC from 1366 + * controlling LPI signaling. This callback disables autonomous 1367 + * EEE at the PHY. 1368 + * 1369 + * Return: 0 on success, negative errno on failure. 1370 + */ 1371 + int (*disable_autonomous_eee)(struct phy_device *dev); 1364 1372 1365 1373 /* Get and Set PHY tunables */ 1366 1374 /** @get_tunable: Return the value of a tunable */