[PATCH net-next v2 0/5] net: phy: Disable MDIO broadcast address on YT8821

From: Jakub Vaněk

Date: Sat Feb 28 2026 - 18:23:20 EST


Hello,

this series is a rewrite of patch [1], which attempted to make the
Motorcomm YT8821 PHY operate reliably in the Cudy M3000 WiFi router.

Background
==========

The issue on the Cudy M3000 is an MDIO address collision at address 0:

* The MediaTek MT7981B internal Gigabit PHY appears to be hardwired
to respond only at MDIO address 0.

* The Motorcomm YT8821 external PHY responds, by default, at address 0
in addition to address 1 selected by its strapping pins.

At a minimum, this means that MDIO transactions intended for the
MT7981B PHY are also interpreted by the YT8821, which causes the
YT8821 to not work reliably.

The YT8821 is not unique in this regard. At least two other vendors
ship PHYs with similar behavior:

* Realtek RTL8221B-VB-CG
* Micrel KSZ8081

It appears to me that multiple vendors may have interpreted IEEE 802.3
Clause 22.2.4.5.5 to mean that MDIO address 0 is a reserved broadcast
address ("A PHY [...] shall always respond to transactions addressed
to PHY Address zero"). However, the omitted part of that sentence
limits the scope, and it does not apply to many PHY types.

What this series does
=====================

The goal of this series is to reconfigure the YT8821 early enough so
that it stops responding on address 0 before the kernel performs the
first access to MDIO address 0.

The approach is as follows:

1. Patches 1 and 2 modify the MDIO bus probing order so that address 0
is scanned last. This allows PHY fixups to reconfigure PHYs found
at addresses 1-31 before address 0 is probed. The core idea was
suggested by @dangowrt on OpenWrt GitHub [2].

2. Patches 3-5 implement the required PHY fixup for the YT8821.
They introduce infrastructure for an "address 0 fixup" that can
be reused by other affected PHYs.

I initially attempted to use the driver .probe() callback. However,
testing showed that this is insufficient: if the YT8821 driver is
built as a module, the .probe() callback does not run early
enough (i.e. before the MT7981B PHY is initialized).

Why this is done in the kernel
==============================

In the v1 discussion [1], the conclusion was that this should ideally
be handled in the bootloader. However, this is not always practical
for OpenWrt deployments:

* On the Cudy M3000, replacing the stock U-Boot is possible, but
doing so removes the ability to easily revert to the vendor
firmware using the procedure described in [3].

* On other platforms, replacing the bootloader may not be possible, and
so OpenWrt may need to have a kernel-based workaround for them [2].

Testing
=======

The series was tested against the v6.12 kernel currently used by
OpenWrt main. It resolves the PHY issues on the Cudy M3000 with the
Motorcomm PHY and does not break networking on the Cudy WR3000H,
which uses a different Realtek PHY.

I also verified that no MDIO access to address 0 occurs before the
YT8821 is reconfigured to stop responding on that address.

The series is rebased on top of v7.0-rc1 and build-tested there.

[1]: https://lore.kernel.org/all/d3bb9c36-5a0e-4339-901d-2dd21bdba395@xxxxxxxxx/#t
[2]: https://github.com/openwrt/openwrt/pull/21584#issuecomment-3941868545
[3]: https://www.cudy.com/en-eu/blogs/faq/how-to-recovery-the-cudy-router-from-openwrt-firmware-to-cudy-official-firmware

Signed-off-by: Jakub Vaněk <linuxtardis@xxxxxxxxx>
---
Changes in v2:
- Introduce changes into the PHY core that allow the broadcast
addresses to be disabled before the first address collision
occurs.
- Move the early disabling of the broadcast address from the
YT8821 .probe() callback into a PHY fixup.
- In motorcomm.c, use ytphy_read_ext_with_lock() for the disabling
as it takes the MDIO bus lock.

Jakub Vaněk (5):
net: mdio_bus: Scan buses in reverse order (31 -> 0)
of: mdio: Scan PHY address 0 last
net: phy: Support PHY fixups on Clause 45 PHYs
net: phy: Add infrastructure for PHY address 0 fixups
net: phy: motorcomm: yt8821: Disable MDIO broadcast

drivers/net/mdio/of_mdio.c | 35 +++++++++++++++--
drivers/net/phy/Makefile | 3 +-
drivers/net/phy/mdio_bus_provider.c | 14 ++++++-
drivers/net/phy/motorcomm.c | 29 ++++++++++++++
drivers/net/phy/phy_common_fixups.c | 59 ++++++++++++++++++++++++++++
drivers/net/phy/phy_device.c | 60 ++++++++++++++++++++---------
drivers/net/phy/phylib-internal.h | 2 +
7 files changed, 176 insertions(+), 26 deletions(-)
create mode 100644 drivers/net/phy/phy_common_fixups.c

--
2.43.0