]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: pcs: rtl930x: force IP mode OFF in deactivate, unforce for MAC modes 23513/head
authorJonas Jelonek <jelonek.jonas@gmail.com>
Wed, 20 May 2026 21:43:33 +0000 (21:43 +0000)
committerJonas Jelonek <jelonek.jonas@gmail.com>
Tue, 26 May 2026 06:38:00 +0000 (08:38 +0200)
Make deactivate fully restore the SerDes to an inert state at both the
MAC and IP layers. Previously deactivate only zeroed the MAC mode via
set_mode(OFF), which on the default branch only writes the MAC mode
register and leaves the IP mode register untouched. The IP mode register
then retained whatever the previous bring-up left behind (force=1 with
a stale mode value, or force=0 from boot defaults), making "deactivate"
not fully deactivate the SerDes.

Replace the set_mode(OFF) call with explicit set_mac_mode(OFF) plus
set_ip_mode(OFF). The latter writes force=1 with mode=OFF, pinning the
IP block to OFF until a subsequent bring-up takes a defined action.

This forced-OFF state would break MAC-driven modes (USXGMII / QSGMII /
XSGMII), which set only the MAC mode register and rely on the IP block
following along. To compensate, add an explicit unforce of the IP mode
force-bit (page 0x1f reg 0x09 bit 6) at the start of the MAC-mode branch
of rtpcs_930x_sds_set_mode. IP-mode bring-up via apply_ip_mode is
unaffected -- it re-asserts force=1 with the target mode value, which
overrides the deactivate force-OFF.

Net result: deactivate fully and explicitly deactivates the SerDes; each
set_mode path takes its own responsibility for the IP mode register
state. The previous asymmetric behaviour (set_mode default branch silently
not touching the IP register) is now explicit code rather than an
implicit accident-of-dispatch.

Verified on RTL930x hardware: SGMII, 2500BASE-X, 10GBASE-R, USXGMII-QX
and XSGMII all bring up correctly with link, traffic and iperf3 as
expected.

Link: https://github.com/openwrt/openwrt/pull/23513
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c

index 99a9ee5ec02654e5b4b9bb705cbc61492b42989e..7c70a0c086439f54cc5af8197d33d8f75daa53f3 100644 (file)
@@ -1852,6 +1852,14 @@ static int rtpcs_930x_sds_set_mode(struct rtpcs_serdes *sds, enum rtpcs_sds_mode
                break;
        }
 
+       /*
+        * MAC-driven modes: release the IP mode force-lock so the MAC side
+        * takes over. deactivate forces IP=OFF; this undoes that.
+        */
+       ret = rtpcs_sds_write_bits(sds, 0x1f, 0x09, 6, 6, 0);
+       if (ret)
+               return ret;
+
        ret = rtpcs_93xx_sds_set_mac_mode(sds, hw_mode);
        if (ret)
                return ret;
@@ -1866,7 +1874,12 @@ static int rtpcs_930x_sds_deactivate(struct rtpcs_serdes *sds)
        /* Power down the SerDes core analog block. */
        rtpcs_930x_sds_set_power(sds, false);
 
-       ret = rtpcs_930x_sds_set_mode(sds, RTPCS_SDS_MODE_OFF);
+       /* Force MAC and IP mode registers to OFF, leaving the SerDes inert. */
+       ret = rtpcs_93xx_sds_set_mac_mode(sds, RTPCS_SDS_MODE_OFF);
+       if (ret)
+               return ret;
+
+       ret = rtpcs_93xx_sds_set_ip_mode(sds, RTPCS_SDS_MODE_OFF);
        if (ret)
                return ret;