net/cnxk: support flow API
authorKiran Kumar K <kirankumark@marvell.com>
Wed, 23 Jun 2021 04:46:49 +0000 (10:16 +0530)
committerJerin Jacob <jerinj@marvell.com>
Wed, 30 Jun 2021 00:07:05 +0000 (02:07 +0200)
Adding initial version of rte_flow support for cnxk family device.
Supported rte_flow ops are flow_validate, flow_create, flow_destroy,
flow_flush, flow_query, flow_isolate.

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
14 files changed:
doc/guides/nics/cnxk.rst
doc/guides/nics/features/cnxk.ini
doc/guides/nics/features/cnxk_vec.ini
doc/guides/nics/features/cnxk_vf.ini
drivers/net/cnxk/cn10k_ethdev.c
drivers/net/cnxk/cn10k_rte_flow.c [new file with mode: 0644]
drivers/net/cnxk/cn10k_rte_flow.h [new file with mode: 0644]
drivers/net/cnxk/cn9k_ethdev.c
drivers/net/cnxk/cn9k_rte_flow.c [new file with mode: 0644]
drivers/net/cnxk/cn9k_rte_flow.h [new file with mode: 0644]
drivers/net/cnxk/cnxk_ethdev.h
drivers/net/cnxk/cnxk_rte_flow.c [new file with mode: 0644]
drivers/net/cnxk/cnxk_rte_flow.h [new file with mode: 0644]
drivers/net/cnxk/meson.build

index 4ee6eb6..bdf1fb1 100644 (file)
@@ -24,6 +24,7 @@ Features of the CNXK Ethdev PMD are:
 - Multiple queues for TX and RX
 - Receiver Side Scaling (RSS)
 - MAC filtering
+- Generic flow API
 - Inner and Outer Checksum offload
 - Port hardware statistics
 - Link state information
@@ -207,6 +208,12 @@ CRC stripping
 The OCTEON CN9K/CN10K SoC family NICs strip the CRC for every packet being received by
 the host interface irrespective of the offload configuration.
 
+RTE flow GRE support
+~~~~~~~~~~~~~~~~~~~~
+
+- ``RTE_FLOW_ITEM_TYPE_GRE_KEY`` works only when checksum and routing
+  bits in the GRE header are equal to 0.
+
 Debugging Options
 -----------------
 
index 192c15a..9d7af2d 100644 (file)
@@ -39,3 +39,37 @@ Module EEPROM dump   = Y
 Linux                = Y
 ARMv8                = Y
 Usage doc            = Y
+
+[rte_flow items]
+any                  = Y
+arp_eth_ipv4         = Y
+esp                  = Y
+eth                  = Y
+e_tag                = Y
+geneve               = Y
+gre                  = Y
+gre_key              = Y
+gtpc                 = Y
+gtpu                 = Y
+higig2               = Y
+icmp                 = Y
+ipv4                 = Y
+ipv6                 = Y
+ipv6_ext             = Y
+mpls                 = Y
+nvgre                = Y
+sctp                 = Y
+tcp                  = Y
+udp                  = Y
+vlan                 = Y
+vxlan                = Y
+vxlan_gpe            = Y
+
+[rte_flow actions]
+count                = Y
+drop                 = Y
+flag                 = Y
+pf                   = Y
+queue                = Y
+security             = Y
+vf                   = Y
index e990480..75c15d1 100644 (file)
@@ -37,3 +37,37 @@ Module EEPROM dump   = Y
 Linux                = Y
 ARMv8                = Y
 Usage doc            = Y
+
+[rte_flow items]
+any                  = Y
+arp_eth_ipv4         = Y
+esp                  = Y
+eth                  = Y
+e_tag                = Y
+geneve               = Y
+gre                  = Y
+gre_key              = Y
+gtpc                 = Y
+gtpu                 = Y
+higig2               = Y
+icmp                 = Y
+ipv4                 = Y
+ipv6                 = Y
+ipv6_ext             = Y
+mpls                 = Y
+nvgre                = Y
+sctp                 = Y
+tcp                  = Y
+udp                  = Y
+vlan                 = Y
+vxlan                = Y
+vxlan_gpe            = Y
+
+[rte_flow actions]
+count                = Y
+drop                 = Y
+flag                 = Y
+pf                   = Y
+queue                = Y
+security             = Y
+vf                   = Y
index 3a4417c..7870930 100644 (file)
@@ -34,3 +34,37 @@ Module EEPROM dump   = Y
 Linux                = Y
 ARMv8                = Y
 Usage doc            = Y
+
+[rte_flow items]
+any                  = Y
+arp_eth_ipv4         = Y
+esp                  = Y
+eth                  = Y
+e_tag                = Y
+geneve               = Y
+gre                  = Y
+gre_key              = Y
+gtpc                 = Y
+gtpu                 = Y
+higig2               = Y
+icmp                 = Y
+ipv4                 = Y
+ipv6                 = Y
+ipv6_ext             = Y
+mpls                 = Y
+nvgre                = Y
+sctp                 = Y
+tcp                  = Y
+udp                  = Y
+vlan                 = Y
+vxlan                = Y
+vxlan_gpe            = Y
+
+[rte_flow actions]
+count                = Y
+drop                 = Y
+flag                 = Y
+pf                   = Y
+queue                = Y
+security             = Y
+vf                   = Y
index 5ff36bb..0396ff6 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright(C) 2021 Marvell.
  */
 #include "cn10k_ethdev.h"
+#include "cn10k_rte_flow.h"
 #include "cn10k_rx.h"
 #include "cn10k_tx.h"
 
@@ -308,6 +309,20 @@ nix_eth_dev_ops_override(void)
        cnxk_eth_dev_ops.dev_ptypes_set = cn10k_nix_ptypes_set;
 }
 
+static void
+npc_flow_ops_override(void)
+{
+       static int init_once;
+
+       if (init_once)
+               return;
+       init_once = 1;
+
+       /* Update platform specific ops */
+       cnxk_flow_ops.create = cn10k_flow_create;
+       cnxk_flow_ops.destroy = cn10k_flow_destroy;
+}
+
 static int
 cn10k_nix_remove(struct rte_pci_device *pci_dev)
 {
@@ -332,6 +347,7 @@ cn10k_nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
        }
 
        nix_eth_dev_ops_override();
+       npc_flow_ops_override();
 
        /* Common probe */
        rc = cnxk_nix_probe(pci_drv, pci_dev);
diff --git a/drivers/net/cnxk/cn10k_rte_flow.c b/drivers/net/cnxk/cn10k_rte_flow.c
new file mode 100644 (file)
index 0000000..65893cc
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+#include <cnxk_rte_flow.h>
+#include "cn10k_rte_flow.h"
+#include "cn10k_ethdev.h"
+
+struct rte_flow *
+cn10k_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
+                 const struct rte_flow_item pattern[],
+                 const struct rte_flow_action actions[],
+                 struct rte_flow_error *error)
+{
+       struct roc_npc_flow *flow;
+
+       flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error);
+       if (!flow)
+               return NULL;
+
+       return (struct rte_flow *)flow;
+}
+
+int
+cn10k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow,
+                  struct rte_flow_error *error)
+{
+       struct roc_npc_flow *flow = (struct roc_npc_flow *)rte_flow;
+
+       return cnxk_flow_destroy(eth_dev, flow, error);
+}
diff --git a/drivers/net/cnxk/cn10k_rte_flow.h b/drivers/net/cnxk/cn10k_rte_flow.h
new file mode 100644 (file)
index 0000000..f64fcf2
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+#ifndef __CN10K_RTE_FLOW_H__
+#define __CN10K_RTE_FLOW_H__
+
+#include <rte_flow_driver.h>
+
+struct rte_flow *cn10k_flow_create(struct rte_eth_dev *dev,
+                                  const struct rte_flow_attr *attr,
+                                  const struct rte_flow_item pattern[],
+                                  const struct rte_flow_action actions[],
+                                  struct rte_flow_error *error);
+int cn10k_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
+                      struct rte_flow_error *error);
+
+#endif /* __CN10K_RTE_FLOW_H__ */
index 2157dca..cf9f7c7 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright(C) 2021 Marvell.
  */
 #include "cn9k_ethdev.h"
+#include "cn9k_rte_flow.h"
 #include "cn9k_rx.h"
 #include "cn9k_tx.h"
 
@@ -317,6 +318,20 @@ nix_eth_dev_ops_override(void)
        cnxk_eth_dev_ops.dev_ptypes_set = cn9k_nix_ptypes_set;
 }
 
+static void
+npc_flow_ops_override(void)
+{
+       static int init_once;
+
+       if (init_once)
+               return;
+       init_once = 1;
+
+       /* Update platform specific ops */
+       cnxk_flow_ops.create = cn9k_flow_create;
+       cnxk_flow_ops.destroy = cn9k_flow_destroy;
+}
+
 static int
 cn9k_nix_remove(struct rte_pci_device *pci_dev)
 {
@@ -342,6 +357,7 @@ cn9k_nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
        }
 
        nix_eth_dev_ops_override();
+       npc_flow_ops_override();
 
        /* Common probe */
        rc = cnxk_nix_probe(pci_drv, pci_dev);
diff --git a/drivers/net/cnxk/cn9k_rte_flow.c b/drivers/net/cnxk/cn9k_rte_flow.c
new file mode 100644 (file)
index 0000000..24e1b92
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+#include <cnxk_rte_flow.h>
+#include "cn9k_ethdev.h"
+#include "cn9k_rte_flow.h"
+
+struct rte_flow *
+cn9k_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
+                const struct rte_flow_item pattern[],
+                const struct rte_flow_action actions[],
+                struct rte_flow_error *error)
+{
+       struct roc_npc_flow *flow;
+
+       flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error);
+       if (!flow)
+               return NULL;
+
+       return (struct rte_flow *)flow;
+}
+
+int
+cn9k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow,
+                 struct rte_flow_error *error)
+{
+       struct roc_npc_flow *flow = (struct roc_npc_flow *)rte_flow;
+
+       return cnxk_flow_destroy(eth_dev, flow, error);
+}
diff --git a/drivers/net/cnxk/cn9k_rte_flow.h b/drivers/net/cnxk/cn9k_rte_flow.h
new file mode 100644 (file)
index 0000000..43d59e1
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+#ifndef __CN9K_RTE_FLOW_H__
+#define __CN9K_RTE_FLOW_H__
+
+#include <rte_flow_driver.h>
+
+struct rte_flow *cn9k_flow_create(struct rte_eth_dev *dev,
+                                 const struct rte_flow_attr *attr,
+                                 const struct rte_flow_item pattern[],
+                                 const struct rte_flow_action actions[],
+                                 struct rte_flow_error *error);
+int cn9k_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
+                     struct rte_flow_error *error);
+
+#endif /* __CN9K_RTE_FLOW_H__ */
index 4879ef9..b7869b4 100644 (file)
@@ -233,6 +233,9 @@ cnxk_eth_txq_to_sp(void *__txq)
 /* Common ethdev ops */
 extern struct eth_dev_ops cnxk_eth_dev_ops;
 
+/* Common flow ops */
+extern struct rte_flow_ops cnxk_flow_ops;
+
 /* Ops */
 int cnxk_nix_probe(struct rte_pci_driver *pci_drv,
                   struct rte_pci_device *pci_dev);
diff --git a/drivers/net/cnxk/cnxk_rte_flow.c b/drivers/net/cnxk/cnxk_rte_flow.c
new file mode 100644 (file)
index 0000000..1695d4f
--- /dev/null
@@ -0,0 +1,330 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+#include <cnxk_rte_flow.h>
+
+const struct cnxk_rte_flow_term_info term[] = {
+       [RTE_FLOW_ITEM_TYPE_ETH] = {ROC_NPC_ITEM_TYPE_ETH,
+                                   sizeof(struct rte_flow_item_eth)},
+       [RTE_FLOW_ITEM_TYPE_VLAN] = {ROC_NPC_ITEM_TYPE_VLAN,
+                                    sizeof(struct rte_flow_item_vlan)},
+       [RTE_FLOW_ITEM_TYPE_E_TAG] = {ROC_NPC_ITEM_TYPE_E_TAG,
+                                     sizeof(struct rte_flow_item_e_tag)},
+       [RTE_FLOW_ITEM_TYPE_IPV4] = {ROC_NPC_ITEM_TYPE_IPV4,
+                                    sizeof(struct rte_flow_item_ipv4)},
+       [RTE_FLOW_ITEM_TYPE_IPV6] = {ROC_NPC_ITEM_TYPE_IPV6,
+                                    sizeof(struct rte_flow_item_ipv6)},
+       [RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4] = {
+               ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4,
+               sizeof(struct rte_flow_item_arp_eth_ipv4)},
+       [RTE_FLOW_ITEM_TYPE_MPLS] = {ROC_NPC_ITEM_TYPE_MPLS,
+                                    sizeof(struct rte_flow_item_mpls)},
+       [RTE_FLOW_ITEM_TYPE_ICMP] = {ROC_NPC_ITEM_TYPE_ICMP,
+                                    sizeof(struct rte_flow_item_icmp)},
+       [RTE_FLOW_ITEM_TYPE_UDP] = {ROC_NPC_ITEM_TYPE_UDP,
+                                   sizeof(struct rte_flow_item_udp)},
+       [RTE_FLOW_ITEM_TYPE_TCP] = {ROC_NPC_ITEM_TYPE_TCP,
+                                   sizeof(struct rte_flow_item_tcp)},
+       [RTE_FLOW_ITEM_TYPE_SCTP] = {ROC_NPC_ITEM_TYPE_SCTP,
+                                    sizeof(struct rte_flow_item_sctp)},
+       [RTE_FLOW_ITEM_TYPE_ESP] = {ROC_NPC_ITEM_TYPE_ESP,
+                                   sizeof(struct rte_flow_item_esp)},
+       [RTE_FLOW_ITEM_TYPE_GRE] = {ROC_NPC_ITEM_TYPE_GRE,
+                                   sizeof(struct rte_flow_item_gre)},
+       [RTE_FLOW_ITEM_TYPE_NVGRE] = {ROC_NPC_ITEM_TYPE_NVGRE,
+                                     sizeof(struct rte_flow_item_nvgre)},
+       [RTE_FLOW_ITEM_TYPE_VXLAN] = {ROC_NPC_ITEM_TYPE_VXLAN,
+                                     sizeof(struct rte_flow_item_vxlan)},
+       [RTE_FLOW_ITEM_TYPE_GTPC] = {ROC_NPC_ITEM_TYPE_GTPC,
+                                    sizeof(struct rte_flow_item_gtp)},
+       [RTE_FLOW_ITEM_TYPE_GTPU] = {ROC_NPC_ITEM_TYPE_GTPU,
+                                    sizeof(struct rte_flow_item_gtp)},
+       [RTE_FLOW_ITEM_TYPE_GENEVE] = {ROC_NPC_ITEM_TYPE_GENEVE,
+                                      sizeof(struct rte_flow_item_geneve)},
+       [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = {
+                       ROC_NPC_ITEM_TYPE_VXLAN_GPE,
+                       sizeof(struct rte_flow_item_vxlan_gpe)},
+       [RTE_FLOW_ITEM_TYPE_IPV6_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_EXT,
+                                        sizeof(struct rte_flow_item_ipv6_ext)},
+       [RTE_FLOW_ITEM_TYPE_VOID] = {ROC_NPC_ITEM_TYPE_VOID, 0},
+       [RTE_FLOW_ITEM_TYPE_ANY] = {ROC_NPC_ITEM_TYPE_ANY, 0},
+       [RTE_FLOW_ITEM_TYPE_GRE_KEY] = {ROC_NPC_ITEM_TYPE_GRE_KEY,
+                                       sizeof(uint32_t)},
+       [RTE_FLOW_ITEM_TYPE_HIGIG2] = {
+               ROC_NPC_ITEM_TYPE_HIGIG2,
+               sizeof(struct rte_flow_item_higig2_hdr)}
+};
+
+static int
+cnxk_map_actions(struct rte_eth_dev *eth_dev,
+                const struct rte_flow_action actions[],
+                struct roc_npc_action in_actions[])
+{
+       const struct rte_flow_action_count *act_count;
+       const struct rte_flow_action_queue *act_q;
+       int rq;
+       int i = 0;
+
+       for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
+               switch (actions->type) {
+               case RTE_FLOW_ACTION_TYPE_VOID:
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_MARK:
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK;
+                       in_actions[i].conf = actions->conf;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_FLAG:
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_COUNT:
+                       act_count = (const struct rte_flow_action_count *)
+                                           actions->conf;
+
+                       if (act_count->shared == 1) {
+                               plt_npc_dbg("Shared counter is not supported");
+                               goto err_exit;
+                       }
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_DROP:
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_PF:
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_PF;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_VF:
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_VF;
+                       in_actions[i].conf = actions->conf;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_QUEUE:
+                       act_q = (const struct rte_flow_action_queue *)
+                                       actions->conf;
+                       rq = act_q->index;
+                       if (rq >= eth_dev->data->nb_rx_queues) {
+                               plt_npc_dbg("Invalid queue index");
+                               goto err_exit;
+                       }
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
+                       in_actions[i].conf = actions->conf;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_RSS:
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_SECURITY:
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC;
+                       break;
+               default:
+                       plt_npc_dbg("Action is not supported = %d",
+                                   actions->type);
+                       goto err_exit;
+               }
+               i++;
+       }
+       in_actions[i].type = ROC_NPC_ACTION_TYPE_END;
+       return 0;
+
+err_exit:
+       return -EINVAL;
+}
+
+static int
+cnxk_map_flow_data(struct rte_eth_dev *eth_dev,
+                  const struct rte_flow_attr *attr,
+                  const struct rte_flow_item pattern[],
+                  const struct rte_flow_action actions[],
+                  struct roc_npc_attr *in_attr,
+                  struct roc_npc_item_info in_pattern[],
+                  struct roc_npc_action in_actions[])
+{
+       int i = 0;
+
+       in_attr->priority = attr->priority;
+       in_attr->ingress = attr->ingress;
+       in_attr->egress = attr->egress;
+
+       while (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
+               in_pattern[i].spec = pattern->spec;
+               in_pattern[i].last = pattern->last;
+               in_pattern[i].mask = pattern->mask;
+               in_pattern[i].type = term[pattern->type].item_type;
+               in_pattern[i].size = term[pattern->type].item_size;
+               pattern++;
+               i++;
+       }
+       in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
+
+       return cnxk_map_actions(eth_dev, actions, in_actions);
+}
+
+static int
+cnxk_flow_validate(struct rte_eth_dev *eth_dev,
+                  const struct rte_flow_attr *attr,
+                  const struct rte_flow_item pattern[],
+                  const struct rte_flow_action actions[],
+                  struct rte_flow_error *error)
+{
+       struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
+       struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_npc *npc = &dev->npc;
+       struct roc_npc_attr in_attr;
+       struct roc_npc_flow flow;
+       int rc;
+
+       memset(&flow, 0, sizeof(flow));
+
+       rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
+                               in_pattern, in_actions);
+       if (rc) {
+               rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
+                                  NULL, "Failed to map flow data");
+               return rc;
+       }
+
+       return roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &flow);
+}
+
+struct roc_npc_flow *
+cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
+                const struct rte_flow_item pattern[],
+                const struct rte_flow_action actions[],
+                struct rte_flow_error *error)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
+       struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
+       struct roc_npc *npc = &dev->npc;
+       struct roc_npc_attr in_attr;
+       struct roc_npc_flow *flow;
+       int errcode;
+       int rc;
+
+       rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
+                               in_pattern, in_actions);
+       if (rc) {
+               rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
+                                  NULL, "Failed to map flow data");
+               return NULL;
+       }
+
+       flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions,
+                                  &errcode);
+       if (errcode != 0) {
+               rte_flow_error_set(error, errcode, errcode, NULL,
+                                  roc_error_msg_get(errcode));
+               return NULL;
+       }
+
+       return flow;
+}
+
+int
+cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
+                 struct rte_flow_error *error)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_npc *npc = &dev->npc;
+       int rc;
+
+       rc = roc_npc_flow_destroy(npc, flow);
+       if (rc)
+               rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                  NULL, "Flow Destroy failed");
+       return rc;
+}
+
+static int
+cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_npc *npc = &dev->npc;
+       int rc;
+
+       rc = roc_npc_mcam_free_all_resources(npc);
+       if (rc) {
+               rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                  NULL, "Failed to flush filter");
+               return -rte_errno;
+       }
+
+       return 0;
+}
+
+static int
+cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
+               const struct rte_flow_action *action, void *data,
+               struct rte_flow_error *error)
+{
+       struct roc_npc_flow *in_flow = (struct roc_npc_flow *)flow;
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_npc *npc = &dev->npc;
+       struct rte_flow_query_count *query = data;
+       const char *errmsg = NULL;
+       int errcode = ENOTSUP;
+       int rc;
+
+       if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
+               errmsg = "Only COUNT is supported in query";
+               goto err_exit;
+       }
+
+       if (in_flow->ctr_id == NPC_COUNTER_NONE) {
+               errmsg = "Counter is not available";
+               goto err_exit;
+       }
+
+       rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
+       if (rc != 0) {
+               errcode = EIO;
+               errmsg = "Error reading flow counter";
+               goto err_exit;
+       }
+       query->hits_set = 1;
+       query->bytes_set = 0;
+
+       if (query->reset)
+               rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id);
+       if (rc != 0) {
+               errcode = EIO;
+               errmsg = "Error clearing flow counter";
+               goto err_exit;
+       }
+
+       return 0;
+
+err_exit:
+       rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                          NULL, errmsg);
+       return -rte_errno;
+}
+
+static int
+cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused,
+                 int enable __rte_unused, struct rte_flow_error *error)
+{
+       /* If we support, we need to un-install the default mcam
+        * entry for this port.
+        */
+
+       rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                          NULL, "Flow isolation not supported");
+
+       return -rte_errno;
+}
+
+struct rte_flow_ops cnxk_flow_ops = {
+       .validate = cnxk_flow_validate,
+       .flush = cnxk_flow_flush,
+       .query = cnxk_flow_query,
+       .isolate = cnxk_flow_isolate,
+};
diff --git a/drivers/net/cnxk/cnxk_rte_flow.h b/drivers/net/cnxk/cnxk_rte_flow.h
new file mode 100644 (file)
index 0000000..bb23629
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+#ifndef __CNXK_RTE_FLOW_H__
+#define __CNXK_RTE_FLOW_H__
+
+#include <rte_flow_driver.h>
+#include <rte_malloc.h>
+
+#include "cnxk_ethdev.h"
+#include "roc_api.h"
+#include "roc_npc_priv.h"
+
+struct cnxk_rte_flow_term_info {
+       uint16_t item_type;
+       uint16_t item_size;
+};
+
+struct roc_npc_flow *cnxk_flow_create(struct rte_eth_dev *dev,
+                                     const struct rte_flow_attr *attr,
+                                     const struct rte_flow_item pattern[],
+                                     const struct rte_flow_action actions[],
+                                     struct rte_flow_error *error);
+int cnxk_flow_destroy(struct rte_eth_dev *dev, struct roc_npc_flow *flow,
+                     struct rte_flow_error *error);
+
+#endif /* __CNXK_RTE_FLOW_H__ */
index 47c1ce1..1c7985d 100644 (file)
@@ -14,12 +14,14 @@ sources = files(
         'cnxk_ethdev_ops.c',
         'cnxk_link.c',
         'cnxk_lookup.c',
+        'cnxk_rte_flow.c',
         'cnxk_stats.c',
 )
 
 # CN9K
 sources += files(
         'cn9k_ethdev.c',
+        'cn9k_rte_flow.c',
         'cn9k_rx.c',
         'cn9k_rx_mseg.c',
         'cn9k_rx_vec.c',
@@ -30,6 +32,7 @@ sources += files(
 # CN10K
 sources += files(
         'cn10k_ethdev.c',
+        'cn10k_rte_flow.c',
         'cn10k_rx.c',
         'cn10k_rx_mseg.c',
         'cn10k_rx_vec.c',