]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
kernel: add patch for YT8821 address collision
authorJakub Vaněk <linuxtardis@gmail.com>
Mon, 2 Mar 2026 19:36:29 +0000 (20:36 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 14 Mar 2026 00:40:32 +0000 (01:40 +0100)
This minimalistic patch should ensure that the Cudy M3000 with the
Motorcomm PHY works reliably. The patch is not upstreamable into the
mainline kernel. However, it could be sufficient as a simple stop-gap
measure until some other solution is found.

Link: https://forum.openwrt.org/t/cudy-m3000-with-motorcomm-phy-how-to-fix-it/247083?u=linuxtardis
Signed-off-by: Jakub Vaněk <linuxtardis@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/22259
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/generic/hack-6.12/755-net-phy-motorcomm-yt8821-bus-collision-workaround.patch [new file with mode: 0644]

diff --git a/target/linux/generic/hack-6.12/755-net-phy-motorcomm-yt8821-bus-collision-workaround.patch b/target/linux/generic/hack-6.12/755-net-phy-motorcomm-yt8821-bus-collision-workaround.patch
new file mode 100644 (file)
index 0000000..28c4c70
--- /dev/null
@@ -0,0 +1,85 @@
+From 63161fb6353493c648a260244f6ac7eca65fd48e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jakub=20Van=C4=9Bk?= <linuxtardis@gmail.com>
+Date: Mon, 2 Mar 2026 20:31:37 +0100
+Subject: [PATCH] net: phy: Work around MDIO collisions in the YT8821 driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The Cudy M3000 router suffers from a MDIO bus collision:
+- The MT7981B internal gigabit PHY listens on address 0.
+- The Motorcomm YT8821 is strapped to listen on address 1,
+  but it initially also listens on address 0 (Motorcomm
+  incorrectly considers that address a broadcast address).
+
+Without this patch, the YT8821 reacts to MDIO commands intended
+for the internal gigabit PHY and that makes it work unreliably.
+The YT8821 state somehow gets corrupted by the commands for the MT7981
+(e.g. we get 100Mbps speeds on gigabit links).
+
+This dirty workaround resets the PHY to cancel out any earlier
+YT8821 register corruption and then it disables the address 0
+as soon as possible. This should make the YT8821 work reliably.
+
+BEWARE though: the PHY will be reset only if the device tree
+node that defines the PHY carries the reset-gpios attribute.
+The PHY will not be reset if the reset GPIO is either on the MDIO
+bus node or is not defined at all. This might not always be a problem --
+some routers do not require the PHY to be reset (e.g. Cudy WR3000H,
+where there likely is less communication with the MT7981B PHY,
+and so the YT8821 PHY works reasonably well there even without this patch).
+
+This patch also does not address the possible MDIO bus collisions
+when the MT7981B PHY driver initially configures that PHY and invokes
+some read transactions on the bus. I am hoping that the MT7981B MDIO
+bus controller gives priority to the internal PHY and so it would
+not be affected by these collisions. However, I don't have anything
+to base this on apart from it "seeming to be working okay".
+
+This patch is unlikely to be mergeable into the mainline kernel.
+Upstream has strongly indicated that they would prefer this problem
+to be resolved by the platform bootloader (e.g. U-Boot), see
+- https://lore.kernel.org/all/d3bb9c36-5a0e-4339-901d-2dd21bdba395@gmail.com/
+- https://lore.kernel.org/all/20260228232241.1274236-1-linuxtardis@gmail.com/
+
+Signed-off-by: Jakub Vaněk <linuxtardis@gmail.com>
+---
+ drivers/net/phy/motorcomm.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/net/phy/motorcomm.c
++++ b/drivers/net/phy/motorcomm.c
+@@ -214,6 +214,9 @@
+ #define YT8521_RC1R_RGMII_2_100_NS            14
+ #define YT8521_RC1R_RGMII_2_250_NS            15
++#define YTPHY_MDIO_ADDRESS_CONTROL_REG                0xA005
++#define YTPHY_MACR_EN_PHY_ADDR_0              BIT(6)
++
+ #define YTPHY_MISC_CONFIG_REG                 0xA006
+ #define YTPHY_MCR_FIBER_SPEED_MASK            BIT(0)
+ #define YTPHY_MCR_FIBER_1000BX                        (0x1 << 0)
+@@ -2659,6 +2662,23 @@ static int yt8821_config_init(struct phy
+       int ret;
+       u16 set;
++      /* Hard-reset the PHY to clear out any register corruption
++       * from preceding MDIO bus conflicts.
++       */
++      phy_device_reset(phydev, 1);
++
++      /* Deassert the reset GPIO under the MDIO bus lock to make
++       * sure that nothing will communicate on the bus until we
++       * disable the broadcast address in the YT8821.
++       */
++      phy_lock_mdio_bus(phydev);
++      phy_device_reset(phydev, 0);
++      ret = ytphy_modify_ext(phydev,
++                             YTPHY_MDIO_ADDRESS_CONTROL_REG,
++                             YTPHY_MACR_EN_PHY_ADDR_0,
++                             0);
++      phy_unlock_mdio_bus(phydev);
++
+       if (phydev->interface == PHY_INTERFACE_MODE_2500BASEX)
+               mode = YT8821_CHIP_MODE_FORCE_BX2500;