kernel: backport fixes for realtek r8152
[openwrt/openwrt.git] / target / linux / generic / backport-5.15 / 774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch
1 From 90c855471a89d3e05ecf5b6464bd04abf2c83b70 Mon Sep 17 00:00:00 2001
2 From: Linus Walleij <linus.walleij@linaro.org>
3 Date: Tue, 5 Oct 2021 21:47:04 +0200
4 Subject: [PATCH 10/11] net: dsa: rtl8366rb: Support setting STP state
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 This adds support for setting the STP state to the RTL8366RB
10 DSA switch. This rids the following message from the kernel on
11 e.g. OpenWrt:
12
13 DSA: failed to set STP state 3 (-95)
14
15 Since the RTL8366RB has one STP state register per FID with
16 two bit per port in each, we simply loop over all the FIDs
17 and set the state on all of them.
18
19 Cc: Vladimir Oltean <olteanv@gmail.com>
20 Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
21 Cc: Mauri Sandberg <sandberg@mailfence.com>
22 Cc: DENG Qingfang <dqfext@gmail.com>
23 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
24 Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
25 Signed-off-by: David S. Miller <davem@davemloft.net>
26 ---
27 drivers/net/dsa/rtl8366rb.c | 48 +++++++++++++++++++++++++++++++++++++
28 1 file changed, 48 insertions(+)
29
30 --- a/drivers/net/dsa/rtl8366rb.c
31 +++ b/drivers/net/dsa/rtl8366rb.c
32 @@ -110,6 +110,18 @@
33
34 #define RTL8366RB_POWER_SAVING_REG 0x0021
35
36 +/* Spanning tree status (STP) control, two bits per port per FID */
37 +#define RTL8366RB_STP_STATE_BASE 0x0050 /* 0x0050..0x0057 */
38 +#define RTL8366RB_STP_STATE_DISABLED 0x0
39 +#define RTL8366RB_STP_STATE_BLOCKING 0x1
40 +#define RTL8366RB_STP_STATE_LEARNING 0x2
41 +#define RTL8366RB_STP_STATE_FORWARDING 0x3
42 +#define RTL8366RB_STP_MASK GENMASK(1, 0)
43 +#define RTL8366RB_STP_STATE(port, state) \
44 + ((state) << ((port) * 2))
45 +#define RTL8366RB_STP_STATE_MASK(port) \
46 + RTL8366RB_STP_STATE((port), RTL8366RB_STP_MASK)
47 +
48 /* CPU port control reg */
49 #define RTL8368RB_CPU_CTRL_REG 0x0061
50 #define RTL8368RB_CPU_PORTS_MSK 0x00FF
51 @@ -234,6 +246,7 @@
52 #define RTL8366RB_NUM_LEDGROUPS 4
53 #define RTL8366RB_NUM_VIDS 4096
54 #define RTL8366RB_PRIORITYMAX 7
55 +#define RTL8366RB_NUM_FIDS 8
56 #define RTL8366RB_FIDMAX 7
57
58 #define RTL8366RB_PORT_1 BIT(0) /* In userspace port 0 */
59 @@ -1309,6 +1322,40 @@ rtl8366rb_port_bridge_flags(struct dsa_s
60 }
61
62 static void
63 +rtl8366rb_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
64 +{
65 + struct realtek_smi *smi = ds->priv;
66 + u32 val;
67 + int i;
68 +
69 + switch (state) {
70 + case BR_STATE_DISABLED:
71 + val = RTL8366RB_STP_STATE_DISABLED;
72 + break;
73 + case BR_STATE_BLOCKING:
74 + case BR_STATE_LISTENING:
75 + val = RTL8366RB_STP_STATE_BLOCKING;
76 + break;
77 + case BR_STATE_LEARNING:
78 + val = RTL8366RB_STP_STATE_LEARNING;
79 + break;
80 + case BR_STATE_FORWARDING:
81 + val = RTL8366RB_STP_STATE_FORWARDING;
82 + break;
83 + default:
84 + dev_err(smi->dev, "unknown bridge state requested\n");
85 + return;
86 + };
87 +
88 + /* Set the same status for the port on all the FIDs */
89 + for (i = 0; i < RTL8366RB_NUM_FIDS; i++) {
90 + regmap_update_bits(smi->map, RTL8366RB_STP_STATE_BASE + i,
91 + RTL8366RB_STP_STATE_MASK(port),
92 + RTL8366RB_STP_STATE(port, val));
93 + }
94 +}
95 +
96 +static void
97 rtl8366rb_port_fast_age(struct dsa_switch *ds, int port)
98 {
99 struct realtek_smi *smi = ds->priv;
100 @@ -1733,6 +1780,7 @@ static const struct dsa_switch_ops rtl83
101 .port_disable = rtl8366rb_port_disable,
102 .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
103 .port_bridge_flags = rtl8366rb_port_bridge_flags,
104 + .port_stp_state_set = rtl8366rb_port_stp_state_set,
105 .port_fast_age = rtl8366rb_port_fast_age,
106 .port_change_mtu = rtl8366rb_change_mtu,
107 .port_max_mtu = rtl8366rb_max_mtu,