Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net v2 0/2] net: restore EEE on MediaTek switches and SoC MACs
@ 2026-08-24  2:41 Aleksei Sviridkin
  2026-08-24  2:41 ` [PATCH net v2 1/2] net: dsa: mt7530: populate lpi_interfaces to fix EEE support Aleksei Sviridkin
  2026-08-24  2:41 ` [PATCH net v2 2/2] net: ethernet: mtk_eth_soc: " Aleksei Sviridkin
  0 siblings, 2 replies; 3+ messages in thread
From: Aleksei Sviridkin @ 2026-08-24  2:41 UTC (permalink / raw)
  To: Chester A . Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
	Felix Fietkau, Lorenzo Bianconi, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, netdev
  Cc: Russell King, Qingfang Deng, Matthias Brugger,
	AngeloGioacchino Del Regno, linux-kernel, linux-arm-kernel,
	linux-mediatek, Aleksei Sviridkin

Both drivers fill in phylink_config.lpi_capabilities and
lpi_timer_default but never lpi_interfaces. phylink treats a MAC as
supporting managed EEE only when the tx_lpi methods are implemented and
BOTH bitmaps are non-empty, which phylink_create() decides once and for
all, so EEE has been off on every mt753x port and on every mtk_eth_soc
MAC that uses mtk_phylink_ops since the two conversions named in the
Fixes: tags. Because the tx_lpi methods ARE implemented, phylink takes
the other branch and calls phy_disable_eee(), which fills
eee_disabled_modes - so userspace cannot enable EEE either.

On an MT7981B board with an MT7531 switch, before these patches:

  == lan1
  Cannot get EEE settings: Not supported
  == lan2
  Cannot get EEE settings: Not supported
  == lan3
  Cannot get EEE settings: Not supported
  == lan4
  Cannot get EEE settings: Not supported
  == wan
  Cannot get EEE settings: Not supported

lan1-3 are the MT7531 internal PHYs, lan4 is an EN8811H on switch port
5 whose MAC side runs 2500BASE-X rate matched to a 1 Gbps media link,
and wan is the mtk_eth_soc MAC with its directly attached 1 Gbps PHY -
so both drivers are covered.

Each patch fills lpi_interfaces from supported_interfaces and leaves
2.5 Gbps out of both bitmaps for now. LPI above 1 Gbps is unvalidated
rather than unsupported: both MACs fold 2.5 Gbps onto their 1 Gbps
speed encoding, so the 1 Gbps EEE force bit is what would govern it.
MediaTek's SDK driver sets the force bits for 100 Mbps and 1 Gbps only,
EEE signalling on 2500BASE-X is outside 802.3, and the 1 us unit of the
wakeup timers is undocumented at 2.5 times the port clock.

Neither driver sets eee_enabled_default, so LPI stays off until
userspace asks for it with ethtool --set-eee. The EEE advertisement is
a different matter: phylink stops force-clearing it, so a PHY that
advertises EEE out of reset advertises it again and the link may
negotiate EEE, without this MAC asserting LPI. MT7531's internal PHYs
and EN7528 are the exceptions, for the reasons in patch 1. Devicetree
eee-broken-* marks act at the PHY level and keep working, so a board
that already distrusts its PHYs stays protected: OpenWrt marks all
modes broken on MT7621's internal PHYs.

The two patches are independent and touch different subsystems; they
are sent together because they are the same bug.

Targeted at net as a regression fix with an active userspace lockout;
can be retargeted at net-next if maintainers prefer.

Based on net-next at 91ec20351349. Both driver files are byte
identical in net/main and the series applies there unchanged.

After the series, all five ports report:

  EEE status: disabled
  Tx LPI: disabled
  Supported EEE link modes:  100baseT/Full
                             1000baseT/Full
  Advertised EEE link modes:  Not reported

No 2.5G mode is offered, which is the narrowed lpi_capabilities, and
nothing is advertised until userspace asks. On this board no PHY came
out of reset advertising EEE, so the case where the advertisement
returns once phylink stops clearing it is not exercised here.

Enabling it on lan1, whose partner advertises EEE at both speeds:

  # ethtool --set-eee lan1 eee on
  EEE status: enabled - active
  Advertised EEE link modes:  100baseT/Full 1000baseT/Full
  Link partner advertised EEE link modes:  100baseT/Full 1000baseT/Full

  # ethtool --set-eee lan1 eee on tx-lpi on
  EEE status: enabled - active
  Tx LPI: 30 (us)

With LPI armed, 30 parallel ICMPv6 streams of 1400-byte payload, 300
packets each one second apart - so every gap crosses the LPI threshold
and the link enters and leaves LPI thousands of times over 300 s - lost
nothing: 300/300 on every stream, tx and rx error counters unchanged,
carrier_changes unchanged, and no mac_enable_tx_lpi errors in dmesg.

On wan the link partner advertises no EEE, so enabling it settles at
"enabled - inactive", which is the correct outcome, and the link
survived the autonegotiation restart. Its Tx LPI reads 1000 (us)
against lan1's 30; see the note below the scissors of patch 1.

lan4 keeps EEE disabled and never arms LPI, which is what dropping
2500BASE-X from lpi_interfaces is for. Forwarding through it was
lossless with no carrier change.

---
v2: commit messages rewritten to carry the Why only, mechanism notes
    moved below the scissors (Andrew Lunn); comments and commit
    messages reworded so the 2.5 Gbps exclusion reads as unvalidated
    rather than impossible (Daniel Golle); no functional changes.
v1: https://lore.kernel.org/netdev/20260822195252.2934-1-f@lex.la/

Aleksei Sviridkin (2):
  net: dsa: mt7530: populate lpi_interfaces to fix EEE support
  net: ethernet: mtk_eth_soc: populate lpi_interfaces to fix EEE support

 drivers/net/dsa/mt7530.c                    | 24 ++++++++++++++++-----
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++++++++---
 2 files changed, 38 insertions(+), 8 deletions(-)

-- 
2.55.0



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH net v2 1/2] net: dsa: mt7530: populate lpi_interfaces to fix EEE support
  2026-08-24  2:41 [PATCH net v2 0/2] net: restore EEE on MediaTek switches and SoC MACs Aleksei Sviridkin
@ 2026-08-24  2:41 ` Aleksei Sviridkin
  2026-08-24  2:41 ` [PATCH net v2 2/2] net: ethernet: mtk_eth_soc: " Aleksei Sviridkin
  1 sibling, 0 replies; 3+ messages in thread
From: Aleksei Sviridkin @ 2026-08-24  2:41 UTC (permalink / raw)
  To: Chester A . Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
	Felix Fietkau, Lorenzo Bianconi, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, netdev
  Cc: Russell King, Qingfang Deng, Matthias Brugger,
	AngeloGioacchino Del Regno, linux-kernel, linux-arm-kernel,
	linux-mediatek, Aleksei Sviridkin

mt753x_phylink_get_caps() fills in lpi_capabilities and
lpi_timer_default but never lpi_interfaces, so phylink treats the MAC
as not supporting EEE: ethtool reports "Not supported" and
phy_disable_eee() keeps userspace locked out. That undoes what
commit 06dfcd4098cf ("net: dsa: mt7530: fix enabling EEE on MT7531
switch on all boards") arranged: EEE off by default, but enableable
with ethtool.

Copy the supported interfaces into lpi_interfaces after
mac_port_get_caps() has populated them, and leave the speeds above
1 Gbps out for now: drop 2500BASE-X from the copy, drop MAC_2500FD
from lpi_capabilities, and skip ports that support neither 100 Mbps
nor 1 Gbps. PMCR folds SPEED_2500 and SPEED_10000 onto
PMCR_FORCE_SPEED_1000, so PMCR_FORCE_EEE1G is what would govern LPI on
those links, and it is unvalidated rather than unsupported: MediaTek's
SDK driver sets the EEE force bits for 100 Mbps and 1 Gbps link speed
only, EEE signalling on 2500BASE-X is outside 802.3, and the 1 us unit
of the wakeup timers is undocumented with the port clock at 2.5 times
the rate. Narrowing lpi_capabilities alone would not do it, since it
gates on the media speed a rate matching PHY reports rather than on
the speed the MAC runs at. On MT7988, EN7581 and AN7583 port 6 is
10 Gbps only and shares PHY_INTERFACE_MODE_INTERNAL with the user
ports, so the interface mask alone cannot tell them apart.

LPI stays off until userspace enables it. The EEE advertisement of a
PHY that advertises it out of reset does come back, since phylink
stops force-clearing it. MT7531's internal PHYs keep the
advertisement mt7531_setup() zeroed, and EN7528 keeps both bitmaps
empty, so EEE stays fully off there.

Fixes: 9cf21773f535 ("net: dsa: mt7530: convert to phylink managed EEE")
Signed-off-by: Aleksei Sviridkin <f@lex.la>
---

Two pre-existing things this patch makes live, neither addressed here:

- The unit of LPI_THRESH is still unspecified, as the comment above
  lpi_timer_default says. With EEE reachable again, ethtool reports
  that raw value as microseconds and writes userspace values back
  unconverted, while mtk_eth_soc treats a structurally identical field
  as milliseconds (DIV_ROUND_UP(timer, 1000)). Reading the default back
  reproduces the same raw value whatever the unit is, but a timer set
  from userspace in microseconds would be off by 1000 if the field is
  in milliseconds. On an MT7531 board ethtool now reports 30 for a
  switch port, the raw LPI_THRESH field, against 1000 for the SoC MAC,
  which is a driver constant already in microseconds; whether the
  hardware means 30 microseconds is exactly the open question. Does
  anyone have the datasheet answer?

- mt753x_phylink_mac_enable_tx_lpi() sets the PMCR force-EEE bits
  without checking the resolved speed or interface, relying entirely on
  phylink never calling it above 1 Gbps. A check there would make the
  driver robust independently of lpi_interfaces being right; if that
  check is ever sent, it will warn loudly.

On leaving the higher speeds out: the absence of 2.5 Gbps EEE force
bits in PMCR is not the argument, since the same reasoning applied to
the speed field would say the switch cannot do 2.5 Gbps at all. The
masks say nobody has validated it, not that the hardware refuses.
Doing that here rather than in a separate patch changes nothing
observable: while lpi_interfaces was empty, lpi_capabilities never
reached phy->advertising_eee.

If PMCR_FORCE_EEE1G does work on the overclocked link, a rate matched
EN8811H port is exactly the setup that would benefit, so this is worth
an experiment later.
 drivers/net/dsa/mt7530.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 2b7be091c056..4ed6218df64b 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3172,23 +3172,37 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
 
 	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
 
+	priv->info->mac_port_get_caps(ds, port, config);
+
 	/* The EN7528 GPHYs report EEE capability, but negotiating EEE with
 	 * common link partners (e.g. Realtek GbE NICs) results in an unstable
 	 * link with dropped frames. Leave the LPI capabilities empty so that
 	 * phylink disables EEE on these PHYs and refuses to enable it from
-	 * userspace.
+	 * userspace. Ports that run at neither 100 Mbps nor 1 Gbps are left
+	 * empty too, since LPI above 1 Gbps is unvalidated.
 	 */
-	if (priv->id != ID_EN7528) {
+	if (priv->id != ID_EN7528 &&
+	    config->mac_capabilities & (MAC_100FD | MAC_1000FD)) {
 		u32 eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
 
-		config->lpi_capabilities = MAC_100FD | MAC_1000FD | MAC_2500FD;
+		/* PMCR folds SPEED_2500 and SPEED_10000 onto
+		 * PMCR_FORCE_SPEED_1000, so LPI above 1 Gbps would be
+		 * governed by PMCR_FORCE_EEE1G and is unvalidated rather than
+		 * unsupported. Leave it out of both bitmaps: lpi_capabilities
+		 * gates on the media speed a rate matching PHY reports, not
+		 * on the speed the MAC runs at.
+		 */
+		config->lpi_capabilities = MAC_100FD | MAC_1000FD;
+		phy_interface_copy(config->lpi_interfaces,
+				   config->supported_interfaces);
+		__clear_bit(PHY_INTERFACE_MODE_2500BASEX,
+			    config->lpi_interfaces);
+
 		/* tx_lpi_timer should be in microseconds. The time units for
 		 * LPI threshold are unspecified.
 		 */
 		config->lpi_timer_default = FIELD_GET(LPI_THRESH_MASK, eeecr);
 	}
-
-	priv->info->mac_port_get_caps(ds, port, config);
 }
 
 static int mt753x_pcs_validate(struct phylink_pcs *pcs,
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH net v2 2/2] net: ethernet: mtk_eth_soc: populate lpi_interfaces to fix EEE support
  2026-08-24  2:41 [PATCH net v2 0/2] net: restore EEE on MediaTek switches and SoC MACs Aleksei Sviridkin
  2026-08-24  2:41 ` [PATCH net v2 1/2] net: dsa: mt7530: populate lpi_interfaces to fix EEE support Aleksei Sviridkin
@ 2026-08-24  2:41 ` Aleksei Sviridkin
  1 sibling, 0 replies; 3+ messages in thread
From: Aleksei Sviridkin @ 2026-08-24  2:41 UTC (permalink / raw)
  To: Chester A . Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
	Felix Fietkau, Lorenzo Bianconi, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, netdev
  Cc: Russell King, Qingfang Deng, Matthias Brugger,
	AngeloGioacchino Del Regno, linux-kernel, linux-arm-kernel,
	linux-mediatek, Aleksei Sviridkin

mtk_add_mac() fills in lpi_capabilities and lpi_timer_default but
never lpi_interfaces, so phylink treats every MAC that uses
mtk_phylink_ops as not supporting EEE: ethtool reports "Not
supported" and phy_disable_eee() keeps userspace locked out. MT7628
is unaffected, as rt5350_phylink_ops has no tx_lpi methods.

Copy the supported interfaces into lpi_interfaces once the SoC
specific fixups have finished changing them, and leave 2.5 Gbps out
for now: drop 2500BASE-X from the copy and MAC_2500FD from
lpi_capabilities. MAC_MCR folds SPEED_2500 onto MAC_MCR_SPEED_1000, so
MAC_MCR_EEE1G is what would govern LPI on such a link, and it is
unvalidated rather than unsupported: MediaTek's SDK driver sets the
EEE force bits for 100 Mbps and 1 Gbps link speed only, EEE signalling
on 2500BASE-X is outside 802.3, and the 1 us unit of the wakeup timers
is undocumented with the port clock at 2.5 times the rate. Narrowing
lpi_capabilities alone would not do it, since it gates on the media
speed a rate matching PHY reports rather than on the speed the MAC
runs at. Drop the xGMII modes too, which mtk_mac_enable_tx_lpi()
refuses outright and which on netsys v3 include the mode of MT7988's
built-in 2.5G PHY.

LPI stays off until userspace enables it. The EEE advertisement of a
PHY that advertises it out of reset does come back, since phylink
stops force-clearing it.

Fixes: 952d7325362f ("net: ethernet: mediatek: add EEE support")
Signed-off-by: Aleksei Sviridkin <f@lex.la>
---

On leaving 2.5 Gbps out: the absence of 2.5 Gbps EEE force bits in
MAC_MCR is not the argument, since the same reasoning applied to the
speed field would say the MAC cannot do 2.5 Gbps at all - 2500BASE-X
here is 1000BASE-X at 2.5 times the clock, and the MAC does not know
the difference. MAC_2500FD was deliberate in the original EEE
submission [1], which set MAC_MCR_EEE1G for SPEED_2500 and SPEED_1000
alike. The masks say nobody has validated it, not that the hardware
refuses.

On the netsys v3 switch MAC the xGMII filter empties lpi_interfaces
outright, as PHY_INTERFACE_MODE_INTERNAL is the only interface it
supports. It is a fixed link port with no PHY, so phylink had no EEE to
manage there before this patch either.

Pre-existing, made live by this patch and not addressed here:
mtk_mac_enable_tx_lpi() programs MT7531's reset wakeup times (17 for
1 Gbps, 36 for 100 Mbps) whenever it runs, as its own comment says, so
they now apply to every SoC driven by mtk_phylink_ops once a user
enables EEE on an eligible interface. Those values do not appear to
have been confirmed for MT7981, MT7986 or MT7988.

[1] https://lore.kernel.org/all/20250210125246.1950142-1-dqfext@gmail.com/
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index be3bd025c41a..37a831f73da6 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4828,7 +4828,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	phy_interface_t phy_mode;
 	struct phylink *phylink;
 	struct mtk_mac *mac;
-	int id, err;
+	int id, err, i;
 	int txqs = 1;
 	u32 val;
 
@@ -4907,8 +4907,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	mac->phylink_config.type = PHYLINK_NETDEV;
 	mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
 		MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
-	mac->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD |
-		MAC_2500FD;
+	/* MAC_MCR folds SPEED_2500 onto MAC_MCR_SPEED_1000, so LPI above
+	 * 1 Gbps would be governed by MAC_MCR_EEE1G and is unvalidated
+	 * rather than unsupported.
+	 */
+	mac->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD;
 	mac->phylink_config.lpi_timer_default = 1000;
 
 	/* MT7623 gmac0 is now missing its speed-specific PLL configuration
@@ -4966,6 +4969,19 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  mac->phylink_config.supported_interfaces);
 
+	phy_interface_copy(mac->phylink_config.lpi_interfaces,
+			   mac->phylink_config.supported_interfaces);
+
+	/* The MAC side of 2500BASE-X is never below 2.5 Gbps, not even when
+	 * a rate matching PHY drops the media to 1 Gbps, and
+	 * mtk_mac_enable_tx_lpi() refuses the xGMII modes outright.
+	 */
+	__clear_bit(PHY_INTERFACE_MODE_2500BASEX,
+		    mac->phylink_config.lpi_interfaces);
+	for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
+		if (mtk_interface_mode_is_xgmii(eth, i))
+			__clear_bit(i, mac->phylink_config.lpi_interfaces);
+
 	phylink = phylink_create(&mac->phylink_config,
 				 of_fwnode_handle(mac->of_node),
 				 phy_mode, mac_ops);
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-24  2:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-24  2:41 [PATCH net v2 0/2] net: restore EEE on MediaTek switches and SoC MACs Aleksei Sviridkin
2026-08-24  2:41 ` [PATCH net v2 1/2] net: dsa: mt7530: populate lpi_interfaces to fix EEE support Aleksei Sviridkin
2026-08-24  2:41 ` [PATCH net v2 2/2] net: ethernet: mtk_eth_soc: " Aleksei Sviridkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox