From e625e7e65026abdc2946451ee8c3742a936eaea6 Mon Sep 17 00:00:00 2001 From: Jonas Jelonek Date: Mon, 16 Mar 2026 13:10:14 +0100 Subject: [PATCH] realtek: pcs: rtl930x: fix 10g RX idle waiting Our implementation waiting for RX idle signal of a 10G SerDes deviates from what the SDK does. While we timeout after 100 reads and thus cannot really control the real time, the SDK times out after 10ms. Adjust that accordingly by switching the timeout to ktime_* functions with a 10ms timeout as per the SDK. While at it, improve the overall style of the function a bit. Suggested-by: Markus Stockhausen Signed-off-by: Jonas Jelonek Link: https://github.com/openwrt/openwrt/pull/22450 Signed-off-by: Robert Marko --- .../files-6.12/drivers/net/pcs/pcs-rtl-otto.c | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c b/target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c index 151cc650bf..98a09eaa1c 100644 --- a/target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c +++ b/target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c @@ -2664,26 +2664,27 @@ static void rtpcs_930x_phy_enable_10g_1g(struct rtpcs_serdes *sds) static int rtpcs_930x_sds_10g_idle(struct rtpcs_serdes *sds) { struct rtpcs_serdes *even_sds = rtpcs_sds_get_even(sds); - bool busy; - int i = 0; + ktime_t timeout; + int bit, busy; + + bit = (sds == even_sds) ? 0 : 1; + timeout = ktime_add_us(ktime_get(), 10000); /* timeout after 10 msecs */ do { - if (sds == even_sds) { - rtpcs_sds_write_bits(sds, 0x1f, 0x2, 15, 0, 53); - busy = !!rtpcs_sds_read_bits(sds, 0x1f, 0x14, 0, 0); - } else { - rtpcs_sds_write_bits(even_sds, 0x1f, 0x2, 15, 0, 53); - busy = !!rtpcs_sds_read_bits(even_sds, 0x1f, 0x14, 1, 1); - } - i++; - } while (busy && i < 100); + rtpcs_sds_write(even_sds, 0x1f, 0x2, 53); + busy = rtpcs_sds_read_bits(even_sds, 0x1f, 0x14, bit, bit); + if (busy < 0) + return busy; - if (i < 100) - return 0; + if (!busy) + return 0; - pr_warn("%s WARNING: Waiting for RX idle timed out, SDS %d\n", + usleep_range(100, 200); /* wait ~100 usecs before retry */ + } while (ktime_before(ktime_get(), timeout)); + + pr_warn("%s: WARNING Waiting for RX idle timed out, SDS %d\n", __func__, sds->id); - return -EIO; + return -ETIMEDOUT; } static int rtpcs_930x_sds_set_polarity(struct rtpcs_serdes *sds,