]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: dsa: rtl93xx: Initialize trunk on probe
authorHarshal Gohel <hg@simonwunderlich.de>
Tue, 27 Jan 2026 09:41:39 +0000 (09:41 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 7 Mar 2026 19:33:21 +0000 (20:33 +0100)
rtl93xx has two distribution algorithm slots that are shared among
multiple trunks.
Each of this slot can be configured to handle L2 and/or L3 packets

Hardware can also be configured to support layer3+4 but that is not
802.3ad compliant. With this commmit I want to focus on getting
layer2 and layer2+3 initialized in two slots.
When a new LAG group is created, depending on the xmit_hash_policy
configuration a slot will be configured in LAG table entry

SPA and VLAN bits made the switch to always choose same link for all
connections which completely dismisses point of Link aggregation.
So avoid these and stick to SMAC + DMAC for L2 packets and
SMAC + DMAC + SIP + DIP for L3 packets

Co-developed-by: Sven Eckelmann <se@simonwunderlich.de>
Signed-off-by: Sven Eckelmann <se@simonwunderlich.de>
Signed-off-by: Jan Fuchs <jf@simonwunderlich.de>
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/21740
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/common.c
target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c
target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c

index cf36f5e077a48b70b9ec91f4b3af7581085fc2e4..7908d736cebfe06cec1edc8489ff55cc4ff01bc7 100644 (file)
@@ -1638,6 +1638,9 @@ static int rtl83xx_sw_probe(struct platform_device *pdev)
                break;
        }
 
+       if (priv->r->lag_switch_init)
+               priv->r->lag_switch_init(priv);
+
        return 0;
 
 err_register_fib_nb:
@@ -1650,6 +1653,31 @@ err_register_switch:
        return err;
 }
 
+void rtldsa_93xx_lag_switch_init(struct rtl838x_switch_priv *priv)
+{
+       u32 trk_ctrlmask = 0;
+       u32 algomask;
+
+       trk_ctrlmask |= RTL93XX_TRK_CTRL_NON_TMN_TUNNEL_HASH_SEL;
+       trk_ctrlmask |= RTL93XX_TRK_CTRL_TRK_STAND_ALONE_MODE;
+       trk_ctrlmask |= RTL93XX_TRK_CTRL_LOCAL_FIRST;
+       trk_ctrlmask |= RTL93XX_TRK_CTRL_LINK_DOWN_AVOID;
+
+       sw_w32(trk_ctrlmask, priv->r->trk_ctrl);
+
+       /* Setup NETDEV_LAG_HASH_L2 on slot 0 */
+       algomask = TRUNK_DISTRIBUTION_ALGO_SMAC_BIT |
+                  TRUNK_DISTRIBUTION_ALGO_DMAC_BIT;
+       priv->r->lag_set_distribution_algorithm(priv, 0, RTL93XX_HASH_MASK_INDEX_L2, algomask);
+
+       /* Setup NETDEV_LAG_HASH_L23 on slot 1 */
+       algomask = TRUNK_DISTRIBUTION_ALGO_SMAC_BIT |
+                  TRUNK_DISTRIBUTION_ALGO_DMAC_BIT |
+                  TRUNK_DISTRIBUTION_ALGO_SIP_BIT |
+                  TRUNK_DISTRIBUTION_ALGO_DIP_BIT;
+       priv->r->lag_set_distribution_algorithm(priv, 0, RTL93XX_HASH_MASK_INDEX_L23, algomask);
+}
+
 static void rtl83xx_sw_remove(struct platform_device *pdev)
 {
        struct rtl838x_switch_priv *priv = platform_get_drvdata(pdev);
index f5b6445d3ba0579c2ec53aedab8d4c81791ad1df..3692506ed3d625e33af27ffc4862cddcf887b507 100644 (file)
 
 #define RTL930X_TRK_MBR_CTRL                   (0xA41C)
 #define RTL930X_TRK_HASH_CTRL                  (0x9F80)
+#define RTL930X_TRK_CTRL                       (0x9F88)
 
 #define RTL931X_TRK_MBR_CTRL                   (0xB8D0)
 #define RTL931X_TRK_HASH_CTRL                  (0xBA70)
+#define RTL931X_TRK_CTRL                       (0xBA78)
 
 /* Attack prevention */
 #define RTL838X_ATK_PRVNT_PORT_EN              (0x5B00)
 #define RTL838X_LED_SW_P_CTRL                  (0xA01C)
 #define RTL838X_LED_SW_P_CTRL_PORT(p)          (RTL838X_LED_SW_P_CTRL + (((p) << 2)))
 
+#define RTL93XX_HASH_MASK_INDEX_L2     (0)
+#define RTL93XX_HASH_MASK_INDEX_L23    (1)
+
+#define RTL93XX_TRK_CTRL_NON_TMN_TUNNEL_HASH_SEL       BIT(0)
+#define RTL93XX_TRK_CTRL_SEP_PORT_SEL                  BIT(1)
+#define RTL93XX_TRK_CTRL_TRK_STAND_ALONE_MODE          BIT(2)
+#define RTL93XX_TRK_CTRL_STK_HASH_CAL                  BIT(3)
+#define RTL93XX_TRK_CTRL_LOCAL_FIRST                   BIT(4)
+#define RTL93XX_TRK_CTRL_CONGST_AVOID                  BIT(5)
+#define RTL93XX_TRK_CTRL_LINK_DOWN_AVOID               BIT(6)
 
 /* special port action controls */
 /* values:
@@ -1448,6 +1460,7 @@ struct rtl838x_switch_priv {
 
 void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv);
 void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv);
+void rtldsa_93xx_lag_switch_init(struct rtl838x_switch_priv *priv);
 int rtldsa_93xx_lag_set_distribution_algorithm(struct rtl838x_switch_priv *priv,
                                               int group, int algoidx, u32 algomsk);
 
index 345e642037ab27826cf570359b49e7e7d84cf30e..5256349d97d675401dc63c2f223ac6887faf21d2 100644 (file)
@@ -2800,6 +2800,7 @@ const struct rtldsa_config rtldsa_930x_cfg = {
        .enable_flood = rtldsa_930x_enable_flood,
        .set_receive_management_action = rtldsa_930x_set_receive_management_action,
        .qos_init = rtldsa_930x_qos_init,
+       .trk_ctrl = RTL930X_TRK_CTRL,
        .trk_hash_ctrl = RTL930X_TRK_HASH_CTRL,
        .prepare_lag_fdb = rtldsa_93xx_prepare_lag_fdb,
        .lag_switch_init = rtldsa_93xx_lag_switch_init,
index e83175312096918076564a59c0b9eba14935565f..df4380b46595f6713b3c9e81de93e20086ed0e0b 100644 (file)
@@ -1924,6 +1924,7 @@ const struct rtldsa_config rtldsa_931x_cfg = {
        .enable_flood = rtldsa_931x_enable_flood,
        .set_receive_management_action = rtldsa_931x_set_receive_management_action,
        .qos_init = rtldsa_931x_qos_init,
+       .trk_ctrl = RTL931X_TRK_CTRL,
        .trk_hash_ctrl = RTL931X_TRK_HASH_CTRL,
        .prepare_lag_fdb = rtldsa_93xx_prepare_lag_fdb,
        .lag_switch_init = rtldsa_93xx_lag_switch_init,