diff mbox series

[RFC,net-next,03/20] net: dsa: propagate the bridge_num to driver .port_bridge_{join,leave} methods

Message ID 20210818120150.892647-4-vladimir.oltean@nxp.com
State New
Headers show
Series DSA FDB isolation | expand

Commit Message

Vladimir Oltean Aug. 18, 2021, 12:01 p.m. UTC
If the driver needs to do something to isolate FDBs of different
bridges, it must be able to reliably get a FDB identifier for each
bridge.

So one might ask: why is the driver not able to call something like
dsa_bridge_num_find(bridge_dev) and find the associated FDB identifier
already provided by the DSA core if it needs to, and not change anything
if it doesn't?

The issue is that drivers might need to do something with the FDB
identifier on .port_bridge_leave too, and the dsa_bridge_num_find
function is stateful: it only retrieves a valid bridge_num if there is
at least one port which has dp->bridge_dev == br.

But the dsa_port_bridge_leave() method first clears dp->bridge_dev and
dp->bridge_num, and only then notifies the driver. The bridge that the
port just left is only present inside the cross-chip notifier attribute,
and is passed by value to the switch driver.

So the bridge_num of the bridge we just left needs to be passed by value
too, just like the bridge_dev itself. And from there, .port_bridge_join
follows the same prototype mostly for symmetry.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/b53/b53_common.c       |  6 ++++--
 drivers/net/dsa/b53/b53_priv.h         |  6 ++++--
 drivers/net/dsa/dsa_loop.c             |  6 ++++--
 drivers/net/dsa/hirschmann/hellcreek.c |  6 ++++--
 drivers/net/dsa/lan9303-core.c         |  4 ++--
 drivers/net/dsa/lantiq_gswip.c         |  4 ++--
 drivers/net/dsa/microchip/ksz_common.c |  4 ++--
 drivers/net/dsa/microchip/ksz_common.h |  4 ++--
 drivers/net/dsa/mt7530.c               |  4 ++--
 drivers/net/dsa/mv88e6xxx/chip.c       | 12 ++++++++----
 drivers/net/dsa/ocelot/felix.c         |  4 ++--
 drivers/net/dsa/qca8k.c                |  6 ++++--
 drivers/net/dsa/sja1105/sja1105_main.c |  4 ++--
 drivers/net/dsa/xrs700x/xrs700x.c      |  4 ++--
 include/net/dsa.h                      |  8 ++++----
 net/dsa/dsa_priv.h                     |  1 +
 net/dsa/port.c                         |  3 +++
 net/dsa/switch.c                       | 11 +++++++----
 18 files changed, 59 insertions(+), 38 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index bd1417a66cbf..d0f00cb0a235 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1847,7 +1847,8 @@  int b53_mdb_del(struct dsa_switch *ds, int port,
 }
 EXPORT_SYMBOL(b53_mdb_del);
 
-int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
+int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br,
+		int bridge_num)
 {
 	struct b53_device *dev = ds->priv;
 	s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
@@ -1898,7 +1899,8 @@  int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
 }
 EXPORT_SYMBOL(b53_br_join);
 
-void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br)
+void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br,
+		  int bridge_num)
 {
 	struct b53_device *dev = ds->priv;
 	struct b53_vlan *vl = &dev->vlans[0];
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index 9bf8319342b0..e3f1e9ff1b50 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -318,8 +318,10 @@  void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
 int b53_get_sset_count(struct dsa_switch *ds, int port, int sset);
 void b53_get_ethtool_phy_stats(struct dsa_switch *ds, int port, uint64_t *data);
-int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge);
-void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *bridge);
+int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge,
+		int bridge_num);
+void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *bridge,
+		  int bridge_num);
 void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state);
 void b53_br_fast_age(struct dsa_switch *ds, int port);
 int b53_br_flags_pre(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
index bfdf3324aac3..c9fefdede1d1 100644
--- a/drivers/net/dsa/dsa_loop.c
+++ b/drivers/net/dsa/dsa_loop.c
@@ -167,7 +167,8 @@  static int dsa_loop_phy_write(struct dsa_switch *ds, int port,
 }
 
 static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,
-				     struct net_device *bridge)
+				     struct net_device *bridge,
+				     int bridge_num)
 {
 	dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
 		__func__, port, bridge->name);
@@ -176,7 +177,8 @@  static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,
 }
 
 static void dsa_loop_port_bridge_leave(struct dsa_switch *ds, int port,
-				       struct net_device *bridge)
+				       struct net_device *bridge,
+				       int bridge_num)
 {
 	dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
 		__func__, port, bridge->name);
diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c
index 5c54ae1be62c..732fff99bfb2 100644
--- a/drivers/net/dsa/hirschmann/hellcreek.c
+++ b/drivers/net/dsa/hirschmann/hellcreek.c
@@ -674,7 +674,8 @@  static int hellcreek_bridge_flags(struct dsa_switch *ds, int port,
 }
 
 static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
-				      struct net_device *br)
+				      struct net_device *br,
+				      int bridge_num)
 {
 	struct hellcreek *hellcreek = ds->priv;
 
@@ -691,7 +692,8 @@  static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
 }
 
 static void hellcreek_port_bridge_leave(struct dsa_switch *ds, int port,
-					struct net_device *br)
+					struct net_device *br,
+					int bridge_num)
 {
 	struct hellcreek *hellcreek = ds->priv;
 
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index d7ce281570b5..4e72fd04eb5f 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -1103,7 +1103,7 @@  static void lan9303_port_disable(struct dsa_switch *ds, int port)
 }
 
 static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
-				    struct net_device *br)
+				    struct net_device *br, int bridge_num)
 {
 	struct lan9303 *chip = ds->priv;
 
@@ -1117,7 +1117,7 @@  static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
 }
 
 static void lan9303_port_bridge_leave(struct dsa_switch *ds, int port,
-				      struct net_device *br)
+				      struct net_device *br, int bridge_num)
 {
 	struct lan9303 *chip = ds->priv;
 
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index e78026ef6d8c..2ce4da567106 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -1128,7 +1128,7 @@  static int gswip_vlan_remove(struct gswip_priv *priv,
 }
 
 static int gswip_port_bridge_join(struct dsa_switch *ds, int port,
-				  struct net_device *bridge)
+				  struct net_device *bridge, int bridge_num)
 {
 	struct gswip_priv *priv = ds->priv;
 	int err;
@@ -1148,7 +1148,7 @@  static int gswip_port_bridge_join(struct dsa_switch *ds, int port,
 }
 
 static void gswip_port_bridge_leave(struct dsa_switch *ds, int port,
-				    struct net_device *bridge)
+				    struct net_device *bridge, int bridge_num)
 {
 	struct gswip_priv *priv = ds->priv;
 
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 1542bfb8b5e5..4f821933e291 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -173,7 +173,7 @@  void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf)
 EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);
 
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
-			 struct net_device *br)
+			 struct net_device *br, int bridge_num)
 {
 	struct ksz_device *dev = ds->priv;
 
@@ -190,7 +190,7 @@  int ksz_port_bridge_join(struct dsa_switch *ds, int port,
 EXPORT_SYMBOL_GPL(ksz_port_bridge_join);
 
 void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
-			   struct net_device *br)
+			   struct net_device *br, int bridge_num)
 {
 	struct ksz_device *dev = ds->priv;
 
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 1597c63988b4..3e905059374b 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -159,9 +159,9 @@  void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
 int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
 void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf);
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
-			 struct net_device *br);
+			 struct net_device *br, int bridge_num);
 void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
-			   struct net_device *br);
+			   struct net_device *br, int bridge_num);
 void ksz_port_fast_age(struct dsa_switch *ds, int port);
 int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
 		      void *data);
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index d757d9dcba51..751e477691f4 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1192,7 +1192,7 @@  mt7530_port_bridge_flags(struct dsa_switch *ds, int port,
 
 static int
 mt7530_port_bridge_join(struct dsa_switch *ds, int port,
-			struct net_device *bridge)
+			struct net_device *bridge, int bridge_num)
 {
 	struct mt7530_priv *priv = ds->priv;
 	u32 port_bitmap = BIT(MT7530_CPU_PORT);
@@ -1305,7 +1305,7 @@  mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
 
 static void
 mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
-			 struct net_device *bridge)
+			 struct net_device *bridge, int bridge_num)
 {
 	struct mt7530_priv *priv = ds->priv;
 	int i;
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 32fd657a325a..37878ccf499c 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2387,7 +2387,8 @@  static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
 }
 
 static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
-				      struct net_device *br)
+				      struct net_device *br,
+				      int bridge_num)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 	int err;
@@ -2400,7 +2401,8 @@  static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
 }
 
 static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
-					struct net_device *br)
+					struct net_device *br,
+					int bridge_num)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 
@@ -2413,7 +2415,8 @@  static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
 
 static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
 					   int tree_index, int sw_index,
-					   int port, struct net_device *br)
+					   int port, struct net_device *br,
+					   int bridge_num)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 	int err;
@@ -2430,7 +2433,8 @@  static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
 
 static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds,
 					     int tree_index, int sw_index,
-					     int port, struct net_device *br)
+					     int port, struct net_device *br,
+					     int bridge_num)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index cbe23b20f3fa..3ab7cf2f0f50 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -695,7 +695,7 @@  static int felix_bridge_flags(struct dsa_switch *ds, int port,
 }
 
 static int felix_bridge_join(struct dsa_switch *ds, int port,
-			     struct net_device *br)
+			     struct net_device *br, int bridge_num)
 {
 	struct ocelot *ocelot = ds->priv;
 
@@ -705,7 +705,7 @@  static int felix_bridge_join(struct dsa_switch *ds, int port,
 }
 
 static void felix_bridge_leave(struct dsa_switch *ds, int port,
-			       struct net_device *br)
+			       struct net_device *br, int bridge_num)
 {
 	struct ocelot *ocelot = ds->priv;
 
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 1f63f50f73f1..9addf99ceead 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -1505,7 +1505,8 @@  qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 }
 
 static int
-qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
+qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br,
+		       int bridge_num)
 {
 	struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
 	int port_mask = BIT(QCA8K_CPU_PORT);
@@ -1534,7 +1535,8 @@  qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
 }
 
 static void
-qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
+qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br,
+			int bridge_num)
 {
 	struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
 	int i;
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 715557c20cb5..12a92deb5e5b 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1985,13 +1985,13 @@  static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
 }
 
 static int sja1105_bridge_join(struct dsa_switch *ds, int port,
-			       struct net_device *br)
+			       struct net_device *br, int bridge_num)
 {
 	return sja1105_bridge_member(ds, port, br, true);
 }
 
 static void sja1105_bridge_leave(struct dsa_switch *ds, int port,
-				 struct net_device *br)
+				 struct net_device *br, int bridge_num)
 {
 	sja1105_bridge_member(ds, port, br, false);
 }
diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c
index 130abb0f1438..230dbbcc48f3 100644
--- a/drivers/net/dsa/xrs700x/xrs700x.c
+++ b/drivers/net/dsa/xrs700x/xrs700x.c
@@ -542,13 +542,13 @@  static int xrs700x_bridge_common(struct dsa_switch *ds, int port,
 }
 
 static int xrs700x_bridge_join(struct dsa_switch *ds, int port,
-			       struct net_device *bridge)
+			       struct net_device *bridge, int bridge_num)
 {
 	return xrs700x_bridge_common(ds, port, bridge, true);
 }
 
 static void xrs700x_bridge_leave(struct dsa_switch *ds, int port,
-				 struct net_device *bridge)
+				 struct net_device *bridge, int bridge_num)
 {
 	xrs700x_bridge_common(ds, port, bridge, false);
 }
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 62820bd1d00d..b2aaef292c6d 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -694,9 +694,9 @@  struct dsa_switch_ops {
 	 */
 	int	(*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
 	int	(*port_bridge_join)(struct dsa_switch *ds, int port,
-				    struct net_device *bridge);
+				    struct net_device *bridge, int bridge_num);
 	void	(*port_bridge_leave)(struct dsa_switch *ds, int port,
-				     struct net_device *bridge);
+				     struct net_device *bridge, int bridge_num);
 	/* Called right after .port_bridge_join() */
 	int	(*port_bridge_tx_fwd_offload)(struct dsa_switch *ds, int port,
 					      struct net_device *bridge,
@@ -776,10 +776,10 @@  struct dsa_switch_ops {
 	 */
 	int	(*crosschip_bridge_join)(struct dsa_switch *ds, int tree_index,
 					 int sw_index, int port,
-					 struct net_device *br);
+					 struct net_device *br, int bridge_num);
 	void	(*crosschip_bridge_leave)(struct dsa_switch *ds, int tree_index,
 					  int sw_index, int port,
-					  struct net_device *br);
+					  struct net_device *br, int bridge_num);
 	int	(*crosschip_lag_change)(struct dsa_switch *ds, int sw_index,
 					int port);
 	int	(*crosschip_lag_join)(struct dsa_switch *ds, int sw_index,
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 88aaf43b2da4..c5caa2d975d2 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -53,6 +53,7 @@  struct dsa_notifier_ageing_time_info {
 /* DSA_NOTIFIER_BRIDGE_* */
 struct dsa_notifier_bridge_info {
 	struct net_device *br;
+	int bridge_num;
 	int tree_index;
 	int sw_index;
 	int port;
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 605c6890e53b..3ef55bd6eb40 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -368,6 +368,8 @@  int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
 	if (err)
 		return err;
 
+	info.bridge_num = dp->bridge_num;
+
 	brport_dev = dsa_port_to_bridge_port(dp);
 
 	err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_JOIN, &info);
@@ -417,6 +419,7 @@  void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
 		.sw_index = dp->ds->index,
 		.port = dp->index,
 		.br = br,
+		.bridge_num = dp->bridge_num,
 	};
 	int bridge_num = dp->bridge_num;
 	int err;
diff --git a/net/dsa/switch.c b/net/dsa/switch.c
index fd1a1c6bf9cf..44d40a267632 100644
--- a/net/dsa/switch.c
+++ b/net/dsa/switch.c
@@ -94,7 +94,8 @@  static int dsa_switch_bridge_join(struct dsa_switch *ds,
 
 	if (dst->index == info->tree_index && ds->index == info->sw_index &&
 	    ds->ops->port_bridge_join) {
-		err = ds->ops->port_bridge_join(ds, info->port, info->br);
+		err = ds->ops->port_bridge_join(ds, info->port, info->br,
+						info->bridge_num);
 		if (err)
 			return err;
 	}
@@ -103,7 +104,8 @@  static int dsa_switch_bridge_join(struct dsa_switch *ds,
 	    ds->ops->crosschip_bridge_join) {
 		err = ds->ops->crosschip_bridge_join(ds, info->tree_index,
 						     info->sw_index,
-						     info->port, info->br);
+						     info->port, info->br,
+						     info->bridge_num);
 		if (err)
 			return err;
 	}
@@ -121,13 +123,14 @@  static int dsa_switch_bridge_leave(struct dsa_switch *ds,
 
 	if (dst->index == info->tree_index && ds->index == info->sw_index &&
 	    ds->ops->port_bridge_leave)
-		ds->ops->port_bridge_leave(ds, info->port, info->br);
+		ds->ops->port_bridge_leave(ds, info->port, info->br,
+					   info->bridge_num);
 
 	if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
 	    ds->ops->crosschip_bridge_leave)
 		ds->ops->crosschip_bridge_leave(ds, info->tree_index,
 						info->sw_index, info->port,
-						info->br);
+						info->br, info->bridge_num);
 
 	/* If the bridge was vlan_filtering, the bridge core doesn't trigger an
 	 * event for changing vlan_filtering setting upon slave ports leaving