]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: refactor RTL930x MAC config to fix PHY ports 18268/head
authorJan Hoffmann <jan@3e8.eu>
Thu, 27 Feb 2025 19:43:26 +0000 (20:43 +0100)
committerSander Vanheule <sander@svanheule.net>
Tue, 1 Apr 2025 18:33:12 +0000 (20:33 +0200)
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@3e8.eu>
Tested-by: Christoph Krapp <achterin@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/18268
Signed-off-by: Sander Vanheule <sander@svanheule.net>
target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h

index cdfe0fe3dc017aceac9e2c9d487c5616c202ede5..46683cbb14223b326c9a75a639aea8c8495a23b7 100644 (file)
@@ -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,
index 13a0bb5ffa394f8ce336e692bb5f4bd8ecd7b7f1..16c609837832877bbb91ab6858f1d5f08d1bd70e 100644 (file)
 #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)
 #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)