fdba021c177c4f41010c2c9703640274f0562489
[openwrt/staging/wigyori.git] /
1 From c25c961fc7f36682f0a530150f1b7453ebc344cd Mon Sep 17 00:00:00 2001
2 From: Matthias Schiffer <mschiffer@universe-factory.net>
3 Date: Tue, 18 Jun 2024 09:17:12 +0200
4 Subject: [PATCH 1/2] net: dsa: mt7530: factor out bridge join/leave logic
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 As preparation for implementing bridge port isolation, move the logic to
10 add and remove bits in the port matrix into a new helper
11 mt7530_update_port_member(), which is called from
12 mt7530_port_bridge_join() and mt7530_port_bridge_leave().
13
14 Another part of the preparation is using dsa_port_offloads_bridge_dev()
15 instead of dsa_port_offloads_bridge() to check for bridge membership, as
16 we don't have a struct dsa_bridge in mt7530_port_bridge_flags().
17
18 The port matrix setting is slightly streamlined, now always first setting
19 the mt7530_port's pm field and then writing the port matrix from that
20 field into the hardware register, instead of duplicating the bit
21 manipulation for both the struct field and the register.
22
23 mt7530_port_bridge_join() was previously using |= to update the port
24 matrix with the port bitmap, which was unnecessary, as pm would only
25 have the CPU port set before joining a bridge; a simple assignment can
26 be used for both joining and leaving (and will also work when individual
27 bits are added/removed in port_bitmap with regard to the previous port
28 matrix, which is what happens with port isolation).
29
30 No functional change intended.
31
32 Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
33 Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
34 Reviewed-by: Arınç ÜNAL <arinc.unal@arinc9.com>
35 Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
36 Signed-off-by: David S. Miller <davem@davemloft.net>
37 ---
38 drivers/net/dsa/mt7530.c | 105 ++++++++++++++++++---------------------
39 1 file changed, 48 insertions(+), 57 deletions(-)
40
41 --- a/drivers/net/dsa/mt7530.c
42 +++ b/drivers/net/dsa/mt7530.c
43 @@ -1302,6 +1302,52 @@ mt7530_stp_state_set(struct dsa_switch *
44 FID_PST(FID_BRIDGED, stp_state));
45 }
46
47 +static void mt7530_update_port_member(struct mt7530_priv *priv, int port,
48 + const struct net_device *bridge_dev,
49 + bool join) __must_hold(&priv->reg_mutex)
50 +{
51 + struct dsa_port *dp = dsa_to_port(priv->ds, port), *other_dp;
52 + struct mt7530_port *p = &priv->ports[port], *other_p;
53 + struct dsa_port *cpu_dp = dp->cpu_dp;
54 + u32 port_bitmap = BIT(cpu_dp->index);
55 + int other_port;
56 +
57 + dsa_switch_for_each_user_port(other_dp, priv->ds) {
58 + other_port = other_dp->index;
59 + other_p = &priv->ports[other_port];
60 +
61 + if (dp == other_dp)
62 + continue;
63 +
64 + /* Add/remove this port to/from the port matrix of the other
65 + * ports in the same bridge. If the port is disabled, port
66 + * matrix is kept and not being setup until the port becomes
67 + * enabled.
68 + */
69 + if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev))
70 + continue;
71 +
72 + if (join) {
73 + other_p->pm |= PCR_MATRIX(BIT(port));
74 + port_bitmap |= BIT(other_port);
75 + } else {
76 + other_p->pm &= ~PCR_MATRIX(BIT(port));
77 + }
78 +
79 + if (other_p->enable)
80 + mt7530_rmw(priv, MT7530_PCR_P(other_port),
81 + PCR_MATRIX_MASK, other_p->pm);
82 + }
83 +
84 + /* Add/remove the all other ports to this port matrix. For !join
85 + * (leaving the bridge), only the CPU port will remain in the port matrix
86 + * of this port.
87 + */
88 + p->pm = PCR_MATRIX(port_bitmap);
89 + if (priv->ports[port].enable)
90 + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, p->pm);
91 +}
92 +
93 static int
94 mt7530_port_pre_bridge_flags(struct dsa_switch *ds, int port,
95 struct switchdev_brport_flags flags,
96 @@ -1345,39 +1391,11 @@ mt7530_port_bridge_join(struct dsa_switc
97 struct dsa_bridge bridge, bool *tx_fwd_offload,
98 struct netlink_ext_ack *extack)
99 {
100 - struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
101 - struct dsa_port *cpu_dp = dp->cpu_dp;
102 - u32 port_bitmap = BIT(cpu_dp->index);
103 struct mt7530_priv *priv = ds->priv;
104
105 mutex_lock(&priv->reg_mutex);
106
107 - dsa_switch_for_each_user_port(other_dp, ds) {
108 - int other_port = other_dp->index;
109 -
110 - if (dp == other_dp)
111 - continue;
112 -
113 - /* Add this port to the port matrix of the other ports in the
114 - * same bridge. If the port is disabled, port matrix is kept
115 - * and not being setup until the port becomes enabled.
116 - */
117 - if (!dsa_port_offloads_bridge(other_dp, &bridge))
118 - continue;
119 -
120 - if (priv->ports[other_port].enable)
121 - mt7530_set(priv, MT7530_PCR_P(other_port),
122 - PCR_MATRIX(BIT(port)));
123 - priv->ports[other_port].pm |= PCR_MATRIX(BIT(port));
124 -
125 - port_bitmap |= BIT(other_port);
126 - }
127 -
128 - /* Add the all other ports to this port matrix. */
129 - if (priv->ports[port].enable)
130 - mt7530_rmw(priv, MT7530_PCR_P(port),
131 - PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
132 - priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
133 + mt7530_update_port_member(priv, port, bridge.dev, true);
134
135 /* Set to fallback mode for independent VLAN learning */
136 mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
137 @@ -1478,38 +1496,11 @@ static void
138 mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
139 struct dsa_bridge bridge)
140 {
141 - struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
142 - struct dsa_port *cpu_dp = dp->cpu_dp;
143 struct mt7530_priv *priv = ds->priv;
144
145 mutex_lock(&priv->reg_mutex);
146
147 - dsa_switch_for_each_user_port(other_dp, ds) {
148 - int other_port = other_dp->index;
149 -
150 - if (dp == other_dp)
151 - continue;
152 -
153 - /* Remove this port from the port matrix of the other ports
154 - * in the same bridge. If the port is disabled, port matrix
155 - * is kept and not being setup until the port becomes enabled.
156 - */
157 - if (!dsa_port_offloads_bridge(other_dp, &bridge))
158 - continue;
159 -
160 - if (priv->ports[other_port].enable)
161 - mt7530_clear(priv, MT7530_PCR_P(other_port),
162 - PCR_MATRIX(BIT(port)));
163 - priv->ports[other_port].pm &= ~PCR_MATRIX(BIT(port));
164 - }
165 -
166 - /* Set the cpu port to be the only one in the port matrix of
167 - * this port.
168 - */
169 - if (priv->ports[port].enable)
170 - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
171 - PCR_MATRIX(BIT(cpu_dp->index)));
172 - priv->ports[port].pm = PCR_MATRIX(BIT(cpu_dp->index));
173 + mt7530_update_port_member(priv, port, bridge.dev, false);
174
175 /* When a port is removed from the bridge, the port would be set up
176 * back to the default as is at initial boot which is a VLAN-unaware