diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2026-05-19 18:45:27 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-05-19 18:45:27 -0700 |
| commit | d03e6124c724e6a380b4bef22e5a1cbc5ddf4cea (patch) | |
| tree | d91ee84fe1eeb34d49d0deea3037a1c5b40abe78 | |
| parent | 960e77ce14a83ef7f226e8e4b4d75765633ba48b (diff) | |
| parent | 8baa7506d793f0636e3f6f01b01ef7be19674d06 (diff) | |
Merge branch 'net-phy-honor-eee_disabled_modes-when-advertising-eee'
Nicolai Buchwitz says:
====================
net: phy: honor eee_disabled_modes when advertising EEE
While debugging why ethtool --show-eee reports "not supported" on a
Raspberry Pi CM4 with eee-broken-1000t / eee-broken-100tx set on the
PHY node, I noticed two phylib helpers copy phydev->supported_eee
into phydev->advertising_eee without applying
phydev->eee_disabled_modes: phy_support_eee() and
phy_advertise_eee_all(). That undoes the filtering phy_probe() set
up after of_set_phy_eee_broken(), so the PHY ends up advertising EEE
for modes that were marked broken in DT (or by the driver via
eee_disabled_modes).
The visible effect on MAC drivers that call phy_support_eee() after
probe (bcmgenet, fec, lan743x, lan78xx, r8169) is that ethtool on the
local interface reports "not supported" (because supported is masked
by eee_disabled_modes and ends up empty), while the link partner
happily sees EEE negotiated and active.
Patch 1 fixes phy_support_eee(). Patch 2 fixes phy_advertise_eee_all(),
which is also reached from genphy_c45_ethtool_set_eee() when user
space passes an empty advertisement.
I went through the other users of supported_eee as suggested by Andrew
and they look fine:
- phy_probe() already masks via eee_disabled_modes after
of_set_phy_eee_broken().
- genphy_c45_ethtool_get_eee() masks supported_eee with
eee_disabled_modes when reporting to user space.
- genphy_c45_ethtool_set_eee() masks user-supplied adv against
eee_disabled_modes, and the empty-adv path is now covered by
patch 2.
- genphy_c45_read_eee_abilities(), read_eee_cap1/cap2 populate
supported_eee from PHY registers (source of truth).
- genphy_c45_read_eee_adv(), read_eee_lpa() and write_eee_adv() use
supported_eee only to gate which MMD registers to access, not to
construct an advertisement.
====================
Link: https://patch.msgid.link/20260518-devel-phy-support-eee-fix-v2-0-05b52626fa68@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/phy/phy_device.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index c2cdf1ae3542..3370eb822017 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -2877,7 +2877,8 @@ EXPORT_SYMBOL(phy_advertise_supported); */ void phy_advertise_eee_all(struct phy_device *phydev) { - linkmode_copy(phydev->advertising_eee, phydev->supported_eee); + linkmode_andnot(phydev->advertising_eee, phydev->supported_eee, + phydev->eee_disabled_modes); } EXPORT_SYMBOL_GPL(phy_advertise_eee_all); @@ -2903,7 +2904,8 @@ EXPORT_SYMBOL_GPL(phy_advertise_eee_all); */ void phy_support_eee(struct phy_device *phydev) { - linkmode_copy(phydev->advertising_eee, phydev->supported_eee); + linkmode_andnot(phydev->advertising_eee, phydev->supported_eee, + phydev->eee_disabled_modes); phydev->eee_cfg.tx_lpi_enabled = true; phydev->eee_cfg.eee_enabled = true; |
