Skip to content

Commit ba8f870

Browse files
Ansueldavem330
authored andcommitted
net: dsa: qca8k: add support for mdb_add/del
Add support for mdb add/del function. The ARL table is used to insert the rule. The rule will be searched, deleted and reinserted with the port mask updated. The function will check if the rule has to be updated or insert directly with no deletion of the old rule. If every port is removed from the port mask, the rule is removed. The rule is set STATIC in the ARL table (aka it doesn't age) to not be flushed by fast age function. Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6a3bdc5 commit ba8f870

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

drivers/net/dsa/qca8k.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,81 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
435435
mutex_unlock(&priv->reg_mutex);
436436
}
437437

438+
static int
439+
qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
440+
const u8 *mac, u16 vid)
441+
{
442+
struct qca8k_fdb fdb = { 0 };
443+
int ret;
444+
445+
mutex_lock(&priv->reg_mutex);
446+
447+
qca8k_fdb_write(priv, vid, 0, mac, 0);
448+
ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
449+
if (ret < 0)
450+
goto exit;
451+
452+
ret = qca8k_fdb_read(priv, &fdb);
453+
if (ret < 0)
454+
goto exit;
455+
456+
/* Rule exist. Delete first */
457+
if (!fdb.aging) {
458+
ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
459+
if (ret)
460+
goto exit;
461+
}
462+
463+
/* Add port to fdb portmask */
464+
fdb.port_mask |= port_mask;
465+
466+
qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
467+
ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
468+
469+
exit:
470+
mutex_unlock(&priv->reg_mutex);
471+
return ret;
472+
}
473+
474+
static int
475+
qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
476+
const u8 *mac, u16 vid)
477+
{
478+
struct qca8k_fdb fdb = { 0 };
479+
int ret;
480+
481+
mutex_lock(&priv->reg_mutex);
482+
483+
qca8k_fdb_write(priv, vid, 0, mac, 0);
484+
ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
485+
if (ret < 0)
486+
goto exit;
487+
488+
/* Rule doesn't exist. Why delete? */
489+
if (!fdb.aging) {
490+
ret = -EINVAL;
491+
goto exit;
492+
}
493+
494+
ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
495+
if (ret)
496+
goto exit;
497+
498+
/* Only port in the rule is this port. Don't re insert */
499+
if (fdb.port_mask == port_mask)
500+
goto exit;
501+
502+
/* Remove port from port mask */
503+
fdb.port_mask &= ~port_mask;
504+
505+
qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
506+
ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
507+
508+
exit:
509+
mutex_unlock(&priv->reg_mutex);
510+
return ret;
511+
}
512+
438513
static int
439514
qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
440515
{
@@ -1925,6 +2000,28 @@ qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
19252000
return 0;
19262001
}
19272002

2003+
static int
2004+
qca8k_port_mdb_add(struct dsa_switch *ds, int port,
2005+
const struct switchdev_obj_port_mdb *mdb)
2006+
{
2007+
struct qca8k_priv *priv = ds->priv;
2008+
const u8 *addr = mdb->addr;
2009+
u16 vid = mdb->vid;
2010+
2011+
return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
2012+
}
2013+
2014+
static int
2015+
qca8k_port_mdb_del(struct dsa_switch *ds, int port,
2016+
const struct switchdev_obj_port_mdb *mdb)
2017+
{
2018+
struct qca8k_priv *priv = ds->priv;
2019+
const u8 *addr = mdb->addr;
2020+
u16 vid = mdb->vid;
2021+
2022+
return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
2023+
}
2024+
19282025
static int
19292026
qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
19302027
struct netlink_ext_ack *extack)
@@ -2033,6 +2130,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
20332130
.port_fdb_add = qca8k_port_fdb_add,
20342131
.port_fdb_del = qca8k_port_fdb_del,
20352132
.port_fdb_dump = qca8k_port_fdb_dump,
2133+
.port_mdb_add = qca8k_port_mdb_add,
2134+
.port_mdb_del = qca8k_port_mdb_del,
20362135
.port_vlan_filtering = qca8k_port_vlan_filtering,
20372136
.port_vlan_add = qca8k_port_vlan_add,
20382137
.port_vlan_del = qca8k_port_vlan_del,

0 commit comments

Comments
 (0)