1
1

realtek: pcs: rtl930x: force IP mode OFF in deactivate, unforce for MAC modes

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>
This commit is contained in:
Jonas Jelonek 2026-05-20 21:43:33 +00:00
parent 788745bae5
commit 383c4469e4
No known key found for this signature in database

View File

@ -1852,6 +1852,14 @@ static int rtpcs_930x_sds_set_mode(struct rtpcs_serdes *sds, enum rtpcs_sds_mode
break; 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); ret = rtpcs_93xx_sds_set_mac_mode(sds, hw_mode);
if (ret) if (ret)
return ret; return ret;
@ -1866,7 +1874,12 @@ static int rtpcs_930x_sds_deactivate(struct rtpcs_serdes *sds)
/* Power down the SerDes core analog block. */ /* Power down the SerDes core analog block. */
rtpcs_930x_sds_set_power(sds, false); 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) if (ret)
return ret; return ret;