[openwrt/openwrt] realtek: pcs: rtl93xx: fix SerDes polarity configuration for RTL931X
LEDE Commits
lede-commits at lists.infradead.org
Sat Nov 15 02:16:23 PST 2025
robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/203b8886bd6f6abc73ec0c861fba3cf4adfec918
commit 203b8886bd6f6abc73ec0c861fba3cf4adfec918
Author: Jonas Jelonek <jelonek.jonas at gmail.com>
AuthorDate: Thu Nov 13 11:25:44 2025 +0000
realtek: pcs: rtl93xx: fix SerDes polarity configuration for RTL931X
Commit 56e9a73d0b added support for configuring the SerDes polarity for
both RTL930X and RTL931X. Based on the code in the Realtek SDK in [1]
and [2], in both cases the same register bits are set. Thus, a common
implementation was provided which worked with e.g. USXGMII or 10GBase-R
configured SerDes.
However, after further tests, a strange issue occured where it didn't
work that well for all SerDes configurations. While running fine for
10GBase-R links on two adjacent SerDes, it didn't for 1000Base-X links
on one of two adjacent SerDes with the link not being detected as a
symptom.
Diving into the SDK again revealed that the referenced implementation of
polarity configuration is (by accident or by purpose) misleading. While
[1] and [3] for RTL930X match, [2] and [4] for RTL931X actually don't.
[4] writes the bits for the 1G polarity setting on different background
SerDes, thus in another frontend page.
Split implementations for RTL930X and RTL931X again and adjust the one
for RTL931X according to [4]. This resolves the issues with 1000Base-X
behavior.
[1] https://github.com/plappermaul/realtek-doc/blob/69d2890a2e2d7a03df6e40e2cd2c32ff5b074dcf/sources/rtk-xgs1210/src/hal/phy/phy_rtl9300.c#L1384
[2] https://github.com/plappermaul/realtek-doc/blob/69d2890a2e2d7a03df6e40e2cd2c32ff5b074dcf/sources/rtk-xgs1210/src/hal/phy/phy_rtl9310.c#L3479
[3] https://github.com/plappermaul/realtek-doc/blob/69d2890a2e2d7a03df6e40e2cd2c32ff5b074dcf/sources/rtk-xgs1210/src/dal/longan/dal_longan_construct.c#L2246
[4] https://github.com/plappermaul/realtek-doc/blob/69d2890a2e2d7a03df6e40e2cd2c32ff5b074dcf/sources/rtk-xgs1210/src/dal/mango/dal_mango_construct.c#L1550
Fixes: 56e9a73d0b ("realtek: pcs: rtl93xx: provide proper SerDes polarity
configuration")
Signed-off-by: Jonas Jelonek <jelonek.jonas at gmail.com>
Link: https://github.com/openwrt/openwrt/pull/20767
Signed-off-by: Robert Marko <robimarko at gmail.com>
---
.../files-6.12/drivers/net/pcs/pcs-rtl-otto.c | 67 ++++++++++++++--------
1 file changed, 44 insertions(+), 23 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 50addac503..57d6ed9899 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
@@ -213,27 +213,6 @@ static struct rtpcs_link *rtpcs_phylink_pcs_to_link(struct phylink_pcs *pcs)
/* Variant-specific functions */
-/* RTL93XX */
-
-static int rtpcs_93xx_sds_set_polarity(struct rtpcs_ctrl *ctrl, u32 sds,
- bool tx_inv, bool rx_inv)
-{
- u8 rx_val = rx_inv ? 1 : 0;
- u8 tx_val = tx_inv ? 1 : 0;
- u32 val;
- int ret;
-
- /* 10GR */
- val = (tx_val << 1) | rx_val;
- ret = rtpcs_sds_write_bits(ctrl, sds, 0x6, 0x2, 14, 13, val);
- if (ret)
- return ret;
-
- /* 1G */
- val = (rx_val << 1) | tx_val;
- return rtpcs_sds_write_bits(ctrl, sds, 0x0, 0x0, 9, 8, val);
-}
-
/* RTL930X */
/* The access registers for SDS_MODE_SEL and the LSB for each SDS within */
@@ -1645,6 +1624,25 @@ static int rtpcs_930x_sds_10g_idle(struct rtpcs_ctrl *ctrl, int sds_num)
return -EIO;
}
+static int rtpcs_930x_sds_set_polarity(struct rtpcs_ctrl *ctrl, u32 sds,
+ bool tx_inv, bool rx_inv)
+{
+ u8 rx_val = rx_inv ? 1 : 0;
+ u8 tx_val = tx_inv ? 1 : 0;
+ u32 val;
+ int ret;
+
+ /* 10GR */
+ val = (tx_val << 1) | rx_val;
+ ret = rtpcs_sds_write_bits(ctrl, sds, 0x6, 0x2, 14, 13, val);
+ if (ret)
+ return ret;
+
+ /* 1G */
+ val = (rx_val << 1) | tx_val;
+ return rtpcs_sds_write_bits(ctrl, sds, 0x0, 0x0, 9, 8, val);
+}
+
static const sds_config rtpcs_930x_sds_cfg_10gr_even[] =
{
/* 1G */
@@ -1917,7 +1915,7 @@ static int rtpcs_930x_setup_serdes(struct rtpcs_ctrl *ctrl, int sds,
pr_info("%s: Configuring RTL9300 SERDES %d\n", __func__, sds);
/* Set SDS polarity */
- rtpcs_93xx_sds_set_polarity(ctrl, sds, ctrl->tx_pol_inv[sds],
+ rtpcs_930x_sds_set_polarity(ctrl, sds, ctrl->tx_pol_inv[sds],
ctrl->rx_pol_inv[sds]);
/* Enable SDS in desired mode */
@@ -2275,6 +2273,29 @@ static int rtpcs_931x_sds_link_sts_get(struct rtpcs_ctrl *ctrl, u32 sds)
return sts1;
}
+static int rtpcs_931x_sds_set_polarity(struct rtpcs_ctrl *ctrl, u32 sds,
+ bool tx_inv, bool rx_inv)
+{
+ u8 rx_val = rx_inv ? 1 : 0;
+ u8 tx_val = tx_inv ? 1 : 0;
+ u32 val;
+ int ret;
+
+ /* 10gr_*_inv */
+ val = (tx_val << 1) | rx_val;
+ ret = rtpcs_sds_write_bits(ctrl, sds, 0x6, 0x2, 14, 13, val);
+ if (ret)
+ return ret;
+
+ /* xsg_*_inv */
+ val = (rx_val << 1) | tx_val;
+ ret = rtpcs_sds_write_bits(ctrl, sds, 0x40, 0x0, 9, 8, val);
+ if (ret)
+ return ret;
+
+ return rtpcs_sds_write_bits(ctrl, sds, 0x80, 0x0, 9, 8, val);
+}
+
static sds_config sds_config_10p3125g_type1[] = {
{ 0x2E, 0x00, 0x0107 }, { 0x2E, 0x01, 0x01A3 }, { 0x2E, 0x02, 0x6A24 },
{ 0x2E, 0x03, 0xD10D }, { 0x2E, 0x04, 0x8000 }, { 0x2E, 0x05, 0xA17E },
@@ -2497,7 +2518,7 @@ static int rtpcs_931x_setup_serdes(struct rtpcs_ctrl *ctrl, int sds,
}
}
- rtpcs_93xx_sds_set_polarity(ctrl, sds, ctrl->tx_pol_inv[sds],
+ rtpcs_931x_sds_set_polarity(ctrl, sds, ctrl->tx_pol_inv[sds],
ctrl->rx_pol_inv[sds]);
val = ori & ~BIT(sds);
More information about the lede-commits
mailing list