Netdev List
 help / color / mirror / Atom feed
From: Vladislav Karmanov <vladislav.karmanov.dev@gmail.com>
To: netdev@vger.kernel.org
Cc: chester.a.unal@arinc9.com, daniel@makrotopia.org,
	dqfext@gmail.com, sean.wang@mediatek.com, andrew@lunn.ch,
	olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com,
	angelogioacchino.delregno@collabora.com,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-mediatek@lists.infradead.org, yangshiji66@outlook.com,
	Vladislav Karmanov <vladislav.karmanov.dev@gmail.com>
Subject: [PATCH net v2] net: dsa: mt7530: do not advertise EEE on MT7621/MT7530 switch
Date: Thu, 20 Aug 2026 23:28:44 +0300	[thread overview]
Message-ID: <20260820202844.1821687-1-vladislav.karmanov.dev@gmail.com> (raw)

From: Shiji Yang <yangshiji66@outlook.com>

There are hardware defects in the MT7530 internal GE PHY EEE support:
with EEE advertised, some link partners cannot establish a stable
connection. On a 2-pair (4-wire) cable where both ends advertise gigabit,
1000BASE-T training cannot succeed, and instead of falling back to
100 Mbps the port flaps in a loop and no link/DHCP lease is obtained.
This is confined to the WAN / phylib bring-up path; the DSA/LAN side on
the same device is unaffected.

The MT7530 internal GE PHY advertises EEE by hardware default. The
eee-broken-100tx / eee-broken-1000t device-tree properties only take
effect during the late PHY config_init path, which is too late for these
link partners: they negotiate EEE before the OS disables it and then
fail to fall back cleanly.

Commit af3b4b0e59de ("net: phy: mediatek-ge: do not disable EEE
advertisement") removed the early EEE-advertisement disable from
mtk_gephy_config_init(), on the rationale that "disabling EEE
advertisement before the PHY driver initialises keeps it off", i.e. that
the DSA subdriver already performs that early disable. That rationale
holds for MT7531, whose mt7531_setup() clears MDIO_AN_EEE_ADV on each
switch PHY, but not for MT7621 (and the dedicated MT7530 IC), whose
mt7530_setup() never had such a loop. So af3b4b0e59de removed the only
early EEE disable covering MT7621/MT7530, reintroducing the flapping.

Regarding the MAC-vs-PHY question: the broken hardware is the PHY (the
MT7530 internal GE PHY, PHY ID 0x03a29412, driven by mediatek-ge), and
MediaTek's own recommendation (Landen Chao, 2021) confirms it: "EEE of
the 10-year-old MT7530 internal gephy has many IOT problems, so it is
recommended to disable its EEE." However, the disable belongs on the
DSA side, not in the PHY driver: af3b4b0e59de itself established that
the PHY-driver-side disable "is somehow enabled afterwards" (it does
not stick), whereas the early disable done in the DSA setup path is what
keeps EEE off -- which is exactly why MT7531 does it in mt7531_setup()
and why af3b4b0e59de considered the mtk-ge disable redundant for MT7531.

Restore the early disable for the affected silicon by clearing
MDIO_AN_EEE_ADV on each switch PHY in mt7530_setup(), gated on a new
`broken_eee` flag in struct mt753x_info rather than an open-coded ID
check, mirroring the existing mt7531_setup() loop. Set broken_eee for
ID_MT7621 and ID_MT7530, which share the same mt7530_setup() and the
same internal GE PHY. Auto-negotiation then falls back to a stable
100 Mbps link instead of hanging at gigabit.

Tested on ASUS RT-AX53U (MT7621): a single clean
"Link is Up - 100Mbps/Full - flow control off" + DHCP lease on a 2-pair
cable, where the unpatched driver loops. Confirmed on kernel 6.12 and
6.18; also confirmed on Netgear R6220 and EdgeRouter-X (both MT7621).

Fixes: af3b4b0e59de ("net: phy: mediatek-ge: do not disable EEE advertisement")
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Signed-off-by: Vladislav Karmanov <vladislav.karmanov.dev@gmail.com>
---
Changes in v2:
- Gate the disable on a new `broken_eee` flag in struct mt753x_info
  instead of an open-coded priv->id == ID_MT7621 check, so it is easy to
  extend to further affected silicon (suggested by Daniel Golle).
- Cover ID_MT7530 (the dedicated MT7530 IC, e.g. BananaPi R2) in addition
  to ID_MT7621: both share mt7530_setup() and the same internal GE PHY
  (suggested by Daniel Golle).
- Address the MAC-vs-PHY placement question in the commit message: the
  broken hardware is the PHY, but the disable belongs on the DSA side
  because af3b4b0e59de showed the PHY-driver-side disable does not stick
  (question by Andrew Lunn).

v1: https://lore.kernel.org/netdev/20260818182829.1580811-1-vladislav.karmanov.dev@gmail.com/

 drivers/net/dsa/mt7530.c | 11 +++++++++++
 drivers/net/dsa/mt7530.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 2a70fa4..cab46c6 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2446,6 +2446,15 @@ mt7530_setup(struct dsa_switch *ds)
 	if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)
 		mt7530_pll_setup(priv);
 
+	if (priv->info->broken_eee) {
+		/* Disable EEE advertisement on the switch PHYs. */
+		for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
+		     i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
+		     i++) {
+			mt7530_phy_write_c45(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+		}
+	}
+
 	mt753x_trap_frames(priv);
 
 	/* Enable and reset MIB counters */
@@ -3298,6 +3307,7 @@ static const struct phylink_mac_ops mt753x_phylink_mac_ops = {
 const struct mt753x_info mt753x_table[] = {
 	[ID_MT7621] = {
 		.id = ID_MT7621,
+		.broken_eee = true,
 		.pcs_ops = &mt7530_pcs_ops,
 		.sw_setup = mt7530_setup,
 		.phy_read_c22 = mt7530_phy_read_c22,
@@ -3309,6 +3319,7 @@ const struct mt753x_info mt753x_table[] = {
 	},
 	[ID_MT7530] = {
 		.id = ID_MT7530,
+		.broken_eee = true,
 		.pcs_ops = &mt7530_pcs_ops,
 		.sw_setup = mt7530_setup,
 		.phy_read_c22 = mt7530_phy_read_c22,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 7e47cd9..fff310f 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -851,6 +851,7 @@ struct mt753x_info {
 	void (*mac_port_config)(struct dsa_switch *ds, int port,
 				unsigned int mode,
 				phy_interface_t interface);
+	bool broken_eee;
 };
 
 /* struct mt7530_priv -	This is the main data structure for holding the state
-- 
2.43.0


             reply	other threads:[~2026-08-20 20:29 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-20 20:28 Vladislav Karmanov [this message]
2026-08-20 21:02 ` [PATCH net v2] net: dsa: mt7530: do not advertise EEE on MT7621/MT7530 switch Andrew Lunn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260820202844.1821687-1-vladislav.karmanov.dev@gmail.com \
    --to=vladislav.karmanov.dev@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=chester.a.unal@arinc9.com \
    --cc=daniel@makrotopia.org \
    --cc=davem@davemloft.net \
    --cc=dqfext@gmail.com \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=matthias.bgg@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=sean.wang@mediatek.com \
    --cc=yangshiji66@outlook.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox