Commit 06b9cce4 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: dsa: pass extack to .port_bridge_join driver methods

As FDB isolation cannot be enforced between VLAN-aware bridges in lack
of hardware assistance like extra FID bits, it seems plausible that many
DSA switches cannot do it. Therefore, they need to reject configurations
with multiple VLAN-aware bridges from the two code paths that can
transition towards that state:

- joining a VLAN-aware bridge
- toggling VLAN awareness on an existing bridge

The .port_vlan_filtering method already propagates the netlink extack to
the driver, let's propagate it from .port_bridge_join too, to make sure
that the driver can use the same function for both.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c2693363
...@@ -1869,7 +1869,7 @@ int b53_mdb_del(struct dsa_switch *ds, int port, ...@@ -1869,7 +1869,7 @@ int b53_mdb_del(struct dsa_switch *ds, int port,
EXPORT_SYMBOL(b53_mdb_del); EXPORT_SYMBOL(b53_mdb_del);
int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge, int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload, struct netlink_ext_ack *extack)
{ {
struct b53_device *dev = ds->priv; struct b53_device *dev = ds->priv;
s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
......
...@@ -324,7 +324,7 @@ void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data); ...@@ -324,7 +324,7 @@ 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); 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); 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 dsa_bridge bridge, int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
bool *tx_fwd_offload); bool *tx_fwd_offload, struct netlink_ext_ack *extack);
void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge); void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state); 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); void b53_br_fast_age(struct dsa_switch *ds, int port);
......
...@@ -168,7 +168,8 @@ static int dsa_loop_phy_write(struct dsa_switch *ds, int port, ...@@ -168,7 +168,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, static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n", dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
__func__, port, bridge.dev->name); __func__, port, bridge.dev->name);
......
...@@ -675,7 +675,8 @@ static int hellcreek_bridge_flags(struct dsa_switch *ds, int port, ...@@ -675,7 +675,8 @@ static int hellcreek_bridge_flags(struct dsa_switch *ds, int port,
static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port, static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
struct hellcreek *hellcreek = ds->priv; struct hellcreek *hellcreek = ds->priv;
......
...@@ -1111,7 +1111,8 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port) ...@@ -1111,7 +1111,8 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port)
static int lan9303_port_bridge_join(struct dsa_switch *ds, int port, static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
struct lan9303 *chip = ds->priv; struct lan9303 *chip = ds->priv;
......
...@@ -1152,7 +1152,8 @@ static int gswip_vlan_remove(struct gswip_priv *priv, ...@@ -1152,7 +1152,8 @@ static int gswip_vlan_remove(struct gswip_priv *priv,
static int gswip_port_bridge_join(struct dsa_switch *ds, int port, static int gswip_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
struct net_device *br = bridge.dev; struct net_device *br = bridge.dev;
struct gswip_priv *priv = ds->priv; struct gswip_priv *priv = ds->priv;
......
...@@ -217,7 +217,8 @@ EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats); ...@@ -217,7 +217,8 @@ EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);
int ksz_port_bridge_join(struct dsa_switch *ds, int port, int ksz_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
/* port_stp_state_set() will be called after to put the port in /* port_stp_state_set() will be called after to put the port in
* appropriate state so there is no need to do anything. * appropriate state so there is no need to do anything.
......
...@@ -159,7 +159,8 @@ void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, ...@@ -159,7 +159,8 @@ 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); 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); 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, int ksz_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, bool *tx_fwd_offload); struct dsa_bridge bridge, bool *tx_fwd_offload,
struct netlink_ext_ack *extack);
void ksz_port_bridge_leave(struct dsa_switch *ds, int port, void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
struct dsa_bridge bridge); struct dsa_bridge bridge);
void ksz_port_fast_age(struct dsa_switch *ds, int port); void ksz_port_fast_age(struct dsa_switch *ds, int port);
......
...@@ -1186,7 +1186,8 @@ mt7530_port_bridge_flags(struct dsa_switch *ds, int port, ...@@ -1186,7 +1186,8 @@ mt7530_port_bridge_flags(struct dsa_switch *ds, int port,
static int static int
mt7530_port_bridge_join(struct dsa_switch *ds, int port, mt7530_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, bool *tx_fwd_offload) struct dsa_bridge bridge, bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
u32 port_bitmap = BIT(MT7530_CPU_PORT); u32 port_bitmap = BIT(MT7530_CPU_PORT);
......
...@@ -2618,7 +2618,8 @@ static int mv88e6xxx_map_virtual_bridge_to_pvt(struct dsa_switch *ds, ...@@ -2618,7 +2618,8 @@ static int mv88e6xxx_map_virtual_bridge_to_pvt(struct dsa_switch *ds,
static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
struct mv88e6xxx_chip *chip = ds->priv; struct mv88e6xxx_chip *chip = ds->priv;
int err; int err;
...@@ -2684,7 +2685,8 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, ...@@ -2684,7 +2685,8 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds, static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
int tree_index, int sw_index, int tree_index, int sw_index,
int port, struct dsa_bridge bridge) int port, struct dsa_bridge bridge,
struct netlink_ext_ack *extack)
{ {
struct mv88e6xxx_chip *chip = ds->priv; struct mv88e6xxx_chip *chip = ds->priv;
int err; int err;
......
...@@ -674,7 +674,8 @@ static int felix_bridge_flags(struct dsa_switch *ds, int port, ...@@ -674,7 +674,8 @@ static int felix_bridge_flags(struct dsa_switch *ds, int port,
} }
static int felix_bridge_join(struct dsa_switch *ds, int port, static int felix_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, bool *tx_fwd_offload) struct dsa_bridge bridge, bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
struct ocelot *ocelot = ds->priv; struct ocelot *ocelot = ds->priv;
......
...@@ -2247,7 +2247,8 @@ qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) ...@@ -2247,7 +2247,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, static int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
int port_mask, cpu_port; int port_mask, cpu_port;
......
...@@ -1189,7 +1189,8 @@ rtl8366rb_port_disable(struct dsa_switch *ds, int port) ...@@ -1189,7 +1189,8 @@ rtl8366rb_port_disable(struct dsa_switch *ds, int port)
static int static int
rtl8366rb_port_bridge_join(struct dsa_switch *ds, int port, rtl8366rb_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
struct realtek_priv *priv = ds->priv; struct realtek_priv *priv = ds->priv;
unsigned int port_bitmap = 0; unsigned int port_bitmap = 0;
......
...@@ -2071,7 +2071,8 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port, ...@@ -2071,7 +2071,8 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
static int sja1105_bridge_join(struct dsa_switch *ds, int port, static int sja1105_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload) bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
int rc; int rc;
......
...@@ -534,7 +534,8 @@ static int xrs700x_bridge_common(struct dsa_switch *ds, int port, ...@@ -534,7 +534,8 @@ static int xrs700x_bridge_common(struct dsa_switch *ds, int port,
} }
static int xrs700x_bridge_join(struct dsa_switch *ds, int port, static int xrs700x_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, bool *tx_fwd_offload) struct dsa_bridge bridge, bool *tx_fwd_offload,
struct netlink_ext_ack *extack)
{ {
return xrs700x_bridge_common(ds, port, bridge, true); return xrs700x_bridge_common(ds, port, bridge, true);
} }
......
...@@ -937,7 +937,8 @@ struct dsa_switch_ops { ...@@ -937,7 +937,8 @@ struct dsa_switch_ops {
int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs); int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
int (*port_bridge_join)(struct dsa_switch *ds, int port, int (*port_bridge_join)(struct dsa_switch *ds, int port,
struct dsa_bridge bridge, struct dsa_bridge bridge,
bool *tx_fwd_offload); bool *tx_fwd_offload,
struct netlink_ext_ack *extack);
void (*port_bridge_leave)(struct dsa_switch *ds, int port, void (*port_bridge_leave)(struct dsa_switch *ds, int port,
struct dsa_bridge bridge); struct dsa_bridge bridge);
void (*port_stp_state_set)(struct dsa_switch *ds, int port, void (*port_stp_state_set)(struct dsa_switch *ds, int port,
...@@ -1021,7 +1022,8 @@ struct dsa_switch_ops { ...@@ -1021,7 +1022,8 @@ struct dsa_switch_ops {
*/ */
int (*crosschip_bridge_join)(struct dsa_switch *ds, int tree_index, int (*crosschip_bridge_join)(struct dsa_switch *ds, int tree_index,
int sw_index, int port, int sw_index, int port,
struct dsa_bridge bridge); struct dsa_bridge bridge,
struct netlink_ext_ack *extack);
void (*crosschip_bridge_leave)(struct dsa_switch *ds, int tree_index, void (*crosschip_bridge_leave)(struct dsa_switch *ds, int tree_index,
int sw_index, int port, int sw_index, int port,
struct dsa_bridge bridge); struct dsa_bridge bridge);
......
...@@ -59,6 +59,7 @@ struct dsa_notifier_bridge_info { ...@@ -59,6 +59,7 @@ struct dsa_notifier_bridge_info {
int sw_index; int sw_index;
int port; int port;
bool tx_fwd_offload; bool tx_fwd_offload;
struct netlink_ext_ack *extack;
}; };
/* DSA_NOTIFIER_FDB_* */ /* DSA_NOTIFIER_FDB_* */
......
...@@ -328,6 +328,7 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, ...@@ -328,6 +328,7 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
.tree_index = dp->ds->dst->index, .tree_index = dp->ds->dst->index,
.sw_index = dp->ds->index, .sw_index = dp->ds->index,
.port = dp->index, .port = dp->index,
.extack = extack,
}; };
struct net_device *dev = dp->slave; struct net_device *dev = dp->slave;
struct net_device *brport_dev; struct net_device *brport_dev;
......
...@@ -96,7 +96,8 @@ static int dsa_switch_bridge_join(struct dsa_switch *ds, ...@@ -96,7 +96,8 @@ static int dsa_switch_bridge_join(struct dsa_switch *ds,
return -EOPNOTSUPP; return -EOPNOTSUPP;
err = ds->ops->port_bridge_join(ds, info->port, info->bridge, err = ds->ops->port_bridge_join(ds, info->port, info->bridge,
&info->tx_fwd_offload); &info->tx_fwd_offload,
info->extack);
if (err) if (err)
return err; return err;
} }
...@@ -105,7 +106,8 @@ static int dsa_switch_bridge_join(struct dsa_switch *ds, ...@@ -105,7 +106,8 @@ static int dsa_switch_bridge_join(struct dsa_switch *ds,
ds->ops->crosschip_bridge_join) { ds->ops->crosschip_bridge_join) {
err = ds->ops->crosschip_bridge_join(ds, info->tree_index, err = ds->ops->crosschip_bridge_join(ds, info->tree_index,
info->sw_index, info->sw_index,
info->port, info->bridge); info->port, info->bridge,
info->extack);
if (err) if (err)
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment