]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: phy: keep register state during RTL8214FC fibre check 21393/head
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Sun, 4 Jan 2026 20:41:12 +0000 (21:41 +0100)
committerStijn Tintel <stijn@linux-ipv6.be>
Fri, 9 Jan 2026 15:20:35 +0000 (17:20 +0200)
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 <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/21393
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c

index 130ff02171b64eef9abdec35f89d16084ce80d31..d06ae0483607b011f7ec455458a2e2ab4f9973a1 100644 (file)
@@ -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);