blob: 8349d319002117050a2241d12a4ef5c9828e653d [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 5d65b64a3d97011796b225ce315b3ce0011551e7 Mon Sep 17 00:00:00 2001
2From: Florian Fainelli <f.fainelli@gmail.com>
3Date: Thu, 24 Oct 2019 12:45:07 -0700
4Subject: [PATCH] net: dsa: b53: Add support for MDB
5
6In preparation for supporting IGMP snooping with or without the use of
7a bridge, add support within b53_common.c to program the ARL entries for
8multicast operations. The key difference is that a multicast ARL entry
9is comprised of a bitmask of enabled ports, instead of a port number.
10
11Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
12Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com>
13Signed-off-by: David S. Miller <davem@davemloft.net>
14---
15 drivers/net/dsa/b53/b53_common.c | 62 ++++++++++++++++++++++++++++++--
16 drivers/net/dsa/b53/b53_priv.h | 8 ++++-
17 2 files changed, 67 insertions(+), 3 deletions(-)
18
19--- a/drivers/net/dsa/b53/b53_common.c
20+++ b/drivers/net/dsa/b53/b53_common.c
21@@ -1549,11 +1549,25 @@ static int b53_arl_op(struct b53_device
22 break;
23 }
24
25- memset(&ent, 0, sizeof(ent));
26- ent.port = port;
27+ /* For multicast address, the port is a bitmask and the validity
28+ * is determined by having at least one port being still active
29+ */
30+ if (!is_multicast_ether_addr(addr)) {
31+ ent.port = port;
32+ ent.is_valid = is_valid;
33+ } else {
34+ if (is_valid)
35+ ent.port |= BIT(port);
36+ else
37+ ent.port &= ~BIT(port);
38+
39+ ent.is_valid = !!(ent.port);
40+ }
41+
42 ent.is_valid = is_valid;
43 ent.vid = vid;
44 ent.is_static = true;
45+ ent.is_age = false;
46 memcpy(ent.mac, addr, ETH_ALEN);
47 b53_arl_from_entry(&mac_vid, &fwd_entry, &ent);
48
49@@ -1672,6 +1686,47 @@ int b53_fdb_dump(struct dsa_switch *ds,
50 }
51 EXPORT_SYMBOL(b53_fdb_dump);
52
53+int b53_mdb_prepare(struct dsa_switch *ds, int port,
54+ const struct switchdev_obj_port_mdb *mdb)
55+{
56+ struct b53_device *priv = ds->priv;
57+
58+ /* 5325 and 5365 require some more massaging, but could
59+ * be supported eventually
60+ */
61+ if (is5325(priv) || is5365(priv))
62+ return -EOPNOTSUPP;
63+
64+ return 0;
65+}
66+EXPORT_SYMBOL(b53_mdb_prepare);
67+
68+void b53_mdb_add(struct dsa_switch *ds, int port,
69+ const struct switchdev_obj_port_mdb *mdb)
70+{
71+ struct b53_device *priv = ds->priv;
72+ int ret;
73+
74+ ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true);
75+ if (ret)
76+ dev_err(ds->dev, "failed to add MDB entry\n");
77+}
78+EXPORT_SYMBOL(b53_mdb_add);
79+
80+int b53_mdb_del(struct dsa_switch *ds, int port,
81+ const struct switchdev_obj_port_mdb *mdb)
82+{
83+ struct b53_device *priv = ds->priv;
84+ int ret;
85+
86+ ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, false);
87+ if (ret)
88+ dev_err(ds->dev, "failed to delete MDB entry\n");
89+
90+ return ret;
91+}
92+EXPORT_SYMBOL(b53_mdb_del);
93+
94 int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
95 {
96 struct b53_device *dev = ds->priv;
97@@ -2050,6 +2105,9 @@ static const struct dsa_switch_ops b53_s
98 .port_fdb_del = b53_fdb_del,
99 .port_mirror_add = b53_mirror_add,
100 .port_mirror_del = b53_mirror_del,
101+ .port_mdb_prepare = b53_mdb_prepare,
102+ .port_mdb_add = b53_mdb_add,
103+ .port_mdb_del = b53_mdb_del,
104 };
105
106 struct b53_chip_data {
107--- a/drivers/net/dsa/b53/b53_priv.h
108+++ b/drivers/net/dsa/b53/b53_priv.h
109@@ -250,7 +250,7 @@ b53_build_op(write48, u64);
110 b53_build_op(write64, u64);
111
112 struct b53_arl_entry {
113- u8 port;
114+ u16 port;
115 u8 mac[ETH_ALEN];
116 u16 vid;
117 u8 is_valid:1;
118@@ -351,6 +351,12 @@ int b53_fdb_del(struct dsa_switch *ds, i
119 const unsigned char *addr, u16 vid);
120 int b53_fdb_dump(struct dsa_switch *ds, int port,
121 dsa_fdb_dump_cb_t *cb, void *data);
122+int b53_mdb_prepare(struct dsa_switch *ds, int port,
123+ const struct switchdev_obj_port_mdb *mdb);
124+void b53_mdb_add(struct dsa_switch *ds, int port,
125+ const struct switchdev_obj_port_mdb *mdb);
126+int b53_mdb_del(struct dsa_switch *ds, int port,
127+ const struct switchdev_obj_port_mdb *mdb);
128 int b53_mirror_add(struct dsa_switch *ds, int port,
129 struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
130 enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port);