net: dsa: add port fast ageing

Today the DSA drivers are in charge of flushing the MAC addresses
associated to a port when its STP state changes from Learning or
Forwarding, to Disabled or Blocking or Listening.

This makes the drivers more complex and hides the generic switch logic.
Introduce a new optional port_fast_age operation to dsa_switch_ops, to
move this logic to the DSA layer and keep drivers simple.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vivien Didelot 2016-09-22 16:49:22 -04:00 committed by David S. Miller
parent 4acfee8143
commit 732f794c1b
2 changed files with 20 additions and 0 deletions

View File

@ -143,6 +143,7 @@ struct dsa_port {
struct net_device *netdev; struct net_device *netdev;
struct device_node *dn; struct device_node *dn;
unsigned int ageing_time; unsigned int ageing_time;
u8 stp_state;
}; };
struct dsa_switch { struct dsa_switch {
@ -339,6 +340,7 @@ struct dsa_switch_ops {
void (*port_bridge_leave)(struct dsa_switch *ds, int port); void (*port_bridge_leave)(struct dsa_switch *ds, int port);
void (*port_stp_state_set)(struct dsa_switch *ds, int port, void (*port_stp_state_set)(struct dsa_switch *ds, int port,
u8 state); u8 state);
void (*port_fast_age)(struct dsa_switch *ds, int port);
/* /*
* VLAN support * VLAN support

View File

@ -71,8 +71,26 @@ static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p)
static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state) static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state)
{ {
struct dsa_port *dp = &ds->ports[port];
if (ds->ops->port_stp_state_set) if (ds->ops->port_stp_state_set)
ds->ops->port_stp_state_set(ds, port, state); ds->ops->port_stp_state_set(ds, port, state);
if (ds->ops->port_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.
*/
if ((dp->stp_state == BR_STATE_LEARNING ||
dp->stp_state == BR_STATE_FORWARDING) &&
(state == BR_STATE_DISABLED ||
state == BR_STATE_BLOCKING ||
state == BR_STATE_LISTENING))
ds->ops->port_fast_age(ds, port);
}
dp->stp_state = state;
} }
static int dsa_slave_open(struct net_device *dev) static int dsa_slave_open(struct net_device *dev)