]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: pcs: configure auto-negotiation on all SoCs
authorJan Hoffmann <jan@3e8.eu>
Sun, 8 Feb 2026 17:10:01 +0000 (18:10 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Wed, 11 Feb 2026 23:33:29 +0000 (00:33 +0100)
RTL83xx uses the BMCR and ADVERTISE registers like RTL93xx to configure
in-band auto-negotiation. Split out the common parts as a new generic
implementation and use it for RTL83xx. RTL93xx retains its own variant
of set_autoneg to support XSGMII, but calls into the generic version for
all other modes.

Tested 1000Base-X auto-negotiation on HPE 1920-8G (RTL8380). Also tested
HPE 1920-24G (RTL8382) and HPE-1920-48G (RTL8393) to make sure this does
not affect PHY ports.

Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Link: https://github.com/openwrt/openwrt/pull/21934
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c

index e7efe0488899897e6fb441c30620a17f851edafb..72379c1d7f118ec132bb837fd9aaea57605f276b 100644 (file)
@@ -444,6 +444,46 @@ static int rtpcs_sds_determine_hw_mode(struct rtpcs_serdes *sds,
        return 0;
 }
 
+/* Generic auto-negotiation config */
+
+static int rtpcs_generic_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg_mode,
+                                        const unsigned long *advertising)
+{
+       u16 bmcr, adv;
+       bool changed = 0;
+       int ret;
+
+       if ((sds->hw_mode == RTPCS_SDS_MODE_1000BASEX) ||
+           (sds->hw_mode == RTPCS_SDS_MODE_2500BASEX)) {
+               adv = ADVERTISE_1000XFULL;
+               if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                     advertising))
+                       adv |= ADVERTISE_1000XPAUSE;
+               if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                     advertising))
+                       adv |= ADVERTISE_1000XPSE_ASYM;
+
+               ret = rtpcs_sds_modify_changed(sds, 0x2, MII_ADVERTISE,
+                                              0xffff, adv);
+               if (ret < 0)
+                       return ret;
+               changed = ret;
+       }
+
+       bmcr = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE : 0;
+
+       ret = rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANENABLE, bmcr);
+       if (ret < 0)
+               return ret;
+
+       return changed;
+}
+
+static void rtpcs_generic_sds_restart_autoneg(struct rtpcs_serdes *sds)
+{
+       rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANRESTART, BMCR_ANRESTART);
+}
+
 /* Variant-specific functions */
 
 /* RTL838X */
@@ -968,9 +1008,7 @@ static int rtpcs_839x_setup_serdes(struct rtpcs_serdes *sds,
 static int rtpcs_93xx_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg_mode,
                                      const unsigned long *advertising)
 {
-       u16 bmcr, adv, en_val;
-       bool changed = 0;
-       int ret;
+       u16 en_val;
 
        switch (sds->hw_mode) {
        case RTPCS_SDS_MODE_XSGMII: /* XSG N-way state */
@@ -978,38 +1016,10 @@ static int rtpcs_93xx_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg
 
                return rtpcs_sds_xsg_write_bits(sds, 0x0, 0x2, 9, 8, en_val);
        default:
-               if ((sds->hw_mode == RTPCS_SDS_MODE_1000BASEX) ||
-                   (sds->hw_mode == RTPCS_SDS_MODE_2500BASEX)) {
-                       adv = ADVERTISE_1000XFULL;
-                       if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-                                             advertising))
-                               adv |= ADVERTISE_1000XPAUSE;
-                       if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-                                             advertising))
-                               adv |= ADVERTISE_1000XPSE_ASYM;
-
-                       ret = rtpcs_sds_modify_changed(sds, 0x2, MII_ADVERTISE,
-                                                      0xffff, adv);
-                       if (ret < 0)
-                               return ret;
-                       changed = ret;
-               }
-
-               bmcr = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE : 0;
-
-               ret = rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANENABLE, bmcr);
-               if (ret < 0)
-                       return ret;
-
-               return changed;
+               return rtpcs_generic_sds_set_autoneg(sds, neg_mode, advertising);
        }
 }
 
-static void rtpcs_93xx_sds_restart_autoneg(struct rtpcs_serdes *sds)
-{
-       rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANRESTART, BMCR_ANRESTART);
-}
-
 static int rtpcs_93xx_init_serdes_common(struct rtpcs_ctrl *ctrl)
 {
        u32 model_info = 0;
@@ -3980,6 +3990,8 @@ static const struct phylink_pcs_ops rtpcs_838x_pcs_ops = {
 static const struct rtpcs_serdes_ops rtpcs_838x_sds_ops = {
        .read                   = rtpcs_generic_sds_op_read,
        .write                  = rtpcs_generic_sds_op_write,
+       .set_autoneg            = rtpcs_generic_sds_set_autoneg,
+       .restart_autoneg        = rtpcs_generic_sds_restart_autoneg,
 };
 
 static const struct rtpcs_config rtpcs_838x_cfg = {
@@ -4006,6 +4018,8 @@ static const struct phylink_pcs_ops rtpcs_839x_pcs_ops = {
 static const struct rtpcs_serdes_ops rtpcs_839x_sds_ops = {
        .read                   = rtpcs_generic_sds_op_read,
        .write                  = rtpcs_generic_sds_op_write,
+       .set_autoneg            = rtpcs_generic_sds_set_autoneg,
+       .restart_autoneg        = rtpcs_generic_sds_restart_autoneg,
 };
 
 static const struct rtpcs_config rtpcs_839x_cfg = {
@@ -4034,7 +4048,7 @@ static const struct rtpcs_serdes_ops rtpcs_930x_sds_ops = {
        .write                  = rtpcs_930x_sds_op_write,
        .xsg_write              = rtpcs_930x_sds_op_xsg_write,
        .set_autoneg            = rtpcs_93xx_sds_set_autoneg,
-       .restart_autoneg        = rtpcs_93xx_sds_restart_autoneg,
+       .restart_autoneg        = rtpcs_generic_sds_restart_autoneg,
 };
 
 static const struct rtpcs_config rtpcs_930x_cfg = {
@@ -4063,7 +4077,7 @@ static const struct rtpcs_serdes_ops rtpcs_931x_sds_ops = {
        .write                  = rtpcs_generic_sds_op_write,
        .xsg_write              = rtpcs_931x_sds_op_xsg_write,
        .set_autoneg            = rtpcs_93xx_sds_set_autoneg,
-       .restart_autoneg        = rtpcs_93xx_sds_restart_autoneg,
+       .restart_autoneg        = rtpcs_generic_sds_restart_autoneg,
 };
 
 static const struct rtpcs_config rtpcs_931x_cfg = {