From: Jonas Jelonek Date: Sat, 11 Oct 2025 21:36:25 +0000 (+0000) Subject: realtek: dsa: allow to drop phy-handle on switch ports X-Git-Tag: v25.12.0-rc1~704 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed240e3cc295231c172931269bdfcbf4babe3471;p=thirdparty%2Fopenwrt.git realtek: dsa: allow to drop phy-handle on switch ports When Realtek SerDes is completely handled by PCS, it is not treated as a regular PHY anymore. Thus, we should be able to drop the currently used pseudo-PHYs and phy-handles for ports which just use the SerDes as PCS but have no PHY attached. Allow to drop the phy-handle from switch port definitions if there is a pcs-handle defined by relaxing several checks in the DSA driver. Signed-off-by: Jonas Jelonek Link: https://github.com/openwrt/openwrt/pull/20577 Signed-off-by: Robert Marko --- diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c index 190e495287c..583ece3208a 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c @@ -336,9 +336,8 @@ static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv) pcs_node = of_parse_phandle(dn, "pcs-handle", 0); phy_node = of_parse_phandle(dn, "phy-handle", 0); - if (!phy_node) { - if (pn != priv->cpu_port) - dev_err(priv->dev, "Port node %d misses phy-handle\n", pn); + if (pn != priv->cpu_port && !phy_node && !pcs_node) { + dev_err(priv->dev, "Port node %d has neither pcs-handle nor phy-handle\n", pn); continue; } @@ -385,6 +384,13 @@ static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv) } } + if (!phy_node) { + if (priv->pcs[pn]) + priv->ports[pn].phy_is_integrated = true; + + continue; + } + /* Check for the integrated SerDes of the RTL8380M first */ if (of_property_read_bool(phy_node, "phy-is-integrated") && priv->id == 0x8380 && pn >= 24) { diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c index 0e5e79c45d0..06909d205f7 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c @@ -51,7 +51,7 @@ static void rtl83xx_enable_phy_polling(struct rtl838x_switch_priv *priv) msleep(1000); /* Enable all ports with a PHY, including the SFP-ports */ for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) + if (priv->ports[i].phy || priv->pcs[i]) v |= BIT_ULL(i); } @@ -436,7 +436,7 @@ static int rtl83xx_setup(struct dsa_switch *ds) * they will work in isolated mode (only traffic between port and CPU). */ for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) { + if (priv->ports[i].phy || priv->pcs[i]) { priv->ports[i].pm = BIT_ULL(priv->cpu_port); priv->r->traffic_set(i, BIT_ULL(i)); } @@ -512,7 +512,7 @@ static int rtl93xx_setup(struct dsa_switch *ds) * they will work in isolated mode (only traffic between port and CPU). */ for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) { + if (priv->ports[i].phy || priv->pcs[i]) { priv->ports[i].pm = BIT_ULL(priv->cpu_port); priv->r->traffic_set(i, BIT_ULL(i)); } @@ -1045,7 +1045,7 @@ static void rtldsa_poll_counters(struct work_struct *work) struct rtldsa_counter_state *counters; for (int i = 0; i < priv->cpu_port; i++) { - if (!priv->ports[i].phy) + if (!priv->ports[i].phy && !priv->pcs[i]) continue; counters = &priv->ports[i].counters; @@ -1064,7 +1064,7 @@ static void rtldsa_init_counters(struct rtl838x_switch_priv *priv) struct rtldsa_counter_state *counters; for (int i = 0; i < priv->cpu_port; i++) { - if (!priv->ports[i].phy) + if (!priv->ports[i].phy && !priv->pcs[i]) continue; counters = &priv->ports[i].counters; diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c index 0f29e2f9cd7..d8eee64354f 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c @@ -2419,7 +2419,7 @@ static void rtl930x_led_init(struct rtl838x_switch_priv *priv) sw_w32_mask(0x3 << pos, 0, RTL930X_LED_PORT_FIB_SET_SEL_CTRL(i)); sw_w32_mask(0x3 << pos, 0, RTL930X_LED_PORT_COPR_SET_SEL_CTRL(i)); - if (!priv->ports[i].phy && !(forced_leds_per_port[i])) + if (!priv->ports[i].phy && !priv->pcs[i] && !(forced_leds_per_port[i])) continue; if (forced_leds_per_port[i] > 0) diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c index 444c843db9c..104fc55d2e6 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c @@ -1547,7 +1547,7 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv) sw_w32_mask(0x3 << pos, 0, RTL931X_LED_PORT_COPR_SET_SEL_CTRL(i)); /* Skip port if not present (auto-detect) or not in forced mask */ - if (!priv->ports[i].phy && !(forced_leds_per_port[i])) + if (!priv->ports[i].phy && !priv->pcs[i] && !(forced_leds_per_port[i])) continue; if (forced_leds_per_port[i] > 0)