Commit 8fc0b699 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'simplify-migration-of-host-filtered-addresses-in-felix-driver'

Vladimir Oltean says:

====================
Simplify migration of host filtered addresses in Felix driver

The purpose of this patch set is to remove the functions
dsa_port_walk_fdbs() and dsa_port_walk_mdbs() from the DSA core, which
were introduced when the Felix driver gained support for unicast
filtering on standalone ports. They get called when changing the tagging
protocol back and forth between "ocelot" and "ocelot-8021q".
I did not realize we could get away without having them.

The patch set was regression-tested using the local_termination.sh
selftest using both tagging protocols.
====================

Link: https://lore.kernel.org/r/20220505162213.307684-1-vladimir.oltean@nxp.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 0a02e282 fe5233b0
...@@ -42,44 +42,6 @@ static struct net_device *felix_classify_db(struct dsa_db db) ...@@ -42,44 +42,6 @@ static struct net_device *felix_classify_db(struct dsa_db db)
} }
} }
/* We are called before felix_npi_port_init(), so ocelot->npi is -1. */
static int felix_migrate_fdbs_to_npi_port(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid,
struct dsa_db db)
{
struct net_device *bridge_dev = felix_classify_db(db);
struct ocelot *ocelot = ds->priv;
int cpu = ocelot->num_phys_ports;
int err;
err = ocelot_fdb_del(ocelot, port, addr, vid, bridge_dev);
if (err)
return err;
return ocelot_fdb_add(ocelot, cpu, addr, vid, bridge_dev);
}
static int felix_migrate_mdbs_to_npi_port(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid,
struct dsa_db db)
{
struct net_device *bridge_dev = felix_classify_db(db);
struct switchdev_obj_port_mdb mdb;
struct ocelot *ocelot = ds->priv;
int cpu = ocelot->num_phys_ports;
int err;
memset(&mdb, 0, sizeof(mdb));
ether_addr_copy(mdb.addr, addr);
mdb.vid = vid;
err = ocelot_port_mdb_del(ocelot, port, &mdb, bridge_dev);
if (err)
return err;
return ocelot_port_mdb_add(ocelot, cpu, &mdb, bridge_dev);
}
static void felix_migrate_pgid_bit(struct dsa_switch *ds, int from, int to, static void felix_migrate_pgid_bit(struct dsa_switch *ds, int from, int to,
int pgid) int pgid)
{ {
...@@ -117,49 +79,6 @@ felix_migrate_flood_to_tag_8021q_port(struct dsa_switch *ds, int port) ...@@ -117,49 +79,6 @@ felix_migrate_flood_to_tag_8021q_port(struct dsa_switch *ds, int port)
felix_migrate_pgid_bit(ds, ocelot->num_phys_ports, port, PGID_BC); felix_migrate_pgid_bit(ds, ocelot->num_phys_ports, port, PGID_BC);
} }
/* ocelot->npi was already set to -1 by felix_npi_port_deinit, so
* ocelot_fdb_add() will not redirect FDB entries towards the
* CPU port module here, which is what we want.
*/
static int
felix_migrate_fdbs_to_tag_8021q_port(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid,
struct dsa_db db)
{
struct net_device *bridge_dev = felix_classify_db(db);
struct ocelot *ocelot = ds->priv;
int cpu = ocelot->num_phys_ports;
int err;
err = ocelot_fdb_del(ocelot, cpu, addr, vid, bridge_dev);
if (err)
return err;
return ocelot_fdb_add(ocelot, port, addr, vid, bridge_dev);
}
static int
felix_migrate_mdbs_to_tag_8021q_port(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid,
struct dsa_db db)
{
struct net_device *bridge_dev = felix_classify_db(db);
struct switchdev_obj_port_mdb mdb;
struct ocelot *ocelot = ds->priv;
int cpu = ocelot->num_phys_ports;
int err;
memset(&mdb, 0, sizeof(mdb));
ether_addr_copy(mdb.addr, addr);
mdb.vid = vid;
err = ocelot_port_mdb_del(ocelot, cpu, &mdb, bridge_dev);
if (err)
return err;
return ocelot_port_mdb_add(ocelot, port, &mdb, bridge_dev);
}
/* Set up VCAP ES0 rules for pushing a tag_8021q VLAN towards the CPU such that /* Set up VCAP ES0 rules for pushing a tag_8021q VLAN towards the CPU such that
* the tagger can perform RX source port identification. * the tagger can perform RX source port identification.
*/ */
...@@ -488,14 +407,11 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu) ...@@ -488,14 +407,11 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
if (err) if (err)
return err; return err;
err = dsa_port_walk_fdbs(ds, cpu, felix_migrate_fdbs_to_tag_8021q_port); err = ocelot_migrate_mdbs(ocelot, BIT(ocelot->num_phys_ports),
BIT(cpu));
if (err) if (err)
goto out_tag_8021q_unregister; goto out_tag_8021q_unregister;
err = dsa_port_walk_mdbs(ds, cpu, felix_migrate_mdbs_to_tag_8021q_port);
if (err)
goto out_migrate_fdbs;
felix_migrate_flood_to_tag_8021q_port(ds, cpu); felix_migrate_flood_to_tag_8021q_port(ds, cpu);
err = felix_update_trapping_destinations(ds, true); err = felix_update_trapping_destinations(ds, true);
...@@ -515,9 +431,7 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu) ...@@ -515,9 +431,7 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
out_migrate_flood: out_migrate_flood:
felix_migrate_flood_to_npi_port(ds, cpu); felix_migrate_flood_to_npi_port(ds, cpu);
dsa_port_walk_mdbs(ds, cpu, felix_migrate_mdbs_to_npi_port); ocelot_migrate_mdbs(ocelot, BIT(cpu), BIT(ocelot->num_phys_ports));
out_migrate_fdbs:
dsa_port_walk_fdbs(ds, cpu, felix_migrate_fdbs_to_npi_port);
out_tag_8021q_unregister: out_tag_8021q_unregister:
dsa_tag_8021q_unregister(ds); dsa_tag_8021q_unregister(ds);
return err; return err;
...@@ -597,24 +511,16 @@ static int felix_setup_tag_npi(struct dsa_switch *ds, int cpu) ...@@ -597,24 +511,16 @@ static int felix_setup_tag_npi(struct dsa_switch *ds, int cpu)
struct ocelot *ocelot = ds->priv; struct ocelot *ocelot = ds->priv;
int err; int err;
err = dsa_port_walk_fdbs(ds, cpu, felix_migrate_fdbs_to_npi_port); err = ocelot_migrate_mdbs(ocelot, BIT(cpu),
BIT(ocelot->num_phys_ports));
if (err) if (err)
return err; return err;
err = dsa_port_walk_mdbs(ds, cpu, felix_migrate_mdbs_to_npi_port);
if (err)
goto out_migrate_fdbs;
felix_migrate_flood_to_npi_port(ds, cpu); felix_migrate_flood_to_npi_port(ds, cpu);
felix_npi_port_init(ocelot, cpu); felix_npi_port_init(ocelot, cpu);
return 0; return 0;
out_migrate_fdbs:
dsa_port_walk_fdbs(ds, cpu, felix_migrate_fdbs_to_tag_8021q_port);
return err;
} }
static void felix_teardown_tag_npi(struct dsa_switch *ds, int cpu) static void felix_teardown_tag_npi(struct dsa_switch *ds, int cpu)
......
...@@ -2610,6 +2610,67 @@ static void ocelot_setup_logical_port_ids(struct ocelot *ocelot) ...@@ -2610,6 +2610,67 @@ static void ocelot_setup_logical_port_ids(struct ocelot *ocelot)
} }
} }
static int ocelot_migrate_mc(struct ocelot *ocelot, struct ocelot_multicast *mc,
unsigned long from_mask, unsigned long to_mask)
{
unsigned char addr[ETH_ALEN];
struct ocelot_pgid *pgid;
u16 vid = mc->vid;
dev_dbg(ocelot->dev,
"Migrating multicast %pM vid %d from port mask 0x%lx to 0x%lx\n",
mc->addr, mc->vid, from_mask, to_mask);
/* First clean up the current port mask from hardware, because
* we'll be modifying it.
*/
ocelot_pgid_free(ocelot, mc->pgid);
ocelot_encode_ports_to_mdb(addr, mc);
ocelot_mact_forget(ocelot, addr, vid);
mc->ports &= ~from_mask;
mc->ports |= to_mask;
pgid = ocelot_mdb_get_pgid(ocelot, mc);
if (IS_ERR(pgid)) {
dev_err(ocelot->dev,
"Cannot allocate PGID for mdb %pM vid %d\n",
mc->addr, mc->vid);
devm_kfree(ocelot->dev, mc);
return PTR_ERR(pgid);
}
mc->pgid = pgid;
ocelot_encode_ports_to_mdb(addr, mc);
if (mc->entry_type != ENTRYTYPE_MACv4 &&
mc->entry_type != ENTRYTYPE_MACv6)
ocelot_write_rix(ocelot, pgid->ports, ANA_PGID_PGID,
pgid->index);
return ocelot_mact_learn(ocelot, pgid->index, addr, vid,
mc->entry_type);
}
int ocelot_migrate_mdbs(struct ocelot *ocelot, unsigned long from_mask,
unsigned long to_mask)
{
struct ocelot_multicast *mc;
int err;
list_for_each_entry(mc, &ocelot->multicast, list) {
if (!(mc->ports & from_mask))
continue;
err = ocelot_migrate_mc(ocelot, mc, from_mask, to_mask);
if (err)
return err;
}
return 0;
}
EXPORT_SYMBOL_GPL(ocelot_migrate_mdbs);
/* Documentation for PORTID_VAL says: /* Documentation for PORTID_VAL says:
* Logical port number for front port. If port is not a member of a LLAG, * Logical port number for front port. If port is not a member of a LLAG,
* then PORTID must be set to the physical port number. * then PORTID must be set to the physical port number.
......
...@@ -1239,12 +1239,6 @@ struct dsa_switch_driver { ...@@ -1239,12 +1239,6 @@ struct dsa_switch_driver {
struct net_device *dsa_dev_to_net_device(struct device *dev); struct net_device *dsa_dev_to_net_device(struct device *dev);
typedef int dsa_fdb_walk_cb_t(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid,
struct dsa_db db);
int dsa_port_walk_fdbs(struct dsa_switch *ds, int port, dsa_fdb_walk_cb_t cb);
int dsa_port_walk_mdbs(struct dsa_switch *ds, int port, dsa_fdb_walk_cb_t cb);
bool dsa_fdb_present_in_other_db(struct dsa_switch *ds, int port, bool dsa_fdb_present_in_other_db(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid, const unsigned char *addr, u16 vid,
struct dsa_db db); struct dsa_db db);
......
...@@ -998,6 +998,9 @@ int ocelot_mact_learn_streamdata(struct ocelot *ocelot, int dst_idx, ...@@ -998,6 +998,9 @@ int ocelot_mact_learn_streamdata(struct ocelot *ocelot, int dst_idx,
enum macaccess_entry_type type, enum macaccess_entry_type type,
int sfid, int ssid); int sfid, int ssid);
int ocelot_migrate_mdbs(struct ocelot *ocelot, unsigned long from_mask,
unsigned long to_mask);
int ocelot_vcap_policer_add(struct ocelot *ocelot, u32 pol_ix, int ocelot_vcap_policer_add(struct ocelot *ocelot, u32 pol_ix,
struct ocelot_policer *pol); struct ocelot_policer *pol);
int ocelot_vcap_policer_del(struct ocelot *ocelot, u32 pol_ix); int ocelot_vcap_policer_del(struct ocelot *ocelot, u32 pol_ix);
......
...@@ -458,46 +458,6 @@ struct dsa_port *dsa_port_from_netdev(struct net_device *netdev) ...@@ -458,46 +458,6 @@ struct dsa_port *dsa_port_from_netdev(struct net_device *netdev)
} }
EXPORT_SYMBOL_GPL(dsa_port_from_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 = 0;
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 = 0;
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);
bool dsa_db_equal(const struct dsa_db *a, const struct dsa_db *b) bool dsa_db_equal(const struct dsa_db *a, const struct dsa_db *b)
{ {
if (a->type != b->type) if (a->type != b->type)
......
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