[openwrt/openwrt] realtek: mdio: enhance reading phy id

LEDE Commits lede-commits at lists.infradead.org
Sun Jan 25 03:12:19 PST 2026


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/322041ffeb9076b1fbc753176723100c0a630976

commit 322041ffeb9076b1fbc753176723100c0a630976
Author: Jonas Jelonek <jelonek.jonas at gmail.com>
AuthorDate: Sun Jan 11 10:12:00 2026 +0000

    realtek: mdio: enhance reading phy id
    
    Reading the PHY ID to assign a PHY config is currently simple. For C45
    two MDIO reads of a hardcoded MMD are done to get the standard PHY ID
    registers. MMD 31 (MMD_VEND2) is used for that purpose, assuming there
    will be a valid PHY ID stored in this MMD in all cases. However, with
    Aquantia AQR813 there's at least one example for which this isn't true.
    This PHY returns 0 for the PHY ID in MMD_VEND2, instead MMD_VEND1 would
    have the correct ID.
    
    Enhance reading the PHY by accessing a common set of MMDs of which most
    PHY at least implement one and have a valid PHY ID in. To keep overhead
    low, do not scan all MMDs. As soon as a valid PHY ID is found, exit and
    use that. This is similar to the kernel logic, jsut reduced to fewer
    MMDs.
    
    Also handle possible errors coming from MDIO reads to avoid reading garbage.
    
    While at it, move reading the PHY ID to a separate function to not
    pollute the poll fixup retrievel function.
    
    Signed-off-by: Jonas Jelonek <jelonek.jonas at gmail.com>
    Link: https://github.com/openwrt/openwrt/pull/21515
    Signed-off-by: Robert Marko <robert.marko at sartura.hr>
---
 .../drivers/net/mdio/mdio-realtek-otto.c           | 56 +++++++++++++++++++---
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c b/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c
index 9ff2a91a17..8e97e21c3f 100644
--- a/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c
+++ b/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c
@@ -532,6 +532,52 @@ static int rtmdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
 	return 0;
 }
 
+static int rtmdio_read_phy_id(struct mii_bus *bus, u8 addr, unsigned int *phy_id)
+{
+	static const int common_mmds[] = {
+		MDIO_MMD_PMAPMD, MDIO_MMD_PCS, MDIO_MMD_AN,
+		MDIO_MMD_VEND1, MDIO_MMD_VEND2
+	};
+	struct rtmdio_bus_priv *priv = bus->priv;
+	int devid1 = 0, devid2 = 0;
+	unsigned int id = 0;
+
+	/* Clause 22 */
+	if (!priv->smi_bus_isc45[priv->smi_bus[addr]]) {
+		devid1 = rtmdio_read(bus, addr, MDIO_DEVID1);
+		devid2 = rtmdio_read(bus, addr, MDIO_DEVID2);
+		if (devid1 < 0 || devid2 < 0)
+			return -EIO;
+
+		id = (devid1 << 16) | devid2;
+		if (!id || (id & 0x1fffffff) == 0x1fffffff)
+			return -ENODEV;
+
+		*phy_id = id;
+		return 0;
+	}
+
+
+	/* Clause 45
+	 * only scan some MMDs which can be considered as common i.e.
+	 * implemented by most PHYs.
+	 */
+	for (int i = 0; i < ARRAY_SIZE(common_mmds); i++) {
+		devid1 = rtmdio_read_c45(bus, addr, common_mmds[i], MDIO_DEVID1);
+		devid2 = rtmdio_read_c45(bus, addr, common_mmds[i], MDIO_DEVID2);
+		if (devid1 < 0 || devid2 < 0)
+			continue;
+
+		id = (devid1 << 16) | devid2;
+		if (id && id != 0xffffffff) {
+			*phy_id = id;
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
 static void rtmdio_get_phy_info(struct mii_bus *bus, int addr, struct rtmdio_phy_info *phyinfo)
 {
 	struct rtmdio_bus_priv *priv = bus->priv;
@@ -547,12 +593,10 @@ static void rtmdio_get_phy_info(struct mii_bus *bus, int addr, struct rtmdio_phy
 		return;
 	}
 
-	if (priv->smi_bus_isc45[priv->smi_bus[addr]])
-		phyinfo->phy_id = (rtmdio_read_c45(bus, addr, 31, 2) << 16) +
-				 rtmdio_read_c45(bus, addr, 31, 3);
-	else
-		phyinfo->phy_id = (rtmdio_read(bus, addr, 2) << 16) +
-				 rtmdio_read(bus, addr, 3);
+	if (rtmdio_read_phy_id(bus, addr, &phyinfo->phy_id) < 0) {
+		phyinfo->phy_unknown = true;
+		return;
+	}
 
 	switch(phyinfo->phy_id) {
 	case RTMDIO_PHY_AQR113C:




More information about the lede-commits mailing list