1 From c5290f636624b98e76a82bd63ffec0a8a9daa620 Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Wed, 27 Jul 2022 13:35:21 +0200
4 Subject: [PATCH 12/14] net: dsa: qca8k: move port VLAN functions to common
7 The same port VLAN functions are used by drivers based on qca8k family
8 switch. Move them to common code to make them accessible also by other
10 Also drop exposing busy_wait and make it static.
12 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
13 Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
14 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
16 drivers/net/dsa/qca/qca8k-8xxx.c | 182 -----------------------------
17 drivers/net/dsa/qca/qca8k-common.c | 179 +++++++++++++++++++++++++++-
18 drivers/net/dsa/qca/qca8k.h | 10 +-
19 3 files changed, 187 insertions(+), 184 deletions(-)
21 --- a/drivers/net/dsa/qca/qca8k-8xxx.c
22 +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
24 #include <linux/of_net.h>
25 #include <linux/of_mdio.h>
26 #include <linux/of_platform.h>
27 -#include <linux/if_bridge.h>
28 #include <linux/mdio.h>
29 #include <linux/phylink.h>
30 #include <linux/gpio/consumer.h>
31 @@ -442,122 +441,6 @@ static struct regmap_config qca8k_regmap
35 -qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
40 - /* Set the command and VLAN index */
41 - reg = QCA8K_VTU_FUNC1_BUSY;
43 - reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
45 - /* Write the function register triggering the table access */
46 - ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
50 - /* wait for completion */
51 - ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
55 - /* Check for table full violation when adding an entry */
56 - if (cmd == QCA8K_VLAN_LOAD) {
57 - ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®);
60 - if (reg & QCA8K_VTU_FUNC1_FULL)
68 -qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
74 - We do the right thing with VLAN 0 and treat it as untagged while
75 - preserving the tag on egress.
80 - mutex_lock(&priv->reg_mutex);
81 - ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
85 - ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®);
88 - reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
89 - reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
91 - reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
93 - reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
95 - ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
98 - ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
101 - mutex_unlock(&priv->reg_mutex);
107 -qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
113 - mutex_lock(&priv->reg_mutex);
114 - ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
118 - ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®);
121 - reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
122 - reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
124 - /* Check if we're the last member to be removed */
126 - for (i = 0; i < QCA8K_NUM_PORTS; i++) {
127 - mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
129 - if ((reg & mask) != mask) {
136 - ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
138 - ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
141 - ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
145 - mutex_unlock(&priv->reg_mutex);
151 qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
152 struct sk_buff *read_skb, u32 *val)
154 @@ -1836,71 +1719,6 @@ exit:
160 -qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
161 - struct netlink_ext_ack *extack)
163 - struct qca8k_priv *priv = ds->priv;
166 - if (vlan_filtering) {
167 - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
168 - QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
169 - QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
171 - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
172 - QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
173 - QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
180 -qca8k_port_vlan_add(struct dsa_switch *ds, int port,
181 - const struct switchdev_obj_port_vlan *vlan,
182 - struct netlink_ext_ack *extack)
184 - bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
185 - bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
186 - struct qca8k_priv *priv = ds->priv;
189 - ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
191 - dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
196 - ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
197 - QCA8K_EGREES_VLAN_PORT_MASK(port),
198 - QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
202 - ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
203 - QCA8K_PORT_VLAN_CVID(vlan->vid) |
204 - QCA8K_PORT_VLAN_SVID(vlan->vid));
211 -qca8k_port_vlan_del(struct dsa_switch *ds, int port,
212 - const struct switchdev_obj_port_vlan *vlan)
214 - struct qca8k_priv *priv = ds->priv;
217 - ret = qca8k_vlan_del(priv, port, vlan->vid);
219 - dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
224 static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
226 --- a/drivers/net/dsa/qca/qca8k-common.c
227 +++ b/drivers/net/dsa/qca/qca8k-common.c
228 @@ -141,7 +141,7 @@ static int qca8k_bulk_write(struct qca8k
232 -int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
233 +static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
237 @@ -354,6 +354,120 @@ exit:
241 +static int qca8k_vlan_access(struct qca8k_priv *priv,
242 + enum qca8k_vlan_cmd cmd, u16 vid)
247 + /* Set the command and VLAN index */
248 + reg = QCA8K_VTU_FUNC1_BUSY;
250 + reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
252 + /* Write the function register triggering the table access */
253 + ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
257 + /* wait for completion */
258 + ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
262 + /* Check for table full violation when adding an entry */
263 + if (cmd == QCA8K_VLAN_LOAD) {
264 + ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®);
267 + if (reg & QCA8K_VTU_FUNC1_FULL)
274 +static int qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid,
280 + /* We do the right thing with VLAN 0 and treat it as untagged while
281 + * preserving the tag on egress.
286 + mutex_lock(&priv->reg_mutex);
287 + ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
291 + ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®);
294 + reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
295 + reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
297 + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
299 + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
301 + ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
304 + ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
307 + mutex_unlock(&priv->reg_mutex);
312 +static int qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
318 + mutex_lock(&priv->reg_mutex);
319 + ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
323 + ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®);
326 + reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
327 + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
329 + /* Check if we're the last member to be removed */
331 + for (i = 0; i < QCA8K_NUM_PORTS; i++) {
332 + mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
334 + if ((reg & mask) != mask) {
341 + ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
343 + ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
346 + ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
350 + mutex_unlock(&priv->reg_mutex);
355 int qca8k_mib_init(struct qca8k_priv *priv)
358 @@ -832,3 +946,66 @@ void qca8k_port_mirror_del(struct dsa_sw
360 dev_err(priv->dev, "Failed to del mirror port from %d", port);
363 +int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port,
364 + bool vlan_filtering,
365 + struct netlink_ext_ack *extack)
367 + struct qca8k_priv *priv = ds->priv;
370 + if (vlan_filtering) {
371 + ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
372 + QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
373 + QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
375 + ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
376 + QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
377 + QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
383 +int qca8k_port_vlan_add(struct dsa_switch *ds, int port,
384 + const struct switchdev_obj_port_vlan *vlan,
385 + struct netlink_ext_ack *extack)
387 + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
388 + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
389 + struct qca8k_priv *priv = ds->priv;
392 + ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
394 + dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
399 + ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
400 + QCA8K_EGREES_VLAN_PORT_MASK(port),
401 + QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
405 + ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
406 + QCA8K_PORT_VLAN_CVID(vlan->vid) |
407 + QCA8K_PORT_VLAN_SVID(vlan->vid));
413 +int qca8k_port_vlan_del(struct dsa_switch *ds, int port,
414 + const struct switchdev_obj_port_vlan *vlan)
416 + struct qca8k_priv *priv = ds->priv;
419 + ret = qca8k_vlan_del(priv, port, vlan->vid);
421 + dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
425 --- a/drivers/net/dsa/qca/qca8k.h
426 +++ b/drivers/net/dsa/qca/qca8k.h
427 @@ -431,7 +431,6 @@ int qca8k_write(struct qca8k_priv *priv,
428 int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val);
430 /* Common ops function */
431 -int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask);
432 void qca8k_fdb_flush(struct qca8k_priv *priv);
434 /* Common ethtool stats function */
435 @@ -487,4 +486,13 @@ int qca8k_port_mirror_add(struct dsa_swi
436 void qca8k_port_mirror_del(struct dsa_switch *ds, int port,
437 struct dsa_mall_mirror_tc_entry *mirror);
439 +/* Common port VLAN function */
440 +int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
441 + struct netlink_ext_ack *extack);
442 +int qca8k_port_vlan_add(struct dsa_switch *ds, int port,
443 + const struct switchdev_obj_port_vlan *vlan,
444 + struct netlink_ext_ack *extack);
445 +int qca8k_port_vlan_del(struct dsa_switch *ds, int port,
446 + const struct switchdev_obj_port_vlan *vlan);
448 #endif /* __QCA8K_H */