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>
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;
/* 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;