[openwrt/openwrt] realtek: dsa: allow to drop phy-handle on switch ports

LEDE Commits lede-commits at lists.infradead.org
Sun Nov 2 07:32:15 PST 2025


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

commit ed240e3cc295231c172931269bdfcbf4babe3471
Author: Jonas Jelonek <jelonek.jonas at gmail.com>
AuthorDate: Sat Oct 11 21:36:25 2025 +0000

    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 <jelonek.jonas at gmail.com>
    Link: https://github.com/openwrt/openwrt/pull/20577
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c      | 12 +++++++++---
 .../linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c   | 10 +++++-----
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c     |  2 +-
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c     |  2 +-
 4 files changed, 16 insertions(+), 10 deletions(-)

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 190e495287..583ece3208 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 0e5e79c45d..06909d205f 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 0f29e2f9cd..d8eee64354 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 444c843db9..104fc55d2e 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)




More information about the lede-commits mailing list