net: dsa: felix: add port fast age support
Add support for flushing the MAC table on a given port in the ocelot switch library, and use this functionality in the felix DSA driver. This operation is needed when a port leaves a bridge to become standalone, and when the learning is disabled, and when the STP state changes to a state where no FDB entry should be present. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Link: https://lore.kernel.org/r/20220107144229.244584-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
a14e6b69f3
commit
5cad43a52e
|
@ -639,6 +639,17 @@ static int felix_set_ageing_time(struct dsa_switch *ds,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void felix_port_fast_age(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct ocelot *ocelot = ds->priv;
|
||||
int err;
|
||||
|
||||
err = ocelot_mact_flush(ocelot, port);
|
||||
if (err)
|
||||
dev_err(ds->dev, "Flushing MAC table on port %d returned %pe\n",
|
||||
port, ERR_PTR(err));
|
||||
}
|
||||
|
||||
static int felix_fdb_dump(struct dsa_switch *ds, int port,
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
|
@ -1622,6 +1633,7 @@ const struct dsa_switch_ops felix_switch_ops = {
|
|||
.phylink_mac_config = felix_phylink_mac_config,
|
||||
.phylink_mac_link_down = felix_phylink_mac_link_down,
|
||||
.phylink_mac_link_up = felix_phylink_mac_link_up,
|
||||
.port_fast_age = felix_port_fast_age,
|
||||
.port_fdb_dump = felix_fdb_dump,
|
||||
.port_fdb_add = felix_fdb_add,
|
||||
.port_fdb_del = felix_fdb_del,
|
||||
|
|
|
@ -1341,6 +1341,43 @@ static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ocelot_mact_flush(struct ocelot *ocelot, int port)
|
||||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&ocelot->mact_lock);
|
||||
|
||||
/* Program ageing filter for a single port */
|
||||
ocelot_write(ocelot, ANA_ANAGEFIL_PID_EN | ANA_ANAGEFIL_PID_VAL(port),
|
||||
ANA_ANAGEFIL);
|
||||
|
||||
/* Flushing dynamic FDB entries requires two successive age scans */
|
||||
ocelot_write(ocelot,
|
||||
ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_AGE),
|
||||
ANA_TABLES_MACACCESS);
|
||||
|
||||
err = ocelot_mact_wait_for_completion(ocelot);
|
||||
if (err) {
|
||||
mutex_unlock(&ocelot->mact_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* And second... */
|
||||
ocelot_write(ocelot,
|
||||
ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_AGE),
|
||||
ANA_TABLES_MACACCESS);
|
||||
|
||||
err = ocelot_mact_wait_for_completion(ocelot);
|
||||
|
||||
/* Restore ageing filter */
|
||||
ocelot_write(ocelot, 0, ANA_ANAGEFIL);
|
||||
|
||||
mutex_unlock(&ocelot->mact_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ocelot_mact_flush);
|
||||
|
||||
int ocelot_fdb_dump(struct ocelot *ocelot, int port,
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
|
|
|
@ -833,6 +833,7 @@ void ocelot_port_bridge_join(struct ocelot *ocelot, int port,
|
|||
struct net_device *bridge);
|
||||
void ocelot_port_bridge_leave(struct ocelot *ocelot, int port,
|
||||
struct net_device *bridge);
|
||||
int ocelot_mact_flush(struct ocelot *ocelot, int port);
|
||||
int ocelot_fdb_dump(struct ocelot *ocelot, int port,
|
||||
dsa_fdb_dump_cb_t *cb, void *data);
|
||||
int ocelot_fdb_add(struct ocelot *ocelot, int port,
|
||||
|
|
Loading…
Reference in New Issue