From 108381e5a1aa314ef626955813a3ee63d3e9adde Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 9 Nov 2025 09:23:48 +0100 Subject: [PATCH] realtek: dsa: Fix LAG id allocation The rtl83xx_lag_can_offload() function always returned an error because ds->num_lag_ids was never set. This basically disabled the DSA lag configuration completely. Drop the private n_lag variable and instead use the DSA specific one. This ensures that all the code always has the same reference for the number of LAGs. Fixes: 32e5b5ee6b86 ("realtek: Add Link Aggregation (aka trunking) support") Signed-off-by: Sven Eckelmann Link: https://github.com/openwrt/openwrt/pull/20707 Signed-off-by: Hauke Mehrtens --- .../drivers/net/dsa/rtl83xx/common.c | 18 +++++++++--------- .../drivers/net/dsa/rtl83xx/debugfs.c | 2 +- .../files-6.12/drivers/net/dsa/rtl83xx/dsa.c | 4 ++-- .../drivers/net/dsa/rtl83xx/rtl838x.h | 1 - 4 files changed, 12 insertions(+), 13 deletions(-) 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 502c130d6f..0a77db6b5d 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 @@ -457,7 +457,7 @@ int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_la return -EINVAL; } - if (group >= priv->n_lags) { + if (group >= priv->ds->num_lag_ids) { pr_err("%s: LAG %d invalid.\n", __func__, group); return -EINVAL; } @@ -467,11 +467,11 @@ int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_la return -EINVAL; } - for (i = 0; i < priv->n_lags; i++) { + for (i = 0; i < priv->ds->num_lag_ids; i++) { if (priv->lags_port_members[i] & BIT_ULL(port)) break; } - if (i != priv->n_lags) { + if (i != priv->ds->num_lag_ids) { pr_err("%s: Port %d already member of LAG %d.\n", __func__, port, i); return -ENOSPC; } @@ -513,7 +513,7 @@ int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port) { struct rtl838x_switch_priv *priv = ds->priv; - if (group >= priv->n_lags) { + if (group >= priv->ds->num_lag_ids) { pr_err("%s: LAG %d invalid.\n", __func__, group); return -EINVAL; } @@ -702,7 +702,7 @@ static int rtl83xx_handle_changeupper(struct rtl838x_switch_priv *priv, mutex_lock(&priv->reg_mutex); - for (i = 0; i < priv->n_lags; i++) { + for (i = 0; i < priv->ds->num_lag_ids; i++) { if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == upper)) break; } @@ -1563,7 +1563,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev) priv->ds->num_ports = 29; priv->fib_entries = 8192; rtl8380_get_version(priv); - priv->n_lags = 8; + priv->ds->num_lag_ids = 8; priv->l2_bucket_size = 4; priv->n_pie_blocks = 12; priv->port_ignore = 0x1f; @@ -1579,7 +1579,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev) priv->ds->num_ports = 53; priv->fib_entries = 16384; rtl8390_get_version(priv); - priv->n_lags = 16; + priv->ds->num_lag_ids = 16; priv->l2_bucket_size = 4; priv->n_pie_blocks = 18; priv->port_ignore = 0x3f; @@ -1598,7 +1598,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev) * be constructed. For now, just set it to a static 'A' */ priv->version = RTL8390_VERSION_A; - priv->n_lags = 16; + priv->ds->num_lag_ids = 16; sw_w32(1, RTL930X_ST_CTRL); priv->l2_bucket_size = 8; priv->n_pie_blocks = 16; @@ -1618,7 +1618,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev) * be constructed. For now, just set it to a static 'A' */ priv->version = RTL8390_VERSION_A; - priv->n_lags = 16; + priv->ds->num_lag_ids = 16; sw_w32(1, RTL931x_ST_CTRL); priv->l2_bucket_size = 8; priv->n_pie_blocks = 16; diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/debugfs.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/debugfs.c index 00f2642624..79387a0c37 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/debugfs.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/debugfs.c @@ -613,7 +613,7 @@ void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv) debugfs_create_u8("id", 0444, port_dir, &priv->cpu_port); /* Create entries for LAGs */ - for (int i = 0; i < priv->n_lags; i++) { + for (int i = 0; i < priv->ds->num_lag_ids; i++) { snprintf(lag_name, sizeof(lag_name), "lag.%02d", i); if (priv->family_id == RTL8380_FAMILY_ID) debugfs_create_x32(lag_name, 0644, rtl838x_dir, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c index 2b743dd53a..1787904b5b 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c @@ -2407,7 +2407,7 @@ static int rtl83xx_port_lag_join(struct dsa_switch *ds, mutex_lock(&priv->reg_mutex); - for (i = 0; i < priv->n_lags; i++) { + for (i = 0; i < priv->ds->num_lag_ids; i++) { if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == lag.dev)) break; } @@ -2446,7 +2446,7 @@ static int rtl83xx_port_lag_leave(struct dsa_switch *ds, int port, struct rtl838x_switch_priv *priv = ds->priv; mutex_lock(&priv->reg_mutex); - for (i = 0; i < priv->n_lags; i++) { + for (i = 0; i < priv->ds->num_lag_ids; i++) { if (priv->lags_port_members[i] & BIT_ULL(port)) { group = i; break; 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 1ab943a681..f0005b6be0 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 @@ -1164,7 +1164,6 @@ struct rtl838x_switch_priv { u32 fib_entries; int l2_bucket_size; struct dentry *dbgfs_dir; - int n_lags; u64 lags_port_members[MAX_LAGS]; struct net_device *lag_devs[MAX_LAGS]; u32 lag_primary[MAX_LAGS]; -- 2.30.2