mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-04 06:54:27 -05:00 
			
		
		
		
	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 */
 |