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 c41172a4ed..7b28c6f4e8 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: + hw_state = 3; break; - case BR_STATE_FORWARDING: /* 3 */ - port_state[index] |= (3 << bit); default: - break; + 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 460f542a6e..744dc0ec14 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 f043b0c577..03b9b7cdcd 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 6af0422abf..f44f8567a7 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 505fd7200d..90dcee3179 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 b116f1e29c..b205f2b7a9 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); }