1
0
Fork 0
forked from mirror/openwrt

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 <markus.stockhausen@gmx.de>
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/22450
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Jonas Jelonek 2026-03-16 13:10:14 +01:00 committed by Robert Marko
parent e198b2504c
commit e625e7e650

View file

@ -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,