net: dsa: felix: migrate host FDB and MDB entries when changing tag proto

The "ocelot" and "ocelot-8021q" tagging protocols make use of different
hardware resources, and host FDB entries have different destination
ports in the switch analyzer module, practically speaking.

So when the user requests a tagging protocol change, the driver must
migrate all host FDB and MDB entries from the NPI port (in fact CPU port
module) towards the same physical port, but this time used as a regular
port.

It is pointless for the felix driver to keep a copy of the host
addresses, when we can create and export DSA helpers for walking through
the addresses that it already needs to keep on the CPU port, for
refcounting purposes.

felix_classify_db() is moved up to avoid a forward declaration.

We pass "bool change" because dp->fdbs and dp->mdbs are uninitialized
lists when felix_setup() first calls felix_set_tag_protocol(), so we
need to avoid calling dsa_port_walk_fdbs() during probe time.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vladimir Oltean 2022-03-02 21:14:13 +02:00 committed by David S. Miller
parent 7569459a52
commit f9cef64fa2
3 changed files with 192 additions and 26 deletions

View file

@ -467,6 +467,46 @@ struct dsa_port *dsa_port_from_netdev(struct net_device *netdev)
}
EXPORT_SYMBOL_GPL(dsa_port_from_netdev);
int dsa_port_walk_fdbs(struct dsa_switch *ds, int port, dsa_fdb_walk_cb_t cb)
{
struct dsa_port *dp = dsa_to_port(ds, port);
struct dsa_mac_addr *a;
int err;
mutex_lock(&dp->addr_lists_lock);
list_for_each_entry(a, &dp->fdbs, list) {
err = cb(ds, port, a->addr, a->vid, a->db);
if (err)
break;
}
mutex_unlock(&dp->addr_lists_lock);
return err;
}
EXPORT_SYMBOL_GPL(dsa_port_walk_fdbs);
int dsa_port_walk_mdbs(struct dsa_switch *ds, int port, dsa_fdb_walk_cb_t cb)
{
struct dsa_port *dp = dsa_to_port(ds, port);
struct dsa_mac_addr *a;
int err;
mutex_lock(&dp->addr_lists_lock);
list_for_each_entry(a, &dp->mdbs, list) {
err = cb(ds, port, a->addr, a->vid, a->db);
if (err)
break;
}
mutex_unlock(&dp->addr_lists_lock);
return err;
}
EXPORT_SYMBOL_GPL(dsa_port_walk_mdbs);
static int __init dsa_init_module(void)
{
int rc;