From 6dae444ee94d05972c842e765daf01de0fe50ce5 Mon Sep 17 00:00:00 2001 From: Jan Hoffmann Date: Thu, 5 Feb 2026 00:17:32 +0100 Subject: [PATCH] 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 Link: https://github.com/openwrt/openwrt/pull/21869 Signed-off-by: Robert Marko --- .../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 5065e4ee393..529c7ff4ad5 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 = { -- 2.47.3