[openwrt/openwrt] realtek: pcs: rtl93xx: implement restarting auto-negotiation

LEDE Commits lede-commits at lists.infradead.org
Fri Feb 6 01:23:46 PST 2026


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/6dae444ee94d05972c842e765daf01de0fe50ce5

commit 6dae444ee94d05972c842e765daf01de0fe50ce5
Author: Jan Hoffmann <jan at 3e8.eu>
AuthorDate: Thu Feb 5 00:17:32 2026 +0100

    realtek: pcs: rtl93xx: implement restarting auto-negotiation
    
    Add a new SerDes operation for restarting in-band negotiation including
    an implemenation for RTL93xx, and call it from .pcs_an_restart.
    
    This is a prerequisite for configuration of the in-band advertisement,
    as changing it requires triggering a restart of auto-negotiation.
    
    Signed-off-by: Jan Hoffmann <jan at 3e8.eu>
    Link: https://github.com/openwrt/openwrt/pull/21869
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../files-6.12/drivers/net/pcs/pcs-rtl-otto.c      | 25 ++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 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 5065e4ee39..529c7ff4ad 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
@@ -165,6 +165,7 @@ struct rtpcs_serdes_ops {
 			 u16 value);
 
 	int (*set_autoneg)(struct rtpcs_serdes *sds, unsigned int neg_mode);
+	void (*restart_autoneg)(struct rtpcs_serdes *sds);
 };
 
 struct rtpcs_serdes {
@@ -962,6 +963,11 @@ static int rtpcs_93xx_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg
 	}
 }
 
+static void rtpcs_93xx_sds_restart_autoneg(struct rtpcs_serdes *sds)
+{
+	rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANRESTART, BMCR_ANRESTART);
+}
+
 /* RTL930X */
 
 /* 
@@ -3702,6 +3708,17 @@ static int rtpcs_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg_mode
 	return sds->ops->set_autoneg(sds, neg_mode);
 }
 
+static void rtpcs_sds_restart_autoneg(struct rtpcs_serdes *sds)
+{
+	if (!sds->ops->restart_autoneg) {
+		dev_warn(sds->ctrl->dev, "restart_autoneg not implemented for SDS %u, skipping\n",
+		         sds->id);
+		return;
+	}
+
+	sds->ops->restart_autoneg(sds);
+}
+
 static void rtpcs_pcs_get_state(struct phylink_pcs *pcs, struct phylink_link_state *state)
 {
 	struct rtpcs_link *link = rtpcs_phylink_pcs_to_link(pcs);
@@ -3767,9 +3784,11 @@ static void rtpcs_pcs_an_restart(struct phylink_pcs *pcs)
 {
 	struct rtpcs_link *link = rtpcs_phylink_pcs_to_link(pcs);
 	struct rtpcs_ctrl *ctrl = link->ctrl;
+	struct rtpcs_serdes *sds = link->sds;
 
-	dev_warn(ctrl->dev, "an_restart() for port %d and sds %d not yet implemented\n",
-		 link->port, link->sds->id);
+	mutex_lock(&ctrl->lock);
+	rtpcs_sds_restart_autoneg(sds);
+	mutex_unlock(&ctrl->lock);
 }
 
 static int rtpcs_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
@@ -4032,6 +4051,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,
 };
 
 static const struct rtpcs_config rtpcs_930x_cfg = {
@@ -4059,6 +4079,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,
 };
 
 static const struct rtpcs_config rtpcs_931x_cfg = {




More information about the lede-commits mailing list