7ace30aeb6
Backport upstream code split patch for qca8k needed for ipq40xx target to correctly implement a DSA driver. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
238 lines
6.5 KiB
Diff
238 lines
6.5 KiB
Diff
From fd3cae2f3ac190d06e48f43739237e02f9dc51ff Mon Sep 17 00:00:00 2001
|
|
From: Christian Marangi <ansuelsmth@gmail.com>
|
|
Date: Wed, 27 Jul 2022 13:35:17 +0200
|
|
Subject: [PATCH 08/14] net: dsa: qca8k: move bridge functions to common code
|
|
|
|
The same bridge functions are used by drivers based on qca8k family
|
|
switch. Move them to common code to make them accessible also by other
|
|
drivers.
|
|
While at it also drop unnecessary qca8k_priv cast for void pointers.
|
|
|
|
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
|
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
---
|
|
drivers/net/dsa/qca/qca8k-8xxx.c | 93 ------------------------------
|
|
drivers/net/dsa/qca/qca8k-common.c | 93 ++++++++++++++++++++++++++++++
|
|
drivers/net/dsa/qca/qca8k.h | 9 +++
|
|
3 files changed, 102 insertions(+), 93 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
@@ -2049,97 +2049,6 @@ exit:
|
|
}
|
|
|
|
static void
|
|
-qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
|
-{
|
|
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
|
- u32 stp_state;
|
|
-
|
|
- switch (state) {
|
|
- case BR_STATE_DISABLED:
|
|
- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
|
|
- break;
|
|
- case BR_STATE_BLOCKING:
|
|
- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
|
|
- break;
|
|
- case BR_STATE_LISTENING:
|
|
- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
|
|
- break;
|
|
- case BR_STATE_LEARNING:
|
|
- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
|
|
- break;
|
|
- case BR_STATE_FORWARDING:
|
|
- default:
|
|
- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
|
|
- break;
|
|
- }
|
|
-
|
|
- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
|
|
- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
|
|
-}
|
|
-
|
|
-static int
|
|
-qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
|
|
-{
|
|
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
|
- int port_mask, cpu_port;
|
|
- int i, ret;
|
|
-
|
|
- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
|
|
- port_mask = BIT(cpu_port);
|
|
-
|
|
- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
|
|
- if (dsa_is_cpu_port(ds, i))
|
|
- continue;
|
|
- if (dsa_to_port(ds, i)->bridge_dev != br)
|
|
- continue;
|
|
- /* Add this port to the portvlan mask of the other ports
|
|
- * in the bridge
|
|
- */
|
|
- ret = regmap_set_bits(priv->regmap,
|
|
- QCA8K_PORT_LOOKUP_CTRL(i),
|
|
- BIT(port));
|
|
- if (ret)
|
|
- return ret;
|
|
- if (i != port)
|
|
- port_mask |= BIT(i);
|
|
- }
|
|
-
|
|
- /* Add all other ports to this ports portvlan mask */
|
|
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
|
|
- QCA8K_PORT_LOOKUP_MEMBER, port_mask);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static void
|
|
-qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
|
|
-{
|
|
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
|
- int cpu_port, i;
|
|
-
|
|
- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
|
|
-
|
|
- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
|
|
- if (dsa_is_cpu_port(ds, i))
|
|
- continue;
|
|
- if (dsa_to_port(ds, i)->bridge_dev != br)
|
|
- continue;
|
|
- /* Remove this port to the portvlan mask of the other ports
|
|
- * in the bridge
|
|
- */
|
|
- regmap_clear_bits(priv->regmap,
|
|
- QCA8K_PORT_LOOKUP_CTRL(i),
|
|
- BIT(port));
|
|
- }
|
|
-
|
|
- /* Set the cpu port to be the only one in the portvlan mask of
|
|
- * this port
|
|
- */
|
|
- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
|
|
- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
|
|
-}
|
|
-
|
|
-static void
|
|
qca8k_port_fast_age(struct dsa_switch *ds, int port)
|
|
{
|
|
struct qca8k_priv *priv = ds->priv;
|
|
--- a/drivers/net/dsa/qca/qca8k-common.c
|
|
+++ b/drivers/net/dsa/qca/qca8k-common.c
|
|
@@ -9,6 +9,7 @@
|
|
#include <linux/netdevice.h>
|
|
#include <linux/bitfield.h>
|
|
#include <net/dsa.h>
|
|
+#include <linux/if_bridge.h>
|
|
|
|
#include "qca8k.h"
|
|
|
|
@@ -276,3 +277,93 @@ int qca8k_get_mac_eee(struct dsa_switch
|
|
/* Nothing to do on the port's MAC */
|
|
return 0;
|
|
}
|
|
+
|
|
+void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
|
+{
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
+ u32 stp_state;
|
|
+
|
|
+ switch (state) {
|
|
+ case BR_STATE_DISABLED:
|
|
+ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
|
|
+ break;
|
|
+ case BR_STATE_BLOCKING:
|
|
+ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
|
|
+ break;
|
|
+ case BR_STATE_LISTENING:
|
|
+ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
|
|
+ break;
|
|
+ case BR_STATE_LEARNING:
|
|
+ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
|
|
+ break;
|
|
+ case BR_STATE_FORWARDING:
|
|
+ default:
|
|
+ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
|
|
+ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
|
|
+}
|
|
+
|
|
+int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
|
|
+ struct net_device *br)
|
|
+{
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
+ int port_mask, cpu_port;
|
|
+ int i, ret;
|
|
+
|
|
+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
|
|
+ port_mask = BIT(cpu_port);
|
|
+
|
|
+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
|
|
+ if (dsa_is_cpu_port(ds, i))
|
|
+ continue;
|
|
+ if (dsa_to_port(ds, i)->bridge_dev != br)
|
|
+ continue;
|
|
+ /* Add this port to the portvlan mask of the other ports
|
|
+ * in the bridge
|
|
+ */
|
|
+ ret = regmap_set_bits(priv->regmap,
|
|
+ QCA8K_PORT_LOOKUP_CTRL(i),
|
|
+ BIT(port));
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ if (i != port)
|
|
+ port_mask |= BIT(i);
|
|
+ }
|
|
+
|
|
+ /* Add all other ports to this ports portvlan mask */
|
|
+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
|
|
+ QCA8K_PORT_LOOKUP_MEMBER, port_mask);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+void qca8k_port_bridge_leave(struct dsa_switch *ds, int port,
|
|
+ struct net_device *br)
|
|
+{
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
+ int cpu_port, i;
|
|
+
|
|
+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
|
|
+
|
|
+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
|
|
+ if (dsa_is_cpu_port(ds, i))
|
|
+ continue;
|
|
+ if (dsa_to_port(ds, i)->bridge_dev != br)
|
|
+ continue;
|
|
+ /* Remove this port to the portvlan mask of the other ports
|
|
+ * in the bridge
|
|
+ */
|
|
+ regmap_clear_bits(priv->regmap,
|
|
+ QCA8K_PORT_LOOKUP_CTRL(i),
|
|
+ BIT(port));
|
|
+ }
|
|
+
|
|
+ /* Set the cpu port to be the only one in the portvlan mask of
|
|
+ * this port
|
|
+ */
|
|
+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
|
|
+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
|
|
+}
|
|
--- a/drivers/net/dsa/qca/qca8k.h
|
|
+++ b/drivers/net/dsa/qca/qca8k.h
|
|
@@ -446,4 +446,11 @@ int qca8k_get_sset_count(struct dsa_swit
|
|
int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee);
|
|
int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
|
|
|
|
+/* Common bridge function */
|
|
+void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
|
|
+int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
|
|
+ struct net_device *br);
|
|
+void qca8k_port_bridge_leave(struct dsa_switch *ds, int port,
|
|
+ struct net_device *br);
|
|
+
|
|
#endif /* __QCA8K_H */
|