]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: dsa: remove family_id check from xstp_state_set()
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Fri, 24 Apr 2026 10:52:55 +0000 (12:52 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Wed, 29 Apr 2026 21:23:11 +0000 (23:23 +0200)
The rtldsa_port_xstp_state_set() function offers a generic interface
to its callers to set the bridge state of one port. While it calls
device specific helpers in the background it runs the data mapping
for each architecture with a family_id check on its own. So the
hardware abstraction is done in two places

- rtldsa_port_xstp_state_set() translates one half
- its helper translate the other half

Convert the signature of the device specific helpers so that this
function does not need to know any hardware details. Instead move
the table/offset/bit calculations into the helpers. This way the
code path uses a consistent hardware abstraction.

- rtldsa_port_xstp_state_set() calls the helpers
- helpers do the hardware translation

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23080
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h
target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c
target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c
target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c
target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c

index c41172a4eda08917b316d932a2fb1ffa5262cc6f..7b28c6f4e84fa55e8815a2a3e2e2e7c40a582cdc 100644 (file)
@@ -1452,52 +1452,31 @@ static void rtldsa_port_xstp_state_set(struct rtl838x_switch_priv *priv, int por
                                       u8 state, u16 mst_slot)
                                       __must_hold(&priv->reg_mutex)
 {
-       /* 838x/930x have 28 ports and 2 bit fields other devices 4 bit fields. */
-       int n = priv->r->cpu_port == RTL838X_CPU_PORT ? 2 : 4;
-       u32 port_state[4];
-       int index, bit;
-       int pos = port;
+       int hw_state;
 
-       /* Ports above or equal CPU port can never be configured */
        if (port >= priv->r->cpu_port)
                return;
 
-       /* For the RTL839x and following, the bits are left-aligned, 838x and 930x
-        * have 64 bit fields, 839x and 931x have 128 bit fields
-        */
-       if (priv->family_id == RTL8390_FAMILY_ID)
-               pos += 12;
-       if (priv->family_id == RTL9300_FAMILY_ID)
-               pos += 3;
-       if (priv->family_id == RTL9310_FAMILY_ID)
-               pos += 8;
-
-       index = n - (pos >> 4) - 1;
-       bit = (pos << 1) % 32;
-
-       priv->r->stp_get(priv, mst_slot, port, port_state);
-
-       pr_debug("Current state, port %d: %d\n", port, (port_state[index] >> bit) & 3);
-       port_state[index] &= ~(3 << bit);
-
        switch (state) {
-       case BR_STATE_DISABLED: /* 0 */
-               port_state[index] |= (0 << bit);
+       case BR_STATE_DISABLED:
+               hw_state = 0;
                break;
-       case BR_STATE_BLOCKING:  /* 4 */
-       case BR_STATE_LISTENING: /* 1 */
-               port_state[index] |= (1 << bit);
+       case BR_STATE_BLOCKING:
+       case BR_STATE_LISTENING:
+               hw_state = 1;
                break;
-       case BR_STATE_LEARNING: /* 2 */
-               port_state[index] |= (2 << bit);
+       case BR_STATE_LEARNING:
+               hw_state = 2;
                break;
-       case BR_STATE_FORWARDING: /* 3 */
-               port_state[index] |= (3 << bit);
-       default:
+       case BR_STATE_FORWARDING:
+               hw_state = 3;
                break;
+       default:
+               dev_err(priv->dev, "stp state %d not supported\n", state);
+               return;
        }
 
-       priv->r->stp_set(priv, mst_slot, port_state);
+       priv->r->stp_set(priv, mst_slot, port, hw_state);
 }
 
 void rtldsa_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
index 460f542a6ed21a23f4f63ebb2377413292bdb8be..744dc0ec146e538a273d5f0a91a1358f7d6fff55 100644 (file)
@@ -1440,7 +1440,7 @@ struct rtldsa_config {
        void (*enable_bcast_flood)(int port, bool enable);
        void (*set_static_move_action)(int port, bool forward);
        int (*stp_get)(struct rtl838x_switch_priv *priv, u16 msti, int port, u32 port_state[]);
-       void (*stp_set)(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]);
+       void (*stp_set)(struct rtl838x_switch_priv *priv, u16 msti, int port, int state);
        int mac_link_sts;
        int  (*mac_force_mode_ctrl)(int port);
        int  (*mac_port_ctrl)(int port);
index f043b0c57794b879df96a42deed1f5dc1bb0c2ff..03b9b7cdcdf97609e521c541369693b08135ecb7 100644 (file)
@@ -655,12 +655,14 @@ static int rtldsa_838x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, int p
        return (port_state[idx] >> bit) & 3;
 }
 
-static void rtl838x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
+static void rtl838x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, int port, int state)
 {
        struct table_reg *r = rtl_table_get(RTL8380_TBL_0, 2);
+       int idx = 1 - (port / 16);
+       int bit = 2 * (port % 16);
 
-       for (int i = 0; i < 2; i++)
-               sw_w32(port_state[i], rtl_table_data(r, i));
+       rtl_table_read(r, msti);
+       sw_w32_mask(0x3 << bit, state << bit, rtl_table_data(r, idx));
        rtl_table_write(r, msti);
        rtl_table_release(r);
 }
index 6af0422abf0849ae581062754d7f7b6a1c5c103b..f44f8567a7e90ffc02922e6f76d6257c3724e496 100644 (file)
@@ -722,12 +722,14 @@ static int rtldsa_839x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, int p
        return (port_state[idx] >> bit) & 3;
 }
 
-static void rtl839x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
+static void rtl839x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, int port, int state)
 {
        struct table_reg *r = rtl_table_get(RTL8390_TBL_0, 5);
+       int idx = 3 - ((port + 12) / 16);
+       int bit = 2 * ((port + 12) % 16);
 
-       for (int i = 0; i < 4; i++)
-               sw_w32(port_state[i], rtl_table_data(r, i));
+       rtl_table_read(r, msti);
+       sw_w32_mask(0x3 << bit, state << bit, rtl_table_data(r, idx));
        rtl_table_write(r, msti);
        rtl_table_release(r);
 }
index 505fd7200d975d17b610e66fd57375c53bc31706..90dcee3179ab473e6aa11a86b1b0d1bfa18ed265 100644 (file)
@@ -641,12 +641,14 @@ static int rtldsa_930x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, int p
        return (port_state[idx] >> bit) & 3;
 }
 
-static void rtl930x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
+static void rtl930x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, int port, int state)
 {
        struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 4);
+       int idx = 1 - ((port + 3) / 16);
+       int bit = 2 * ((port + 3) % 16);
 
-       for (int i = 0; i < 2; i++)
-               sw_w32(port_state[i], rtl_table_data(r, i));
+       rtl_table_read(r, msti);
+       sw_w32_mask(0x3 << bit, state << bit, rtl_table_data(r, idx));
        rtl_table_write(r, msti);
        rtl_table_release(r);
 }
index b116f1e29cec2de6e8609e3eac33b00242f04ab1..b205f2b7a93e9a6d645a5db96e090ffd032c9bd5 100644 (file)
@@ -264,12 +264,14 @@ static int rtldsa_931x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, int p
        return (port_state[idx] >> bit) & 3;
 }
 
-static void rtl931x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
+static void rtl931x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, int port, int state)
 {
        struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 5);
+       int idx = 3 - ((port + 8) / 16);
+       int bit = 2 * ((port + 8) % 16);
 
-       for (int i = 0; i < 4; i++)
-               sw_w32(port_state[i], rtl_table_data(r, i));
+       rtl_table_read(r, msti);
+       sw_w32_mask(0x3 << bit, state << bit, rtl_table_data(r, idx));
        rtl_table_write(r, msti);
        rtl_table_release(r);
 }