From f556b54a2cb095e781173a740a5ab5cdec29b486 Mon Sep 17 00:00:00 2001 From: Harshal Gohel Date: Tue, 27 Jan 2026 09:41:39 +0000 Subject: [PATCH] realtek: dsa: rtl93xx: Initialize trunk on probe 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 Signed-off-by: Sven Eckelmann Signed-off-by: Jan Fuchs Signed-off-by: Harshal Gohel Link: https://github.com/openwrt/openwrt/pull/21740 Signed-off-by: Hauke Mehrtens --- .../drivers/net/dsa/rtl83xx/common.c | 28 +++++++++++++++++++ .../drivers/net/dsa/rtl83xx/rtl838x.h | 13 +++++++++ .../drivers/net/dsa/rtl83xx/rtl930x.c | 1 + .../drivers/net/dsa/rtl83xx/rtl931x.c | 1 + 4 files changed, 43 insertions(+) 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 cf36f5e077..7908d736ce 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 @@ -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); diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h index f5b6445d3b..3692506ed3 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h @@ -408,9 +408,11 @@ #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) @@ -511,6 +513,16 @@ #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); 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 345e642037..5256349d97 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 @@ -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, 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 e831753120..df4380b465 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 @@ -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,