summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/mscc/ocelot.c
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2022-02-16 16:30:10 +0200
committerDavid S. Miller <davem@davemloft.net>2022-02-17 14:06:51 +0000
commite42bd4ed09aaf57949f199ae02d20a7108ccf73b (patch)
treeb4ec4808d9c6d01c9f7314118988aa7aa294a4c3 /drivers/net/ethernet/mscc/ocelot.c
parent2960bb14ea27e8ce48e05534eb6737de1176fe22 (diff)
net: mscc: ocelot: keep traps in a list
When using the ocelot-8021q tagging protocol, the CPU port isn't configured as an NPI port, but is a regular port. So a "trap to CPU" operation is actually a "redirect" operation. So DSA needs to set up the trapping action one way or another, depending on the tagging protocol in use. To ease DSA's work of modifying the action, keep all currently installed traps in a list, so that DSA can live-patch them when the tagging protocol changes. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mscc/ocelot.c')
-rw-r--r--drivers/net/ethernet/mscc/ocelot.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 502e64764cbd..5356d9316943 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1495,6 +1495,7 @@ int ocelot_trap_add(struct ocelot *ocelot, int port, unsigned long cookie,
trap->action.cpu_copy_ena = true;
trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
trap->action.port_mask = 0;
+ list_add_tail(&trap->trap_list, &ocelot->traps);
new = true;
}
@@ -1506,8 +1507,10 @@ int ocelot_trap_add(struct ocelot *ocelot, int port, unsigned long cookie,
err = ocelot_vcap_filter_replace(ocelot, trap);
if (err) {
trap->ingress_port_mask &= ~BIT(port);
- if (!trap->ingress_port_mask)
+ if (!trap->ingress_port_mask) {
+ list_del(&trap->trap_list);
kfree(trap);
+ }
return err;
}
@@ -1527,8 +1530,11 @@ int ocelot_trap_del(struct ocelot *ocelot, int port, unsigned long cookie)
return 0;
trap->ingress_port_mask &= ~BIT(port);
- if (!trap->ingress_port_mask)
+ if (!trap->ingress_port_mask) {
+ list_del(&trap->trap_list);
+
return ocelot_vcap_filter_del(ocelot, trap);
+ }
return ocelot_vcap_filter_replace(ocelot, trap);
}