Commit 5d65b64a authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller

net: dsa: b53: Add support for MDB

In preparation for supporting IGMP snooping with or without the use of
a bridge, add support within b53_common.c to program the ARL entries for
multicast operations. The key difference is that a multicast ARL entry
is comprised of a bitmask of enabled ports, instead of a port number.
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Reviewed-by: default avatarVivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7a9eff98
......@@ -1503,11 +1503,25 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
idx = 1;
}
memset(&ent, 0, sizeof(ent));
/* For multicast address, the port is a bitmask and the validity
* is determined by having at least one port being still active
*/
if (!is_multicast_ether_addr(addr)) {
ent.port = port;
ent.is_valid = is_valid;
} else {
if (is_valid)
ent.port |= BIT(port);
else
ent.port &= ~BIT(port);
ent.is_valid = !!(ent.port);
}
ent.is_valid = is_valid;
ent.vid = vid;
ent.is_static = true;
ent.is_age = false;
memcpy(ent.mac, addr, ETH_ALEN);
b53_arl_from_entry(&mac_vid, &fwd_entry, &ent);
......@@ -1626,6 +1640,47 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,
}
EXPORT_SYMBOL(b53_fdb_dump);
int b53_mdb_prepare(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb)
{
struct b53_device *priv = ds->priv;
/* 5325 and 5365 require some more massaging, but could
* be supported eventually
*/
if (is5325(priv) || is5365(priv))
return -EOPNOTSUPP;
return 0;
}
EXPORT_SYMBOL(b53_mdb_prepare);
void b53_mdb_add(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb)
{
struct b53_device *priv = ds->priv;
int ret;
ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true);
if (ret)
dev_err(ds->dev, "failed to add MDB entry\n");
}
EXPORT_SYMBOL(b53_mdb_add);
int b53_mdb_del(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb)
{
struct b53_device *priv = ds->priv;
int ret;
ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, false);
if (ret)
dev_err(ds->dev, "failed to delete MDB entry\n");
return ret;
}
EXPORT_SYMBOL(b53_mdb_del);
int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
{
struct b53_device *dev = ds->priv;
......@@ -1994,6 +2049,9 @@ static const struct dsa_switch_ops b53_switch_ops = {
.port_fdb_del = b53_fdb_del,
.port_mirror_add = b53_mirror_add,
.port_mirror_del = b53_mirror_del,
.port_mdb_prepare = b53_mdb_prepare,
.port_mdb_add = b53_mdb_add,
.port_mdb_del = b53_mdb_del,
};
struct b53_chip_data {
......
......@@ -250,7 +250,7 @@ b53_build_op(write48, u64);
b53_build_op(write64, u64);
struct b53_arl_entry {
u8 port;
u16 port;
u8 mac[ETH_ALEN];
u16 vid;
u8 is_valid:1;
......@@ -351,6 +351,12 @@ int b53_fdb_del(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid);
int b53_fdb_dump(struct dsa_switch *ds, int port,
dsa_fdb_dump_cb_t *cb, void *data);
int b53_mdb_prepare(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb);
void b53_mdb_add(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb);
int b53_mdb_del(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb);
int b53_mirror_add(struct dsa_switch *ds, int port,
struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port);
......
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