diff options
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.c | 7 | ||||
-rw-r--r-- | include/net/dsa.h | 1 | ||||
-rw-r--r-- | net/dsa/dsa_priv.h | 2 | ||||
-rw-r--r-- | net/dsa/port.c | 35 |
4 files changed, 33 insertions, 12 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index c2c5f1573fe5..c45ca2473743 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -5797,7 +5797,6 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port, struct netlink_ext_ack *extack) { struct mv88e6xxx_chip *chip = ds->priv; - bool do_fast_age = false; int err = -EOPNOTSUPP; mv88e6xxx_reg_lock(chip); @@ -5809,9 +5808,6 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port, err = mv88e6xxx_port_set_assoc_vector(chip, port, pav); if (err) goto out; - - if (!learning) - do_fast_age = true; } if (flags.mask & BR_FLOOD) { @@ -5843,9 +5839,6 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port, out: mv88e6xxx_reg_unlock(chip); - if (do_fast_age) - mv88e6xxx_port_fast_age(ds, port); - return err; } diff --git a/include/net/dsa.h b/include/net/dsa.h index d7dc26d316ea..995e9d3f9cfc 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -254,6 +254,7 @@ struct dsa_port { struct device_node *dn; unsigned int ageing_time; bool vlan_filtering; + bool learning; u8 stp_state; struct net_device *bridge_dev; int bridge_num; diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 8dad40b2cf5c..9575cabd3ec3 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -241,7 +241,7 @@ int dsa_port_host_mdb_del(const struct dsa_port *dp, int dsa_port_pre_bridge_flags(const struct dsa_port *dp, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack); -int dsa_port_bridge_flags(const struct dsa_port *dp, +int dsa_port_bridge_flags(struct dsa_port *dp, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack); int dsa_port_vlan_add(struct dsa_port *dp, diff --git a/net/dsa/port.c b/net/dsa/port.c index ef5e08b09bb7..d6a35a03acd6 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -30,6 +30,16 @@ static int dsa_port_notify(const struct dsa_port *dp, unsigned long e, void *v) return dsa_tree_notify(dp->ds->dst, e, v); } +static void dsa_port_fast_age(const struct dsa_port *dp) +{ + struct dsa_switch *ds = dp->ds; + + if (!ds->ops->port_fast_age) + return; + + ds->ops->port_fast_age(ds, dp->index); +} + int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age) { struct dsa_switch *ds = dp->ds; @@ -40,7 +50,7 @@ int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age) ds->ops->port_stp_state_set(ds, port, state); - if (do_fast_age && ds->ops->port_fast_age) { + if (do_fast_age) { /* Fast age FDB entries or flush appropriate forwarding database * for the given port, if we are moving it from Learning or * Forwarding state, to Disabled or Blocking or Listening state. @@ -54,7 +64,7 @@ int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age) (state == BR_STATE_DISABLED || state == BR_STATE_BLOCKING || state == BR_STATE_LISTENING)) - ds->ops->port_fast_age(ds, port); + dsa_port_fast_age(dp); } dp->stp_state = state; @@ -633,16 +643,33 @@ int dsa_port_pre_bridge_flags(const struct dsa_port *dp, return ds->ops->port_pre_bridge_flags(ds, dp->index, flags, extack); } -int dsa_port_bridge_flags(const struct dsa_port *dp, +int dsa_port_bridge_flags(struct dsa_port *dp, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack) { struct dsa_switch *ds = dp->ds; + int err; if (!ds->ops->port_bridge_flags) return -EOPNOTSUPP; - return ds->ops->port_bridge_flags(ds, dp->index, flags, extack); + err = ds->ops->port_bridge_flags(ds, dp->index, flags, extack); + if (err) + return err; + + if (flags.mask & BR_LEARNING) { + bool learning = flags.val & BR_LEARNING; + + if (learning == dp->learning) + return 0; + + if (dp->learning && !learning) + dsa_port_fast_age(dp); + + dp->learning = learning; + } + + return 0; } int dsa_port_mtu_change(struct dsa_port *dp, int new_mtu, |