From: Jonas Jelonek Date: Wed, 20 May 2026 19:57:32 +0000 (+0000) Subject: realtek: pcs: rtl930x: lift SerDes core power-cycle into {de,}activate X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=788745bae50dc4cd7c6ebefcd4a8a5df57b3ae21;p=thirdparty%2Fopenwrt.git realtek: pcs: rtl930x: lift SerDes core power-cycle into {de,}activate Move rtpcs_930x_sds_set_power() and rtpcs_930x_sds_rx_reset() out of rtpcs_930x_sds_apply_ip_mode() and into rtpcs_930x_sds_{de,}activate(). After this, apply_ip_mode is pure IP-mode/CMU/state-machine programming and the SerDes-core analog power is owned by the outer phase pair, the same place that already owns the 1G/10G PHY block and fiber RX power. Behavioural change: USXGMII / QSGMII / XSGMII modes did not previously go through apply_ip_mode and therefore never had the SerDes-core power gated on mode transitions. After this commit, every mode transition power-cycles the SerDes core via the outer deactivate/activate. For the SGMII / 1000BASE-X / 2500BASE-X / 10GBASE-R path the set of register writes is unchanged; only the relative ordering vs. the fiber/PHY power writes shifts: set_power(false) now precedes those writes (was after), set_power(true) now follows them (was before). Verified on RTL930x hardware: SGMII, 2500BASE-X, 10GBASE-R, USXGMII-QX and XSGMII all come up with link, ping and iperf3 throughput as expected. Link: https://github.com/openwrt/openwrt/pull/23513 Signed-off-by: Jonas Jelonek --- diff --git a/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c b/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c index 4de3a2ed935..99a9ee5ec02 100644 --- a/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c +++ b/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c @@ -1804,7 +1804,6 @@ static int rtpcs_930x_sds_apply_ip_mode(struct rtpcs_serdes *sds, * if this sequence should quit early in case of errors. */ - rtpcs_930x_sds_set_power(sds, false); ret = rtpcs_93xx_sds_set_ip_mode(sds, RTPCS_SDS_MODE_OFF); if (ret < 0) return ret; @@ -1828,8 +1827,6 @@ static int rtpcs_930x_sds_apply_ip_mode(struct rtpcs_serdes *sds, pr_err("%s: SDS %d could not reset state machine\n", __func__, sds->id); - rtpcs_930x_sds_set_power(sds, true); - rtpcs_930x_sds_rx_reset(sds, hw_mode); return 0; } @@ -1866,6 +1863,9 @@ static int rtpcs_930x_sds_deactivate(struct rtpcs_serdes *sds) { int 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); if (ret) return ret; @@ -1888,6 +1888,10 @@ static int rtpcs_930x_sds_activate(struct rtpcs_serdes *sds) { int ret; + /* Power up the SerDes core analog block and reset its RX path. */ + rtpcs_930x_sds_set_power(sds, true); + rtpcs_930x_sds_rx_reset(sds, sds->hw_mode); + /* Enable fiber RX. */ ret = rtpcs_sds_write_bits(sds, 0x20, 2, 12, 12, 0); if (ret)