[openwrt/openwrt] realtek: pcs: configure auto-negotiation on all SoCs

LEDE Commits lede-commits at lists.infradead.org
Wed Feb 11 15:34:15 PST 2026


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/a517d94c9f5993a1847a2c9a8bc01e2744b83b3c

commit a517d94c9f5993a1847a2c9a8bc01e2744b83b3c
Author: Jan Hoffmann <jan at 3e8.eu>
AuthorDate: Sun Feb 8 18:10:01 2026 +0100

    realtek: pcs: configure auto-negotiation on all SoCs
    
    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 at 3e8.eu>
    Link: https://github.com/openwrt/openwrt/pull/21934
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../files-6.12/drivers/net/pcs/pcs-rtl-otto.c      | 82 +++++++++++++---------
 1 file changed, 48 insertions(+), 34 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 e7efe04888..72379c1d7f 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
@@ -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 = {




More information about the lede-commits mailing list