[openwrt/openwrt] realtek: refactor RTL930x MAC config to fix PHY ports

LEDE Commits lede-commits at lists.infradead.org
Tue Apr 1 11:35:22 PDT 2025


svanheule pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/a7e1e138172a1e4f9c35db93c11d026bb3338e24

commit a7e1e138172a1e4f9c35db93c11d026bb3338e24
Author: Jan Hoffmann <jan at 3e8.eu>
AuthorDate: Thu Feb 27 20:43:26 2025 +0100

    realtek: refactor RTL930x MAC config to fix PHY ports
    
    Currently, network ports using PHYs get a link, but there is no traffic.
    Make it work again by moving the MAC config to phylink_mac_link_up.
    
    A similiar change has been previously applied for RTL83xx in commit
    cd958d945be0 ("realtek: 6.6: refactor mac config and link up for
    RTL83xx").
    
    Fixes: https://github.com/openwrt/openwrt/issues/17010
    Signed-off-by: Jan Hoffmann <jan at 3e8.eu>
    Tested-by: Christoph Krapp <achterin at gmail.com>
    Link: https://github.com/openwrt/openwrt/pull/18268
    Signed-off-by: Sander Vanheule <sander at svanheule.net>
---
 .../files-6.6/drivers/net/dsa/rtl83xx/dsa.c        | 86 ++++++++++------------
 .../files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h    |  5 ++
 2 files changed, 44 insertions(+), 47 deletions(-)

diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
index cdfe0fe3dc..46683cbb14 100644
--- a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
@@ -798,10 +798,6 @@ static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port,
 {
 	struct rtl838x_switch_priv *priv = ds->priv;
 	int sds_num;
-	u32 reg;
-
-	pr_info("%s port %d, mode %x, phy-mode: %s, speed %d, link %d\n", __func__,
-		port, mode, phy_modes(state->interface), state->speed, state->link);
 
 	/* Nothing to be done for the CPU-port */
 	if (port == priv->cpu_port)
@@ -817,48 +813,6 @@ static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port,
 	     state->interface == PHY_INTERFACE_MODE_SGMII ||
 	     state->interface == PHY_INTERFACE_MODE_10GBASER))
 		rtl9300_serdes_setup(port, sds_num, state->interface);
-
-	reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
-	reg &= ~(0xf << 3);
-
-	switch (state->speed) {
-	case SPEED_10000:
-		reg |= 4 << 3;
-		break;
-	case SPEED_5000:
-		reg |= 6 << 3;
-		break;
-	case SPEED_2500:
-		reg |= 5 << 3;
-		break;
-	case SPEED_1000:
-		reg |= 2 << 3;
-		break;
-	case SPEED_100:
-		reg |= 1 << 3;
-		break;
-	default:
-		/* Also covers 10M */
-		break;
-	}
-
-	if (state->link)
-		reg |= RTL930X_FORCE_LINK_EN;
-
-	if (priv->lagmembers & BIT_ULL(port))
-		reg |= RTL930X_DUPLEX_MODE | RTL930X_FORCE_LINK_EN;
-
-	if (state->duplex == DUPLEX_FULL)
-		reg |= RTL930X_DUPLEX_MODE;
-	else
-		reg &= ~RTL930X_DUPLEX_MODE; /* Clear duplex bit otherwise */
-
-	if (priv->ports[port].phy_is_integrated)
-		reg &= ~RTL930X_FORCE_EN; /* Clear MAC_FORCE_EN to allow SDS-MAC link */
-	else
-		reg |= RTL930X_FORCE_EN;
-
-	sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
 }
 
 static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
@@ -964,11 +918,49 @@ static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
 				   int speed, int duplex,
 				   bool tx_pause, bool rx_pause)
 {
+	struct dsa_port *dp = dsa_to_port(ds, port);
 	struct rtl838x_switch_priv *priv = ds->priv;
+	u32 mcr, spdsel;
+
+	if (speed == SPEED_10000)
+		spdsel = RTL_SPEED_10000;
+	else if (speed == SPEED_5000)
+		spdsel = RTL_SPEED_5000;
+	else if (speed == SPEED_2500)
+		spdsel = RTL_SPEED_2500;
+	else if (speed == SPEED_1000)
+		spdsel = RTL_SPEED_1000;
+	else if (speed == SPEED_100)
+		spdsel = RTL_SPEED_100;
+	else
+		spdsel = RTL_SPEED_10;
+
+	mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
+
+	if (priv->family_id == RTL9300_FAMILY_ID) {
+		mcr &= ~RTL930X_RX_PAUSE_EN;
+		mcr &= ~RTL930X_TX_PAUSE_EN;
+		mcr &= ~RTL930X_DUPLEX_MODE;
+		mcr &= ~RTL930X_SPEED_MASK;
+		mcr |= RTL930X_FORCE_LINK_EN;
+		mcr |= spdsel << RTL930X_SPEED_SHIFT;
+
+		if (tx_pause)
+			mcr |= RTL930X_TX_PAUSE_EN;
+		if (rx_pause)
+			mcr |= RTL930X_RX_PAUSE_EN;
+		if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
+			mcr |= RTL930X_DUPLEX_MODE;
+		if (dsa_port_is_cpu(dp) || !priv->ports[port].phy_is_integrated)
+			mcr |= RTL930X_FORCE_EN;
+	}
+
+	pr_debug("%s port %d, mode %x, speed %d, duplex %d, txpause %d, rxpause %d: set mcr=%08x\n",
+		__func__, port, mode, speed, duplex, tx_pause, rx_pause, mcr);
+	sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
 
 	/* Restart TX/RX to port */
 	sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
-	/* TODO: Set speed/duplex/pauses */
 }
 
 static void rtl83xx_get_strings(struct dsa_switch *ds,
diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h
index 13a0bb5ffa..16c6098378 100644
--- a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h
@@ -147,6 +147,9 @@
 #define RTL_SPEED_10				0
 #define RTL_SPEED_100				1
 #define RTL_SPEED_1000				2
+#define RTL_SPEED_2500				5
+#define RTL_SPEED_5000				6
+#define RTL_SPEED_10000				4
 
 #define RTL83XX_FORCE_EN			(1 << 0)
 #define RTL83XX_FORCE_LINK_EN			(1 << 1)
@@ -169,6 +172,8 @@
 #define RTL930X_FORCE_EN			(1 << 0)
 #define RTL930X_FORCE_LINK_EN			(1 << 1)
 #define RTL930X_DUPLEX_MODE			(1 << 2)
+#define RTL930X_SPEED_SHIFT			(3)
+#define RTL930X_SPEED_MASK			(15 << RTL930X_SPEED_SHIFT)
 #define RTL930X_TX_PAUSE_EN			(1 << 7)
 #define RTL930X_RX_PAUSE_EN			(1 << 8)
 #define RTL930X_MAC_FORCE_FC_EN			(1 << 9)




More information about the lede-commits mailing list