From 926ffa10b40855889149c4a78d01cdeda2b821db Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Fri, 11 Jul 2025 06:58:59 -0400 Subject: [PATCH] realtek: simplify RTL8218B/RTL8214Fx detection The current implementation has several issues: - it uses the hacky phy_port* macros - it uses SoC dependent raw pages - it disables/enables SoC dependent polling Get rid of these dependencies and access the mdio bus the normal way. Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/19372 Signed-off-by: Hauke Mehrtens --- .../files-6.12/drivers/net/phy/rtl83xx-phy.c | 49 +++++++------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c index f8eddaec4f5..e794b1296d7 100644 --- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c +++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c @@ -22,10 +22,8 @@ extern struct rtl83xx_soc_info soc_info; extern struct mutex smi_lock; extern int phy_package_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val); extern int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val); -extern int phy_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val); extern int phy_package_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum); extern int phy_package_read_paged(struct phy_device *phydev, int page, u32 regnum); -extern int phy_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum); #define PHY_PAGE_2 2 #define PHY_PAGE_4 4 @@ -157,9 +155,9 @@ static int resume_polling(u64 saved_state) static int rtl821x_match_phy_device(struct phy_device *phydev) { - u64 poll_state; - int rawpage, port = phydev->mdio.addr & ~3; - int oldpage, chip_mode, chip_cfg_mode; + int oldpage, oldxpage, chip_mode, chip_cfg_mode; + struct mii_bus *bus = phydev->mdio.bus; + int addr = phydev->mdio.addr & ~3; if (phydev->phy_id == PHY_ID_RTL8218B_E) return PHY_IS_RTL8218B_E; @@ -167,36 +165,27 @@ static int rtl821x_match_phy_device(struct phy_device *phydev) if (phydev->phy_id != PHY_ID_RTL8214_OR_8218) return PHY_IS_NOT_RTL821X; - if (soc_info.family == RTL8380_FAMILY_ID) - rawpage = RTL838X_PAGE_RAW; - else if (soc_info.family == RTL8390_FAMILY_ID) - rawpage = RTL839X_PAGE_RAW; - else - return PHY_IS_NOT_RTL821X; - - poll_state = disable_polling(port); /* - * At this stage the write_page()/read_page() PHY functions are not yet - * registered and normal paged access is not possible. The following - * detection routine works because our MDIO bus has all the Realtek - * PHY page handling (register 31) integrated into the port functions. + * RTL8214FC and RTL8218B are the same PHYs with different configurations. That info is + * stored in the first PHY of the package. In all known configurations packages start at + * bus addresses that are multiples of four. Avoid paged access as this is not available + * during detection. */ - oldpage = phy_port_read_paged(phydev, port, rawpage, 31); - phy_port_write_paged(phydev, port, rawpage, 31, 0xa42); - phy_port_write_paged(phydev, port, rawpage, 29, 0x008); - phy_port_write_paged(phydev, port, rawpage, 31, 0x278); - phy_port_write_paged(phydev, port, rawpage, 18, 0x455); - phy_port_write_paged(phydev, port, rawpage, 31, 0x260); - chip_mode = phy_port_read_paged(phydev, port, rawpage, 18); - phy_port_write_paged(phydev, port, rawpage, 31, 0xa42); - phy_port_write_paged(phydev, port, rawpage, 29, 0x000); - phy_port_write_paged(phydev, port, rawpage, 31, oldpage); - resume_polling(poll_state); + oldpage = mdiobus_read(bus, addr, 0x1f); + oldxpage = mdiobus_read(bus, addr, 0x1e); + + mdiobus_write(bus, addr, 0x1e, 0x8); + mdiobus_write(bus, addr, 0x1f, 0x278); + mdiobus_write(bus, addr, 0x12, 0x455); + mdiobus_write(bus, addr, 0x1f, 0x260); + chip_mode = mdiobus_read(bus, addr, 0x12); + dev_dbg(&phydev->mdio.dev, "got RTL8218B/RTL8214Fx chip mode %04x\n", chip_mode); - pr_debug("%s(%d): got chip mode %x\n", __func__, phydev->mdio.addr, chip_mode); + mdiobus_write(bus, addr, 0x1e, oldxpage); + mdiobus_write(bus, addr, 0x1f, oldpage); - /* we checked the 4th port of a RTL8218B and got no config values */ + /* no values while reading the 5th port during 5-8th port detection of RTL8218B */ if (!chip_mode) return PHY_IS_RTL8218B_E; -- 2.47.2