From: Markus Stockhausen Date: Fri, 24 Apr 2026 10:52:55 +0000 (+0200) Subject: realtek: dsa: remove family_id check from xstp_state_set() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b8af1958290cd2ffc1e693c0310dfebd737b6b6;p=thirdparty%2Fopenwrt.git realtek: dsa: remove family_id check from xstp_state_set() 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 Link: https://github.com/openwrt/openwrt/pull/23080 Signed-off-by: Hauke Mehrtens --- diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c index c41172a4eda..7b28c6f4e84 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c @@ -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) diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h index 460f542a6ed..744dc0ec146 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h @@ -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); diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c index f043b0c5779..03b9b7cdcdf 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c @@ -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); } diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c index 6af0422abf0..f44f8567a7e 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c @@ -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); } diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c index 505fd7200d9..90dcee3179a 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c @@ -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); } diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c index b116f1e29ce..b205f2b7a93 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c @@ -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); }