From 1137aaa1c97e44bf1f5582250dc7a030828dcd53 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Sun, 4 Jan 2026 21:41:12 +0100 Subject: [PATCH] realtek: phy: keep register state during RTL8214FC fibre check Reading the fibre status of a RTL8214FC needs access to the page register (31) and the extended page register (30). The current implementation has two issues. - The extended page register is not restored after changes - Instead of register 30 its write-only sibling 29 is used. This has the following side effect: During regular polling kernel calls rtl8214fc_read_status and determines the media status via __rtl8214fc_media_is_fibre. Writing to register 29 a copy of that value is handed over to register 30. This makes use of mdio tools for the first port of the RTL8214FC hard. Register 30 is overwritten with zero every second. Change access from register 29 to register 30 and adapt the sequence to restore register 30 contents at the end. Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/21393 Signed-off-by: Stijn Tintel --- .../realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 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 130ff02171b..d06ae048360 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 @@ -436,14 +436,16 @@ static bool __rtl8214fc_media_is_fibre(struct phy_device *phydev) struct phy_device *basephy = get_base_phy(phydev); static int regs[] = {16, 19, 20, 21}; int reg = regs[phydev->mdio.addr & 3]; - int oldpage, val; + int oldpage, oldxpage, val; - /* The fiber status is a package "global" in the first phy. */ oldpage = __phy_read(basephy, RTL8XXX_PAGE_SELECT); - __phy_write(basephy, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL); + oldxpage = __phy_read(basephy, RTL821XEXT_MEDIA_PAGE_SELECT); + + __phy_write(basephy, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL); __phy_write(basephy, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PORT); val = __phy_read(basephy, reg); - __phy_write(basephy, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); + + __phy_write(basephy, RTL821XEXT_MEDIA_PAGE_SELECT, oldxpage); __phy_write(basephy, RTL8XXX_PAGE_SELECT, oldpage); return !(val & BMCR_PDOWN); -- 2.47.3