DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 00/11] Add basic flow support for corenic firmware
@ 2023-11-03  6:25 Chaoyong He
  2023-11-03  6:25 ` [PATCH 01/11] net/nfp: move some source files Chaoyong He
                   ` (13 more replies)
  0 siblings, 14 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:25 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He

Add the very basic rte_flow support for corenic firmware.

Chaoyong He (11):
  net/nfp: move some source files
  drivers: add the structures and functions for flow offload
  net/nfp: add the control message channel
  net/nfp: support flow API for CoreNIC firmware
  net/nfp: support Ethernet flow item
  net/nfp: support drop flow action
  net/nfp: support IPv4 flow item
  net/nfp: support IPv6 flow item
  net/nfp: support TCP/UDP/SCTP flow items
  drivers: support MARK flow action
  net/nfp: support QUEUE flow action

 drivers/common/nfp/nfp_common_ctrl.h          |    2 +
 drivers/net/nfp/flower/nfp_conntrack.h        |    2 +-
 drivers/net/nfp/flower/nfp_flower_cmsg.h      |    2 +-
 .../{nfp_flow.c => flower/nfp_flower_flow.c}  |    4 +-
 .../{nfp_flow.h => flower/nfp_flower_flow.h}  |   10 +-
 .../net/nfp/flower/nfp_flower_representor.c   |    2 +-
 drivers/net/nfp/meson.build                   |    4 +-
 drivers/net/nfp/nfp_ethdev.c                  |   27 +-
 drivers/net/nfp/nfp_net_cmsg.c                |   66 ++
 drivers/net/nfp/nfp_net_cmsg.h                |  176 +++
 drivers/net/nfp/nfp_net_common.h              |   12 +
 drivers/net/nfp/nfp_net_ctrl.h                |    1 +
 drivers/net/nfp/nfp_net_flow.c                | 1003 +++++++++++++++++
 drivers/net/nfp/nfp_net_flow.h                |   30 +
 drivers/net/nfp/nfp_rxtx.c                    |   18 +
 15 files changed, 1341 insertions(+), 18 deletions(-)
 rename drivers/net/nfp/{nfp_flow.c => flower/nfp_flower_flow.c} (99%)
 rename drivers/net/nfp/{nfp_flow.h => flower/nfp_flower_flow.h} (96%)
 create mode 100644 drivers/net/nfp/nfp_net_cmsg.c
 create mode 100644 drivers/net/nfp/nfp_net_cmsg.h
 create mode 100644 drivers/net/nfp/nfp_net_flow.c
 create mode 100644 drivers/net/nfp/nfp_net_flow.h

-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 01/11] net/nfp: move some source files
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
@ 2023-11-03  6:25 ` Chaoyong He
  2023-11-03  6:25 ` [PATCH 02/11] drivers: add the structures and functions for flow offload Chaoyong He
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:25 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Rename module 'nfp_flow' into 'nfp_flower_flow' and move the source
files into the 'flower' sub-directory.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/flower/nfp_conntrack.h                 |  2 +-
 drivers/net/nfp/flower/nfp_flower_cmsg.h               |  2 +-
 .../net/nfp/{nfp_flow.c => flower/nfp_flower_flow.c}   |  4 ++--
 .../net/nfp/{nfp_flow.h => flower/nfp_flower_flow.h}   | 10 +++++-----
 drivers/net/nfp/flower/nfp_flower_representor.c        |  2 +-
 drivers/net/nfp/meson.build                            |  2 +-
 6 files changed, 11 insertions(+), 11 deletions(-)
 rename drivers/net/nfp/{nfp_flow.c => flower/nfp_flower_flow.c} (99%)
 rename drivers/net/nfp/{nfp_flow.h => flower/nfp_flower_flow.h} (96%)

diff --git a/drivers/net/nfp/flower/nfp_conntrack.h b/drivers/net/nfp/flower/nfp_conntrack.h
index 5abab4e984..9bfca236ed 100644
--- a/drivers/net/nfp/flower/nfp_conntrack.h
+++ b/drivers/net/nfp/flower/nfp_conntrack.h
@@ -11,7 +11,7 @@
 #include <ethdev_driver.h>
 #include <rte_flow.h>
 
-#include "../nfp_flow.h"
+#include "nfp_flower_flow.h"
 
 struct nfp_ct_map_entry;
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index c2938fb6f6..45543816ae 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -6,8 +6,8 @@
 #ifndef __NFP_CMSG_H__
 #define __NFP_CMSG_H__
 
-#include "../nfp_flow.h"
 #include "nfp_flower.h"
+#include "nfp_flower_flow.h"
 
 struct nfp_flower_cmsg_hdr {
 	rte_be16_t pad;
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/flower/nfp_flower_flow.c
similarity index 99%
rename from drivers/net/nfp/nfp_flow.c
rename to drivers/net/nfp/flower/nfp_flower_flow.c
index f832b52d89..e26be30d18 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/flower/nfp_flower_flow.c
@@ -3,7 +3,7 @@
  * All rights reserved.
  */
 
-#include "nfp_flow.h"
+#include "nfp_flower_flow.h"
 
 #include <rte_flow_driver.h>
 #include <rte_hash.h>
@@ -4318,7 +4318,7 @@ static const struct rte_flow_ops nfp_flow_ops = {
 };
 
 int
-nfp_net_flow_ops_get(struct rte_eth_dev *dev,
+nfp_flow_ops_get(struct rte_eth_dev *dev,
 		const struct rte_flow_ops **ops)
 {
 	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0) {
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/flower/nfp_flower_flow.h
similarity index 96%
rename from drivers/net/nfp/nfp_flow.h
rename to drivers/net/nfp/flower/nfp_flower_flow.h
index 09e5b30dd8..75f18c6bd5 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/flower/nfp_flower_flow.h
@@ -3,10 +3,10 @@
  * All rights reserved.
  */
 
-#ifndef __NFP_FLOW_H__
-#define __NFP_FLOW_H__
+#ifndef __NFP_FLOWER_FLOW_H__
+#define __NFP_FLOWER_FLOW_H__
 
-#include "nfp_net_common.h"
+#include "../nfp_net_common.h"
 
 /* The firmware expects lengths in units of long words */
 #define NFP_FL_LW_SIZ                   2
@@ -182,7 +182,7 @@ struct nfp_flower_representor;
 
 int nfp_flow_priv_init(struct nfp_pf_dev *pf_dev);
 void nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev);
-int nfp_net_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops);
+int nfp_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops);
 bool nfp_flow_inner_item_get(const struct rte_flow_item items[],
 		const struct rte_flow_item **inner_item);
 struct rte_flow *nfp_flow_process(struct nfp_flower_representor *representor,
@@ -202,4 +202,4 @@ int nfp_flow_destroy(struct rte_eth_dev *dev,
 		struct rte_flow *nfp_flow,
 		struct rte_flow_error *error);
 
-#endif /* __NFP_FLOW_H__ */
+#endif /* __NFP_FLOWER_FLOW_H__ */
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index 0f0e63aae0..c23a82c356 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -334,7 +334,7 @@ static const struct eth_dev_ops nfp_flower_repr_dev_ops = {
 	.mac_addr_set         = nfp_flower_repr_mac_addr_set,
 	.fw_version_get       = nfp_net_firmware_version_get,
 
-	.flow_ops_get         = nfp_net_flow_ops_get,
+	.flow_ops_get         = nfp_flow_ops_get,
 	.mtr_ops_get          = nfp_net_mtr_ops_get,
 };
 
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index cf9c16266d..8407073af8 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -11,6 +11,7 @@ sources = files(
         'flower/nfp_flower.c',
         'flower/nfp_flower_cmsg.c',
         'flower/nfp_flower_ctrl.c',
+        'flower/nfp_flower_flow.c',
         'flower/nfp_flower_representor.c',
         'nfd3/nfp_nfd3_dp.c',
         'nfdk/nfp_nfdk_dp.c',
@@ -30,7 +31,6 @@ sources = files(
         'nfp_cpp_bridge.c',
         'nfp_ethdev.c',
         'nfp_ethdev_vf.c',
-        'nfp_flow.c',
         'nfp_ipsec.c',
         'nfp_logs.c',
         'nfp_mtr.c',
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 02/11] drivers: add the structures and functions for flow offload
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
  2023-11-03  6:25 ` [PATCH 01/11] net/nfp: move some source files Chaoyong He
@ 2023-11-03  6:25 ` Chaoyong He
  2023-11-03  6:25 ` [PATCH 03/11] net/nfp: add the control message channel Chaoyong He
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:25 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the structures and functions to process flow table, which is used in
the rte_flow offload logics.
This module is used for the CoreNIC firmware.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/common/nfp/nfp_common_ctrl.h |   1 +
 drivers/net/nfp/meson.build          |   1 +
 drivers/net/nfp/nfp_ethdev.c         |  26 +++--
 drivers/net/nfp/nfp_net_common.h     |  11 ++
 drivers/net/nfp/nfp_net_flow.c       | 162 +++++++++++++++++++++++++++
 drivers/net/nfp/nfp_net_flow.h       |  28 +++++
 6 files changed, 222 insertions(+), 7 deletions(-)
 create mode 100644 drivers/net/nfp/nfp_net_flow.c
 create mode 100644 drivers/net/nfp/nfp_net_flow.h

diff --git a/drivers/common/nfp/nfp_common_ctrl.h b/drivers/common/nfp/nfp_common_ctrl.h
index d09fd2b892..cbde987736 100644
--- a/drivers/common/nfp/nfp_common_ctrl.h
+++ b/drivers/common/nfp/nfp_common_ctrl.h
@@ -223,6 +223,7 @@ struct nfp_net_fw_ver {
 #define NFP_NET_CFG_CTRL_IPSEC_SM_LOOKUP  (0x1 << 3) /**< SA short match lookup */
 #define NFP_NET_CFG_CTRL_IPSEC_LM_LOOKUP  (0x1 << 4) /**< SA long match lookup */
 #define NFP_NET_CFG_CTRL_MULTI_PF         (0x1 << 5)
+#define NFP_NET_CFG_CTRL_FLOW_STEER       (0x1 << 8) /**< Flow Steering */
 #define NFP_NET_CFG_CTRL_IN_ORDER         (0x1 << 11) /**< Virtio in-order flag */
 
 #define NFP_NET_CFG_CAP_WORD1           0x00a4
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 8407073af8..0d0a0bd8f4 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -36,6 +36,7 @@ sources = files(
         'nfp_mtr.c',
         'nfp_net_common.c',
         'nfp_net_ctrl.c',
+        'nfp_net_flow.c',
         'nfp_rxtx.c',
 )
 
diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index f02caf8056..af5e5d333a 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -23,6 +23,7 @@
 #include "nfp_cpp_bridge.h"
 #include "nfp_ipsec.h"
 #include "nfp_logs.h"
+#include "nfp_net_flow.h"
 
 #define NFP_PF_DRIVER_NAME net_nfp_pf
 
@@ -150,6 +151,10 @@ nfp_net_start(struct rte_eth_dev *dev)
 		ctrl_extend |= NFP_NET_CFG_CTRL_IPSEC_SM_LOOKUP
 				| NFP_NET_CFG_CTRL_IPSEC_LM_LOOKUP;
 
+	/* Enable flow steer by extend ctrl word1. */
+	if ((cap_extend & NFP_NET_CFG_CTRL_FLOW_STEER) != 0)
+		ctrl_extend |= NFP_NET_CFG_CTRL_FLOW_STEER;
+
 	update = NFP_NET_CFG_UPDATE_GEN;
 	if (nfp_ext_reconfig(hw, ctrl_extend, update) != 0)
 		return -EIO;
@@ -692,6 +697,14 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
 	/* Recording current stats counters values */
 	nfp_net_stats_reset(eth_dev);
 
+	if ((hw->cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER) != 0) {
+		err = nfp_net_flow_priv_init(pf_dev, port);
+		if (err != 0) {
+			PMD_INIT_LOG(ERR, "Init net flow priv failed");
+			return err;
+		}
+	}
+
 	return 0;
 }
 
@@ -1115,14 +1128,13 @@ nfp_init_app_fw_nic(struct nfp_pf_dev *pf_dev,
 port_cleanup:
 	for (i = 0; i < app_fw_nic->total_phyports; i++) {
 		id = nfp_function_id_get(pf_dev, i);
+		hw = app_fw_nic->ports[id];
 
-		if (app_fw_nic->ports[id] != NULL &&
-				app_fw_nic->ports[id]->eth_dev != NULL) {
-			struct rte_eth_dev *tmp_dev;
-			tmp_dev = app_fw_nic->ports[id]->eth_dev;
-			nfp_ipsec_uninit(tmp_dev);
-			rte_eth_dev_release_port(tmp_dev);
-			app_fw_nic->ports[id] = NULL;
+		if (hw != NULL && hw->eth_dev != NULL) {
+			nfp_ipsec_uninit(hw->eth_dev);
+			if ((hw->super.cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER) != 0)
+				nfp_net_flow_priv_uninit(pf_dev, id);
+			rte_eth_dev_release_port(hw->eth_dev);
 		}
 	}
 	nfp_cpp_area_free(pf_dev->ctrl_area);
diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h
index 30fea7ae02..48791af93a 100644
--- a/drivers/net/nfp/nfp_net_common.h
+++ b/drivers/net/nfp/nfp_net_common.h
@@ -108,6 +108,14 @@ struct nfp_pf_dev {
 	struct nfp_multi_pf multi_pf;
 };
 
+#define NFP_NET_FLOW_LIMIT    1024
+
+struct nfp_net_priv {
+	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
+	struct rte_hash *flow_table; /**< Hash table to store flow rules. */
+	uint16_t flow_count; /**< Flow count in hash table */
+};
+
 struct nfp_app_fw_nic {
 	/** Backpointer to the PF device */
 	struct nfp_pf_dev *pf_dev;
@@ -177,6 +185,9 @@ struct nfp_net_hw {
 	struct nfp_net_tlv_caps tlv_caps;
 
 	struct nfp_net_ipsec_data *ipsec_data;
+
+	/** Used for rte_flow of CoreNIC firmware */
+	struct nfp_net_priv *priv;
 };
 
 static inline uint32_t
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
new file mode 100644
index 0000000000..6c02b0f82e
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include "nfp_net_flow.h"
+
+#include <rte_flow_driver.h>
+#include <rte_hash.h>
+#include <rte_jhash.h>
+#include <rte_malloc.h>
+
+#include "nfp_logs.h"
+
+__rte_unused static int
+nfp_net_flow_table_add(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+
+	ret = rte_hash_add_key_data(priv->flow_table, &nfp_flow->hash_key, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Add to flow table failed.");
+		return ret;
+	}
+
+	return 0;
+}
+
+__rte_unused static int
+nfp_net_flow_table_delete(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+
+	ret = rte_hash_del_key(priv->flow_table, &nfp_flow->hash_key);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Delete from flow table failed.");
+		return ret;
+	}
+
+	return 0;
+}
+
+__rte_unused static struct rte_flow *
+nfp_net_flow_table_search(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int index;
+	struct rte_flow *flow_find;
+
+	index = rte_hash_lookup_data(priv->flow_table, &nfp_flow->hash_key,
+			(void **)&flow_find);
+	if (index < 0) {
+		PMD_DRV_LOG(DEBUG, "Data NOT found in the flow table.");
+		return NULL;
+	}
+
+	return flow_find;
+}
+
+__rte_unused static struct rte_flow *
+nfp_net_flow_alloc(uint32_t match_len,
+		uint32_t action_len,
+		uint32_t port_id)
+{
+	char *data;
+	struct rte_flow *nfp_flow;
+	struct nfp_net_flow_payload *payload;
+
+	nfp_flow = rte_zmalloc("nfp_flow", sizeof(struct rte_flow), 0);
+	if (nfp_flow == NULL)
+		return NULL;
+
+	data = rte_zmalloc("nfp_flow_payload", match_len + action_len, 0);
+	if (data == NULL)
+		goto free_flow;
+
+	nfp_flow->port_id      = port_id;
+	payload                = &nfp_flow->payload;
+	payload->match_len     = match_len;
+	payload->action_len    = action_len;
+	payload->match_data    = data;
+	payload->action_data   = data + match_len;
+
+	return nfp_flow;
+
+free_flow:
+	rte_free(nfp_flow);
+
+	return NULL;
+}
+
+__rte_unused static void
+nfp_net_flow_free(struct rte_flow *nfp_flow)
+{
+	rte_free(nfp_flow->payload.match_data);
+	rte_free(nfp_flow);
+}
+
+int
+nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev,
+		uint16_t port)
+{
+	int ret = 0;
+	struct nfp_net_priv *priv;
+	char flow_name[RTE_HASH_NAMESIZE];
+	struct nfp_app_fw_nic *app_fw_nic;
+	const char *pci_name = strchr(pf_dev->pci_dev->name, ':') + 1;
+
+	snprintf(flow_name, sizeof(flow_name), "%s_fl_%u", pci_name, port);
+
+	struct rte_hash_parameters flow_hash_params = {
+		.name       = flow_name,
+		.entries    = NFP_NET_FLOW_LIMIT,
+		.hash_func  = rte_jhash,
+		.socket_id  = rte_socket_id(),
+		.key_len    = sizeof(uint32_t),
+		.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,
+	};
+
+	priv = rte_zmalloc("nfp_app_nic_priv", sizeof(struct nfp_net_priv), 0);
+	if (priv == NULL) {
+		PMD_INIT_LOG(ERR, "NFP app nic priv creation failed");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(pf_dev->app_fw_priv);
+	app_fw_nic->ports[port]->priv = priv;
+	priv->hash_seed = (uint32_t)rte_rand();
+
+	/* Flow table */
+	flow_hash_params.hash_func_init_val = priv->hash_seed;
+	priv->flow_table = rte_hash_create(&flow_hash_params);
+	if (priv->flow_table == NULL) {
+		PMD_INIT_LOG(ERR, "flow hash table creation failed");
+		ret = -ENOMEM;
+		goto free_priv;
+	}
+
+	return 0;
+
+free_priv:
+	rte_free(priv);
+exit:
+	return ret;
+}
+
+void
+nfp_net_flow_priv_uninit(struct nfp_pf_dev *pf_dev,
+		uint16_t port)
+{
+	struct nfp_net_priv *priv;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[port]->priv;
+
+	rte_hash_free(priv->flow_table);
+	rte_free(priv);
+}
diff --git a/drivers/net/nfp/nfp_net_flow.h b/drivers/net/nfp/nfp_net_flow.h
new file mode 100644
index 0000000000..5ec80ba3b6
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_flow.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef __NFP_NET_FLOW_H__
+#define __NFP_NET_FLOW_H__
+
+#include "nfp_net_common.h"
+
+struct nfp_net_flow_payload {
+	uint16_t cmsg_type;
+	uint8_t match_len;
+	uint8_t action_len;
+	char *match_data;
+	char *action_data;
+};
+
+struct rte_flow {
+	struct nfp_net_flow_payload payload;
+	uint32_t hash_key;
+	uint32_t port_id;
+};
+
+int nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev, uint16_t port);
+void nfp_net_flow_priv_uninit(struct nfp_pf_dev *pf_dev, uint16_t port);
+
+#endif /* __NFP_NET_FLOW_H__ */
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 03/11] net/nfp: add the control message channel
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
  2023-11-03  6:25 ` [PATCH 01/11] net/nfp: move some source files Chaoyong He
  2023-11-03  6:25 ` [PATCH 02/11] drivers: add the structures and functions for flow offload Chaoyong He
@ 2023-11-03  6:25 ` Chaoyong He
  2023-11-03  6:25 ` [PATCH 04/11] net/nfp: support flow API for CoreNIC firmware Chaoyong He
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:25 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Using the mailbox, which serves as the control message channel
between driver and CoreNIC firmware.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/meson.build    |  1 +
 drivers/net/nfp/nfp_net_cmsg.c | 66 ++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_net_cmsg.h | 37 +++++++++++++++++++
 drivers/net/nfp/nfp_net_ctrl.h |  1 +
 4 files changed, 105 insertions(+)
 create mode 100644 drivers/net/nfp/nfp_net_cmsg.c
 create mode 100644 drivers/net/nfp/nfp_net_cmsg.h

diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 0d0a0bd8f4..46be6f60cd 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -34,6 +34,7 @@ sources = files(
         'nfp_ipsec.c',
         'nfp_logs.c',
         'nfp_mtr.c',
+        'nfp_net_cmsg.c',
         'nfp_net_common.c',
         'nfp_net_ctrl.c',
         'nfp_net_flow.c',
diff --git a/drivers/net/nfp/nfp_net_cmsg.c b/drivers/net/nfp/nfp_net_cmsg.c
new file mode 100644
index 0000000000..f2f694be0b
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_cmsg.c
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include "nfp_net_cmsg.h"
+
+#include <rte_malloc.h>
+
+#include "nfp_logs.h"
+
+struct nfp_net_cmsg *
+nfp_net_cmsg_alloc(uint32_t msg_size)
+{
+	struct nfp_net_cmsg *cmsg;
+
+	cmsg = rte_zmalloc(NULL, msg_size, 0);
+	if (cmsg == NULL) {
+		PMD_DRV_LOG(ERR, "Failed malloc memory.");
+		return NULL;
+	}
+
+	return cmsg;
+}
+
+void
+nfp_net_cmsg_free(struct nfp_net_cmsg *cmsg)
+{
+	rte_free(cmsg);
+}
+
+int
+nfp_net_cmsg_xmit(struct nfp_net_hw *hw,
+		struct nfp_net_cmsg *cmsg,
+		uint32_t msg_size)
+{
+	int ret;
+	uint32_t i;
+
+	for (i = 0; i < msg_size; i++)
+		nn_cfg_writel(&hw->super, NFP_NET_CFG_MBOX_VAL + 4 * i, *((uint32_t *)cmsg + i));
+
+	ret = nfp_net_mbox_reconfig(hw, NFP_NET_CFG_MBOX_CMD_FLOW_STEER);
+	switch (ret) {
+	case NFP_NET_CFG_MBOX_RET_FS_OK:
+		break;
+	case NFP_NET_CFG_MBOX_RET_FS_ERR_NO_SPACE:
+		PMD_DRV_LOG(ERR, "Not enough space for cmd %u", cmsg->cmd);
+		ret = -ENOSPC;
+		break;
+	case NFP_NET_CFG_MBOX_RET_FS_ERR_MASK_FULL:
+		PMD_DRV_LOG(ERR, "The mask table is full for cmd %u", cmsg->cmd);
+		ret = -EXFULL;
+		break;
+	case NFP_NET_CFG_MBOX_RET_FS_ERR_CMD_INVALID:
+		PMD_DRV_LOG(ERR, "The mbox cmd %u invalid", cmsg->cmd);
+		ret = -EINVAL;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unrecognized mbox cmd %u", cmsg->cmd);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
new file mode 100644
index 0000000000..15e0bb60d8
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef __NFP_NET_CMSG_H__
+#define __NFP_NET_CMSG_H__
+
+#include "nfp_net_common.h"
+
+enum nfp_net_cfg_mbox_cmd {
+	NFP_NET_CFG_MBOX_CMD_FS_ADD_V4,       /* Add Flow Steer rule for V4 table */
+	NFP_NET_CFG_MBOX_CMD_FS_DEL_V4,       /* Delete Flow Steer rule for V4 table */
+	NFP_NET_CFG_MBOX_CMD_FS_ADD_V6,       /* Add Flow Steer rule for V4 table */
+	NFP_NET_CFG_MBOX_CMD_FS_DEL_V6,       /* Delete Flow Steer rule for V4 table */
+	NFP_NET_CFG_MBOX_CMD_FS_ADD_ETHTYPE,  /* Add Flow Steer rule for Ethtype table */
+	NFP_NET_CFG_MBOX_CMD_FS_DEL_ETHTYPE,  /* Delete Flow Steer rule for Ethtype table */
+};
+
+enum nfp_net_cfg_mbox_ret {
+	NFP_NET_CFG_MBOX_RET_FS_OK,               /* No error happen */
+	NFP_NET_CFG_MBOX_RET_FS_ERR_NO_SPACE,     /* Return error code no space */
+	NFP_NET_CFG_MBOX_RET_FS_ERR_MASK_FULL,    /* Return error code mask table full */
+	NFP_NET_CFG_MBOX_RET_FS_ERR_CMD_INVALID,  /* Return error code invalid cmd */
+};
+
+/* 4B cmd, and up to 500B data. */
+struct nfp_net_cmsg {
+	uint32_t cmd;     /**< One of nfp_net_cfg_mbox_cmd */
+	uint32_t data[0];
+};
+
+struct nfp_net_cmsg *nfp_net_cmsg_alloc(uint32_t msg_size);
+void nfp_net_cmsg_free(struct nfp_net_cmsg *cmsg);
+int nfp_net_cmsg_xmit(struct nfp_net_hw *hw, struct nfp_net_cmsg *cmsg, uint32_t msg_size);
+
+#endif /* __NFP_NET_CMSG_H__ */
diff --git a/drivers/net/nfp/nfp_net_ctrl.h b/drivers/net/nfp/nfp_net_ctrl.h
index ee1b784bb1..7ac0f89571 100644
--- a/drivers/net/nfp/nfp_net_ctrl.h
+++ b/drivers/net/nfp/nfp_net_ctrl.h
@@ -92,6 +92,7 @@
 #define NFP_NET_CFG_MBOX_SIMPLE_VAL           0x8
 
 #define NFP_NET_CFG_MBOX_CMD_IPSEC            3
+#define NFP_NET_CFG_MBOX_CMD_FLOW_STEER       10
 
 /*
  * TLV capabilities
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 04/11] net/nfp: support flow API for CoreNIC firmware
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (2 preceding siblings ...)
  2023-11-03  6:25 ` [PATCH 03/11] net/nfp: add the control message channel Chaoyong He
@ 2023-11-03  6:25 ` Chaoyong He
  2023-11-03  6:26 ` [PATCH 05/11] net/nfp: support Ethernet flow item Chaoyong He
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:25 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the flow validate/create/destroy/flush API of nfp PMD with CoreNIC
firmware.

The flow create API construct a control cmsg and send it to
firmware, then add this flow to the hash table.

The flow destroy API construct a control cmsg and send it to
firmware, then delete this flow from the hash table.

The flow flush API just iterate the flows in hash table and
call the flow destroy API.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_ethdev.c     |   1 +
 drivers/net/nfp/nfp_net_cmsg.h   |  28 +++
 drivers/net/nfp/nfp_net_common.h |   1 +
 drivers/net/nfp/nfp_net_flow.c   | 409 ++++++++++++++++++++++++++++++-
 drivers/net/nfp/nfp_net_flow.h   |   2 +
 5 files changed, 434 insertions(+), 7 deletions(-)

diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index af5e5d333a..37dae8a82a 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -530,6 +530,7 @@ static const struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.fw_version_get         = nfp_net_firmware_version_get,
 	.flow_ctrl_get          = nfp_net_flow_ctrl_get,
 	.flow_ctrl_set          = nfp_net_flow_ctrl_set,
+	.flow_ops_get           = nfp_net_flow_ops_get,
 };
 
 static inline void
diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index 15e0bb60d8..b526feaff2 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -8,6 +8,34 @@
 
 #include "nfp_net_common.h"
 
+#define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
+#define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
+#define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
+
+/**
+ * Action data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-------------------------------+-------------------------------+
+ *    0  |                 |    Queue    |              Actions          |
+ *       +-----------------+-------------+-------------------------------+
+ *    1  |                         Mark ID                               |
+ *       +---------------------------------------------------------------+
+ *
+ * Queue – Queue ID, 7 bits.
+ * Actions – An action bitmap, each bit represents an action type:
+ *       - Bit 0: Drop action. Drop the packet.
+ *       - Bit 1: Queue action. Use the queue specified by “Queue” field.
+ *                If not set, the queue is usually specified by RSS.
+ *       - Bit 2: Mark action. Mark packet with Mark ID.
+ */
+struct nfp_net_cmsg_action {
+	uint16_t action;
+	uint8_t queue;
+	uint8_t spare;
+	uint16_t mark_id;
+};
+
 enum nfp_net_cfg_mbox_cmd {
 	NFP_NET_CFG_MBOX_CMD_FS_ADD_V4,       /* Add Flow Steer rule for V4 table */
 	NFP_NET_CFG_MBOX_CMD_FS_DEL_V4,       /* Delete Flow Steer rule for V4 table */
diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h
index 48791af93a..464a191a9c 100644
--- a/drivers/net/nfp/nfp_net_common.h
+++ b/drivers/net/nfp/nfp_net_common.h
@@ -114,6 +114,7 @@ struct nfp_net_priv {
 	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
 	struct rte_hash *flow_table; /**< Hash table to store flow rules. */
 	uint16_t flow_count; /**< Flow count in hash table */
+	bool flow_position[NFP_NET_FLOW_LIMIT]; /**< Flow position array */
 };
 
 struct nfp_app_fw_nic {
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 6c02b0f82e..88386a31f0 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -11,8 +11,9 @@
 #include <rte_malloc.h>
 
 #include "nfp_logs.h"
+#include "nfp_net_cmsg.h"
 
-__rte_unused static int
+static int
 nfp_net_flow_table_add(struct nfp_net_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -27,7 +28,7 @@ nfp_net_flow_table_add(struct nfp_net_priv *priv,
 	return 0;
 }
 
-__rte_unused static int
+static int
 nfp_net_flow_table_delete(struct nfp_net_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -42,7 +43,7 @@ nfp_net_flow_table_delete(struct nfp_net_priv *priv,
 	return 0;
 }
 
-__rte_unused static struct rte_flow *
+static struct rte_flow *
 nfp_net_flow_table_search(struct nfp_net_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -59,11 +60,58 @@ nfp_net_flow_table_search(struct nfp_net_priv *priv,
 	return flow_find;
 }
 
-__rte_unused static struct rte_flow *
-nfp_net_flow_alloc(uint32_t match_len,
+static int
+nfp_net_flow_position_acquire(struct nfp_net_priv *priv,
+		uint32_t priority,
+		struct rte_flow *nfp_flow)
+{
+	uint32_t i;
+
+	if (priority != 0) {
+		i = NFP_NET_FLOW_LIMIT - priority - 1;
+
+		if (priv->flow_position[i]) {
+			PMD_DRV_LOG(ERR, "There is already a flow rule in this place.");
+			return -EAGAIN;
+		}
+
+		priv->flow_position[i] = true;
+		nfp_flow->position = priority;
+		return 0;
+	}
+
+	for (i = 0; i < NFP_NET_FLOW_LIMIT; i++) {
+		if (!priv->flow_position[i]) {
+			priv->flow_position[i] = true;
+			break;
+		}
+	}
+
+	if (i == NFP_NET_FLOW_LIMIT) {
+		PMD_DRV_LOG(ERR, "The limited flow number is reach.");
+		return -ERANGE;
+	}
+
+	nfp_flow->position = NFP_NET_FLOW_LIMIT - i - 1;
+
+	return 0;
+}
+
+static void
+nfp_net_flow_position_free(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	priv->flow_position[nfp_flow->position] = false;
+}
+
+static struct rte_flow *
+nfp_net_flow_alloc(struct nfp_net_priv *priv,
+		uint32_t priority,
+		uint32_t match_len,
 		uint32_t action_len,
 		uint32_t port_id)
 {
+	int ret;
 	char *data;
 	struct rte_flow *nfp_flow;
 	struct nfp_net_flow_payload *payload;
@@ -76,6 +124,10 @@ nfp_net_flow_alloc(uint32_t match_len,
 	if (data == NULL)
 		goto free_flow;
 
+	ret = nfp_net_flow_position_acquire(priv, priority, nfp_flow);
+	if (ret != 0)
+		goto free_payload;
+
 	nfp_flow->port_id      = port_id;
 	payload                = &nfp_flow->payload;
 	payload->match_len     = match_len;
@@ -85,19 +137,362 @@ nfp_net_flow_alloc(uint32_t match_len,
 
 	return nfp_flow;
 
+free_payload:
+	rte_free(data);
 free_flow:
 	rte_free(nfp_flow);
 
 	return NULL;
 }
 
-__rte_unused static void
-nfp_net_flow_free(struct rte_flow *nfp_flow)
+static void
+nfp_net_flow_free(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
 {
+	nfp_net_flow_position_free(priv, nfp_flow);
 	rte_free(nfp_flow->payload.match_data);
 	rte_free(nfp_flow);
 }
 
+static int
+nfp_net_flow_calculate_items(const struct rte_flow_item items[],
+		uint32_t *match_len)
+{
+	const struct rte_flow_item *item;
+
+	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
+		switch (item->type) {
+		default:
+			PMD_DRV_LOG(ERR, "Can't calculate match length");
+			*match_len = 0;
+			return -ENOTSUP;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static void
+nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
+		uint32_t match_len)
+{
+	switch (match_len) {
+	default:
+		break;
+	}
+}
+
+static struct rte_flow *
+nfp_net_flow_setup(struct rte_eth_dev *dev,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		__rte_unused const struct rte_flow_action actions[])
+{
+	int ret;
+	char *hash_data;
+	uint32_t port_id;
+	uint32_t action_len;
+	struct nfp_net_hw *hw;
+	uint32_t match_len = 0;
+	struct nfp_net_priv *priv;
+	struct rte_flow *nfp_flow;
+	struct rte_flow *flow_find;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[hw->idx]->priv;
+
+	ret = nfp_net_flow_calculate_items(items, &match_len);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Key layers calculate failed.");
+		return NULL;
+	}
+
+	action_len = sizeof(struct nfp_net_cmsg_action);
+	port_id = ((struct nfp_net_hw *)dev->data->dev_private)->nfp_idx;
+
+	nfp_flow = nfp_net_flow_alloc(priv, attr->priority, match_len, action_len, port_id);
+	if (nfp_flow == NULL) {
+		PMD_DRV_LOG(ERR, "Alloc nfp flow failed.");
+		return NULL;
+	}
+
+	/* Calculate and store the hash_key for later use */
+	hash_data = nfp_flow->payload.match_data;
+	nfp_flow->hash_key = rte_jhash(hash_data, match_len + action_len,
+			priv->hash_seed);
+
+	/* Find the flow in hash table */
+	flow_find = nfp_net_flow_table_search(priv, nfp_flow);
+	if (flow_find != NULL) {
+		PMD_DRV_LOG(ERR, "This flow is already exist.");
+		goto free_flow;
+	}
+
+	priv->flow_count++;
+
+	nfp_net_flow_process_priority(nfp_flow, match_len);
+
+	return nfp_flow;
+
+free_flow:
+	nfp_net_flow_free(priv, nfp_flow);
+
+	return NULL;
+}
+
+static int
+nfp_net_flow_teardown(struct nfp_net_priv *priv,
+		__rte_unused struct rte_flow *nfp_flow)
+{
+	priv->flow_count--;
+
+	return 0;
+}
+
+static int
+nfp_net_flow_offload(struct nfp_net_hw *hw,
+		struct rte_flow *flow,
+		bool delete_flag)
+{
+	int ret;
+	char *tmp;
+	uint32_t msg_size;
+	struct nfp_net_cmsg *cmsg;
+
+	msg_size = sizeof(uint32_t) + flow->payload.match_len +
+			flow->payload.action_len;
+	cmsg = nfp_net_cmsg_alloc(msg_size);
+	if (cmsg == NULL) {
+		PMD_DRV_LOG(ERR, "Alloc cmsg failed.");
+		return -ENOMEM;
+	}
+
+	cmsg->cmd = flow->payload.cmsg_type;
+	if (delete_flag)
+		cmsg->cmd++;
+
+	tmp = (char *)cmsg->data;
+	rte_memcpy(tmp, flow->payload.match_data, flow->payload.match_len);
+	tmp += flow->payload.match_len;
+	rte_memcpy(tmp, flow->payload.action_data, flow->payload.action_len);
+
+	ret = nfp_net_cmsg_xmit(hw, cmsg, msg_size);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Send cmsg failed.");
+		ret = -EINVAL;
+		goto free_cmsg;
+	}
+
+free_cmsg:
+	nfp_net_cmsg_free(cmsg);
+
+	return ret;
+}
+
+static int
+nfp_net_flow_validate(struct rte_eth_dev *dev,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct nfp_net_hw *hw;
+	struct rte_flow *nfp_flow;
+	struct nfp_net_priv *priv;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[hw->idx]->priv;
+
+	nfp_flow = nfp_net_flow_setup(dev, attr, items, actions);
+	if (nfp_flow == NULL) {
+		return rte_flow_error_set(error, ENOTSUP,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "This flow can not be offloaded.");
+	}
+
+	ret = nfp_net_flow_teardown(priv, nfp_flow);
+	if (ret != 0) {
+		return rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow resource free failed.");
+	}
+
+	nfp_net_flow_free(priv, nfp_flow);
+
+	return 0;
+}
+
+static struct rte_flow *
+nfp_net_flow_create(struct rte_eth_dev *dev,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct nfp_net_hw *hw;
+	struct rte_flow *nfp_flow;
+	struct nfp_net_priv *priv;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[hw->idx]->priv;
+
+	nfp_flow = nfp_net_flow_setup(dev, attr, items, actions);
+	if (nfp_flow == NULL) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "This flow can not be offloaded.");
+		return NULL;
+	}
+
+	/* Add the flow to flow hash table */
+	ret = nfp_net_flow_table_add(priv, nfp_flow);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Add flow to the flow table failed.");
+		goto flow_teardown;
+	}
+
+	/* Add the flow to hardware */
+	ret = nfp_net_flow_offload(hw, nfp_flow, false);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Add flow to firmware failed.");
+		goto table_delete;
+	}
+
+	return nfp_flow;
+
+table_delete:
+	nfp_net_flow_table_delete(priv, nfp_flow);
+flow_teardown:
+	nfp_net_flow_teardown(priv, nfp_flow);
+	nfp_net_flow_free(priv, nfp_flow);
+
+	return NULL;
+}
+
+static int
+nfp_net_flow_destroy(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct nfp_net_hw *hw;
+	struct nfp_net_priv *priv;
+	struct rte_flow *flow_find;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[hw->idx]->priv;
+
+	/* Find the flow in flow hash table */
+	flow_find = nfp_net_flow_table_search(priv, nfp_flow);
+	if (flow_find == NULL) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow does not exist.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Delete the flow from hardware */
+	ret = nfp_net_flow_offload(hw, nfp_flow, true);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Delete flow from firmware failed.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Delete the flow from flow hash table */
+	ret = nfp_net_flow_table_delete(priv, nfp_flow);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Delete flow from the flow table failed.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = nfp_net_flow_teardown(priv, nfp_flow);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow teardown failed.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+exit:
+	nfp_net_flow_free(priv, nfp_flow);
+
+	return ret;
+}
+
+static int
+nfp_net_flow_flush(struct rte_eth_dev *dev,
+		struct rte_flow_error *error)
+{
+	int ret = 0;
+	void *next_data;
+	uint32_t iter = 0;
+	const void *next_key;
+	struct nfp_net_hw *hw;
+	struct rte_flow *nfp_flow;
+	struct rte_hash *flow_table;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	flow_table = app_fw_nic->ports[hw->idx]->priv->flow_table;
+
+	while (rte_hash_iterate(flow_table, &next_key, &next_data, &iter) >= 0) {
+		nfp_flow = next_data;
+		ret = nfp_net_flow_destroy(dev, nfp_flow, error);
+		if (ret != 0)
+			break;
+	}
+
+	return ret;
+}
+
+static const struct rte_flow_ops nfp_net_flow_ops = {
+	.validate                = nfp_net_flow_validate,
+	.create                  = nfp_net_flow_create,
+	.destroy                 = nfp_net_flow_destroy,
+	.flush                   = nfp_net_flow_flush,
+};
+
+int
+nfp_net_flow_ops_get(struct rte_eth_dev *dev,
+		const struct rte_flow_ops **ops)
+{
+	struct nfp_net_hw *hw;
+
+	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {
+		*ops = NULL;
+		PMD_DRV_LOG(ERR, "Port is a representor.");
+		return -EINVAL;
+	}
+
+	hw = dev->data->dev_private;
+	if ((hw->super.cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER) == 0) {
+		*ops = NULL;
+		return 0;
+	}
+
+	*ops = &nfp_net_flow_ops;
+
+	return 0;
+}
+
 int
 nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev,
 		uint16_t port)
diff --git a/drivers/net/nfp/nfp_net_flow.h b/drivers/net/nfp/nfp_net_flow.h
index 5ec80ba3b6..558cd0e2bb 100644
--- a/drivers/net/nfp/nfp_net_flow.h
+++ b/drivers/net/nfp/nfp_net_flow.h
@@ -20,9 +20,11 @@ struct rte_flow {
 	struct nfp_net_flow_payload payload;
 	uint32_t hash_key;
 	uint32_t port_id;
+	uint32_t position;    /**< Use as priority */
 };
 
 int nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev, uint16_t port);
 void nfp_net_flow_priv_uninit(struct nfp_pf_dev *pf_dev, uint16_t port);
+int nfp_net_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops);
 
 #endif /* __NFP_NET_FLOW_H__ */
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 05/11] net/nfp: support Ethernet flow item
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (3 preceding siblings ...)
  2023-11-03  6:25 ` [PATCH 04/11] net/nfp: support flow API for CoreNIC firmware Chaoyong He
@ 2023-11-03  6:26 ` Chaoyong He
  2023-11-03  6:26 ` [PATCH 06/11] net/nfp: support drop flow action Chaoyong He
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding data structure and logics, to support the offload
of ethernet item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_cmsg.h |  13 +++
 drivers/net/nfp/nfp_net_flow.c | 169 +++++++++++++++++++++++++++++++++
 2 files changed, 182 insertions(+)

diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index b526feaff2..a95f4ef831 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -8,6 +8,19 @@
 
 #include "nfp_net_common.h"
 
+/**
+ * Match EtherType data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-------------------------------+-------------------------------+
+ *    0  |                               |            Ethtype            |
+ *       +-----------------+-------------+-------------------------------+
+ */
+struct nfp_net_cmsg_match_eth {
+	uint16_t ether_type;
+	uint16_t spare;
+};
+
 #define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
 #define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
 #define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 88386a31f0..4ef4aafb16 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -13,6 +13,28 @@
 #include "nfp_logs.h"
 #include "nfp_net_cmsg.h"
 
+/* Static initializer for a list of subsequent item types */
+#define NEXT_ITEM(...) \
+	((const enum rte_flow_item_type []){ \
+		__VA_ARGS__, RTE_FLOW_ITEM_TYPE_END, \
+	})
+
+/* Process structure associated with a flow item */
+struct nfp_net_flow_item_proc {
+	/* Bit-mask for fields supported by this PMD. */
+	const void *mask_support;
+	/* Bit-mask to use when @p item->mask is not provided. */
+	const void *mask_default;
+	/* Size in bytes for @p mask_support and @p mask_default. */
+	const uint32_t mask_sz;
+	/* Merge a pattern item into a flow rule handle. */
+	int (*merge)(struct rte_flow *nfp_flow,
+			const struct rte_flow_item *item,
+			const struct nfp_net_flow_item_proc *proc);
+	/* List of possible subsequent items. */
+	const enum rte_flow_item_type *const next_item;
+};
+
 static int
 nfp_net_flow_table_add(struct nfp_net_priv *priv,
 		struct rte_flow *nfp_flow)
@@ -162,6 +184,10 @@ nfp_net_flow_calculate_items(const struct rte_flow_item items[],
 
 	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
 		switch (item->type) {
+		case RTE_FLOW_ITEM_TYPE_ETH:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_ETH detected");
+			*match_len = sizeof(struct nfp_net_cmsg_match_eth);
+			return 0;
 		default:
 			PMD_DRV_LOG(ERR, "Can't calculate match length");
 			*match_len = 0;
@@ -172,6 +198,143 @@ nfp_net_flow_calculate_items(const struct rte_flow_item items[],
 	return -EINVAL;
 }
 
+static int
+nfp_net_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,
+		const struct rte_flow_item *item,
+		__rte_unused const struct nfp_net_flow_item_proc *proc)
+{
+	struct nfp_net_cmsg_match_eth *eth;
+	const struct rte_flow_item_eth *spec;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(ERR, "NFP flow merge eth: no item->spec!");
+		return -EINVAL;
+	}
+
+	nfp_flow->payload.cmsg_type = NFP_NET_CFG_MBOX_CMD_FS_ADD_ETHTYPE;
+
+	eth = (struct nfp_net_cmsg_match_eth *)nfp_flow->payload.match_data;
+	eth->ether_type = rte_be_to_cpu_16(spec->type);
+
+	return 0;
+}
+
+/* Graph of supported items and associated process function */
+static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
+	[RTE_FLOW_ITEM_TYPE_END] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+	},
+	[RTE_FLOW_ITEM_TYPE_ETH] = {
+		.merge = nfp_net_flow_merge_eth,
+	},
+};
+
+static int
+nfp_net_flow_item_check(const struct rte_flow_item *item,
+		const struct nfp_net_flow_item_proc *proc)
+{
+	uint32_t i;
+	int ret = 0;
+	const uint8_t *mask;
+
+	/* item->last and item->mask cannot exist without item->spec. */
+	if (item->spec == NULL) {
+		if (item->mask || item->last) {
+			PMD_DRV_LOG(ERR, "'mask' or 'last' field provided"
+					" without a corresponding 'spec'.");
+			return -EINVAL;
+		}
+
+		/* No spec, no mask, no problem. */
+		return 0;
+	}
+
+	mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+	/*
+	 * Single-pass check to make sure that:
+	 * - Mask is supported, no bits are set outside proc->mask_support.
+	 * - Both item->spec and item->last are included in mask.
+	 */
+	for (i = 0; i != proc->mask_sz; ++i) {
+		if (mask[i] == 0)
+			continue;
+
+		if ((mask[i] | ((const uint8_t *)proc->mask_support)[i]) !=
+				((const uint8_t *)proc->mask_support)[i]) {
+			PMD_DRV_LOG(ERR, "Unsupported field found in 'mask'.");
+			ret = -EINVAL;
+			break;
+		}
+
+		if (item->last != NULL &&
+				(((const uint8_t *)item->spec)[i] & mask[i]) !=
+				(((const uint8_t *)item->last)[i] & mask[i])) {
+			PMD_DRV_LOG(ERR, "Range between 'spec' and 'last'"
+					" is larger than 'mask'.");
+			ret = -ERANGE;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int
+nfp_net_flow_compile_items(const struct rte_flow_item items[],
+		struct rte_flow *nfp_flow)
+{
+	uint32_t i;
+	int ret = 0;
+	const struct rte_flow_item *item;
+	const struct nfp_net_flow_item_proc *proc_list;
+
+	proc_list = nfp_net_flow_item_proc_list;
+
+	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
+		const struct nfp_net_flow_item_proc *proc = NULL;
+
+		for (i = 0; (proc_list->next_item != NULL) &&
+				(proc_list->next_item[i] != RTE_FLOW_ITEM_TYPE_END); ++i) {
+			if (proc_list->next_item[i] == item->type) {
+				proc = &nfp_net_flow_item_proc_list[item->type];
+				break;
+			}
+		}
+
+		if (proc == NULL) {
+			PMD_DRV_LOG(ERR, "No next item provided for %d", item->type);
+			ret = -ENOTSUP;
+			break;
+		}
+
+		/* Perform basic sanity checks */
+		ret = nfp_net_flow_item_check(item, proc);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "NFP flow item %d check failed", item->type);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (proc->merge == NULL) {
+			PMD_DRV_LOG(ERR, "NFP flow item %d no proc function", item->type);
+			ret = -ENOTSUP;
+			break;
+		}
+
+		ret = proc->merge(nfp_flow, item, proc);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "NFP flow item %d exact merge failed", item->type);
+			break;
+		}
+
+		proc_list = proc;
+	}
+
+	return ret;
+}
+
 static void
 nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
 		uint32_t match_len)
@@ -218,6 +381,12 @@ nfp_net_flow_setup(struct rte_eth_dev *dev,
 		return NULL;
 	}
 
+	ret = nfp_net_flow_compile_items(items, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "NFP flow item process failed.");
+		goto free_flow;
+	}
+
 	/* Calculate and store the hash_key for later use */
 	hash_data = nfp_flow->payload.match_data;
 	nfp_flow->hash_key = rte_jhash(hash_data, match_len + action_len,
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 06/11] net/nfp: support drop flow action
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (4 preceding siblings ...)
  2023-11-03  6:26 ` [PATCH 05/11] net/nfp: support Ethernet flow item Chaoyong He
@ 2023-11-03  6:26 ` Chaoyong He
  2023-11-03  6:26 ` [PATCH 07/11] net/nfp: support IPv4 flow item Chaoyong He
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding logics to support the offload of drop action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_flow.c | 39 +++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 4ef4aafb16..65c922071e 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -335,6 +335,37 @@ nfp_net_flow_compile_items(const struct rte_flow_item items[],
 	return ret;
 }
 
+static void
+nfp_net_flow_action_drop(struct rte_flow *nfp_flow)
+{
+	struct nfp_net_cmsg_action *action_data;
+
+	action_data = (struct nfp_net_cmsg_action *)nfp_flow->payload.action_data;
+
+	action_data->action = NFP_NET_CMSG_ACTION_DROP;
+}
+
+static int
+nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
+		struct rte_flow *nfp_flow)
+{
+	const struct rte_flow_action *action;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+		switch (action->type) {
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_DROP");
+			nfp_net_flow_action_drop(nfp_flow);
+			return 0;
+		default:
+			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
+			return -ENOTSUP;
+		}
+	}
+
+	return 0;
+}
+
 static void
 nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
 		uint32_t match_len)
@@ -349,7 +380,7 @@ static struct rte_flow *
 nfp_net_flow_setup(struct rte_eth_dev *dev,
 		const struct rte_flow_attr *attr,
 		const struct rte_flow_item items[],
-		__rte_unused const struct rte_flow_action actions[])
+		const struct rte_flow_action actions[])
 {
 	int ret;
 	char *hash_data;
@@ -387,6 +418,12 @@ nfp_net_flow_setup(struct rte_eth_dev *dev,
 		goto free_flow;
 	}
 
+	ret = nfp_net_flow_compile_actions(actions, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "NFP flow action process failed.");
+		goto free_flow;
+	}
+
 	/* Calculate and store the hash_key for later use */
 	hash_data = nfp_flow->payload.match_data;
 	nfp_flow->hash_key = rte_jhash(hash_data, match_len + action_len,
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 07/11] net/nfp: support IPv4 flow item
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (5 preceding siblings ...)
  2023-11-03  6:26 ` [PATCH 06/11] net/nfp: support drop flow action Chaoyong He
@ 2023-11-03  6:26 ` Chaoyong He
  2023-11-03  6:26 ` [PATCH 08/11] net/nfp: support IPv6 " Chaoyong He
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding data structure and logics, to support the offload
of IPv4 item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_cmsg.h | 37 ++++++++++++++++++++++
 drivers/net/nfp/nfp_net_flow.c | 58 ++++++++++++++++++++++++++++++++--
 2 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index a95f4ef831..9bc064d9d7 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -21,6 +21,43 @@ struct nfp_net_cmsg_match_eth {
 	uint16_t spare;
 };
 
+/**
+ * Match IPv4 data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-----+-------------------------+---------------+---------------+
+ *    0  |     |        Position         |   L4 Proto    | L4 Proto Mask |
+ *       +-----+-------------------------+---------------+---------------+
+ *    1  |                             SIP4                              |
+ *       +---------------------------------------------------------------+
+ *    2  |                           SIP4 Mask                           |
+ *       +---------------------------------------------------------------+
+ *    3  |                             DIP4                              |
+ *       +---------------------------------------------------------------+
+ *    4  |                           DIP4 Mask                           |
+ *       +-------------------------------+-------------------------------+
+ *    5  |             SPort             |           SPort Mask          |
+ *       +-------------------------------+-------------------------------+
+ *    6  |             DPort             |           DPort Mask          |
+ *       +-----------------+-------------+-------------------------------+
+ *
+ * Position – Position index of the rule, 13bits.
+ *            As priority, smaller value indicates higher priority.
+ */
+struct nfp_net_cmsg_match_v4 {
+	uint8_t l4_protocol_mask;
+	uint8_t l4_protocol;
+	uint16_t position;
+	uint32_t src_ipv4;
+	uint32_t src_ipv4_mask;
+	uint32_t dst_ipv4;
+	uint32_t dst_ipv4_mask;
+	uint16_t src_port;
+	uint16_t src_port_mask;
+	uint16_t dst_port;
+	uint16_t dst_port_mask;
+};
+
 #define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
 #define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
 #define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 65c922071e..e918c67135 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -188,6 +188,10 @@ nfp_net_flow_calculate_items(const struct rte_flow_item items[],
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_ETH detected");
 			*match_len = sizeof(struct nfp_net_cmsg_match_eth);
 			return 0;
+		case RTE_FLOW_ITEM_TYPE_IPV4:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected");
+			*match_len = sizeof(struct nfp_net_cmsg_match_v4);
+			return 0;
 		default:
 			PMD_DRV_LOG(ERR, "Can't calculate match length");
 			*match_len = 0;
@@ -220,14 +224,58 @@ nfp_net_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,
 	return 0;
 }
 
+static int
+nfp_net_flow_merge_ipv4(struct rte_flow *nfp_flow,
+		const struct rte_flow_item *item,
+		const struct nfp_net_flow_item_proc *proc)
+{
+	struct nfp_net_cmsg_match_v4 *ipv4;
+	const struct rte_flow_item_ipv4 *mask;
+	const struct rte_flow_item_ipv4 *spec;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "NFP flow merge ipv4: no item->spec!");
+		return 0;
+	}
+
+	mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+	nfp_flow->payload.cmsg_type = NFP_NET_CFG_MBOX_CMD_FS_ADD_V4;
+	ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
+
+	ipv4->l4_protocol_mask = mask->hdr.next_proto_id;
+	ipv4->src_ipv4_mask    = rte_be_to_cpu_32(mask->hdr.src_addr);
+	ipv4->dst_ipv4_mask    = rte_be_to_cpu_32(mask->hdr.dst_addr);
+
+	ipv4->l4_protocol  = spec->hdr.next_proto_id;
+	ipv4->src_ipv4     = rte_be_to_cpu_32(spec->hdr.src_addr);
+	ipv4->dst_ipv4     = rte_be_to_cpu_32(spec->hdr.dst_addr);
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH,
+				RTE_FLOW_ITEM_TYPE_IPV4),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
 		.merge = nfp_net_flow_merge_eth,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.mask_support = &(const struct rte_flow_item_ipv4){
+			.hdr = {
+				.next_proto_id = 0xff,
+				.src_addr      = RTE_BE32(0xffffffff),
+				.dst_addr      = RTE_BE32(0xffffffff),
+			},
+		},
+		.mask_default = &rte_flow_item_ipv4_mask,
+		.mask_sz = sizeof(struct rte_flow_item_ipv4),
+		.merge = nfp_net_flow_merge_ipv4,
+	},
 };
 
 static int
@@ -367,10 +415,16 @@ nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 }
 
 static void
-nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
+nfp_net_flow_process_priority(struct rte_flow *nfp_flow,
 		uint32_t match_len)
 {
+	struct nfp_net_cmsg_match_v4 *ipv4;
+
 	switch (match_len) {
+	case sizeof(struct nfp_net_cmsg_match_v4):
+		ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
+		ipv4->position = nfp_flow->position;
+		break;
 	default:
 		break;
 	}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 08/11] net/nfp: support IPv6 flow item
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (6 preceding siblings ...)
  2023-11-03  6:26 ` [PATCH 07/11] net/nfp: support IPv4 flow item Chaoyong He
@ 2023-11-03  6:26 ` Chaoyong He
  2023-11-03  6:26 ` [PATCH 09/11] net/nfp: support TCP/UDP/SCTP flow items Chaoyong He
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding data structure and logics, to support the offload
of IPv6 item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_cmsg.h | 61 +++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_net_flow.c | 66 +++++++++++++++++++++++++++++++++-
 2 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index 9bc064d9d7..e177ac7cd6 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -58,6 +58,67 @@ struct nfp_net_cmsg_match_v4 {
 	uint16_t dst_port_mask;
 };
 
+/**
+ * Match IPv6 data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-----+-------------------------+---------------+---------------+
+ *    0  |     |        Position         |   L4 Proto    | L4 Proto Mask |
+ *       +-----+-------------------------+---------------+---------------+
+ *    1  |                            SIP6 (0-3B)                        |
+ *       +---------------------------------------------------------------+
+ *    2  |                            SIP6 (4-7B)                        |
+ *       +---------------------------------------------------------------+
+ *    3  |                            SIP6 (8-11B)                       |
+ *       +---------------------------------------------------------------+
+ *    4  |                            SIP6 (12-15B)                      |
+ *       +---------------------------------------------------------------+
+ *    5  |                         SIP6 Mask (0-3B)                      |
+ *       +---------------------------------------------------------------+
+ *    6  |                         SIP6 Mask (4-7B)                      |
+ *       +---------------------------------------------------------------+
+ *    7  |                         SIP6 Mask (8-11B)                     |
+ *       +---------------------------------------------------------------+
+ *    8  |                         SIP6 Mask (12-15B)                    |
+ *       +---------------------------------------------------------------+
+ *    9  |                            DIP6 (0-3B)                        |
+ *       +---------------------------------------------------------------+
+ *    10 |                            DIP6 (4-7B)                        |
+ *       +---------------------------------------------------------------+
+ *    11 |                            DIP6 (8-11B)                       |
+ *       +---------------------------------------------------------------+
+ *    12 |                            DIP6 (12-15B)                      |
+ *       +---------------------------------------------------------------+
+ *    13 |                         DIP6 Mask (0-3B)                      |
+ *       +---------------------------------------------------------------+
+ *    14 |                         DIP6 Mask (4-7B)                      |
+ *       +---------------------------------------------------------------+
+ *    15 |                         DIP6 Mask (8-11B)                     |
+ *       +---------------------------------------------------------------+
+ *    16 |                         DIP6 Mask (12-15B)                    |
+ *       +-------------------------------+-------------------------------+
+ *    17 |             SPort             |           SPort Mask          |
+ *       +-------------------------------+-------------------------------+
+ *    18 |             DPort             |           DPort Mask          |
+ *       +-----------------+-------------+-------------------------------+
+ *
+ * Position – Position index of the rule, 13bits.
+ *            As priority, smaller value indicates higher priority.
+ */
+struct nfp_net_cmsg_match_v6 {
+	uint8_t l4_protocol_mask;
+	uint8_t l4_protocol;
+	uint16_t position;
+	uint8_t src_ipv6[16];
+	uint8_t src_ipv6_mask[16];
+	uint8_t dst_ipv6[16];
+	uint8_t dst_ipv6_mask[16];
+	uint16_t src_port_mask;
+	uint16_t src_port;
+	uint16_t dst_port_mask;
+	uint16_t dst_port;
+};
+
 #define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
 #define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
 #define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index e918c67135..c57f5d6328 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -192,6 +192,10 @@ nfp_net_flow_calculate_items(const struct rte_flow_item items[],
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected");
 			*match_len = sizeof(struct nfp_net_cmsg_match_v4);
 			return 0;
+		case RTE_FLOW_ITEM_TYPE_IPV6:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV6 detected");
+			*match_len = sizeof(struct nfp_net_cmsg_match_v6);
+			return 0;
 		default:
 			PMD_DRV_LOG(ERR, "Can't calculate match length");
 			*match_len = 0;
@@ -255,11 +259,52 @@ nfp_net_flow_merge_ipv4(struct rte_flow *nfp_flow,
 	return 0;
 }
 
+static int
+nfp_net_flow_merge_ipv6(struct rte_flow *nfp_flow,
+		const struct rte_flow_item *item,
+		const struct nfp_net_flow_item_proc *proc)
+{
+	uint32_t i;
+	struct nfp_net_cmsg_match_v6 *ipv6;
+	const struct rte_flow_item_ipv6 *mask;
+	const struct rte_flow_item_ipv6 *spec;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "NFP flow merge ipv6: no item->spec!");
+		return 0;
+	}
+
+	mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+	nfp_flow->payload.cmsg_type = NFP_NET_CFG_MBOX_CMD_FS_ADD_V6;
+	ipv6 = (struct nfp_net_cmsg_match_v6 *)nfp_flow->payload.match_data;
+
+	ipv6->l4_protocol_mask = mask->hdr.proto;
+	for (i = 0; i < sizeof(ipv6->src_ipv6); i += 4) {
+		ipv6->src_ipv6_mask[i] = mask->hdr.src_addr[i + 3];
+		ipv6->src_ipv6_mask[i + 1] = mask->hdr.src_addr[i + 2];
+		ipv6->src_ipv6_mask[i + 2] = mask->hdr.src_addr[i + 1];
+		ipv6->src_ipv6_mask[i + 3] = mask->hdr.src_addr[i];
+	}
+
+	ipv6->l4_protocol = spec->hdr.proto;
+	for (i = 0; i < sizeof(ipv6->src_ipv6); i += 4) {
+		ipv6->src_ipv6[i] = spec->hdr.src_addr[i + 3];
+		ipv6->src_ipv6[i + 1] = spec->hdr.src_addr[i + 2];
+		ipv6->src_ipv6[i + 2] = spec->hdr.src_addr[i + 1];
+		ipv6->src_ipv6[i + 3] = spec->hdr.src_addr[i];
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH,
-				RTE_FLOW_ITEM_TYPE_IPV4),
+				RTE_FLOW_ITEM_TYPE_IPV4,
+				RTE_FLOW_ITEM_TYPE_IPV6),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
 		.merge = nfp_net_flow_merge_eth,
@@ -276,6 +321,20 @@ static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 		.mask_sz = sizeof(struct rte_flow_item_ipv4),
 		.merge = nfp_net_flow_merge_ipv4,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.mask_support = &(const struct rte_flow_item_ipv6){
+			.hdr = {
+				.proto    = 0xff,
+				.src_addr = "\xff\xff\xff\xff\xff\xff\xff\xff"
+						"\xff\xff\xff\xff\xff\xff\xff\xff",
+				.dst_addr = "\xff\xff\xff\xff\xff\xff\xff\xff"
+						"\xff\xff\xff\xff\xff\xff\xff\xff",
+			},
+		},
+		.mask_default = &rte_flow_item_ipv6_mask,
+		.mask_sz = sizeof(struct rte_flow_item_ipv6),
+		.merge = nfp_net_flow_merge_ipv6,
+	},
 };
 
 static int
@@ -419,12 +478,17 @@ nfp_net_flow_process_priority(struct rte_flow *nfp_flow,
 		uint32_t match_len)
 {
 	struct nfp_net_cmsg_match_v4 *ipv4;
+	struct nfp_net_cmsg_match_v6 *ipv6;
 
 	switch (match_len) {
 	case sizeof(struct nfp_net_cmsg_match_v4):
 		ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
 		ipv4->position = nfp_flow->position;
 		break;
+	case sizeof(struct nfp_net_cmsg_match_v6):
+		ipv6 = (struct nfp_net_cmsg_match_v6 *)nfp_flow->payload.match_data;
+		ipv6->position = nfp_flow->position;
+		break;
 	default:
 		break;
 	}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 09/11] net/nfp: support TCP/UDP/SCTP flow items
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (7 preceding siblings ...)
  2023-11-03  6:26 ` [PATCH 08/11] net/nfp: support IPv6 " Chaoyong He
@ 2023-11-03  6:26 ` Chaoyong He
  2023-11-03  6:26 ` [PATCH 10/11] drivers: support MARK flow action Chaoyong He
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding logics to support the offload of TCP/UDP/SCTP
items.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_flow.c | 86 ++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index c57f5d6328..d07667a62a 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -299,6 +299,53 @@ nfp_net_flow_merge_ipv6(struct rte_flow *nfp_flow,
 	return 0;
 }
 
+static int
+nfp_flow_merge_l4(struct rte_flow *nfp_flow,
+		const struct rte_flow_item *item,
+		const struct nfp_net_flow_item_proc *proc)
+{
+	const struct rte_flow_item_tcp *mask;
+	const struct rte_flow_item_tcp *spec;
+	struct nfp_net_cmsg_match_v4 *ipv4 = NULL;
+	struct nfp_net_cmsg_match_v6 *ipv6 = NULL;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(ERR, "NFP flow merge tcp: no item->spec!");
+		return -EINVAL;
+	}
+
+	mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+	switch (nfp_flow->payload.cmsg_type) {
+	case NFP_NET_CFG_MBOX_CMD_FS_ADD_V4:
+		ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
+		break;
+	case NFP_NET_CFG_MBOX_CMD_FS_ADD_V6:
+		ipv6 = (struct nfp_net_cmsg_match_v6 *)nfp_flow->payload.match_data;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "L3 layer neither IPv4 nor IPv6.");
+		return -EINVAL;
+	}
+
+	if (ipv4 != NULL) {
+		ipv4->src_port_mask = rte_be_to_cpu_16(mask->hdr.src_port);
+		ipv4->dst_port_mask = rte_be_to_cpu_16(mask->hdr.dst_port);
+
+		ipv4->src_port = rte_be_to_cpu_16(spec->hdr.src_port);
+		ipv4->dst_port = rte_be_to_cpu_16(spec->hdr.dst_port);
+	} else {
+		ipv6->src_port_mask = rte_be_to_cpu_16(mask->hdr.src_port);
+		ipv6->dst_port_mask = rte_be_to_cpu_16(mask->hdr.dst_port);
+
+		ipv6->src_port = rte_be_to_cpu_16(spec->hdr.src_port);
+		ipv6->dst_port = rte_be_to_cpu_16(spec->hdr.dst_port);
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -310,6 +357,9 @@ static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 		.merge = nfp_net_flow_merge_eth,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+				RTE_FLOW_ITEM_TYPE_UDP,
+				RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.next_proto_id = 0xff,
@@ -322,6 +372,9 @@ static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 		.merge = nfp_net_flow_merge_ipv4,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+				RTE_FLOW_ITEM_TYPE_UDP,
+				RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.proto    = 0xff,
@@ -335,6 +388,39 @@ static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 		.mask_sz = sizeof(struct rte_flow_item_ipv6),
 		.merge = nfp_net_flow_merge_ipv6,
 	},
+	[RTE_FLOW_ITEM_TYPE_TCP] = {
+		.mask_support = &(const struct rte_flow_item_tcp){
+			.hdr = {
+				.src_port  = RTE_BE16(0xffff),
+				.dst_port  = RTE_BE16(0xffff),
+			},
+		},
+		.mask_default = &rte_flow_item_tcp_mask,
+		.mask_sz = sizeof(struct rte_flow_item_tcp),
+		.merge = nfp_flow_merge_l4,
+	},
+	[RTE_FLOW_ITEM_TYPE_UDP] = {
+		.mask_support = &(const struct rte_flow_item_udp){
+			.hdr = {
+				.src_port = RTE_BE16(0xffff),
+				.dst_port = RTE_BE16(0xffff),
+			},
+		},
+		.mask_default = &rte_flow_item_udp_mask,
+		.mask_sz = sizeof(struct rte_flow_item_udp),
+		.merge = nfp_flow_merge_l4,
+	},
+	[RTE_FLOW_ITEM_TYPE_SCTP] = {
+		.mask_support = &(const struct rte_flow_item_sctp){
+			.hdr = {
+				.src_port  = RTE_BE16(0xffff),
+				.dst_port  = RTE_BE16(0xffff),
+			},
+		},
+		.mask_default = &rte_flow_item_sctp_mask,
+		.mask_sz = sizeof(struct rte_flow_item_sctp),
+		.merge = nfp_flow_merge_l4,
+	},
 };
 
 static int
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 10/11] drivers: support MARK flow action
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (8 preceding siblings ...)
  2023-11-03  6:26 ` [PATCH 09/11] net/nfp: support TCP/UDP/SCTP flow items Chaoyong He
@ 2023-11-03  6:26 ` Chaoyong He
  2023-11-03  6:26 ` [PATCH 11/11] net/nfp: support QUEUE " Chaoyong He
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding logics to support the offload of MARK action.
Also add the related logics to parse the mark id and put into the mbuf
structure, and assigned the offload flags.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/common/nfp/nfp_common_ctrl.h |  1 +
 drivers/net/nfp/nfp_net_flow.c       | 18 ++++++++++++++++++
 drivers/net/nfp/nfp_rxtx.c           | 18 ++++++++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/drivers/common/nfp/nfp_common_ctrl.h b/drivers/common/nfp/nfp_common_ctrl.h
index cbde987736..d65fcd17cb 100644
--- a/drivers/common/nfp/nfp_common_ctrl.h
+++ b/drivers/common/nfp/nfp_common_ctrl.h
@@ -33,6 +33,7 @@
 
 /* Prepend field types */
 #define NFP_NET_META_HASH               1 /* Next field carries hash type */
+#define NFP_NET_META_MARK               2
 #define NFP_NET_META_VLAN               4
 #define NFP_NET_META_PORTID             5
 #define NFP_NET_META_IPSEC              9
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index d07667a62a..674aff075e 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -538,6 +538,20 @@ nfp_net_flow_action_drop(struct rte_flow *nfp_flow)
 	action_data->action = NFP_NET_CMSG_ACTION_DROP;
 }
 
+static void
+nfp_net_flow_action_mark(struct rte_flow *nfp_flow,
+		const struct rte_flow_action *action)
+{
+	struct nfp_net_cmsg_action *action_data;
+	const struct rte_flow_action_mark *mark;
+
+	action_data = (struct nfp_net_cmsg_action *)nfp_flow->payload.action_data;
+	mark = action->conf;
+
+	action_data->action |= NFP_NET_CMSG_ACTION_MARK;
+	action_data->mark_id = mark->id;
+}
+
 static int
 nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 		struct rte_flow *nfp_flow)
@@ -550,6 +564,10 @@ nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_DROP");
 			nfp_net_flow_action_drop(nfp_flow);
 			return 0;
+		case RTE_FLOW_ACTION_TYPE_MARK:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_MARK");
+			nfp_net_flow_action_mark(nfp_flow, action);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index b2a9ba6875..a04601edfa 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -25,6 +25,8 @@ struct nfp_meta_parsed {
 	uint32_t port_id;         /**< Port id value */
 	uint32_t sa_idx;          /**< IPsec SA index */
 	uint32_t hash;            /**< RSS hash value */
+	uint32_t mark_id;         /**< Mark id value */
+	uint16_t flags;           /**< Bitmap to indicate if meta exist */
 	uint8_t hash_type;        /**< RSS hash type */
 	uint8_t ipsec_type;       /**< IPsec type */
 	uint8_t vlan_layer;       /**< The valid number of value in @vlan[] */
@@ -290,6 +292,10 @@ nfp_net_parse_chained_meta(uint8_t *meta_base,
 			meta->sa_idx = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
 			meta->ipsec_type = meta_info & NFP_NET_META_FIELD_MASK;
 			break;
+		case NFP_NET_META_MARK:
+			meta->flags |= (1 << NFP_NET_META_MARK);
+			meta->mark_id = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
+			break;
 		default:
 			/* Unsupported metadata can be a performance issue */
 			return false;
@@ -434,6 +440,17 @@ nfp_net_parse_meta_ipsec(struct nfp_meta_parsed *meta,
 	}
 }
 
+static void
+nfp_net_parse_meta_mark(const struct nfp_meta_parsed *meta,
+		struct rte_mbuf *mbuf)
+{
+	if (((meta->flags >> NFP_NET_META_MARK) & 0x1) == 0)
+		return;
+
+	mbuf->hash.fdir.hi = meta->mark_id;
+	mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
+}
+
 /* Parse the metadata from packet */
 static void
 nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
@@ -458,6 +475,7 @@ nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
 			nfp_net_parse_meta_vlan(meta, rxds, rxq, mb);
 			nfp_net_parse_meta_qinq(meta, rxq, mb);
 			nfp_net_parse_meta_ipsec(meta, rxq, mb);
+			nfp_net_parse_meta_mark(meta, mb);
 		} else {
 			PMD_RX_LOG(DEBUG, "RX chained metadata format is wrong!");
 		}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 11/11] net/nfp: support QUEUE flow action
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (9 preceding siblings ...)
  2023-11-03  6:26 ` [PATCH 10/11] drivers: support MARK flow action Chaoyong He
@ 2023-11-03  6:26 ` Chaoyong He
  2023-11-03 16:12 ` [PATCH 00/11] Add basic flow support for corenic firmware Ferruh Yigit
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-11-03  6:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding logics to support the offload of QUEUE action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_flow.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 674aff075e..67071272a2 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -552,6 +552,20 @@ nfp_net_flow_action_mark(struct rte_flow *nfp_flow,
 	action_data->mark_id = mark->id;
 }
 
+static void
+nfp_net_flow_action_queue(struct rte_flow *nfp_flow,
+		const struct rte_flow_action *action)
+{
+	struct nfp_net_cmsg_action *action_data;
+	const struct rte_flow_action_queue *queue;
+
+	action_data = (struct nfp_net_cmsg_action *)nfp_flow->payload.action_data;
+	queue = action->conf;
+
+	action_data->action |= NFP_NET_CMSG_ACTION_QUEUE;
+	action_data->queue = queue->index;
+}
+
 static int
 nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 		struct rte_flow *nfp_flow)
@@ -568,6 +582,10 @@ nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_MARK");
 			nfp_net_flow_action_mark(nfp_flow, action);
 			break;
+		case RTE_FLOW_ACTION_TYPE_QUEUE:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_QUEUE");
+			nfp_net_flow_action_queue(nfp_flow, action);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (10 preceding siblings ...)
  2023-11-03  6:26 ` [PATCH 11/11] net/nfp: support QUEUE " Chaoyong He
@ 2023-11-03 16:12 ` Ferruh Yigit
  2023-11-07  1:42   ` Chaoyong He
  2023-11-03 17:01 ` Ferruh Yigit
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
  13 siblings, 1 reply; 37+ messages in thread
From: Ferruh Yigit @ 2023-11-03 16:12 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He

On 11/3/2023 6:25 AM, Chaoyong He wrote:
> Add the very basic rte_flow support for corenic firmware.
> 
> Chaoyong He (11):
>   net/nfp: move some source files
>   drivers: add the structures and functions for flow offload
>   net/nfp: add the control message channel
>   net/nfp: support flow API for CoreNIC firmware
>   net/nfp: support Ethernet flow item
>   net/nfp: support drop flow action
>   net/nfp: support IPv4 flow item
>   net/nfp: support IPv6 flow item
>   net/nfp: support TCP/UDP/SCTP flow items
>   drivers: support MARK flow action
>   net/nfp: support QUEUE flow action
> 

Recheck-request: iol-compile-amd64-testing, iol-unit-amd64-testing	

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (11 preceding siblings ...)
  2023-11-03 16:12 ` [PATCH 00/11] Add basic flow support for corenic firmware Ferruh Yigit
@ 2023-11-03 17:01 ` Ferruh Yigit
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
  13 siblings, 0 replies; 37+ messages in thread
From: Ferruh Yigit @ 2023-11-03 17:01 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers

On 11/3/2023 6:25 AM, Chaoyong He wrote:
> Add the very basic rte_flow support for corenic firmware.
> 
> Chaoyong He (11):
>   net/nfp: move some source files
>   drivers: add the structures and functions for flow offload
>   net/nfp: add the control message channel
>   net/nfp: support flow API for CoreNIC firmware
>   net/nfp: support Ethernet flow item
>   net/nfp: support drop flow action
>   net/nfp: support IPv4 flow item
>   net/nfp: support IPv6 flow item
>   net/nfp: support TCP/UDP/SCTP flow items
>   drivers: support MARK flow action
>   net/nfp: support QUEUE flow action
>

`./devtools/check-doc-vs-code.sh` gives some warnings [1], can you
please check them?

Please update the .ini file in the relevant patch where feature is
added, don't update it in a separate patch.


[1]
$ ./devtools/check-doc-vs-code.sh
rte_flow doc out of sync for nfp
        action mark
        action queue


^ permalink raw reply	[flat|nested] 37+ messages in thread

* RE: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-03 16:12 ` [PATCH 00/11] Add basic flow support for corenic firmware Ferruh Yigit
@ 2023-11-07  1:42   ` Chaoyong He
  2023-11-07  9:18     ` Ferruh Yigit
  0 siblings, 1 reply; 37+ messages in thread
From: Chaoyong He @ 2023-11-07  1:42 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: oss-drivers

> On 11/3/2023 6:25 AM, Chaoyong He wrote:
> > Add the very basic rte_flow support for corenic firmware.
> >
> > Chaoyong He (11):
> >   net/nfp: move some source files
> >   drivers: add the structures and functions for flow offload
> >   net/nfp: add the control message channel
> >   net/nfp: support flow API for CoreNIC firmware
> >   net/nfp: support Ethernet flow item
> >   net/nfp: support drop flow action
> >   net/nfp: support IPv4 flow item
> >   net/nfp: support IPv6 flow item
> >   net/nfp: support TCP/UDP/SCTP flow items
> >   drivers: support MARK flow action
> >   net/nfp: support QUEUE flow action
> >
> 
> Recheck-request: iol-compile-amd64-testing, iol-unit-amd64-testing

Seems both compile problems was introduced by this commit:
https://github.com/Corigine/dpdk-next-net-private/commit/34ff088cc24159c9fa6e61242efb76d0289b4e37

```
ethdev: set and query RSS hash algorithm
Currently, rte_eth_rss_conf supports configuring and querying
RSS hash functions, rss key and it's length, but not RSS hash
algorithm.

The structure ``rte_eth_dev_info`` is extended by adding a new
field "rss_algo_capa". Drivers are responsible for reporting this
capa and configurations of RSS hash algorithm can be verified based
on the capability. The default value of "rss_algo_capa" is
RTE_ETH_HASH_ALGO_CAPA_MASK(DEFAULT) if drivers do not report it.

The structure ``rte_eth_rss_conf`` is extended by adding a new
field "algorithm". This represents the RSS algorithms to apply.
If the value of "algorithm" used for configuration is a gibberish
value, drivers should report the error.

To check whether the drivers report valid "algorithm", it is set
to default value before querying in rte_eth_dev_rss_hash_conf_get().

Signed-off-by: Jie Hai <haijie1@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
```

Which was not related with this patch series, I think?

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-07  1:42   ` Chaoyong He
@ 2023-11-07  9:18     ` Ferruh Yigit
  2023-11-07  9:23       ` Chaoyong He
  0 siblings, 1 reply; 37+ messages in thread
From: Ferruh Yigit @ 2023-11-07  9:18 UTC (permalink / raw)
  To: Chaoyong He, dpdklab, Patrick Robb; +Cc: oss-drivers, dev

On 11/7/2023 1:42 AM, Chaoyong He wrote:
>> On 11/3/2023 6:25 AM, Chaoyong He wrote:
>>> Add the very basic rte_flow support for corenic firmware.
>>>
>>> Chaoyong He (11):
>>>   net/nfp: move some source files
>>>   drivers: add the structures and functions for flow offload
>>>   net/nfp: add the control message channel
>>>   net/nfp: support flow API for CoreNIC firmware
>>>   net/nfp: support Ethernet flow item
>>>   net/nfp: support drop flow action
>>>   net/nfp: support IPv4 flow item
>>>   net/nfp: support IPv6 flow item
>>>   net/nfp: support TCP/UDP/SCTP flow items
>>>   drivers: support MARK flow action
>>>   net/nfp: support QUEUE flow action
>>>
>>
>> Recheck-request: iol-compile-amd64-testing, iol-unit-amd64-testing
> 
> Seems both compile problems was introduced by this commit:
> https://github.com/Corigine/dpdk-next-net-private/commit/34ff088cc24159c9fa6e61242efb76d0289b4e37
> 
> ```
> ethdev: set and query RSS hash algorithm
> Currently, rte_eth_rss_conf supports configuring and querying
> RSS hash functions, rss key and it's length, but not RSS hash
> algorithm.
> 
> The structure ``rte_eth_dev_info`` is extended by adding a new
> field "rss_algo_capa". Drivers are responsible for reporting this
> capa and configurations of RSS hash algorithm can be verified based
> on the capability. The default value of "rss_algo_capa" is
> RTE_ETH_HASH_ALGO_CAPA_MASK(DEFAULT) if drivers do not report it.
> 
> The structure ``rte_eth_rss_conf`` is extended by adding a new
> field "algorithm". This represents the RSS algorithms to apply.
> If the value of "algorithm" used for configuration is a gibberish
> value, drivers should report the error.
> 
> To check whether the drivers report valid "algorithm", it is set
> to default value before querying in rte_eth_dev_rss_hash_conf_get().
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
> Acked-by: Huisong Li <lihuisong@huawei.com>
> Acked-by: Chengwen Feng <fengchengwen@huawei.com>
> Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
> ```
> 
> Which was not related with this patch series, I think?
>

Yes, build error is not related with this patch, and it is fixed in
next-net, that is why I tried to re-trigger the test, but it didn't work
somehow [1].

Btw, this set is pending because of other change request, not because of
the reported build failure.


[1]
https://patchwork.dpdk.org/project/dpdk/patch/20231103062606.2632012-12-chaoyong.he@corigine.com/



^ permalink raw reply	[flat|nested] 37+ messages in thread

* RE: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-07  9:18     ` Ferruh Yigit
@ 2023-11-07  9:23       ` Chaoyong He
  2023-11-07 16:50         ` Patrick Robb
  0 siblings, 1 reply; 37+ messages in thread
From: Chaoyong He @ 2023-11-07  9:23 UTC (permalink / raw)
  To: Ferruh Yigit, dpdklab, Patrick Robb; +Cc: oss-drivers, dev

> On 11/7/2023 1:42 AM, Chaoyong He wrote:
> >> On 11/3/2023 6:25 AM, Chaoyong He wrote:
> >>> Add the very basic rte_flow support for corenic firmware.
> >>>
> >>> Chaoyong He (11):
> >>>   net/nfp: move some source files
> >>>   drivers: add the structures and functions for flow offload
> >>>   net/nfp: add the control message channel
> >>>   net/nfp: support flow API for CoreNIC firmware
> >>>   net/nfp: support Ethernet flow item
> >>>   net/nfp: support drop flow action
> >>>   net/nfp: support IPv4 flow item
> >>>   net/nfp: support IPv6 flow item
> >>>   net/nfp: support TCP/UDP/SCTP flow items
> >>>   drivers: support MARK flow action
> >>>   net/nfp: support QUEUE flow action
> >>>
> >>
> >> Recheck-request: iol-compile-amd64-testing, iol-unit-amd64-testing
> >
> > Seems both compile problems was introduced by this commit:
> > https://github.com/Corigine/dpdk-next-net-
> private/commit/34ff088cc2415
> > 9c9fa6e61242efb76d0289b4e37
> >
> > ```
> > ethdev: set and query RSS hash algorithm Currently, rte_eth_rss_conf
> > supports configuring and querying RSS hash functions, rss key and it's
> > length, but not RSS hash algorithm.
> >
> > The structure ``rte_eth_dev_info`` is extended by adding a new field
> > "rss_algo_capa". Drivers are responsible for reporting this capa and
> > configurations of RSS hash algorithm can be verified based on the
> > capability. The default value of "rss_algo_capa" is
> > RTE_ETH_HASH_ALGO_CAPA_MASK(DEFAULT) if drivers do not report it.
> >
> > The structure ``rte_eth_rss_conf`` is extended by adding a new field
> > "algorithm". This represents the RSS algorithms to apply.
> > If the value of "algorithm" used for configuration is a gibberish
> > value, drivers should report the error.
> >
> > To check whether the drivers report valid "algorithm", it is set to
> > default value before querying in rte_eth_dev_rss_hash_conf_get().
> >
> > Signed-off-by: Jie Hai <haijie1@huawei.com>
> > Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
> > Acked-by: Huisong Li <lihuisong@huawei.com>
> > Acked-by: Chengwen Feng <fengchengwen@huawei.com>
> > Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com> ```
> >
> > Which was not related with this patch series, I think?
> >
> 
> Yes, build error is not related with this patch, and it is fixed in next-net, that is
> why I tried to re-trigger the test, but it didn't work somehow [1].
> 
> Btw, this set is pending because of other change request, not because of the
> reported build failure.

Oh, yes, I understand, the reason is I need to also update the 'nfp.ini' document.
But we decide delay this patch set to the next version of DPDK as we found still need some
modification to the logic of flower firmware.
Thanks.
> 
> 
> [1]
> https://patchwork.dpdk.org/project/dpdk/patch/20231103062606.263201
> 2-12-chaoyong.he@corigine.com/
> 


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-07  9:23       ` Chaoyong He
@ 2023-11-07 16:50         ` Patrick Robb
  2023-11-07 17:04           ` Patrick Robb
  0 siblings, 1 reply; 37+ messages in thread
From: Patrick Robb @ 2023-11-07 16:50 UTC (permalink / raw)
  To: Chaoyong He; +Cc: Ferruh Yigit, dpdklab, oss-drivers, dev

[-- Attachment #1: Type: text/plain, Size: 204 bytes --]

Recheck-request: iol-compile-amd64-testing, iol-unit-amd64-testing

Weird. I will dig up the original job which polled for the previous retest
request, and see whether this new one runs through properly.

[-- Attachment #2: Type: text/html, Size: 252 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-07 16:50         ` Patrick Robb
@ 2023-11-07 17:04           ` Patrick Robb
  2023-11-07 20:19             ` Ferruh Yigit
  0 siblings, 1 reply; 37+ messages in thread
From: Patrick Robb @ 2023-11-07 17:04 UTC (permalink / raw)
  To: Chaoyong He; +Cc: Ferruh Yigit, dpdklab, oss-drivers, dev

[-- Attachment #1: Type: text/plain, Size: 713 bytes --]

Sorry, now I understand what is causing confusion. When a retest is
requested, that retest is done on the original dpdk artifact we created for
the patchseries. We don't pull again, re-apply, and then rerun the testing.
I think that is the behavior you were expecting, Ferruh.

We have discussed whether this is an important option to support in future
iterations of the retest-request feature. One idea is to add another option
in the retest request schema which allows for the requester to indicate
they want the patch re-applied onto the newer branch, and testing rerun
with that new dpdk. It's good to see that this is a use case which would
see application. Will be aiming to add this support in the future.

[-- Attachment #2: Type: text/html, Size: 795 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-07 17:04           ` Patrick Robb
@ 2023-11-07 20:19             ` Ferruh Yigit
  2023-11-07 21:59               ` Patrick Robb
  0 siblings, 1 reply; 37+ messages in thread
From: Ferruh Yigit @ 2023-11-07 20:19 UTC (permalink / raw)
  To: Patrick Robb, Chaoyong He; +Cc: dpdklab, oss-drivers, dev

On 11/7/2023 5:04 PM, Patrick Robb wrote:
> Sorry, now I understand what is causing confusion. When a retest is
> requested, that retest is done on the original dpdk artifact we created
> for the patchseries. We don't pull again, re-apply, and then rerun the
> testing. I think that is the behavior you were expecting, Ferruh. 
> 

Hi Patrick,

Thanks for clarification, yes that was my expectation.

> We have discussed whether this is an important option to support in
> future iterations of the retest-request feature. One idea is to add
> another option in the retest request schema which allows for the
> requester to indicate they want the patch re-applied onto the newer
> branch, and testing rerun with that new dpdk. It's good to see that this
> is a use case which would see application. Will be aiming to add this
> support in the future.  
>

I am also not sure if this is the common usecase, lets record the need,
we can decide what to support based on it.


And as a generic approach, what about following syntax:
Recheck-request,attribute=value: ...

And for above case, attribute can be "pull=true" ...


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] Add basic flow support for corenic firmware
  2023-11-07 20:19             ` Ferruh Yigit
@ 2023-11-07 21:59               ` Patrick Robb
  0 siblings, 0 replies; 37+ messages in thread
From: Patrick Robb @ 2023-11-07 21:59 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: Chaoyong He, dpdklab, oss-drivers, dev

[-- Attachment #1: Type: text/plain, Size: 456 bytes --]

On Tue, Nov 7, 2023 at 3:19 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:

>
> I am also not sure if this is the common usecase, lets record the need,
> we can decide what to support based on it.
>
>
> And as a generic approach, what about following syntax:
> Recheck-request,attribute=value: ...
>
> And for above case, attribute can be "pull=true" ...
>
> That syntax looks reasonable, and if it's omitted, default is pull=false.
Thanks!

[-- Attachment #2: Type: text/html, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 00/11] Add basic flow support for corenic firmware
  2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
                   ` (12 preceding siblings ...)
  2023-11-03 17:01 ` Ferruh Yigit
@ 2023-12-05  2:54 ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 01/11] net/nfp: move some source files Chaoyong He
                     ` (11 more replies)
  13 siblings, 12 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He

Add the very basic rte_flow support for corenic firmware.

---
v2:
* Update the 'nfp.ini' document.
* Rebase to the latest main branch.
---

Chaoyong He (11):
  net/nfp: move some source files
  net/nfp: add the structures and functions for flow offload
  net/nfp: add the control message channel
  net/nfp: support flow API for CoreNIC firmware
  net/nfp: support Ethernet flow item
  net/nfp: support drop flow action
  net/nfp: support IPv4 flow item
  net/nfp: support IPv6 flow item
  net/nfp: support TCP/UDP/SCTP flow items
  net/nfp: support MARK flow action
  net/nfp: support QUEUE flow action

 doc/guides/nics/features/nfp.ini              |    2 +
 drivers/common/nfp/nfp_common_ctrl.h          |    2 +
 drivers/net/nfp/flower/nfp_conntrack.h        |    2 +-
 drivers/net/nfp/flower/nfp_flower_cmsg.h      |    2 +-
 .../{nfp_flow.c => flower/nfp_flower_flow.c}  |    4 +-
 .../{nfp_flow.h => flower/nfp_flower_flow.h}  |   10 +-
 .../net/nfp/flower/nfp_flower_representor.c   |    2 +-
 drivers/net/nfp/meson.build                   |    4 +-
 drivers/net/nfp/nfp_ethdev.c                  |   28 +-
 drivers/net/nfp/nfp_net_cmsg.c                |   66 ++
 drivers/net/nfp/nfp_net_cmsg.h                |  176 +++
 drivers/net/nfp/nfp_net_common.h              |   12 +
 drivers/net/nfp/nfp_net_ctrl.h                |    1 +
 drivers/net/nfp/nfp_net_flow.c                | 1017 +++++++++++++++++
 drivers/net/nfp/nfp_net_flow.h                |   30 +
 drivers/net/nfp/nfp_rxtx.c                    |   18 +
 16 files changed, 1359 insertions(+), 17 deletions(-)
 rename drivers/net/nfp/{nfp_flow.c => flower/nfp_flower_flow.c} (99%)
 rename drivers/net/nfp/{nfp_flow.h => flower/nfp_flower_flow.h} (96%)
 create mode 100644 drivers/net/nfp/nfp_net_cmsg.c
 create mode 100644 drivers/net/nfp/nfp_net_cmsg.h
 create mode 100644 drivers/net/nfp/nfp_net_flow.c
 create mode 100644 drivers/net/nfp/nfp_net_flow.h

-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 01/11] net/nfp: move some source files
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 02/11] net/nfp: add the structures and functions for flow offload Chaoyong He
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Rename module 'nfp_flow' into 'nfp_flower_flow' and move the source
files into the 'flower' sub-directory.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/flower/nfp_conntrack.h                 |  2 +-
 drivers/net/nfp/flower/nfp_flower_cmsg.h               |  2 +-
 .../net/nfp/{nfp_flow.c => flower/nfp_flower_flow.c}   |  4 ++--
 .../net/nfp/{nfp_flow.h => flower/nfp_flower_flow.h}   | 10 +++++-----
 drivers/net/nfp/flower/nfp_flower_representor.c        |  2 +-
 drivers/net/nfp/meson.build                            |  2 +-
 6 files changed, 11 insertions(+), 11 deletions(-)
 rename drivers/net/nfp/{nfp_flow.c => flower/nfp_flower_flow.c} (99%)
 rename drivers/net/nfp/{nfp_flow.h => flower/nfp_flower_flow.h} (96%)

diff --git a/drivers/net/nfp/flower/nfp_conntrack.h b/drivers/net/nfp/flower/nfp_conntrack.h
index 5abab4e984..9bfca236ed 100644
--- a/drivers/net/nfp/flower/nfp_conntrack.h
+++ b/drivers/net/nfp/flower/nfp_conntrack.h
@@ -11,7 +11,7 @@
 #include <ethdev_driver.h>
 #include <rte_flow.h>
 
-#include "../nfp_flow.h"
+#include "nfp_flower_flow.h"
 
 struct nfp_ct_map_entry;
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index c2938fb6f6..45543816ae 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -6,8 +6,8 @@
 #ifndef __NFP_CMSG_H__
 #define __NFP_CMSG_H__
 
-#include "../nfp_flow.h"
 #include "nfp_flower.h"
+#include "nfp_flower_flow.h"
 
 struct nfp_flower_cmsg_hdr {
 	rte_be16_t pad;
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/flower/nfp_flower_flow.c
similarity index 99%
rename from drivers/net/nfp/nfp_flow.c
rename to drivers/net/nfp/flower/nfp_flower_flow.c
index f832b52d89..e26be30d18 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/flower/nfp_flower_flow.c
@@ -3,7 +3,7 @@
  * All rights reserved.
  */
 
-#include "nfp_flow.h"
+#include "nfp_flower_flow.h"
 
 #include <rte_flow_driver.h>
 #include <rte_hash.h>
@@ -4318,7 +4318,7 @@ static const struct rte_flow_ops nfp_flow_ops = {
 };
 
 int
-nfp_net_flow_ops_get(struct rte_eth_dev *dev,
+nfp_flow_ops_get(struct rte_eth_dev *dev,
 		const struct rte_flow_ops **ops)
 {
 	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0) {
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/flower/nfp_flower_flow.h
similarity index 96%
rename from drivers/net/nfp/nfp_flow.h
rename to drivers/net/nfp/flower/nfp_flower_flow.h
index 09e5b30dd8..75f18c6bd5 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/flower/nfp_flower_flow.h
@@ -3,10 +3,10 @@
  * All rights reserved.
  */
 
-#ifndef __NFP_FLOW_H__
-#define __NFP_FLOW_H__
+#ifndef __NFP_FLOWER_FLOW_H__
+#define __NFP_FLOWER_FLOW_H__
 
-#include "nfp_net_common.h"
+#include "../nfp_net_common.h"
 
 /* The firmware expects lengths in units of long words */
 #define NFP_FL_LW_SIZ                   2
@@ -182,7 +182,7 @@ struct nfp_flower_representor;
 
 int nfp_flow_priv_init(struct nfp_pf_dev *pf_dev);
 void nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev);
-int nfp_net_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops);
+int nfp_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops);
 bool nfp_flow_inner_item_get(const struct rte_flow_item items[],
 		const struct rte_flow_item **inner_item);
 struct rte_flow *nfp_flow_process(struct nfp_flower_representor *representor,
@@ -202,4 +202,4 @@ int nfp_flow_destroy(struct rte_eth_dev *dev,
 		struct rte_flow *nfp_flow,
 		struct rte_flow_error *error);
 
-#endif /* __NFP_FLOW_H__ */
+#endif /* __NFP_FLOWER_FLOW_H__ */
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index 02089d390e..7d8c055b80 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -435,7 +435,7 @@ static const struct eth_dev_ops nfp_flower_repr_dev_ops = {
 	.mac_addr_set         = nfp_flower_repr_mac_addr_set,
 	.fw_version_get       = nfp_net_firmware_version_get,
 
-	.flow_ops_get         = nfp_net_flow_ops_get,
+	.flow_ops_get         = nfp_flow_ops_get,
 	.mtr_ops_get          = nfp_net_mtr_ops_get,
 };
 
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index cf9c16266d..8407073af8 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -11,6 +11,7 @@ sources = files(
         'flower/nfp_flower.c',
         'flower/nfp_flower_cmsg.c',
         'flower/nfp_flower_ctrl.c',
+        'flower/nfp_flower_flow.c',
         'flower/nfp_flower_representor.c',
         'nfd3/nfp_nfd3_dp.c',
         'nfdk/nfp_nfdk_dp.c',
@@ -30,7 +31,6 @@ sources = files(
         'nfp_cpp_bridge.c',
         'nfp_ethdev.c',
         'nfp_ethdev_vf.c',
-        'nfp_flow.c',
         'nfp_ipsec.c',
         'nfp_logs.c',
         'nfp_mtr.c',
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 02/11] net/nfp: add the structures and functions for flow offload
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 01/11] net/nfp: move some source files Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 03/11] net/nfp: add the control message channel Chaoyong He
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the structures and functions to process flow table, which is used in
the rte_flow offload logics.
This module is used for the CoreNIC firmware.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/common/nfp/nfp_common_ctrl.h |   1 +
 drivers/net/nfp/meson.build          |   1 +
 drivers/net/nfp/nfp_ethdev.c         |  27 ++++-
 drivers/net/nfp/nfp_net_common.h     |  11 ++
 drivers/net/nfp/nfp_net_flow.c       | 166 +++++++++++++++++++++++++++
 drivers/net/nfp/nfp_net_flow.h       |  28 +++++
 6 files changed, 228 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/nfp/nfp_net_flow.c
 create mode 100644 drivers/net/nfp/nfp_net_flow.h

diff --git a/drivers/common/nfp/nfp_common_ctrl.h b/drivers/common/nfp/nfp_common_ctrl.h
index d09fd2b892..cbde987736 100644
--- a/drivers/common/nfp/nfp_common_ctrl.h
+++ b/drivers/common/nfp/nfp_common_ctrl.h
@@ -223,6 +223,7 @@ struct nfp_net_fw_ver {
 #define NFP_NET_CFG_CTRL_IPSEC_SM_LOOKUP  (0x1 << 3) /**< SA short match lookup */
 #define NFP_NET_CFG_CTRL_IPSEC_LM_LOOKUP  (0x1 << 4) /**< SA long match lookup */
 #define NFP_NET_CFG_CTRL_MULTI_PF         (0x1 << 5)
+#define NFP_NET_CFG_CTRL_FLOW_STEER       (0x1 << 8) /**< Flow Steering */
 #define NFP_NET_CFG_CTRL_IN_ORDER         (0x1 << 11) /**< Virtio in-order flag */
 
 #define NFP_NET_CFG_CAP_WORD1           0x00a4
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 8407073af8..0d0a0bd8f4 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -36,6 +36,7 @@ sources = files(
         'nfp_mtr.c',
         'nfp_net_common.c',
         'nfp_net_ctrl.c',
+        'nfp_net_flow.c',
         'nfp_rxtx.c',
 )
 
diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index 537b4fe792..d0a1950ff3 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -23,6 +23,7 @@
 #include "nfp_cpp_bridge.h"
 #include "nfp_ipsec.h"
 #include "nfp_logs.h"
+#include "nfp_net_flow.h"
 
 #define NFP_PF_DRIVER_NAME net_nfp_pf
 
@@ -151,6 +152,10 @@ nfp_net_start(struct rte_eth_dev *dev)
 		ctrl_extend |= NFP_NET_CFG_CTRL_IPSEC_SM_LOOKUP
 				| NFP_NET_CFG_CTRL_IPSEC_LM_LOOKUP;
 
+	/* Enable flow steer by extend ctrl word1. */
+	if ((cap_extend & NFP_NET_CFG_CTRL_FLOW_STEER) != 0)
+		ctrl_extend |= NFP_NET_CFG_CTRL_FLOW_STEER;
+
 	update = NFP_NET_CFG_UPDATE_GEN;
 	if (nfp_ext_reconfig(hw, ctrl_extend, update) != 0)
 		return -EIO;
@@ -323,6 +328,10 @@ nfp_net_uninit(struct rte_eth_dev *eth_dev)
 	struct nfp_net_hw *net_hw;
 
 	net_hw = eth_dev->data->dev_private;
+
+	if ((net_hw->super.cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER) != 0)
+		nfp_net_flow_priv_uninit(net_hw->pf_dev, net_hw->idx);
+
 	rte_free(net_hw->eth_xstats_base);
 	nfp_ipsec_uninit(eth_dev);
 	if (net_hw->mac_stats_area != NULL)
@@ -762,6 +771,14 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
 	/* Recording current stats counters values */
 	nfp_net_stats_reset(eth_dev);
 
+	if ((hw->cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER) != 0) {
+		err = nfp_net_flow_priv_init(pf_dev, port);
+		if (err != 0) {
+			PMD_INIT_LOG(ERR, "Init net flow priv failed");
+			goto xstats_free;
+		}
+	}
+
 	return 0;
 
 xstats_free:
@@ -1195,13 +1212,11 @@ nfp_init_app_fw_nic(struct nfp_pf_dev *pf_dev,
 port_cleanup:
 	for (i = 0; i < app_fw_nic->total_phyports; i++) {
 		id = nfp_function_id_get(pf_dev, i);
+		hw = app_fw_nic->ports[id];
 
-		if (app_fw_nic->ports[id] != NULL &&
-				app_fw_nic->ports[id]->eth_dev != NULL) {
-			struct rte_eth_dev *tmp_dev;
-			tmp_dev = app_fw_nic->ports[id]->eth_dev;
-			nfp_net_uninit(tmp_dev);
-			rte_eth_dev_release_port(tmp_dev);
+		if (hw != NULL && hw->eth_dev != NULL) {
+			nfp_net_uninit(hw->eth_dev);
+			rte_eth_dev_release_port(hw->eth_dev);
 		}
 	}
 	nfp_cpp_area_release_free(pf_dev->ctrl_area);
diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h
index ded491cbdc..eb668a1505 100644
--- a/drivers/net/nfp/nfp_net_common.h
+++ b/drivers/net/nfp/nfp_net_common.h
@@ -108,6 +108,14 @@ struct nfp_pf_dev {
 	struct nfp_multi_pf multi_pf;
 };
 
+#define NFP_NET_FLOW_LIMIT    1024
+
+struct nfp_net_priv {
+	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
+	struct rte_hash *flow_table; /**< Hash table to store flow rules. */
+	uint16_t flow_count; /**< Flow count in hash table */
+};
+
 struct nfp_app_fw_nic {
 	/** Backpointer to the PF device */
 	struct nfp_pf_dev *pf_dev;
@@ -177,6 +185,9 @@ struct nfp_net_hw {
 	struct nfp_net_tlv_caps tlv_caps;
 
 	struct nfp_net_ipsec_data *ipsec_data;
+
+	/** Used for rte_flow of CoreNIC firmware */
+	struct nfp_net_priv *priv;
 };
 
 static inline uint32_t
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
new file mode 100644
index 0000000000..25da9ed8ac
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -0,0 +1,166 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include "nfp_net_flow.h"
+
+#include <rte_flow_driver.h>
+#include <rte_hash.h>
+#include <rte_jhash.h>
+#include <rte_malloc.h>
+
+#include "nfp_logs.h"
+
+__rte_unused static int
+nfp_net_flow_table_add(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+
+	ret = rte_hash_add_key_data(priv->flow_table, &nfp_flow->hash_key, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Add to flow table failed.");
+		return ret;
+	}
+
+	return 0;
+}
+
+__rte_unused static int
+nfp_net_flow_table_delete(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+
+	ret = rte_hash_del_key(priv->flow_table, &nfp_flow->hash_key);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Delete from flow table failed.");
+		return ret;
+	}
+
+	return 0;
+}
+
+__rte_unused static struct rte_flow *
+nfp_net_flow_table_search(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int index;
+	struct rte_flow *flow_find;
+
+	index = rte_hash_lookup_data(priv->flow_table, &nfp_flow->hash_key,
+			(void **)&flow_find);
+	if (index < 0) {
+		PMD_DRV_LOG(DEBUG, "Data NOT found in the flow table.");
+		return NULL;
+	}
+
+	return flow_find;
+}
+
+__rte_unused static struct rte_flow *
+nfp_net_flow_alloc(uint32_t match_len,
+		uint32_t action_len,
+		uint32_t port_id)
+{
+	char *data;
+	struct rte_flow *nfp_flow;
+	struct nfp_net_flow_payload *payload;
+
+	nfp_flow = rte_zmalloc("nfp_flow", sizeof(struct rte_flow), 0);
+	if (nfp_flow == NULL)
+		return NULL;
+
+	data = rte_zmalloc("nfp_flow_payload", match_len + action_len, 0);
+	if (data == NULL)
+		goto free_flow;
+
+	nfp_flow->port_id      = port_id;
+	payload                = &nfp_flow->payload;
+	payload->match_len     = match_len;
+	payload->action_len    = action_len;
+	payload->match_data    = data;
+	payload->action_data   = data + match_len;
+
+	return nfp_flow;
+
+free_flow:
+	rte_free(nfp_flow);
+
+	return NULL;
+}
+
+__rte_unused static void
+nfp_net_flow_free(struct rte_flow *nfp_flow)
+{
+	rte_free(nfp_flow->payload.match_data);
+	rte_free(nfp_flow);
+}
+
+int
+nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev,
+		uint16_t port)
+{
+	int ret = 0;
+	struct nfp_net_priv *priv;
+	char flow_name[RTE_HASH_NAMESIZE];
+	struct nfp_app_fw_nic *app_fw_nic;
+	const char *pci_name = strchr(pf_dev->pci_dev->name, ':') + 1;
+
+	snprintf(flow_name, sizeof(flow_name), "%s_fl_%u", pci_name, port);
+
+	struct rte_hash_parameters flow_hash_params = {
+		.name       = flow_name,
+		.entries    = NFP_NET_FLOW_LIMIT,
+		.hash_func  = rte_jhash,
+		.socket_id  = rte_socket_id(),
+		.key_len    = sizeof(uint32_t),
+		.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,
+	};
+
+	priv = rte_zmalloc("nfp_app_nic_priv", sizeof(struct nfp_net_priv), 0);
+	if (priv == NULL) {
+		PMD_INIT_LOG(ERR, "NFP app nic priv creation failed");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(pf_dev->app_fw_priv);
+	app_fw_nic->ports[port]->priv = priv;
+	priv->hash_seed = (uint32_t)rte_rand();
+
+	/* Flow table */
+	flow_hash_params.hash_func_init_val = priv->hash_seed;
+	priv->flow_table = rte_hash_create(&flow_hash_params);
+	if (priv->flow_table == NULL) {
+		PMD_INIT_LOG(ERR, "flow hash table creation failed");
+		ret = -ENOMEM;
+		goto free_priv;
+	}
+
+	return 0;
+
+free_priv:
+	rte_free(priv);
+exit:
+	return ret;
+}
+
+void
+nfp_net_flow_priv_uninit(struct nfp_pf_dev *pf_dev,
+		uint16_t port)
+{
+	struct nfp_net_priv *priv;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	if (pf_dev == NULL)
+		return;
+
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[port]->priv;
+	if (priv != NULL)
+		rte_hash_free(priv->flow_table);
+
+	rte_free(priv);
+}
diff --git a/drivers/net/nfp/nfp_net_flow.h b/drivers/net/nfp/nfp_net_flow.h
new file mode 100644
index 0000000000..5ec80ba3b6
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_flow.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef __NFP_NET_FLOW_H__
+#define __NFP_NET_FLOW_H__
+
+#include "nfp_net_common.h"
+
+struct nfp_net_flow_payload {
+	uint16_t cmsg_type;
+	uint8_t match_len;
+	uint8_t action_len;
+	char *match_data;
+	char *action_data;
+};
+
+struct rte_flow {
+	struct nfp_net_flow_payload payload;
+	uint32_t hash_key;
+	uint32_t port_id;
+};
+
+int nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev, uint16_t port);
+void nfp_net_flow_priv_uninit(struct nfp_pf_dev *pf_dev, uint16_t port);
+
+#endif /* __NFP_NET_FLOW_H__ */
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 03/11] net/nfp: add the control message channel
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 01/11] net/nfp: move some source files Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 02/11] net/nfp: add the structures and functions for flow offload Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-08 19:15     ` Ferruh Yigit
  2023-12-05  2:54   ` [PATCH v2 04/11] net/nfp: support flow API for CoreNIC firmware Chaoyong He
                     ` (8 subsequent siblings)
  11 siblings, 1 reply; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Using the mailbox, which serves as the control message channel
between driver and CoreNIC firmware.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/meson.build    |  1 +
 drivers/net/nfp/nfp_net_cmsg.c | 66 ++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_net_cmsg.h | 37 +++++++++++++++++++
 drivers/net/nfp/nfp_net_ctrl.h |  1 +
 4 files changed, 105 insertions(+)
 create mode 100644 drivers/net/nfp/nfp_net_cmsg.c
 create mode 100644 drivers/net/nfp/nfp_net_cmsg.h

diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 0d0a0bd8f4..46be6f60cd 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -34,6 +34,7 @@ sources = files(
         'nfp_ipsec.c',
         'nfp_logs.c',
         'nfp_mtr.c',
+        'nfp_net_cmsg.c',
         'nfp_net_common.c',
         'nfp_net_ctrl.c',
         'nfp_net_flow.c',
diff --git a/drivers/net/nfp/nfp_net_cmsg.c b/drivers/net/nfp/nfp_net_cmsg.c
new file mode 100644
index 0000000000..f2f694be0b
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_cmsg.c
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include "nfp_net_cmsg.h"
+
+#include <rte_malloc.h>
+
+#include "nfp_logs.h"
+
+struct nfp_net_cmsg *
+nfp_net_cmsg_alloc(uint32_t msg_size)
+{
+	struct nfp_net_cmsg *cmsg;
+
+	cmsg = rte_zmalloc(NULL, msg_size, 0);
+	if (cmsg == NULL) {
+		PMD_DRV_LOG(ERR, "Failed malloc memory.");
+		return NULL;
+	}
+
+	return cmsg;
+}
+
+void
+nfp_net_cmsg_free(struct nfp_net_cmsg *cmsg)
+{
+	rte_free(cmsg);
+}
+
+int
+nfp_net_cmsg_xmit(struct nfp_net_hw *hw,
+		struct nfp_net_cmsg *cmsg,
+		uint32_t msg_size)
+{
+	int ret;
+	uint32_t i;
+
+	for (i = 0; i < msg_size; i++)
+		nn_cfg_writel(&hw->super, NFP_NET_CFG_MBOX_VAL + 4 * i, *((uint32_t *)cmsg + i));
+
+	ret = nfp_net_mbox_reconfig(hw, NFP_NET_CFG_MBOX_CMD_FLOW_STEER);
+	switch (ret) {
+	case NFP_NET_CFG_MBOX_RET_FS_OK:
+		break;
+	case NFP_NET_CFG_MBOX_RET_FS_ERR_NO_SPACE:
+		PMD_DRV_LOG(ERR, "Not enough space for cmd %u", cmsg->cmd);
+		ret = -ENOSPC;
+		break;
+	case NFP_NET_CFG_MBOX_RET_FS_ERR_MASK_FULL:
+		PMD_DRV_LOG(ERR, "The mask table is full for cmd %u", cmsg->cmd);
+		ret = -EXFULL;
+		break;
+	case NFP_NET_CFG_MBOX_RET_FS_ERR_CMD_INVALID:
+		PMD_DRV_LOG(ERR, "The mbox cmd %u invalid", cmsg->cmd);
+		ret = -EINVAL;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unrecognized mbox cmd %u", cmsg->cmd);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
new file mode 100644
index 0000000000..15e0bb60d8
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef __NFP_NET_CMSG_H__
+#define __NFP_NET_CMSG_H__
+
+#include "nfp_net_common.h"
+
+enum nfp_net_cfg_mbox_cmd {
+	NFP_NET_CFG_MBOX_CMD_FS_ADD_V4,       /* Add Flow Steer rule for V4 table */
+	NFP_NET_CFG_MBOX_CMD_FS_DEL_V4,       /* Delete Flow Steer rule for V4 table */
+	NFP_NET_CFG_MBOX_CMD_FS_ADD_V6,       /* Add Flow Steer rule for V4 table */
+	NFP_NET_CFG_MBOX_CMD_FS_DEL_V6,       /* Delete Flow Steer rule for V4 table */
+	NFP_NET_CFG_MBOX_CMD_FS_ADD_ETHTYPE,  /* Add Flow Steer rule for Ethtype table */
+	NFP_NET_CFG_MBOX_CMD_FS_DEL_ETHTYPE,  /* Delete Flow Steer rule for Ethtype table */
+};
+
+enum nfp_net_cfg_mbox_ret {
+	NFP_NET_CFG_MBOX_RET_FS_OK,               /* No error happen */
+	NFP_NET_CFG_MBOX_RET_FS_ERR_NO_SPACE,     /* Return error code no space */
+	NFP_NET_CFG_MBOX_RET_FS_ERR_MASK_FULL,    /* Return error code mask table full */
+	NFP_NET_CFG_MBOX_RET_FS_ERR_CMD_INVALID,  /* Return error code invalid cmd */
+};
+
+/* 4B cmd, and up to 500B data. */
+struct nfp_net_cmsg {
+	uint32_t cmd;     /**< One of nfp_net_cfg_mbox_cmd */
+	uint32_t data[0];
+};
+
+struct nfp_net_cmsg *nfp_net_cmsg_alloc(uint32_t msg_size);
+void nfp_net_cmsg_free(struct nfp_net_cmsg *cmsg);
+int nfp_net_cmsg_xmit(struct nfp_net_hw *hw, struct nfp_net_cmsg *cmsg, uint32_t msg_size);
+
+#endif /* __NFP_NET_CMSG_H__ */
diff --git a/drivers/net/nfp/nfp_net_ctrl.h b/drivers/net/nfp/nfp_net_ctrl.h
index ee1b784bb1..7ac0f89571 100644
--- a/drivers/net/nfp/nfp_net_ctrl.h
+++ b/drivers/net/nfp/nfp_net_ctrl.h
@@ -92,6 +92,7 @@
 #define NFP_NET_CFG_MBOX_SIMPLE_VAL           0x8
 
 #define NFP_NET_CFG_MBOX_CMD_IPSEC            3
+#define NFP_NET_CFG_MBOX_CMD_FLOW_STEER       10
 
 /*
  * TLV capabilities
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 04/11] net/nfp: support flow API for CoreNIC firmware
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (2 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 03/11] net/nfp: add the control message channel Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 05/11] net/nfp: support Ethernet flow item Chaoyong He
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the flow validate/create/destroy/flush API of nfp PMD with CoreNIC
firmware.

The flow create API construct a control cmsg and send it to
firmware, then add this flow to the hash table.

The flow destroy API construct a control cmsg and send it to
firmware, then delete this flow from the hash table.

The flow flush API just iterate the flows in hash table and
call the flow destroy API.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_ethdev.c     |   1 +
 drivers/net/nfp/nfp_net_cmsg.h   |  28 +++
 drivers/net/nfp/nfp_net_common.h |   1 +
 drivers/net/nfp/nfp_net_flow.c   | 409 ++++++++++++++++++++++++++++++-
 drivers/net/nfp/nfp_net_flow.h   |   2 +
 5 files changed, 434 insertions(+), 7 deletions(-)

diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index d0a1950ff3..336d18491e 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -604,6 +604,7 @@ static const struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.fw_version_get         = nfp_net_firmware_version_get,
 	.flow_ctrl_get          = nfp_net_flow_ctrl_get,
 	.flow_ctrl_set          = nfp_net_flow_ctrl_set,
+	.flow_ops_get           = nfp_net_flow_ops_get,
 };
 
 static inline void
diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index 15e0bb60d8..b526feaff2 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -8,6 +8,34 @@
 
 #include "nfp_net_common.h"
 
+#define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
+#define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
+#define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
+
+/**
+ * Action data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-------------------------------+-------------------------------+
+ *    0  |                 |    Queue    |              Actions          |
+ *       +-----------------+-------------+-------------------------------+
+ *    1  |                         Mark ID                               |
+ *       +---------------------------------------------------------------+
+ *
+ * Queue – Queue ID, 7 bits.
+ * Actions – An action bitmap, each bit represents an action type:
+ *       - Bit 0: Drop action. Drop the packet.
+ *       - Bit 1: Queue action. Use the queue specified by “Queue” field.
+ *                If not set, the queue is usually specified by RSS.
+ *       - Bit 2: Mark action. Mark packet with Mark ID.
+ */
+struct nfp_net_cmsg_action {
+	uint16_t action;
+	uint8_t queue;
+	uint8_t spare;
+	uint16_t mark_id;
+};
+
 enum nfp_net_cfg_mbox_cmd {
 	NFP_NET_CFG_MBOX_CMD_FS_ADD_V4,       /* Add Flow Steer rule for V4 table */
 	NFP_NET_CFG_MBOX_CMD_FS_DEL_V4,       /* Delete Flow Steer rule for V4 table */
diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h
index eb668a1505..305b221a15 100644
--- a/drivers/net/nfp/nfp_net_common.h
+++ b/drivers/net/nfp/nfp_net_common.h
@@ -114,6 +114,7 @@ struct nfp_net_priv {
 	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
 	struct rte_hash *flow_table; /**< Hash table to store flow rules. */
 	uint16_t flow_count; /**< Flow count in hash table */
+	bool flow_position[NFP_NET_FLOW_LIMIT]; /**< Flow position array */
 };
 
 struct nfp_app_fw_nic {
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 25da9ed8ac..658bdff1f9 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -11,8 +11,9 @@
 #include <rte_malloc.h>
 
 #include "nfp_logs.h"
+#include "nfp_net_cmsg.h"
 
-__rte_unused static int
+static int
 nfp_net_flow_table_add(struct nfp_net_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -27,7 +28,7 @@ nfp_net_flow_table_add(struct nfp_net_priv *priv,
 	return 0;
 }
 
-__rte_unused static int
+static int
 nfp_net_flow_table_delete(struct nfp_net_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -42,7 +43,7 @@ nfp_net_flow_table_delete(struct nfp_net_priv *priv,
 	return 0;
 }
 
-__rte_unused static struct rte_flow *
+static struct rte_flow *
 nfp_net_flow_table_search(struct nfp_net_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -59,11 +60,58 @@ nfp_net_flow_table_search(struct nfp_net_priv *priv,
 	return flow_find;
 }
 
-__rte_unused static struct rte_flow *
-nfp_net_flow_alloc(uint32_t match_len,
+static int
+nfp_net_flow_position_acquire(struct nfp_net_priv *priv,
+		uint32_t priority,
+		struct rte_flow *nfp_flow)
+{
+	uint32_t i;
+
+	if (priority != 0) {
+		i = NFP_NET_FLOW_LIMIT - priority - 1;
+
+		if (priv->flow_position[i]) {
+			PMD_DRV_LOG(ERR, "There is already a flow rule in this place.");
+			return -EAGAIN;
+		}
+
+		priv->flow_position[i] = true;
+		nfp_flow->position = priority;
+		return 0;
+	}
+
+	for (i = 0; i < NFP_NET_FLOW_LIMIT; i++) {
+		if (!priv->flow_position[i]) {
+			priv->flow_position[i] = true;
+			break;
+		}
+	}
+
+	if (i == NFP_NET_FLOW_LIMIT) {
+		PMD_DRV_LOG(ERR, "The limited flow number is reach.");
+		return -ERANGE;
+	}
+
+	nfp_flow->position = NFP_NET_FLOW_LIMIT - i - 1;
+
+	return 0;
+}
+
+static void
+nfp_net_flow_position_free(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	priv->flow_position[nfp_flow->position] = false;
+}
+
+static struct rte_flow *
+nfp_net_flow_alloc(struct nfp_net_priv *priv,
+		uint32_t priority,
+		uint32_t match_len,
 		uint32_t action_len,
 		uint32_t port_id)
 {
+	int ret;
 	char *data;
 	struct rte_flow *nfp_flow;
 	struct nfp_net_flow_payload *payload;
@@ -76,6 +124,10 @@ nfp_net_flow_alloc(uint32_t match_len,
 	if (data == NULL)
 		goto free_flow;
 
+	ret = nfp_net_flow_position_acquire(priv, priority, nfp_flow);
+	if (ret != 0)
+		goto free_payload;
+
 	nfp_flow->port_id      = port_id;
 	payload                = &nfp_flow->payload;
 	payload->match_len     = match_len;
@@ -85,19 +137,362 @@ nfp_net_flow_alloc(uint32_t match_len,
 
 	return nfp_flow;
 
+free_payload:
+	rte_free(data);
 free_flow:
 	rte_free(nfp_flow);
 
 	return NULL;
 }
 
-__rte_unused static void
-nfp_net_flow_free(struct rte_flow *nfp_flow)
+static void
+nfp_net_flow_free(struct nfp_net_priv *priv,
+		struct rte_flow *nfp_flow)
 {
+	nfp_net_flow_position_free(priv, nfp_flow);
 	rte_free(nfp_flow->payload.match_data);
 	rte_free(nfp_flow);
 }
 
+static int
+nfp_net_flow_calculate_items(const struct rte_flow_item items[],
+		uint32_t *match_len)
+{
+	const struct rte_flow_item *item;
+
+	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
+		switch (item->type) {
+		default:
+			PMD_DRV_LOG(ERR, "Can't calculate match length");
+			*match_len = 0;
+			return -ENOTSUP;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static void
+nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
+		uint32_t match_len)
+{
+	switch (match_len) {
+	default:
+		break;
+	}
+}
+
+static struct rte_flow *
+nfp_net_flow_setup(struct rte_eth_dev *dev,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		__rte_unused const struct rte_flow_action actions[])
+{
+	int ret;
+	char *hash_data;
+	uint32_t port_id;
+	uint32_t action_len;
+	struct nfp_net_hw *hw;
+	uint32_t match_len = 0;
+	struct nfp_net_priv *priv;
+	struct rte_flow *nfp_flow;
+	struct rte_flow *flow_find;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[hw->idx]->priv;
+
+	ret = nfp_net_flow_calculate_items(items, &match_len);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Key layers calculate failed.");
+		return NULL;
+	}
+
+	action_len = sizeof(struct nfp_net_cmsg_action);
+	port_id = ((struct nfp_net_hw *)dev->data->dev_private)->nfp_idx;
+
+	nfp_flow = nfp_net_flow_alloc(priv, attr->priority, match_len, action_len, port_id);
+	if (nfp_flow == NULL) {
+		PMD_DRV_LOG(ERR, "Alloc nfp flow failed.");
+		return NULL;
+	}
+
+	/* Calculate and store the hash_key for later use */
+	hash_data = nfp_flow->payload.match_data;
+	nfp_flow->hash_key = rte_jhash(hash_data, match_len + action_len,
+			priv->hash_seed);
+
+	/* Find the flow in hash table */
+	flow_find = nfp_net_flow_table_search(priv, nfp_flow);
+	if (flow_find != NULL) {
+		PMD_DRV_LOG(ERR, "This flow is already exist.");
+		goto free_flow;
+	}
+
+	priv->flow_count++;
+
+	nfp_net_flow_process_priority(nfp_flow, match_len);
+
+	return nfp_flow;
+
+free_flow:
+	nfp_net_flow_free(priv, nfp_flow);
+
+	return NULL;
+}
+
+static int
+nfp_net_flow_teardown(struct nfp_net_priv *priv,
+		__rte_unused struct rte_flow *nfp_flow)
+{
+	priv->flow_count--;
+
+	return 0;
+}
+
+static int
+nfp_net_flow_offload(struct nfp_net_hw *hw,
+		struct rte_flow *flow,
+		bool delete_flag)
+{
+	int ret;
+	char *tmp;
+	uint32_t msg_size;
+	struct nfp_net_cmsg *cmsg;
+
+	msg_size = sizeof(uint32_t) + flow->payload.match_len +
+			flow->payload.action_len;
+	cmsg = nfp_net_cmsg_alloc(msg_size);
+	if (cmsg == NULL) {
+		PMD_DRV_LOG(ERR, "Alloc cmsg failed.");
+		return -ENOMEM;
+	}
+
+	cmsg->cmd = flow->payload.cmsg_type;
+	if (delete_flag)
+		cmsg->cmd++;
+
+	tmp = (char *)cmsg->data;
+	rte_memcpy(tmp, flow->payload.match_data, flow->payload.match_len);
+	tmp += flow->payload.match_len;
+	rte_memcpy(tmp, flow->payload.action_data, flow->payload.action_len);
+
+	ret = nfp_net_cmsg_xmit(hw, cmsg, msg_size);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Send cmsg failed.");
+		ret = -EINVAL;
+		goto free_cmsg;
+	}
+
+free_cmsg:
+	nfp_net_cmsg_free(cmsg);
+
+	return ret;
+}
+
+static int
+nfp_net_flow_validate(struct rte_eth_dev *dev,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct nfp_net_hw *hw;
+	struct rte_flow *nfp_flow;
+	struct nfp_net_priv *priv;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[hw->idx]->priv;
+
+	nfp_flow = nfp_net_flow_setup(dev, attr, items, actions);
+	if (nfp_flow == NULL) {
+		return rte_flow_error_set(error, ENOTSUP,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "This flow can not be offloaded.");
+	}
+
+	ret = nfp_net_flow_teardown(priv, nfp_flow);
+	if (ret != 0) {
+		return rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow resource free failed.");
+	}
+
+	nfp_net_flow_free(priv, nfp_flow);
+
+	return 0;
+}
+
+static struct rte_flow *
+nfp_net_flow_create(struct rte_eth_dev *dev,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct nfp_net_hw *hw;
+	struct rte_flow *nfp_flow;
+	struct nfp_net_priv *priv;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[hw->idx]->priv;
+
+	nfp_flow = nfp_net_flow_setup(dev, attr, items, actions);
+	if (nfp_flow == NULL) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "This flow can not be offloaded.");
+		return NULL;
+	}
+
+	/* Add the flow to flow hash table */
+	ret = nfp_net_flow_table_add(priv, nfp_flow);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Add flow to the flow table failed.");
+		goto flow_teardown;
+	}
+
+	/* Add the flow to hardware */
+	ret = nfp_net_flow_offload(hw, nfp_flow, false);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Add flow to firmware failed.");
+		goto table_delete;
+	}
+
+	return nfp_flow;
+
+table_delete:
+	nfp_net_flow_table_delete(priv, nfp_flow);
+flow_teardown:
+	nfp_net_flow_teardown(priv, nfp_flow);
+	nfp_net_flow_free(priv, nfp_flow);
+
+	return NULL;
+}
+
+static int
+nfp_net_flow_destroy(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct nfp_net_hw *hw;
+	struct nfp_net_priv *priv;
+	struct rte_flow *flow_find;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	priv = app_fw_nic->ports[hw->idx]->priv;
+
+	/* Find the flow in flow hash table */
+	flow_find = nfp_net_flow_table_search(priv, nfp_flow);
+	if (flow_find == NULL) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow does not exist.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Delete the flow from hardware */
+	ret = nfp_net_flow_offload(hw, nfp_flow, true);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Delete flow from firmware failed.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Delete the flow from flow hash table */
+	ret = nfp_net_flow_table_delete(priv, nfp_flow);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Delete flow from the flow table failed.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = nfp_net_flow_teardown(priv, nfp_flow);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow teardown failed.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+exit:
+	nfp_net_flow_free(priv, nfp_flow);
+
+	return ret;
+}
+
+static int
+nfp_net_flow_flush(struct rte_eth_dev *dev,
+		struct rte_flow_error *error)
+{
+	int ret = 0;
+	void *next_data;
+	uint32_t iter = 0;
+	const void *next_key;
+	struct nfp_net_hw *hw;
+	struct rte_flow *nfp_flow;
+	struct rte_hash *flow_table;
+	struct nfp_app_fw_nic *app_fw_nic;
+
+	hw = dev->data->dev_private;
+	app_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);
+	flow_table = app_fw_nic->ports[hw->idx]->priv->flow_table;
+
+	while (rte_hash_iterate(flow_table, &next_key, &next_data, &iter) >= 0) {
+		nfp_flow = next_data;
+		ret = nfp_net_flow_destroy(dev, nfp_flow, error);
+		if (ret != 0)
+			break;
+	}
+
+	return ret;
+}
+
+static const struct rte_flow_ops nfp_net_flow_ops = {
+	.validate                = nfp_net_flow_validate,
+	.create                  = nfp_net_flow_create,
+	.destroy                 = nfp_net_flow_destroy,
+	.flush                   = nfp_net_flow_flush,
+};
+
+int
+nfp_net_flow_ops_get(struct rte_eth_dev *dev,
+		const struct rte_flow_ops **ops)
+{
+	struct nfp_net_hw *hw;
+
+	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {
+		*ops = NULL;
+		PMD_DRV_LOG(ERR, "Port is a representor.");
+		return -EINVAL;
+	}
+
+	hw = dev->data->dev_private;
+	if ((hw->super.ctrl_ext & NFP_NET_CFG_CTRL_FLOW_STEER) == 0) {
+		*ops = NULL;
+		return 0;
+	}
+
+	*ops = &nfp_net_flow_ops;
+
+	return 0;
+}
+
 int
 nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev,
 		uint16_t port)
diff --git a/drivers/net/nfp/nfp_net_flow.h b/drivers/net/nfp/nfp_net_flow.h
index 5ec80ba3b6..558cd0e2bb 100644
--- a/drivers/net/nfp/nfp_net_flow.h
+++ b/drivers/net/nfp/nfp_net_flow.h
@@ -20,9 +20,11 @@ struct rte_flow {
 	struct nfp_net_flow_payload payload;
 	uint32_t hash_key;
 	uint32_t port_id;
+	uint32_t position;    /**< Use as priority */
 };
 
 int nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev, uint16_t port);
 void nfp_net_flow_priv_uninit(struct nfp_pf_dev *pf_dev, uint16_t port);
+int nfp_net_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops);
 
 #endif /* __NFP_NET_FLOW_H__ */
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 05/11] net/nfp: support Ethernet flow item
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (3 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 04/11] net/nfp: support flow API for CoreNIC firmware Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 06/11] net/nfp: support drop flow action Chaoyong He
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding data structure and logics, to support the offload
of ethernet item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_cmsg.h |  13 +++
 drivers/net/nfp/nfp_net_flow.c | 169 +++++++++++++++++++++++++++++++++
 2 files changed, 182 insertions(+)

diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index b526feaff2..a95f4ef831 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -8,6 +8,19 @@
 
 #include "nfp_net_common.h"
 
+/**
+ * Match EtherType data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-------------------------------+-------------------------------+
+ *    0  |                               |            Ethtype            |
+ *       +-----------------+-------------+-------------------------------+
+ */
+struct nfp_net_cmsg_match_eth {
+	uint16_t ether_type;
+	uint16_t spare;
+};
+
 #define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
 #define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
 #define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 658bdff1f9..5b6c8553d8 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -13,6 +13,28 @@
 #include "nfp_logs.h"
 #include "nfp_net_cmsg.h"
 
+/* Static initializer for a list of subsequent item types */
+#define NEXT_ITEM(...) \
+	((const enum rte_flow_item_type []){ \
+		__VA_ARGS__, RTE_FLOW_ITEM_TYPE_END, \
+	})
+
+/* Process structure associated with a flow item */
+struct nfp_net_flow_item_proc {
+	/* Bit-mask for fields supported by this PMD. */
+	const void *mask_support;
+	/* Bit-mask to use when @p item->mask is not provided. */
+	const void *mask_default;
+	/* Size in bytes for @p mask_support and @p mask_default. */
+	const uint32_t mask_sz;
+	/* Merge a pattern item into a flow rule handle. */
+	int (*merge)(struct rte_flow *nfp_flow,
+			const struct rte_flow_item *item,
+			const struct nfp_net_flow_item_proc *proc);
+	/* List of possible subsequent items. */
+	const enum rte_flow_item_type *const next_item;
+};
+
 static int
 nfp_net_flow_table_add(struct nfp_net_priv *priv,
 		struct rte_flow *nfp_flow)
@@ -162,6 +184,10 @@ nfp_net_flow_calculate_items(const struct rte_flow_item items[],
 
 	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
 		switch (item->type) {
+		case RTE_FLOW_ITEM_TYPE_ETH:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_ETH detected");
+			*match_len = sizeof(struct nfp_net_cmsg_match_eth);
+			return 0;
 		default:
 			PMD_DRV_LOG(ERR, "Can't calculate match length");
 			*match_len = 0;
@@ -172,6 +198,143 @@ nfp_net_flow_calculate_items(const struct rte_flow_item items[],
 	return -EINVAL;
 }
 
+static int
+nfp_net_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,
+		const struct rte_flow_item *item,
+		__rte_unused const struct nfp_net_flow_item_proc *proc)
+{
+	struct nfp_net_cmsg_match_eth *eth;
+	const struct rte_flow_item_eth *spec;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(ERR, "NFP flow merge eth: no item->spec!");
+		return -EINVAL;
+	}
+
+	nfp_flow->payload.cmsg_type = NFP_NET_CFG_MBOX_CMD_FS_ADD_ETHTYPE;
+
+	eth = (struct nfp_net_cmsg_match_eth *)nfp_flow->payload.match_data;
+	eth->ether_type = rte_be_to_cpu_16(spec->type);
+
+	return 0;
+}
+
+/* Graph of supported items and associated process function */
+static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
+	[RTE_FLOW_ITEM_TYPE_END] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+	},
+	[RTE_FLOW_ITEM_TYPE_ETH] = {
+		.merge = nfp_net_flow_merge_eth,
+	},
+};
+
+static int
+nfp_net_flow_item_check(const struct rte_flow_item *item,
+		const struct nfp_net_flow_item_proc *proc)
+{
+	uint32_t i;
+	int ret = 0;
+	const uint8_t *mask;
+
+	/* item->last and item->mask cannot exist without item->spec. */
+	if (item->spec == NULL) {
+		if (item->mask || item->last) {
+			PMD_DRV_LOG(ERR, "'mask' or 'last' field provided"
+					" without a corresponding 'spec'.");
+			return -EINVAL;
+		}
+
+		/* No spec, no mask, no problem. */
+		return 0;
+	}
+
+	mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+	/*
+	 * Single-pass check to make sure that:
+	 * - Mask is supported, no bits are set outside proc->mask_support.
+	 * - Both item->spec and item->last are included in mask.
+	 */
+	for (i = 0; i != proc->mask_sz; ++i) {
+		if (mask[i] == 0)
+			continue;
+
+		if ((mask[i] | ((const uint8_t *)proc->mask_support)[i]) !=
+				((const uint8_t *)proc->mask_support)[i]) {
+			PMD_DRV_LOG(ERR, "Unsupported field found in 'mask'.");
+			ret = -EINVAL;
+			break;
+		}
+
+		if (item->last != NULL &&
+				(((const uint8_t *)item->spec)[i] & mask[i]) !=
+				(((const uint8_t *)item->last)[i] & mask[i])) {
+			PMD_DRV_LOG(ERR, "Range between 'spec' and 'last'"
+					" is larger than 'mask'.");
+			ret = -ERANGE;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int
+nfp_net_flow_compile_items(const struct rte_flow_item items[],
+		struct rte_flow *nfp_flow)
+{
+	uint32_t i;
+	int ret = 0;
+	const struct rte_flow_item *item;
+	const struct nfp_net_flow_item_proc *proc_list;
+
+	proc_list = nfp_net_flow_item_proc_list;
+
+	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
+		const struct nfp_net_flow_item_proc *proc = NULL;
+
+		for (i = 0; (proc_list->next_item != NULL) &&
+				(proc_list->next_item[i] != RTE_FLOW_ITEM_TYPE_END); ++i) {
+			if (proc_list->next_item[i] == item->type) {
+				proc = &nfp_net_flow_item_proc_list[item->type];
+				break;
+			}
+		}
+
+		if (proc == NULL) {
+			PMD_DRV_LOG(ERR, "No next item provided for %d", item->type);
+			ret = -ENOTSUP;
+			break;
+		}
+
+		/* Perform basic sanity checks */
+		ret = nfp_net_flow_item_check(item, proc);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "NFP flow item %d check failed", item->type);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (proc->merge == NULL) {
+			PMD_DRV_LOG(ERR, "NFP flow item %d no proc function", item->type);
+			ret = -ENOTSUP;
+			break;
+		}
+
+		ret = proc->merge(nfp_flow, item, proc);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "NFP flow item %d exact merge failed", item->type);
+			break;
+		}
+
+		proc_list = proc;
+	}
+
+	return ret;
+}
+
 static void
 nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
 		uint32_t match_len)
@@ -218,6 +381,12 @@ nfp_net_flow_setup(struct rte_eth_dev *dev,
 		return NULL;
 	}
 
+	ret = nfp_net_flow_compile_items(items, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "NFP flow item process failed.");
+		goto free_flow;
+	}
+
 	/* Calculate and store the hash_key for later use */
 	hash_data = nfp_flow->payload.match_data;
 	nfp_flow->hash_key = rte_jhash(hash_data, match_len + action_len,
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 06/11] net/nfp: support drop flow action
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (4 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 05/11] net/nfp: support Ethernet flow item Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 07/11] net/nfp: support IPv4 flow item Chaoyong He
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding logics to support the offload of drop action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_flow.c | 39 +++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 5b6c8553d8..c8b6902bf1 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -335,6 +335,37 @@ nfp_net_flow_compile_items(const struct rte_flow_item items[],
 	return ret;
 }
 
+static void
+nfp_net_flow_action_drop(struct rte_flow *nfp_flow)
+{
+	struct nfp_net_cmsg_action *action_data;
+
+	action_data = (struct nfp_net_cmsg_action *)nfp_flow->payload.action_data;
+
+	action_data->action = NFP_NET_CMSG_ACTION_DROP;
+}
+
+static int
+nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
+		struct rte_flow *nfp_flow)
+{
+	const struct rte_flow_action *action;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+		switch (action->type) {
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_DROP");
+			nfp_net_flow_action_drop(nfp_flow);
+			return 0;
+		default:
+			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
+			return -ENOTSUP;
+		}
+	}
+
+	return 0;
+}
+
 static void
 nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
 		uint32_t match_len)
@@ -349,7 +380,7 @@ static struct rte_flow *
 nfp_net_flow_setup(struct rte_eth_dev *dev,
 		const struct rte_flow_attr *attr,
 		const struct rte_flow_item items[],
-		__rte_unused const struct rte_flow_action actions[])
+		const struct rte_flow_action actions[])
 {
 	int ret;
 	char *hash_data;
@@ -387,6 +418,12 @@ nfp_net_flow_setup(struct rte_eth_dev *dev,
 		goto free_flow;
 	}
 
+	ret = nfp_net_flow_compile_actions(actions, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "NFP flow action process failed.");
+		goto free_flow;
+	}
+
 	/* Calculate and store the hash_key for later use */
 	hash_data = nfp_flow->payload.match_data;
 	nfp_flow->hash_key = rte_jhash(hash_data, match_len + action_len,
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 07/11] net/nfp: support IPv4 flow item
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (5 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 06/11] net/nfp: support drop flow action Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 08/11] net/nfp: support IPv6 " Chaoyong He
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding data structure and logics, to support the offload
of IPv4 item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_cmsg.h | 37 ++++++++++++++++++++++
 drivers/net/nfp/nfp_net_flow.c | 58 ++++++++++++++++++++++++++++++++--
 2 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index a95f4ef831..9bc064d9d7 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -21,6 +21,43 @@ struct nfp_net_cmsg_match_eth {
 	uint16_t spare;
 };
 
+/**
+ * Match IPv4 data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-----+-------------------------+---------------+---------------+
+ *    0  |     |        Position         |   L4 Proto    | L4 Proto Mask |
+ *       +-----+-------------------------+---------------+---------------+
+ *    1  |                             SIP4                              |
+ *       +---------------------------------------------------------------+
+ *    2  |                           SIP4 Mask                           |
+ *       +---------------------------------------------------------------+
+ *    3  |                             DIP4                              |
+ *       +---------------------------------------------------------------+
+ *    4  |                           DIP4 Mask                           |
+ *       +-------------------------------+-------------------------------+
+ *    5  |             SPort             |           SPort Mask          |
+ *       +-------------------------------+-------------------------------+
+ *    6  |             DPort             |           DPort Mask          |
+ *       +-----------------+-------------+-------------------------------+
+ *
+ * Position – Position index of the rule, 13bits.
+ *            As priority, smaller value indicates higher priority.
+ */
+struct nfp_net_cmsg_match_v4 {
+	uint8_t l4_protocol_mask;
+	uint8_t l4_protocol;
+	uint16_t position;
+	uint32_t src_ipv4;
+	uint32_t src_ipv4_mask;
+	uint32_t dst_ipv4;
+	uint32_t dst_ipv4_mask;
+	uint16_t src_port;
+	uint16_t src_port_mask;
+	uint16_t dst_port;
+	uint16_t dst_port_mask;
+};
+
 #define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
 #define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
 #define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index c8b6902bf1..6edb96c17a 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -188,6 +188,10 @@ nfp_net_flow_calculate_items(const struct rte_flow_item items[],
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_ETH detected");
 			*match_len = sizeof(struct nfp_net_cmsg_match_eth);
 			return 0;
+		case RTE_FLOW_ITEM_TYPE_IPV4:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected");
+			*match_len = sizeof(struct nfp_net_cmsg_match_v4);
+			return 0;
 		default:
 			PMD_DRV_LOG(ERR, "Can't calculate match length");
 			*match_len = 0;
@@ -220,14 +224,58 @@ nfp_net_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,
 	return 0;
 }
 
+static int
+nfp_net_flow_merge_ipv4(struct rte_flow *nfp_flow,
+		const struct rte_flow_item *item,
+		const struct nfp_net_flow_item_proc *proc)
+{
+	struct nfp_net_cmsg_match_v4 *ipv4;
+	const struct rte_flow_item_ipv4 *mask;
+	const struct rte_flow_item_ipv4 *spec;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "NFP flow merge ipv4: no item->spec!");
+		return 0;
+	}
+
+	mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+	nfp_flow->payload.cmsg_type = NFP_NET_CFG_MBOX_CMD_FS_ADD_V4;
+	ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
+
+	ipv4->l4_protocol_mask = mask->hdr.next_proto_id;
+	ipv4->src_ipv4_mask    = rte_be_to_cpu_32(mask->hdr.src_addr);
+	ipv4->dst_ipv4_mask    = rte_be_to_cpu_32(mask->hdr.dst_addr);
+
+	ipv4->l4_protocol  = spec->hdr.next_proto_id;
+	ipv4->src_ipv4     = rte_be_to_cpu_32(spec->hdr.src_addr);
+	ipv4->dst_ipv4     = rte_be_to_cpu_32(spec->hdr.dst_addr);
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH,
+				RTE_FLOW_ITEM_TYPE_IPV4),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
 		.merge = nfp_net_flow_merge_eth,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.mask_support = &(const struct rte_flow_item_ipv4){
+			.hdr = {
+				.next_proto_id = 0xff,
+				.src_addr      = RTE_BE32(0xffffffff),
+				.dst_addr      = RTE_BE32(0xffffffff),
+			},
+		},
+		.mask_default = &rte_flow_item_ipv4_mask,
+		.mask_sz = sizeof(struct rte_flow_item_ipv4),
+		.merge = nfp_net_flow_merge_ipv4,
+	},
 };
 
 static int
@@ -367,10 +415,16 @@ nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 }
 
 static void
-nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
+nfp_net_flow_process_priority(struct rte_flow *nfp_flow,
 		uint32_t match_len)
 {
+	struct nfp_net_cmsg_match_v4 *ipv4;
+
 	switch (match_len) {
+	case sizeof(struct nfp_net_cmsg_match_v4):
+		ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
+		ipv4->position = nfp_flow->position;
+		break;
 	default:
 		break;
 	}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 08/11] net/nfp: support IPv6 flow item
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (6 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 07/11] net/nfp: support IPv4 flow item Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 09/11] net/nfp: support TCP/UDP/SCTP flow items Chaoyong He
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding data structure and logics, to support the offload
of IPv6 item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_cmsg.h | 61 +++++++++++++++++++++++++++
 drivers/net/nfp/nfp_net_flow.c | 76 +++++++++++++++++++++++++++++++++-
 2 files changed, 136 insertions(+), 1 deletion(-)

diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index 9bc064d9d7..e177ac7cd6 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -58,6 +58,67 @@ struct nfp_net_cmsg_match_v4 {
 	uint16_t dst_port_mask;
 };
 
+/**
+ * Match IPv6 data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-----+-------------------------+---------------+---------------+
+ *    0  |     |        Position         |   L4 Proto    | L4 Proto Mask |
+ *       +-----+-------------------------+---------------+---------------+
+ *    1  |                            SIP6 (0-3B)                        |
+ *       +---------------------------------------------------------------+
+ *    2  |                            SIP6 (4-7B)                        |
+ *       +---------------------------------------------------------------+
+ *    3  |                            SIP6 (8-11B)                       |
+ *       +---------------------------------------------------------------+
+ *    4  |                            SIP6 (12-15B)                      |
+ *       +---------------------------------------------------------------+
+ *    5  |                         SIP6 Mask (0-3B)                      |
+ *       +---------------------------------------------------------------+
+ *    6  |                         SIP6 Mask (4-7B)                      |
+ *       +---------------------------------------------------------------+
+ *    7  |                         SIP6 Mask (8-11B)                     |
+ *       +---------------------------------------------------------------+
+ *    8  |                         SIP6 Mask (12-15B)                    |
+ *       +---------------------------------------------------------------+
+ *    9  |                            DIP6 (0-3B)                        |
+ *       +---------------------------------------------------------------+
+ *    10 |                            DIP6 (4-7B)                        |
+ *       +---------------------------------------------------------------+
+ *    11 |                            DIP6 (8-11B)                       |
+ *       +---------------------------------------------------------------+
+ *    12 |                            DIP6 (12-15B)                      |
+ *       +---------------------------------------------------------------+
+ *    13 |                         DIP6 Mask (0-3B)                      |
+ *       +---------------------------------------------------------------+
+ *    14 |                         DIP6 Mask (4-7B)                      |
+ *       +---------------------------------------------------------------+
+ *    15 |                         DIP6 Mask (8-11B)                     |
+ *       +---------------------------------------------------------------+
+ *    16 |                         DIP6 Mask (12-15B)                    |
+ *       +-------------------------------+-------------------------------+
+ *    17 |             SPort             |           SPort Mask          |
+ *       +-------------------------------+-------------------------------+
+ *    18 |             DPort             |           DPort Mask          |
+ *       +-----------------+-------------+-------------------------------+
+ *
+ * Position – Position index of the rule, 13bits.
+ *            As priority, smaller value indicates higher priority.
+ */
+struct nfp_net_cmsg_match_v6 {
+	uint8_t l4_protocol_mask;
+	uint8_t l4_protocol;
+	uint16_t position;
+	uint8_t src_ipv6[16];
+	uint8_t src_ipv6_mask[16];
+	uint8_t dst_ipv6[16];
+	uint8_t dst_ipv6_mask[16];
+	uint16_t src_port_mask;
+	uint16_t src_port;
+	uint16_t dst_port_mask;
+	uint16_t dst_port;
+};
+
 #define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
 #define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
 #define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 6edb96c17a..56846e3935 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -192,6 +192,10 @@ nfp_net_flow_calculate_items(const struct rte_flow_item items[],
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected");
 			*match_len = sizeof(struct nfp_net_cmsg_match_v4);
 			return 0;
+		case RTE_FLOW_ITEM_TYPE_IPV6:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV6 detected");
+			*match_len = sizeof(struct nfp_net_cmsg_match_v6);
+			return 0;
 		default:
 			PMD_DRV_LOG(ERR, "Can't calculate match length");
 			*match_len = 0;
@@ -255,11 +259,62 @@ nfp_net_flow_merge_ipv4(struct rte_flow *nfp_flow,
 	return 0;
 }
 
+static int
+nfp_net_flow_merge_ipv6(struct rte_flow *nfp_flow,
+		const struct rte_flow_item *item,
+		const struct nfp_net_flow_item_proc *proc)
+{
+	uint32_t i;
+	struct nfp_net_cmsg_match_v6 *ipv6;
+	const struct rte_flow_item_ipv6 *mask;
+	const struct rte_flow_item_ipv6 *spec;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "NFP flow merge ipv6: no item->spec!");
+		return 0;
+	}
+
+	mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+	nfp_flow->payload.cmsg_type = NFP_NET_CFG_MBOX_CMD_FS_ADD_V6;
+	ipv6 = (struct nfp_net_cmsg_match_v6 *)nfp_flow->payload.match_data;
+
+	ipv6->l4_protocol_mask = mask->hdr.proto;
+	for (i = 0; i < sizeof(ipv6->src_ipv6); i += 4) {
+		ipv6->src_ipv6_mask[i] = mask->hdr.src_addr[i + 3];
+		ipv6->src_ipv6_mask[i + 1] = mask->hdr.src_addr[i + 2];
+		ipv6->src_ipv6_mask[i + 2] = mask->hdr.src_addr[i + 1];
+		ipv6->src_ipv6_mask[i + 3] = mask->hdr.src_addr[i];
+
+		ipv6->dst_ipv6_mask[i] = mask->hdr.dst_addr[i + 3];
+		ipv6->dst_ipv6_mask[i + 1] = mask->hdr.dst_addr[i + 2];
+		ipv6->dst_ipv6_mask[i + 2] = mask->hdr.dst_addr[i + 1];
+		ipv6->dst_ipv6_mask[i + 3] = mask->hdr.dst_addr[i];
+	}
+
+	ipv6->l4_protocol = spec->hdr.proto;
+	for (i = 0; i < sizeof(ipv6->src_ipv6); i += 4) {
+		ipv6->src_ipv6[i] = spec->hdr.src_addr[i + 3];
+		ipv6->src_ipv6[i + 1] = spec->hdr.src_addr[i + 2];
+		ipv6->src_ipv6[i + 2] = spec->hdr.src_addr[i + 1];
+		ipv6->src_ipv6[i + 3] = spec->hdr.src_addr[i];
+
+		ipv6->dst_ipv6[i] = spec->hdr.dst_addr[i + 3];
+		ipv6->dst_ipv6[i + 1] = spec->hdr.dst_addr[i + 2];
+		ipv6->dst_ipv6[i + 2] = spec->hdr.dst_addr[i + 1];
+		ipv6->dst_ipv6[i + 3] = spec->hdr.dst_addr[i];
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH,
-				RTE_FLOW_ITEM_TYPE_IPV4),
+				RTE_FLOW_ITEM_TYPE_IPV4,
+				RTE_FLOW_ITEM_TYPE_IPV6),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
 		.merge = nfp_net_flow_merge_eth,
@@ -276,6 +331,20 @@ static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 		.mask_sz = sizeof(struct rte_flow_item_ipv4),
 		.merge = nfp_net_flow_merge_ipv4,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.mask_support = &(const struct rte_flow_item_ipv6){
+			.hdr = {
+				.proto    = 0xff,
+				.src_addr = "\xff\xff\xff\xff\xff\xff\xff\xff"
+						"\xff\xff\xff\xff\xff\xff\xff\xff",
+				.dst_addr = "\xff\xff\xff\xff\xff\xff\xff\xff"
+						"\xff\xff\xff\xff\xff\xff\xff\xff",
+			},
+		},
+		.mask_default = &rte_flow_item_ipv6_mask,
+		.mask_sz = sizeof(struct rte_flow_item_ipv6),
+		.merge = nfp_net_flow_merge_ipv6,
+	},
 };
 
 static int
@@ -419,12 +488,17 @@ nfp_net_flow_process_priority(struct rte_flow *nfp_flow,
 		uint32_t match_len)
 {
 	struct nfp_net_cmsg_match_v4 *ipv4;
+	struct nfp_net_cmsg_match_v6 *ipv6;
 
 	switch (match_len) {
 	case sizeof(struct nfp_net_cmsg_match_v4):
 		ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
 		ipv4->position = nfp_flow->position;
 		break;
+	case sizeof(struct nfp_net_cmsg_match_v6):
+		ipv6 = (struct nfp_net_cmsg_match_v6 *)nfp_flow->payload.match_data;
+		ipv6->position = nfp_flow->position;
+		break;
 	default:
 		break;
 	}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 09/11] net/nfp: support TCP/UDP/SCTP flow items
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (7 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 08/11] net/nfp: support IPv6 " Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 10/11] net/nfp: support MARK flow action Chaoyong He
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding logics to support the offload of TCP/UDP/SCTP
items.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_net_flow.c | 86 ++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 56846e3935..f561e9ecbe 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -309,6 +309,53 @@ nfp_net_flow_merge_ipv6(struct rte_flow *nfp_flow,
 	return 0;
 }
 
+static int
+nfp_flow_merge_l4(struct rte_flow *nfp_flow,
+		const struct rte_flow_item *item,
+		const struct nfp_net_flow_item_proc *proc)
+{
+	const struct rte_flow_item_tcp *mask;
+	const struct rte_flow_item_tcp *spec;
+	struct nfp_net_cmsg_match_v4 *ipv4 = NULL;
+	struct nfp_net_cmsg_match_v6 *ipv6 = NULL;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(ERR, "NFP flow merge tcp: no item->spec!");
+		return -EINVAL;
+	}
+
+	mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+	switch (nfp_flow->payload.cmsg_type) {
+	case NFP_NET_CFG_MBOX_CMD_FS_ADD_V4:
+		ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
+		break;
+	case NFP_NET_CFG_MBOX_CMD_FS_ADD_V6:
+		ipv6 = (struct nfp_net_cmsg_match_v6 *)nfp_flow->payload.match_data;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "L3 layer neither IPv4 nor IPv6.");
+		return -EINVAL;
+	}
+
+	if (ipv4 != NULL) {
+		ipv4->src_port_mask = rte_be_to_cpu_16(mask->hdr.src_port);
+		ipv4->dst_port_mask = rte_be_to_cpu_16(mask->hdr.dst_port);
+
+		ipv4->src_port = rte_be_to_cpu_16(spec->hdr.src_port);
+		ipv4->dst_port = rte_be_to_cpu_16(spec->hdr.dst_port);
+	} else {
+		ipv6->src_port_mask = rte_be_to_cpu_16(mask->hdr.src_port);
+		ipv6->dst_port_mask = rte_be_to_cpu_16(mask->hdr.dst_port);
+
+		ipv6->src_port = rte_be_to_cpu_16(spec->hdr.src_port);
+		ipv6->dst_port = rte_be_to_cpu_16(spec->hdr.dst_port);
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -320,6 +367,9 @@ static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 		.merge = nfp_net_flow_merge_eth,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+				RTE_FLOW_ITEM_TYPE_UDP,
+				RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.next_proto_id = 0xff,
@@ -332,6 +382,9 @@ static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 		.merge = nfp_net_flow_merge_ipv4,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+				RTE_FLOW_ITEM_TYPE_UDP,
+				RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.proto    = 0xff,
@@ -345,6 +398,39 @@ static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
 		.mask_sz = sizeof(struct rte_flow_item_ipv6),
 		.merge = nfp_net_flow_merge_ipv6,
 	},
+	[RTE_FLOW_ITEM_TYPE_TCP] = {
+		.mask_support = &(const struct rte_flow_item_tcp){
+			.hdr = {
+				.src_port  = RTE_BE16(0xffff),
+				.dst_port  = RTE_BE16(0xffff),
+			},
+		},
+		.mask_default = &rte_flow_item_tcp_mask,
+		.mask_sz = sizeof(struct rte_flow_item_tcp),
+		.merge = nfp_flow_merge_l4,
+	},
+	[RTE_FLOW_ITEM_TYPE_UDP] = {
+		.mask_support = &(const struct rte_flow_item_udp){
+			.hdr = {
+				.src_port = RTE_BE16(0xffff),
+				.dst_port = RTE_BE16(0xffff),
+			},
+		},
+		.mask_default = &rte_flow_item_udp_mask,
+		.mask_sz = sizeof(struct rte_flow_item_udp),
+		.merge = nfp_flow_merge_l4,
+	},
+	[RTE_FLOW_ITEM_TYPE_SCTP] = {
+		.mask_support = &(const struct rte_flow_item_sctp){
+			.hdr = {
+				.src_port  = RTE_BE16(0xffff),
+				.dst_port  = RTE_BE16(0xffff),
+			},
+		},
+		.mask_default = &rte_flow_item_sctp_mask,
+		.mask_sz = sizeof(struct rte_flow_item_sctp),
+		.merge = nfp_flow_merge_l4,
+	},
 };
 
 static int
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 10/11] net/nfp: support MARK flow action
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (8 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 09/11] net/nfp: support TCP/UDP/SCTP flow items Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-05  2:54   ` [PATCH v2 11/11] net/nfp: support QUEUE " Chaoyong He
  2023-12-08 16:39   ` [PATCH v2 00/11] Add basic flow support for corenic firmware Ferruh Yigit
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding logics to support the offload of MARK action.
Also add the related logics to parse the mark id and put into the mbuf
structure, and assigned the offload flags.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 doc/guides/nics/features/nfp.ini     |  1 +
 drivers/common/nfp/nfp_common_ctrl.h |  1 +
 drivers/net/nfp/nfp_net_flow.c       | 18 ++++++++++++++++++
 drivers/net/nfp/nfp_rxtx.c           | 18 ++++++++++++++++++
 4 files changed, 38 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 1a09c4cbaf..248fd34a39 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -48,6 +48,7 @@ conntrack            = Y
 count                = Y
 drop                 = Y
 jump                 = Y
+mark                 = Y
 meter                = Y
 of_pop_vlan          = Y
 of_push_vlan         = Y
diff --git a/drivers/common/nfp/nfp_common_ctrl.h b/drivers/common/nfp/nfp_common_ctrl.h
index cbde987736..d65fcd17cb 100644
--- a/drivers/common/nfp/nfp_common_ctrl.h
+++ b/drivers/common/nfp/nfp_common_ctrl.h
@@ -33,6 +33,7 @@
 
 /* Prepend field types */
 #define NFP_NET_META_HASH               1 /* Next field carries hash type */
+#define NFP_NET_META_MARK               2
 #define NFP_NET_META_VLAN               4
 #define NFP_NET_META_PORTID             5
 #define NFP_NET_META_IPSEC              9
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index f561e9ecbe..71f126156e 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -548,6 +548,20 @@ nfp_net_flow_action_drop(struct rte_flow *nfp_flow)
 	action_data->action = NFP_NET_CMSG_ACTION_DROP;
 }
 
+static void
+nfp_net_flow_action_mark(struct rte_flow *nfp_flow,
+		const struct rte_flow_action *action)
+{
+	struct nfp_net_cmsg_action *action_data;
+	const struct rte_flow_action_mark *mark;
+
+	action_data = (struct nfp_net_cmsg_action *)nfp_flow->payload.action_data;
+	mark = action->conf;
+
+	action_data->action |= NFP_NET_CMSG_ACTION_MARK;
+	action_data->mark_id = mark->id;
+}
+
 static int
 nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 		struct rte_flow *nfp_flow)
@@ -560,6 +574,10 @@ nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_DROP");
 			nfp_net_flow_action_drop(nfp_flow);
 			return 0;
+		case RTE_FLOW_ACTION_TYPE_MARK:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_MARK");
+			nfp_net_flow_action_mark(nfp_flow, action);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index f21e120a43..5094bbf145 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -25,6 +25,8 @@ struct nfp_meta_parsed {
 	uint32_t port_id;         /**< Port id value */
 	uint32_t sa_idx;          /**< IPsec SA index */
 	uint32_t hash;            /**< RSS hash value */
+	uint32_t mark_id;         /**< Mark id value */
+	uint16_t flags;           /**< Bitmap to indicate if meta exist */
 	uint8_t hash_type;        /**< RSS hash type */
 	uint8_t ipsec_type;       /**< IPsec type */
 	uint8_t vlan_layer;       /**< The valid number of value in @vlan[] */
@@ -290,6 +292,10 @@ nfp_net_parse_chained_meta(uint8_t *meta_base,
 			meta->sa_idx = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
 			meta->ipsec_type = meta_info & NFP_NET_META_FIELD_MASK;
 			break;
+		case NFP_NET_META_MARK:
+			meta->flags |= (1 << NFP_NET_META_MARK);
+			meta->mark_id = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
+			break;
 		default:
 			/* Unsupported metadata can be a performance issue */
 			return false;
@@ -434,6 +440,17 @@ nfp_net_parse_meta_ipsec(struct nfp_meta_parsed *meta,
 	}
 }
 
+static void
+nfp_net_parse_meta_mark(const struct nfp_meta_parsed *meta,
+		struct rte_mbuf *mbuf)
+{
+	if (((meta->flags >> NFP_NET_META_MARK) & 0x1) == 0)
+		return;
+
+	mbuf->hash.fdir.hi = meta->mark_id;
+	mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
+}
+
 /* Parse the metadata from packet */
 static void
 nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
@@ -458,6 +475,7 @@ nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
 			nfp_net_parse_meta_vlan(meta, rxds, rxq, mb);
 			nfp_net_parse_meta_qinq(meta, rxq, mb);
 			nfp_net_parse_meta_ipsec(meta, rxq, mb);
+			nfp_net_parse_meta_mark(meta, mb);
 		} else {
 			PMD_RX_LOG(DEBUG, "RX chained metadata format is wrong!");
 		}
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 11/11] net/nfp: support QUEUE flow action
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (9 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 10/11] net/nfp: support MARK flow action Chaoyong He
@ 2023-12-05  2:54   ` Chaoyong He
  2023-12-08 16:39   ` [PATCH v2 00/11] Add basic flow support for corenic firmware Ferruh Yigit
  11 siblings, 0 replies; 37+ messages in thread
From: Chaoyong He @ 2023-12-05  2:54 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang

Add the corresponding logics to support the offload of QUEUE action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_net_flow.c   | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 248fd34a39..df1d403c6e 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -54,6 +54,7 @@ of_pop_vlan          = Y
 of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
+queue                = Y
 raw_decap            = Y
 raw_encap            = Y
 represented_port     = Y
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 71f126156e..98e8499756 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -562,6 +562,20 @@ nfp_net_flow_action_mark(struct rte_flow *nfp_flow,
 	action_data->mark_id = mark->id;
 }
 
+static void
+nfp_net_flow_action_queue(struct rte_flow *nfp_flow,
+		const struct rte_flow_action *action)
+{
+	struct nfp_net_cmsg_action *action_data;
+	const struct rte_flow_action_queue *queue;
+
+	action_data = (struct nfp_net_cmsg_action *)nfp_flow->payload.action_data;
+	queue = action->conf;
+
+	action_data->action |= NFP_NET_CMSG_ACTION_QUEUE;
+	action_data->queue = queue->index;
+}
+
 static int
 nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 		struct rte_flow *nfp_flow)
@@ -578,6 +592,10 @@ nfp_net_flow_compile_actions(const struct rte_flow_action actions[],
 			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_MARK");
 			nfp_net_flow_action_mark(nfp_flow, action);
 			break;
+		case RTE_FLOW_ACTION_TYPE_QUEUE:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_QUEUE");
+			nfp_net_flow_action_queue(nfp_flow, action);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 00/11] Add basic flow support for corenic firmware
  2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
                     ` (10 preceding siblings ...)
  2023-12-05  2:54   ` [PATCH v2 11/11] net/nfp: support QUEUE " Chaoyong He
@ 2023-12-08 16:39   ` Ferruh Yigit
  2023-12-11  1:42     ` Chaoyong He
  11 siblings, 1 reply; 37+ messages in thread
From: Ferruh Yigit @ 2023-12-08 16:39 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers

On 12/5/2023 2:54 AM, Chaoyong He wrote:
> Add the very basic rte_flow support for corenic firmware.
> 
> ---
> v2:
> * Update the 'nfp.ini' document.
> * Rebase to the latest main branch.
> ---
> 
> Chaoyong He (11):
>   net/nfp: move some source files
>   net/nfp: add the structures and functions for flow offload
>   net/nfp: add the control message channel
>   net/nfp: support flow API for CoreNIC firmware
>   net/nfp: support Ethernet flow item
>   net/nfp: support drop flow action
>   net/nfp: support IPv4 flow item
>   net/nfp: support IPv6 flow item
>   net/nfp: support TCP/UDP/SCTP flow items
>   net/nfp: support MARK flow action
>   net/nfp: support QUEUE flow action
>

Series applied to dpdk-next-net/main, thanks.


Flower firmware already supports flow API, right?
What is the difference of these two firmware? Are they both actively used?

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 03/11] net/nfp: add the control message channel
  2023-12-05  2:54   ` [PATCH v2 03/11] net/nfp: add the control message channel Chaoyong He
@ 2023-12-08 19:15     ` Ferruh Yigit
  0 siblings, 0 replies; 37+ messages in thread
From: Ferruh Yigit @ 2023-12-08 19:15 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers, Long Wu, Peng Zhang, Stephen Hemminger

On 12/5/2023 2:54 AM, Chaoyong He wrote:
> diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
> new file mode 100644
> index 0000000000..15e0bb60d8
> --- /dev/null
> +++ b/drivers/net/nfp/nfp_net_cmsg.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright (c) 2023 Corigine, Inc.
> + * All rights reserved.
> + */
> +
> +#ifndef __NFP_NET_CMSG_H__
> +#define __NFP_NET_CMSG_H__
> +
> +#include "nfp_net_common.h"
> +
> +enum nfp_net_cfg_mbox_cmd {
> +	NFP_NET_CFG_MBOX_CMD_FS_ADD_V4,       /* Add Flow Steer rule for V4 table */
> +	NFP_NET_CFG_MBOX_CMD_FS_DEL_V4,       /* Delete Flow Steer rule for V4 table */
> +	NFP_NET_CFG_MBOX_CMD_FS_ADD_V6,       /* Add Flow Steer rule for V4 table */
> +	NFP_NET_CFG_MBOX_CMD_FS_DEL_V6,       /* Delete Flow Steer rule for V4 table */
> +	NFP_NET_CFG_MBOX_CMD_FS_ADD_ETHTYPE,  /* Add Flow Steer rule for Ethtype table */
> +	NFP_NET_CFG_MBOX_CMD_FS_DEL_ETHTYPE,  /* Delete Flow Steer rule for Ethtype table */
> +};
> +
> +enum nfp_net_cfg_mbox_ret {
> +	NFP_NET_CFG_MBOX_RET_FS_OK,               /* No error happen */
> +	NFP_NET_CFG_MBOX_RET_FS_ERR_NO_SPACE,     /* Return error code no space */
> +	NFP_NET_CFG_MBOX_RET_FS_ERR_MASK_FULL,    /* Return error code mask table full */
> +	NFP_NET_CFG_MBOX_RET_FS_ERR_CMD_INVALID,  /* Return error code invalid cmd */
> +};
> +
> +/* 4B cmd, and up to 500B data. */
> +struct nfp_net_cmsg {
> +	uint32_t cmd;     /**< One of nfp_net_cfg_mbox_cmd */
> +	uint32_t data[0];
> +};
> 
Converted 'data' to flex array, 'uint32_t data[];' while merging,

since there is already an effort to switch all zero length array to C99
standard flex array:
https://patchwork.dpdk.org/project/dpdk/list/?series=30410


^ permalink raw reply	[flat|nested] 37+ messages in thread

* RE: [PATCH v2 00/11] Add basic flow support for corenic firmware
  2023-12-08 16:39   ` [PATCH v2 00/11] Add basic flow support for corenic firmware Ferruh Yigit
@ 2023-12-11  1:42     ` Chaoyong He
  2023-12-11 14:06       ` Ferruh Yigit
  0 siblings, 1 reply; 37+ messages in thread
From: Chaoyong He @ 2023-12-11  1:42 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: oss-drivers

> On 12/5/2023 2:54 AM, Chaoyong He wrote:
> > Add the very basic rte_flow support for corenic firmware.
> >
> > ---
> > v2:
> > * Update the 'nfp.ini' document.
> > * Rebase to the latest main branch.
> > ---
> >
> > Chaoyong He (11):
> >   net/nfp: move some source files
> >   net/nfp: add the structures and functions for flow offload
> >   net/nfp: add the control message channel
> >   net/nfp: support flow API for CoreNIC firmware
> >   net/nfp: support Ethernet flow item
> >   net/nfp: support drop flow action
> >   net/nfp: support IPv4 flow item
> >   net/nfp: support IPv6 flow item
> >   net/nfp: support TCP/UDP/SCTP flow items
> >   net/nfp: support MARK flow action
> >   net/nfp: support QUEUE flow action
> >
> 
> Series applied to dpdk-next-net/main, thanks.
> 
> 
> Flower firmware already supports flow API, right?
Correct.

> What is the difference of these two firmware? Are they both actively used?
The flower firmware aims to support as much flow APIs (and match patterns/actions)as possible, 
and the corenic firmware will only support very limited ones (just enough) to some strict user case, like flow steering, 
bond offload ...

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 00/11] Add basic flow support for corenic firmware
  2023-12-11  1:42     ` Chaoyong He
@ 2023-12-11 14:06       ` Ferruh Yigit
  0 siblings, 0 replies; 37+ messages in thread
From: Ferruh Yigit @ 2023-12-11 14:06 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers

On 12/11/2023 1:42 AM, Chaoyong He wrote:
>> On 12/5/2023 2:54 AM, Chaoyong He wrote:
>>> Add the very basic rte_flow support for corenic firmware.
>>>
>>> ---
>>> v2:
>>> * Update the 'nfp.ini' document.
>>> * Rebase to the latest main branch.
>>> ---
>>>
>>> Chaoyong He (11):
>>>   net/nfp: move some source files
>>>   net/nfp: add the structures and functions for flow offload
>>>   net/nfp: add the control message channel
>>>   net/nfp: support flow API for CoreNIC firmware
>>>   net/nfp: support Ethernet flow item
>>>   net/nfp: support drop flow action
>>>   net/nfp: support IPv4 flow item
>>>   net/nfp: support IPv6 flow item
>>>   net/nfp: support TCP/UDP/SCTP flow items
>>>   net/nfp: support MARK flow action
>>>   net/nfp: support QUEUE flow action
>>>
>>
>> Series applied to dpdk-next-net/main, thanks.
>>
>>
>> Flower firmware already supports flow API, right?
> Correct.
> 
>> What is the difference of these two firmware? Are they both actively used?
> The flower firmware aims to support as much flow APIs (and match patterns/actions)as possible, 
> and the corenic firmware will only support very limited ones (just enough) to some strict user case, like flow steering, 
> bond offload ...
>

I see, thanks for the information.

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2023-12-11 14:06 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-03  6:25 [PATCH 00/11] Add basic flow support for corenic firmware Chaoyong He
2023-11-03  6:25 ` [PATCH 01/11] net/nfp: move some source files Chaoyong He
2023-11-03  6:25 ` [PATCH 02/11] drivers: add the structures and functions for flow offload Chaoyong He
2023-11-03  6:25 ` [PATCH 03/11] net/nfp: add the control message channel Chaoyong He
2023-11-03  6:25 ` [PATCH 04/11] net/nfp: support flow API for CoreNIC firmware Chaoyong He
2023-11-03  6:26 ` [PATCH 05/11] net/nfp: support Ethernet flow item Chaoyong He
2023-11-03  6:26 ` [PATCH 06/11] net/nfp: support drop flow action Chaoyong He
2023-11-03  6:26 ` [PATCH 07/11] net/nfp: support IPv4 flow item Chaoyong He
2023-11-03  6:26 ` [PATCH 08/11] net/nfp: support IPv6 " Chaoyong He
2023-11-03  6:26 ` [PATCH 09/11] net/nfp: support TCP/UDP/SCTP flow items Chaoyong He
2023-11-03  6:26 ` [PATCH 10/11] drivers: support MARK flow action Chaoyong He
2023-11-03  6:26 ` [PATCH 11/11] net/nfp: support QUEUE " Chaoyong He
2023-11-03 16:12 ` [PATCH 00/11] Add basic flow support for corenic firmware Ferruh Yigit
2023-11-07  1:42   ` Chaoyong He
2023-11-07  9:18     ` Ferruh Yigit
2023-11-07  9:23       ` Chaoyong He
2023-11-07 16:50         ` Patrick Robb
2023-11-07 17:04           ` Patrick Robb
2023-11-07 20:19             ` Ferruh Yigit
2023-11-07 21:59               ` Patrick Robb
2023-11-03 17:01 ` Ferruh Yigit
2023-12-05  2:54 ` [PATCH v2 " Chaoyong He
2023-12-05  2:54   ` [PATCH v2 01/11] net/nfp: move some source files Chaoyong He
2023-12-05  2:54   ` [PATCH v2 02/11] net/nfp: add the structures and functions for flow offload Chaoyong He
2023-12-05  2:54   ` [PATCH v2 03/11] net/nfp: add the control message channel Chaoyong He
2023-12-08 19:15     ` Ferruh Yigit
2023-12-05  2:54   ` [PATCH v2 04/11] net/nfp: support flow API for CoreNIC firmware Chaoyong He
2023-12-05  2:54   ` [PATCH v2 05/11] net/nfp: support Ethernet flow item Chaoyong He
2023-12-05  2:54   ` [PATCH v2 06/11] net/nfp: support drop flow action Chaoyong He
2023-12-05  2:54   ` [PATCH v2 07/11] net/nfp: support IPv4 flow item Chaoyong He
2023-12-05  2:54   ` [PATCH v2 08/11] net/nfp: support IPv6 " Chaoyong He
2023-12-05  2:54   ` [PATCH v2 09/11] net/nfp: support TCP/UDP/SCTP flow items Chaoyong He
2023-12-05  2:54   ` [PATCH v2 10/11] net/nfp: support MARK flow action Chaoyong He
2023-12-05  2:54   ` [PATCH v2 11/11] net/nfp: support QUEUE " Chaoyong He
2023-12-08 16:39   ` [PATCH v2 00/11] Add basic flow support for corenic firmware Ferruh Yigit
2023-12-11  1:42     ` Chaoyong He
2023-12-11 14:06       ` Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).