[openwrt/openwrt] realtek: 6.6: refactor mac config and link up for RTL83xx

LEDE Commits lede-commits at lists.infradead.org
Sat Sep 14 12:30:38 PDT 2024


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

commit cd958d945be06a1b810d55912f32d6e922d952ea
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Tue Aug 27 08:01:57 2024 -0400

    realtek: 6.6: refactor mac config and link up for RTL83xx
    
    Since kernel commit c5714f68a76bcad3d ("net: phylink: explicitly invalidate
    link_state members in mac_config") it should be clear that link data can
    only be used in mac_link_up(). Refactor that for the RTL83xx targets.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
---
 .../files-6.6/drivers/net/dsa/rtl83xx/dsa.c        | 161 +++++++++------------
 .../files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h    |  15 +-
 2 files changed, 81 insertions(+), 95 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 e32933ee91..7ec3f4af1b 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
@@ -671,104 +671,31 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
 					unsigned int mode,
 					const struct phylink_link_state *state)
 {
+	struct dsa_port *dp = dsa_to_port(ds, port);
 	struct rtl838x_switch_priv *priv = ds->priv;
-	u32 reg;
-	int speed_bit = priv->family_id == RTL8380_FAMILY_ID ? 4 : 3;
+	u32 mcr;
 
 	pr_debug("%s port %d, mode %x\n", __func__, port, mode);
 
-	if (port == priv->cpu_port) {
-		/* Set Speed, duplex, flow control
-		 * FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL
-		 * | SPD_SEL = 0b10 | FORCE_FC_EN | PHY_MASTER_SLV_MANUAL_EN
-		 * | MEDIA_SEL
-		 */
-		if (priv->family_id == RTL8380_FAMILY_ID) {
-			sw_w32(0x6192F, priv->r->mac_force_mode_ctrl(priv->cpu_port));
-			/* allow CRC errors on CPU-port */
-			sw_w32_mask(0, 0x8, RTL838X_MAC_PORT_CTRL(priv->cpu_port));
-		} else {
-			sw_w32_mask(0, 3, priv->r->mac_force_mode_ctrl(priv->cpu_port));
-		}
+	/* currently only needed for RTL8380 */
+	if (priv->family_id != RTL8380_FAMILY_ID)
 		return;
-	}
-
-	reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
-	/* Auto-Negotiation does not work for MAC in RTL8390 */
-	if (priv->family_id == RTL8380_FAMILY_ID) {
-		if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
-			pr_debug("PHY autonegotiates\n");
-			reg |= RTL838X_NWAY_EN;
-			sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
-			rtl83xx_config_interface(port, state->interface);
-			return;
-		}
-	}
 
-	if (mode != MLO_AN_FIXED)
-		pr_debug("Fixed state.\n");
-
-	/* Clear id_mode_dis bit, and the existing port mode, let
-		 * RGMII_MODE_EN bet set by mac_link_{up,down}  */
-	if (priv->family_id == RTL8380_FAMILY_ID) {
-		reg &= ~(RTL838X_RX_PAUSE_EN | RTL838X_TX_PAUSE_EN);
-		if (state->pause & MLO_PAUSE_TXRX_MASK) {
-			if (state->pause & MLO_PAUSE_TX)
-				reg |= RTL838X_TX_PAUSE_EN;
-			reg |= RTL838X_RX_PAUSE_EN;
-		}
-	} else if (priv->family_id == RTL8390_FAMILY_ID) {
-		reg &= ~(RTL839X_RX_PAUSE_EN | RTL839X_TX_PAUSE_EN);
-		if (state->pause & MLO_PAUSE_TXRX_MASK) {
-			if (state->pause & MLO_PAUSE_TX)
-				reg |= RTL839X_TX_PAUSE_EN;
-			reg |= RTL839X_RX_PAUSE_EN;
-		}
-	}
-
-
-	reg &= ~(3 << speed_bit);
-	switch (state->speed) {
-	case SPEED_1000:
-		reg |= 2 << speed_bit;
-		break;
-	case SPEED_100:
-		reg |= 1 << speed_bit;
-		break;
-	default:
-		break; /* Ignore, including 10MBit which has a speed value of 0 */
+	if (dsa_port_is_cpu(dp)) {
+		/* allow CRC errors on CPU-port */
+		sw_w32_mask(0, 0x8, priv->r->mac_port_ctrl(port));
+		return;
 	}
 
-	if (priv->family_id == RTL8380_FAMILY_ID) {
-		reg &= ~(RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN);
-		if (state->link)
-			reg |= RTL838X_FORCE_LINK_EN;
-		if (state->duplex == RTL838X_DUPLEX_MODE)
-			reg |= RTL838X_DUPLEX_MODE;
-	} else if (priv->family_id == RTL8390_FAMILY_ID) {
-		reg &= ~(RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN);
-		if (state->link)
-			reg |= RTL839X_FORCE_LINK_EN;
-		if (state->duplex == RTL839X_DUPLEX_MODE)
-			reg |= RTL839X_DUPLEX_MODE;
-	}
-
-	/* LAG members must use DUPLEX and we need to enable the link */
-	if (priv->lagmembers & BIT_ULL(port)) {
-		switch(priv->family_id) {
-		case RTL8380_FAMILY_ID:
-			reg |= (RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN);
-		break;
-		case RTL8390_FAMILY_ID:
-			reg |= (RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN);
-		break;
-		}
+	mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
+	if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
+		pr_debug("port %d PHY autonegotiates\n", port);
+		rtl83xx_config_interface(port, state->interface);
+		mcr |= RTL838X_NWAY_EN;
+	} else {
+		mcr &= ~RTL838X_NWAY_EN;
 	}
-
-	/* Disable AN */
-	if (priv->family_id == RTL8380_FAMILY_ID)
-		reg &= ~RTL838X_NWAY_EN;
-	sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
+	sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
 }
 
 static void rtl931x_phylink_mac_config(struct dsa_switch *ds, int port,
@@ -916,12 +843,14 @@ static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
 				     phy_interface_t interface)
 {
 	struct rtl838x_switch_priv *priv = ds->priv;
+	int mask = 0;
 
 	/* Stop TX/RX to port */
 	sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
 
 	/* No longer force link */
-	sw_w32_mask(0x3, 0, priv->r->mac_force_mode_ctrl(port));
+	mask = RTL83XX_FORCE_EN | RTL83XX_FORCE_LINK_EN;
+	sw_w32_mask(mask, 0, priv->r->mac_force_mode_ctrl(port));
 }
 
 static void rtl93xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
@@ -949,10 +878,60 @@ static void rtl83xx_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_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 == RTL8380_FAMILY_ID) {
+		mcr &= ~RTL838X_RX_PAUSE_EN;
+		mcr &= ~RTL838X_TX_PAUSE_EN;
+		mcr &= ~RTL838X_DUPLEX_MODE;
+		mcr &= ~RTL838X_SPEED_MASK;
+		mcr |= RTL83XX_FORCE_LINK_EN;
+		mcr |= spdsel << RTL838X_SPEED_SHIFT;
+
+		if (tx_pause)
+			mcr |= RTL838X_TX_PAUSE_EN;
+		if (rx_pause)
+			mcr |= RTL838X_RX_PAUSE_EN;
+		if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
+			mcr |= RTL838X_DUPLEX_MODE;
+		if (dsa_port_is_cpu(dp))
+			mcr |= RTL83XX_FORCE_EN;
+
+	} else if (priv->family_id == RTL8390_FAMILY_ID) {
+		mcr &= ~RTL839X_RX_PAUSE_EN;
+		mcr &= ~RTL839X_TX_PAUSE_EN;
+		mcr &= ~RTL839X_DUPLEX_MODE;
+		mcr &= ~RTL839X_SPEED_MASK;
+		mcr |= RTL83XX_FORCE_LINK_EN;
+		mcr |= spdsel << RTL839X_SPEED_SHIFT;
+
+		if (tx_pause)
+			mcr |= RTL839X_TX_PAUSE_EN;
+		if (rx_pause)
+			mcr |= RTL839X_RX_PAUSE_EN;
+		if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
+			mcr |= RTL839X_DUPLEX_MODE;
+		if (dsa_port_is_cpu(dp))
+			mcr |= RTL83XX_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 rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
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 176fd07fe4..13a0bb5ffa 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
@@ -144,17 +144,24 @@
 #define RTL931X_MAC_LINK_MEDIA_STS		(0x0EC8)
 
 /* MAC link state bits */
-#define RTL838X_FORCE_EN			(1 << 0)
-#define RTL838X_FORCE_LINK_EN			(1 << 1)
+#define RTL_SPEED_10				0
+#define RTL_SPEED_100				1
+#define RTL_SPEED_1000				2
+
+#define RTL83XX_FORCE_EN			(1 << 0)
+#define RTL83XX_FORCE_LINK_EN			(1 << 1)
+
 #define RTL838X_NWAY_EN				(1 << 2)
 #define RTL838X_DUPLEX_MODE			(1 << 3)
+#define RTL838X_SPEED_SHIFT			(4)
+#define RTL838X_SPEED_MASK			(3 << RTL838X_SPEED_SHIFT)
 #define RTL838X_TX_PAUSE_EN			(1 << 6)
 #define RTL838X_RX_PAUSE_EN			(1 << 7)
 #define RTL838X_MAC_FORCE_FC_EN			(1 << 8)
 
-#define RTL839X_FORCE_EN			(1 << 0)
-#define RTL839X_FORCE_LINK_EN			(1 << 1)
 #define RTL839X_DUPLEX_MODE			(1 << 2)
+#define RTL839X_SPEED_SHIFT			(3)
+#define RTL839X_SPEED_MASK			(3 << RTL839X_SPEED_SHIFT)
 #define RTL839X_TX_PAUSE_EN			(1 << 5)
 #define RTL839X_RX_PAUSE_EN			(1 << 6)
 #define RTL839X_MAC_FORCE_FC_EN			(1 << 7)




More information about the lede-commits mailing list