]> www.infradead.org Git - nvme.git/commitdiff
net: sparx5: add bookkeeping code for matchall rules
authorDaniel Machon <daniel.machon@microchip.com>
Sat, 20 Apr 2024 19:29:11 +0000 (21:29 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 24 Apr 2024 12:08:06 +0000 (13:08 +0100)
In preparation for new tc matchall rules, we add a bit of bookkeeping
code to keep track of them. The rules are identified by the cookie
passed from the tc stack.

Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/microchip/sparx5/sparx5_main.c
drivers/net/ethernet/microchip/sparx5/sparx5_main.h
drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c

index 3c066b62e68947cf81fc34c1169cc2edd2991d5a..b64c814eac11e8096a0c9d3c52965f8ce63798ee 100644 (file)
@@ -899,6 +899,9 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
                dev_err(sparx5->dev, "PTP failed\n");
                goto cleanup_ports;
        }
+
+       INIT_LIST_HEAD(&sparx5->mall_entries);
+
        goto cleanup_config;
 
 cleanup_ports:
index 316fed5f27355207146875ee80b3636420ca4945..4de37a5387a4991882703290eee393002e78fdad 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ptp_clock_kernel.h>
 #include <linux/hrtimer.h>
 #include <linux/debugfs.h>
+#include <net/flow_offload.h>
 
 #include "sparx5_main_regs.h"
 
@@ -227,6 +228,14 @@ struct sparx5_mdb_entry {
        u16 pgid_idx;
 };
 
+struct sparx5_mall_entry {
+       struct list_head list;
+       struct sparx5_port *port;
+       unsigned long cookie;
+       enum flow_action_id type;
+       bool ingress;
+};
+
 #define SPARX5_PTP_TIMEOUT             msecs_to_jiffies(10)
 #define SPARX5_SKB_CB(skb) \
        ((struct sparx5_skb_cb *)((skb)->cb))
@@ -295,6 +304,7 @@ struct sparx5 {
        struct vcap_control *vcap_ctrl;
        /* PGID allocation map */
        u8 pgid_map[PGID_TABLE_SIZE];
+       struct list_head mall_entries;
        /* Common root for debugfs */
        struct dentry *debugfs_root;
 };
index d88a93f226065834d22c36c050c094a93be2248d..2a33b347098fc24b501dfc4eeeb0a8a68ab20fb7 100644 (file)
 #include "sparx5_main.h"
 #include "sparx5_vcap_impl.h"
 
+static struct sparx5_mall_entry *
+sparx5_tc_matchall_entry_find(struct list_head *entries, unsigned long cookie)
+{
+       struct sparx5_mall_entry *entry;
+
+       list_for_each_entry(entry, entries, list) {
+               if (entry->cookie == cookie)
+                       return entry;
+       }
+
+       return NULL;
+}
+
+static void sparx5_tc_matchall_parse_action(struct sparx5_port *port,
+                                           struct sparx5_mall_entry *entry,
+                                           struct flow_action_entry *action,
+                                           bool ingress,
+                                           unsigned long cookie)
+{
+       entry->port = port;
+       entry->type = action->id;
+       entry->ingress = ingress;
+       entry->cookie = cookie;
+}
+
 static int sparx5_tc_matchall_replace(struct net_device *ndev,
                                      struct tc_cls_matchall_offload *tmo,
                                      bool ingress)
 {
        struct sparx5_port *port = netdev_priv(ndev);
+       struct sparx5_mall_entry *mall_entry;
        struct flow_action_entry *action;
        struct sparx5 *sparx5;
        int err;
@@ -27,6 +53,16 @@ static int sparx5_tc_matchall_replace(struct net_device *ndev,
        }
        action = &tmo->rule->action.entries[0];
 
+       mall_entry = kzalloc(sizeof(*mall_entry), GFP_KERNEL);
+       if (!mall_entry)
+               return -ENOMEM;
+
+       sparx5_tc_matchall_parse_action(port,
+                                       mall_entry,
+                                       action,
+                                       ingress,
+                                       tmo->cookie);
+
        sparx5 = port->sparx5;
        switch (action->id) {
        case FLOW_ACTION_GOTO:
@@ -59,6 +95,9 @@ static int sparx5_tc_matchall_replace(struct net_device *ndev,
                NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action");
                return -EOPNOTSUPP;
        }
+
+       list_add_tail(&mall_entry->list, &sparx5->mall_entries);
+
        return 0;
 }
 
@@ -67,19 +106,26 @@ static int sparx5_tc_matchall_destroy(struct net_device *ndev,
                                      bool ingress)
 {
        struct sparx5_port *port = netdev_priv(ndev);
-       struct sparx5 *sparx5;
+       struct sparx5 *sparx5 = port->sparx5;
+       struct sparx5_mall_entry *entry;
        int err;
 
-       sparx5 = port->sparx5;
-       if (!tmo->rule && tmo->cookie) {
+       entry = sparx5_tc_matchall_entry_find(&sparx5->mall_entries,
+                                             tmo->cookie);
+       if (!entry)
+               return -ENOENT;
+
+       if (entry->type == FLOW_ACTION_GOTO) {
                err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev,
                                          0, 0, tmo->cookie, false);
-               if (err)
-                       return err;
-               return 0;
+       } else {
+               NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action");
+               err = -EOPNOTSUPP;
        }
-       NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action");
-       return -EOPNOTSUPP;
+
+       list_del(&entry->list);
+
+       return err;
 }
 
 int sparx5_tc_matchall(struct net_device *ndev,