]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: pcs: rtl931x: fix clearing symbol errors
authorJonas Jelonek <jelonek.jonas@gmail.com>
Sat, 20 Dec 2025 18:36:56 +0000 (18:36 +0000)
committerRobert Marko <robimarko@gmail.com>
Mon, 29 Dec 2025 16:06:19 +0000 (17:06 +0100)
Fix the implementation to clear symbol errors. Up to now, it was barely
functional because important modes weren't handled. Add another function
(which is needed in the future anyway) and pick to missing bits from
that function into the symbol clearing function to handle the modes
1000Base-X and 10GBaseR too. All that is based on [1].

While at it, rename the function to adhere to a common naming scheme and
fix some minor style issues.

[1] https://github.com/plappermaul/realtek-doc/blob/69d2890a2e2d7a03df6e40e2cd2c32ff5b074dcf/sources/rtk-dms1250/src/hal/phy/phy_rtl9310.c#L703

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/20736
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c

index d2268ae76d02d57f56589bc03ab9814f8797ddf2..768952b4725401bd0bf67b78c0d0c91310ba9eb6 100644 (file)
@@ -2340,30 +2340,64 @@ static void rtpcs_931x_sds_disable(struct rtpcs_serdes *sds)
                     RTL931X_SERDES_MODE_CTRL + (sds->id >> 2) * 4, 0x9f);
 }
 
-static void rtpcs_931x_sds_symerr_clear(struct rtpcs_serdes *sds,
-                                       phy_interface_t mode)
+__maybe_unused
+static int rtpcs_931x_sds_fiber_get_symerr(struct rtpcs_serdes *sds,
+                                          phy_interface_t mode)
 {
+       int symerr, val, val2;
+
        switch (mode) {
-       case PHY_INTERFACE_MODE_NA:
+       case PHY_INTERFACE_MODE_10GBASER:
+               symerr = rtpcs_sds_read_bits(sds, 0x5, 0x1, 7, 0);
                break;
+       case PHY_INTERFACE_MODE_1000BASEX:
+               rtpcs_sds_write_bits(sds, 0x41, 0x18, 2, 0, 0x0);
+
+               val = rtpcs_sds_read_bits(sds, 0x41, 0x3, 15, 8);
+               val2 = rtpcs_sds_read_bits(sds, 0x41, 0x2, 15, 0);
+               symerr = (val << 16) | val2;
+               break;
+       default:
+               symerr = -EINVAL;
+       }
+
+       return symerr;
+}
+
+static void rtpcs_931x_sds_clear_symerr(struct rtpcs_serdes *sds,
+                                       phy_interface_t mode)
+{
+       switch (mode) {
+       case PHY_INTERFACE_MODE_SGMII:
+       case PHY_INTERFACE_MODE_HISGMII:
        case PHY_INTERFACE_MODE_XGMII:
                for (int i = 0; i < 4; ++i) {
-                       rtpcs_sds_write_bits(sds, 0x41, 24,  2, 0, i);
-                       rtpcs_sds_write_bits(sds, 0x41,  3, 15, 8, 0x0);
-                       rtpcs_sds_write_bits(sds, 0x41,  2, 15, 0, 0x0);
+                       rtpcs_sds_write_bits(sds, 0x41, 0x18, 2, 0, i);
+                       rtpcs_sds_write_bits(sds, 0x41, 0x3, 15, 8, 0x0);
+                       rtpcs_sds_write_bits(sds, 0x41, 0x2, 15, 0, 0x0);
                }
 
                for (int i = 0; i < 4; ++i) {
-                       rtpcs_sds_write_bits(sds, 0x81, 24,  2, 0, i);
-                       rtpcs_sds_write_bits(sds, 0x81,  3, 15, 8, 0x0);
-                       rtpcs_sds_write_bits(sds, 0x81,  2, 15, 0, 0x0);
+                       rtpcs_sds_write_bits(sds, 0x81, 0x18, 2, 0, i);
+                       rtpcs_sds_write_bits(sds, 0x81, 0x3, 15, 8, 0x0);
+                       rtpcs_sds_write_bits(sds, 0x81, 0x2, 15, 0, 0x0);
                }
 
-               rtpcs_sds_write_bits(sds, 0x41, 0, 15, 0, 0x0);
-               rtpcs_sds_write_bits(sds, 0x41, 1, 15, 8, 0x0);
-               rtpcs_sds_write_bits(sds, 0x81, 0, 15, 0, 0x0);
-               rtpcs_sds_write_bits(sds, 0x81, 1, 15, 8, 0x0);
+               rtpcs_sds_write_bits(sds, 0x41, 0x0, 15, 0, 0x0);
+               rtpcs_sds_write_bits(sds, 0x41, 0x1, 15, 8, 0x0);
+               rtpcs_sds_write_bits(sds, 0x81, 0x0, 15, 0, 0x0);
+               rtpcs_sds_write_bits(sds, 0x81, 0x1, 15, 8, 0x0);
                break;
+       case PHY_INTERFACE_MODE_1000BASEX:
+               rtpcs_sds_write_bits(sds, 0x41, 0x18, 2, 0, 0x0);
+               rtpcs_sds_write_bits(sds, 0x41, 0x3, 15, 8, 0x0);
+               rtpcs_sds_write_bits(sds, 0x41, 0x2, 15, 0, 0x0);
+               break;
+       case PHY_INTERFACE_MODE_10GBASER:
+               /* to be verified: clear on read? */
+               rtpcs_sds_read_bits(sds, 0x5, 0x1, 7, 0);
+               break;
+       case PHY_INTERFACE_MODE_NA:
        default:
                break;
        }
@@ -2383,7 +2417,7 @@ static void rtpcs_931x_sds_fiber_mode_set(struct rtpcs_serdes *sds,
        u32 val;
 
        /* clear symbol error count before changing mode */
-       rtpcs_931x_sds_symerr_clear(sds, mode);
+       rtpcs_931x_sds_clear_symerr(sds, mode);
 
        rtpcs_931x_sds_disable(sds);