From 466dfa0770220cebad2e58e1905489328fc9daf7 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 26 Feb 2016 13:16:05 -0500 Subject: net: dsa: mv88e6xxx: assign dynamic FDB to bridges Give a new bridge a fresh FDB, assign it to its members, and restore a fresh FDB to a port leaving a bridge. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 0f064889ea08..0f169119cbb8 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2093,19 +2093,56 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *bridge) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + u16 fid; + int i, err; + + mutex_lock(&ps->smi_mutex); + + /* Get or create the bridge FID and assign it to the port */ + for (i = 0; i < ps->num_ports; ++i) + if (ps->ports[i].bridge_dev == bridge) + break; + + if (i < ps->num_ports) + err = _mv88e6xxx_port_fid_get(ds, i, &fid); + else + err = _mv88e6xxx_fid_new(ds, &fid); + if (err) + goto unlock; + + err = _mv88e6xxx_port_fid_set(ds, port, fid); + if (err) + goto unlock; ps->ports[port].bridge_dev = bridge; +unlock: + mutex_unlock(&ps->smi_mutex); - return 0; + return err; } int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + u16 fid; + int err; + + mutex_lock(&ps->smi_mutex); + + /* Give the port a fresh Filtering Information Database */ + err = _mv88e6xxx_fid_new(ds, &fid); + if (err) + goto unlock; + + err = _mv88e6xxx_port_fid_set(ds, port, fid); + if (err) + goto unlock; ps->ports[port].bridge_dev = NULL; +unlock: + mutex_unlock(&ps->smi_mutex); - return 0; + return err; } static int mv88e6xxx_setup_port_default_vlan(struct dsa_switch *ds, int port) -- cgit v1.2.3