]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: pcs: rtl838x: migrate MAC mode setting to regmap_field
authorJonas Jelonek <jelonek.jonas@gmail.com>
Mon, 20 Apr 2026 19:35:13 +0000 (19:35 +0000)
committerRobert Marko <robimarko@gmail.com>
Mon, 27 Apr 2026 08:34:32 +0000 (10:34 +0200)
Replace rtpcs_838x_sds_set_mode()'s inline shift/mask arithmetic with
a regmap_field computed and allocated at probe time. The field layout
is regular (5-bit per SerDes, reverse-packed in SDS_MODE_SEL), so the
position can be derived arithmetically from the SerDes ID rather than
declared in a table.

The function keeps its wrapper role because SerDes 4 and 5 have a
second companion register (INT_MODE_CTRL) with its own per-mode value
encoding. Since RTL838x is the only variant with this quirk and the
register is written from only one call site, it is kept inline rather
than abstracted into its own config table.

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

index 60b914ab33abfa26823f68e4aa9fc3152b36c649..a28b6044cdd5b4c7fe4e31799fa2d2501bf88e8a 100644 (file)
@@ -650,6 +650,14 @@ static int rtpcs_sds_set_mac_mode(struct rtpcs_serdes *sds, enum rtpcs_sds_mode
 
 /* RTL838X */
 
+/* RTL838X SDS_MODE_SEL field values */
+static const s16 rtpcs_838x_sds_hw_mode_vals[RTPCS_SDS_MODE_MAX] = {
+       [0 ... RTPCS_SDS_MODE_MAX - 1]  = -1,
+       [RTPCS_SDS_MODE_1000BASEX]      = 0x4,
+       [RTPCS_SDS_MODE_SGMII]          = 0x2,
+       [RTPCS_SDS_MODE_QSGMII]         = 0x6,
+};
+
 #define SDS(ctrl,n)    (&(ctrl)->serdes[n])
 
 static void rtpcs_838x_sds_patch_01_qsgmii_6275b(struct rtpcs_ctrl *ctrl)
@@ -812,42 +820,39 @@ static int rtpcs_838x_sds_power(struct rtpcs_serdes *sds, bool power_on)
        return ret;
 }
 
-static int rtpcs_838x_sds_set_mode(struct rtpcs_serdes *sds,
-                                  enum rtpcs_sds_mode hw_mode)
+/*
+ * RTL838X wrapper: after setting the MAC mode, SerDes 4-5 also need the
+ * companion INT_MODE_CTRL field written.
+ */
+static int rtpcs_838x_sds_set_mode(struct rtpcs_serdes *sds, enum rtpcs_sds_mode hw_mode)
 {
-       u8 sds_mode_shift, int_mode_shift;
-       u32 sds_mode_val, int_mode_val;
+       u8 int_mode_shift, int_mode_val;
+       int ret;
+
+       ret = rtpcs_sds_set_mac_mode(sds, hw_mode);
+       if (ret)
+               return ret;
+
+       if (sds->id < 4)
+               return 0;
 
+       int_mode_shift = (sds->id == 5) ? 3 : 0;
        switch (hw_mode) {
        case RTPCS_SDS_MODE_1000BASEX:
-               sds_mode_val = 0x4;
                int_mode_val = 0x1;
                break;
        case RTPCS_SDS_MODE_SGMII:
-               sds_mode_val = 0x2;
                int_mode_val = 0x2;
                break;
        case RTPCS_SDS_MODE_QSGMII:
-               sds_mode_val = 0x6;
                int_mode_val = 0x5;
                break;
        default:
                return -EINVAL;
        }
 
-       /* Configure SerDes module mode (all SDS 0-5) */
-       sds_mode_shift = (5 - sds->id) * 5;
-       regmap_write_bits(sds->ctrl->map, RTPCS_838X_SDS_MODE_SEL,
-                         0x1f << sds_mode_shift, sds_mode_val << sds_mode_shift);
-
-       /* Configure MAC interface mode (only SDS 4-5) */
-       if (sds->id >= 4) {
-               int_mode_shift = (sds->id == 5) ? 3 : 0;
-               regmap_write_bits(sds->ctrl->map, RTPCS_838X_INT_MODE_CTRL,
-                                 0x7 << int_mode_shift, int_mode_val << int_mode_shift);
-       }
-
-       return 0;
+       return regmap_write_bits(sds->ctrl->map, RTPCS_838X_INT_MODE_CTRL,
+                                0x7 << int_mode_shift, int_mode_val << int_mode_shift);
 }
 
 static int rtpcs_838x_sds_patch(struct rtpcs_serdes *sds,
@@ -894,8 +899,16 @@ static int rtpcs_838x_sds_patch(struct rtpcs_serdes *sds,
 
 static int rtpcs_838x_sds_probe(struct rtpcs_serdes *sds)
 {
+       u8 lsb = (5 - sds->id) * 5;
+
        sds->type = RTPCS_SDS_TYPE_5G;
-       return 0;
+
+       /*
+        * SDS_MODE_SEL packs 5-bit fields in reverse order: SDS 0 at [25:29],
+        * SDS 5 at [0:4].
+        */
+       return rtpcs_sds_alloc_field(sds, &sds->swcore_regs.mac_mode,
+                                    RTPCS_838X_SDS_MODE_SEL, lsb, lsb + 4);
 }
 
 static int rtpcs_838x_init(struct rtpcs_ctrl *ctrl)
@@ -4367,6 +4380,7 @@ static const struct rtpcs_config rtpcs_838x_cfg = {
        .pcs_ops                = &rtpcs_838x_pcs_ops,
        .sds_ops                = &rtpcs_838x_sds_ops,
        .sds_regs               = &rtpcs_838x_sds_regs,
+       .sds_hw_mode_vals       = rtpcs_838x_sds_hw_mode_vals,
        .init                   = rtpcs_838x_init,
        .sds_probe              = rtpcs_838x_sds_probe,
        .setup_serdes           = rtpcs_838x_setup_serdes,