Skip to content

Commit 4bb33bf

Browse files
committed
net: sparx5: support enabling/disabling of multicast snooping
L2 forwarding of ipv4 and ipv6 multicast frames is done by looking up the equivalent l2 multicast address in the forwarding table. Add support for enabling/disabling l2 forwarding of ipv4 and ipv6 traffic, by using the SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED callback to dynamically learn and forget entries. Effectively, this means that based on the mcast_ena variable, multicast frames are either forwarded according to the multicast PGID masks, or the flood masks. Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
1 parent 20c5338 commit 4bb33bf

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

drivers/net/ethernet/microchip/sparx5/sparx5_main.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ struct sparx5_port {
300300
u16 ts_id;
301301
struct sk_buff_head tx_skbs;
302302
bool is_mrouter;
303+
bool mcast_ena;
303304
/* QOS port configuration */
304305
struct mchp_qos_port_conf qos_port_conf;
305306
/* Frame preemption configuration */
@@ -1113,6 +1114,9 @@ int sparx5_handle_mdb_add(struct net_device *dev, struct notifier_block *nb,
11131114

11141115
int sparx5_handle_mdb_del(struct net_device *dev, struct notifier_block *nb,
11151116
const struct switchdev_obj_port_mdb *v);
1117+
int sparx5_mdb_entries_clear(struct sparx5 *sparx5);
1118+
int sparx5_mdb_entries_restore(struct sparx5 *sparx5);
1119+
11161120

11171121
/* FDMA return action codes for checking if the frame is valid
11181122
* FDMA_PASS, frame is valid and can be used

drivers/net/ethernet/microchip/sparx5/sparx5_mdb.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,31 @@
1212
#include "sparx5_mrp.h"
1313
#include "sparx5_tc.h"
1414

15+
int sparx5_mdb_entries_clear(struct sparx5 *sparx5)
16+
{
17+
struct sparx5_mdb_entry *mdb_entry;
18+
19+
mutex_lock(&sparx5->mdb_lock);
20+
list_for_each_entry(mdb_entry, &sparx5->mdb_entries, list)
21+
sparx5_mact_forget(sparx5, mdb_entry->addr, mdb_entry->vid);
22+
mutex_unlock(&sparx5->mdb_lock);
23+
24+
return 0;
25+
}
26+
27+
int sparx5_mdb_entries_restore(struct sparx5 *sparx5)
28+
{
29+
struct sparx5_mdb_entry *mdb_entry;
30+
31+
mutex_lock(&sparx5->mdb_lock);
32+
list_for_each_entry(mdb_entry, &sparx5->mdb_entries, list)
33+
sparx5_mact_learn(sparx5, mdb_entry->pgid_idx, mdb_entry->addr,
34+
mdb_entry->vid);
35+
mutex_unlock(&sparx5->mdb_lock);
36+
37+
return 0;
38+
}
39+
1540
static int sparx5_mdb_entry_alloc(struct sparx5 *sparx5,
1641
const unsigned char *addr,
1742
u16 vid,

drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,30 @@ static void sparx5_port_attr_mrouter_set(struct sparx5_port *port,
138138
sparx5_port_update_mcast_ip_flood(port, flood_flag);
139139
}
140140

141+
static void sparx5_port_attr_mc_set(struct sparx5_port *port, bool mcast_ena)
142+
{
143+
struct sparx5 *sparx5 = port->sparx5;
144+
145+
port->mcast_ena = mcast_ena;
146+
147+
if (mcast_ena)
148+
/* Forward multicast frames according to PGID mask. */
149+
sparx5_mdb_entries_restore(sparx5);
150+
else
151+
/* Flood multicast frames according to MC flood mask. */
152+
sparx5_mdb_entries_clear(sparx5);
153+
154+
spx5_rmw(ANA_CL_CAPTURE_CFG_CPU_IGMP_REDIR_ENA_SET(mcast_ena) |
155+
ANA_CL_CAPTURE_CFG_CPU_MLD_REDIR_ENA_SET(mcast_ena),
156+
ANA_CL_CAPTURE_CFG_CPU_IGMP_REDIR_ENA |
157+
ANA_CL_CAPTURE_CFG_CPU_MLD_REDIR_ENA,
158+
sparx5, ANA_CL_CAPTURE_CFG(port->portno));
159+
160+
spx5_rmw(ANA_L3_L3MC_CTRL_IPMC_TTL_COPY_ENA_SET(mcast_ena),
161+
ANA_L3_L3MC_CTRL_IPMC_TTL_COPY_ENA,
162+
sparx5, ANA_L3_L3MC_CTRL(port->portno));
163+
}
164+
141165
static int sparx5_port_attr_set(struct net_device *dev, const void *ctx,
142166
const struct switchdev_attr *attr,
143167
struct netlink_ext_ack *extack)
@@ -174,6 +198,9 @@ static int sparx5_port_attr_set(struct net_device *dev, const void *ctx,
174198
case SWITCHDEV_ATTR_ID_MRP_PORT_ROLE:
175199
sparx5_handle_mrp_port_role(port, attr->u.mrp_port_role);
176200
break;
201+
case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
202+
sparx5_port_attr_mc_set(port, !attr->u.mc_disabled);
203+
break;
177204
default:
178205
return -EOPNOTSUPP;
179206
}

0 commit comments

Comments
 (0)