@@ -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];
@@ -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,
@@ -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);
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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);
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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);
}
@@ -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);
}
@@ -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,
@@ -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;
@@ -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;
@@ -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
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(-)