net: mscc: ocelot: keep traps in a list
authorVladimir Oltean <vladimir.oltean@nxp.com>
Wed, 16 Feb 2022 14:30:10 +0000 (16:30 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 17 Feb 2022 14:06:51 +0000 (14:06 +0000)
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>
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/mscc/ocelot_flower.c
drivers/net/ethernet/mscc/ocelot_vcap.c
include/soc/mscc/ocelot.h
include/soc/mscc/ocelot_vcap.h

index 502e64764cbdf8c2df74eba9b8d85809643891f3..5356d93169435353285d2e2663ba6feb0a91cefe 100644 (file)
@@ -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);
 }
index 949858891973d4bd6c03406dcd087710839ac0e7..7106137f98ee8792b0f986acc566369f65559080 100644 (file)
@@ -279,6 +279,7 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,
                        filter->action.cpu_copy_ena = true;
                        filter->action.cpu_qu_num = 0;
                        filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
+                       list_add_tail(&filter->trap_list, &ocelot->traps);
                        break;
                case FLOW_ACTION_POLICE:
                        if (filter->block_id == PSFP_BLOCK_ID) {
@@ -840,6 +841,8 @@ int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
 
        ret = ocelot_flower_parse(ocelot, port, ingress, f, filter);
        if (ret) {
+               if (!list_empty(&filter->trap_list))
+                       list_del(&filter->trap_list);
                kfree(filter);
                return ret;
        }
index d3544413a8a433b1cd6a0c3882ae2cd3ea476c98..852054da9db9b48aefa6375e575a02a5835061a7 100644 (file)
@@ -1401,6 +1401,7 @@ int ocelot_vcap_init(struct ocelot *ocelot)
        }
 
        INIT_LIST_HEAD(&ocelot->dummy_rules);
+       INIT_LIST_HEAD(&ocelot->traps);
        INIT_LIST_HEAD(&ocelot->vcap_pol.pol_list);
 
        return 0;
index 2d7456c0e77d104d3eba10a0741d7e0d815fb8ce..78f56502bc090876595c6574ae7ad140b12a2f5b 100644 (file)
@@ -689,6 +689,7 @@ struct ocelot {
        u8                              base_mac[ETH_ALEN];
 
        struct list_head                vlans;
+       struct list_head                traps;
 
        /* Switches like VSC9959 have flooding per traffic class */
        int                             num_flooding_pgids;
index ae0eec7f5dd2d3ede9363ffe88628c3d59925e36..69b3d880302d8cccdb0793500aaba3c09eb6fd40 100644 (file)
@@ -682,6 +682,7 @@ struct ocelot_vcap_id {
 
 struct ocelot_vcap_filter {
        struct list_head list;
+       struct list_head trap_list;
 
        enum ocelot_vcap_filter_type type;
        int block_id;