mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-10 03:09:08 +08:00
067d7e9f90
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
131 lines
3.9 KiB
Diff
131 lines
3.9 KiB
Diff
From 5d65b64a3d97011796b225ce315b3ce0011551e7 Mon Sep 17 00:00:00 2001
|
|
From: Florian Fainelli <f.fainelli@gmail.com>
|
|
Date: Thu, 24 Oct 2019 12:45:07 -0700
|
|
Subject: [PATCH] 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: Florian Fainelli <f.fainelli@gmail.com>
|
|
Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/dsa/b53/b53_common.c | 62 ++++++++++++++++++++++++++++++--
|
|
drivers/net/dsa/b53/b53_priv.h | 8 ++++-
|
|
2 files changed, 67 insertions(+), 3 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/b53/b53_common.c
|
|
+++ b/drivers/net/dsa/b53/b53_common.c
|
|
@@ -1549,11 +1549,25 @@ static int b53_arl_op(struct b53_device
|
|
break;
|
|
}
|
|
|
|
- memset(&ent, 0, sizeof(ent));
|
|
- ent.port = port;
|
|
+ /* 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);
|
|
|
|
@@ -1672,6 +1686,47 @@ int b53_fdb_dump(struct dsa_switch *ds,
|
|
}
|
|
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;
|
|
@@ -2050,6 +2105,9 @@ static const struct dsa_switch_ops b53_s
|
|
.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 {
|
|
--- a/drivers/net/dsa/b53/b53_priv.h
|
|
+++ b/drivers/net/dsa/b53/b53_priv.h
|
|
@@ -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, i
|
|
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);
|