DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD
@ 2022-10-18 11:26 Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 01/25] net/nfp: fix the requirement of cpp bridge service Chaoyong He
                   ` (26 more replies)
  0 siblings, 27 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

This is the second patch series to add the support of rte_flow offload for
nfp PMD, includes:
Implement the rte_flow related API
Implement the offload framework of nfp card
Add the offload support of common rte_flow pattern items
Add the offload support of common rte_flow actions

* Changes since v2
- Change the release note.
- Change the headline of commit message.
- Adjust the order of commits to prevent the memory problem.

* Changes since v2
- Fix one problem import by the first patch series

* Changes since v1
- Add the 'Depends-on' tag

Chaoyong He (25):
  net/nfp: fix the requirement of cpp bridge service
  net/nfp: add the structures and functions for flow offload
  net/nfp: add the stats process logic in ctrl VNIC service
  net/nfp: add the flow APIs of nfp PMD
  net/nfp: support basic flow items
  net/nfp: support basic flow actions
  net/nfp: support VLAN flow item
  net/nfp: support IPv4 flow item
  net/nfp: support IPv6 flow item
  net/nfp: support TCP flow item
  net/nfp: support UDP flow item
  net/nfp: support SCTP flow item
  net/nfp: support SRC MAC flow action
  net/nfp: support DST MAC flow action
  net/nfp: support pop VLAN flow action
  net/nfp: support push VLAN flow action
  net/nfp: support SRC IPv4 flow action
  net/nfp: support DST IPv4 flow action
  net/nfp: support SRC IPv6 flow action
  net/nfp: support DST IPv6 flow action
  net/nfp: support TP SRC flow action
  net/nfp: support TP DST flow action
  net/nfp: support TTL flow action
  net/nfp: support IPv4 DSCP flow action
  net/nfp: support IPv6 DSCP flow action

 doc/guides/nics/features/nfp.ini                |   31 +
 doc/guides/rel_notes/release_22_11.rst          |    2 +
 drivers/net/nfp/flower/nfp_flower.c             |   11 +-
 drivers/net/nfp/flower/nfp_flower.h             |    2 +
 drivers/net/nfp/flower/nfp_flower_cmsg.c        |   69 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h        |  337 ++++
 drivers/net/nfp/flower/nfp_flower_ctrl.c        |   73 +-
 drivers/net/nfp/flower/nfp_flower_representor.c |    3 +
 drivers/net/nfp/meson.build                     |    3 +
 drivers/net/nfp/nfp_ethdev.c                    |    7 +-
 drivers/net/nfp/nfp_flow.c                      | 2294 +++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h                      |  175 ++
 12 files changed, 2997 insertions(+), 10 deletions(-)
 create mode 100644 drivers/net/nfp/nfp_flow.c
 create mode 100644 drivers/net/nfp/nfp_flow.h

-- 
1.8.3.1


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

* [PATCH v4 01/25] net/nfp: fix the requirement of cpp bridge service
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 12:39   ` Ferruh Yigit
  2022-10-18 11:26 ` [PATCH v4 02/25] net/nfp: add the structures and functions for flow offload Chaoyong He
                   ` (25 subsequent siblings)
  26 siblings, 1 reply; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

The cpp bridge service is needed for some debug tools, and should be
optional, so remove the mandatory requirement of service lcore parameter.

Fixes: b18804219537 ("net/nfp: add initial flower firmware support")

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/nfp_ethdev.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index f11a1b6..b105edb 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -1066,11 +1066,8 @@
 
 	/* register the CPP bridge service here for primary use */
 	ret = nfp_enable_cpp_service(pf_dev->cpp);
-	if (ret != 0) {
-		PMD_INIT_LOG(ERR, "Enable cpp service failed.");
-		ret = -EINVAL;
-		goto hwqueues_cleanup;
-	}
+	if (ret != 0)
+		PMD_INIT_LOG(INFO, "Enable cpp service failed.");
 
 	return 0;
 
-- 
1.8.3.1


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

* [PATCH v4 02/25] net/nfp: add the structures and functions for flow offload
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 01/25] net/nfp: fix the requirement of cpp bridge service Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 03/25] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the structures and functions to process mask table, flow
table, and flow stats id, which are used in the rte_flow
offload logics.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower.c |  11 +-
 drivers/net/nfp/flower/nfp_flower.h |   2 +
 drivers/net/nfp/meson.build         |   3 +
 drivers/net/nfp/nfp_flow.c          | 507 ++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h          | 101 +++++++
 5 files changed, 623 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/nfp/nfp_flow.c
 create mode 100644 drivers/net/nfp/nfp_flow.h

diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index 3e97f5c..168bf0c 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -15,6 +15,7 @@
 #include "../nfp_ctrl.h"
 #include "../nfp_cpp_bridge.h"
 #include "../nfp_rxtx.h"
+#include "../nfp_flow.h"
 #include "../nfpcore/nfp_mip.h"
 #include "../nfpcore/nfp_rtsym.h"
 #include "../nfpcore/nfp_nsp.h"
@@ -1089,13 +1090,19 @@
 
 	pf_dev->app_fw_priv = app_fw_flower;
 
+	ret = nfp_flow_priv_init(pf_dev);
+	if (ret != 0) {
+		PMD_INIT_LOG(ERR, "init flow priv failed");
+		goto app_cleanup;
+	}
+
 	/* Allocate memory for the PF AND ctrl vNIC here (hence the * 2) */
 	pf_hw = rte_zmalloc_socket("nfp_pf_vnic", 2 * sizeof(struct nfp_net_adapter),
 			RTE_CACHE_LINE_SIZE, numa_node);
 	if (pf_hw == NULL) {
 		PMD_INIT_LOG(ERR, "Could not malloc nfp pf vnic");
 		ret = -ENOMEM;
-		goto app_cleanup;
+		goto flow_priv_cleanup;
 	}
 
 	/* Map the PF ctrl bar */
@@ -1173,6 +1180,8 @@
 	nfp_cpp_area_free(pf_dev->ctrl_area);
 vnic_cleanup:
 	rte_free(pf_hw);
+flow_priv_cleanup:
+	nfp_flow_priv_uninit(pf_dev);
 app_cleanup:
 	rte_free(app_fw_flower);
 
diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index 48f597a..b90391c 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -51,6 +51,8 @@ struct nfp_app_fw_flower {
 
 	/* PF representor */
 	struct nfp_flower_representor *pf_repr;
+
+	struct nfp_flow_priv *flow_priv;
 };
 
 int nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev);
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 8a63979..7416fd3 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -27,4 +27,7 @@ sources = files(
         'nfp_cpp_bridge.c',
         'nfp_ethdev_vf.c',
         'nfp_ethdev.c',
+        'nfp_flow.c',
 )
+
+deps += ['hash']
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
new file mode 100644
index 0000000..97f5d1b
--- /dev/null
+++ b/drivers/net/nfp/nfp_flow.c
@@ -0,0 +1,507 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include <rte_flow_driver.h>
+#include <rte_hash.h>
+#include <rte_jhash.h>
+#include <bus_pci_driver.h>
+
+#include "nfp_common.h"
+#include "nfp_flow.h"
+#include "nfp_logs.h"
+#include "flower/nfp_flower.h"
+#include "nfpcore/nfp_mip.h"
+#include "nfpcore/nfp_rtsym.h"
+
+struct nfp_mask_id_entry {
+	uint32_t hash_key;
+	uint32_t ref_cnt;
+	uint8_t mask_id;
+};
+
+static int
+nfp_mask_id_alloc(struct nfp_flow_priv *priv, uint8_t *mask_id)
+{
+	uint8_t temp_id;
+	uint8_t freed_id;
+	struct circ_buf *ring;
+
+	/* Checking for unallocated entries first. */
+	if (priv->mask_ids.init_unallocated > 0) {
+		*mask_id = priv->mask_ids.init_unallocated;
+		priv->mask_ids.init_unallocated--;
+		return 0;
+	}
+
+	/* Checking if buffer is empty. */
+	freed_id = NFP_FLOWER_MASK_ENTRY_RS - 1;
+	ring = &priv->mask_ids.free_list;
+	if (ring->head == ring->tail) {
+		*mask_id = freed_id;
+		return -ENOENT;
+	}
+
+	rte_memcpy(&temp_id, &ring->buf[ring->tail], NFP_FLOWER_MASK_ELEMENT_RS);
+	*mask_id = temp_id;
+
+	rte_memcpy(&ring->buf[ring->tail], &freed_id, NFP_FLOWER_MASK_ELEMENT_RS);
+	ring->tail = (ring->tail + NFP_FLOWER_MASK_ELEMENT_RS) %
+			(NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS);
+
+	return 0;
+}
+
+static int
+nfp_mask_id_free(struct nfp_flow_priv *priv, uint8_t mask_id)
+{
+	struct circ_buf *ring;
+
+	ring = &priv->mask_ids.free_list;
+
+	/* Checking if buffer is full. */
+	if (CIRC_SPACE(ring->head, ring->tail, NFP_FLOWER_MASK_ENTRY_RS) == 0)
+		return -ENOBUFS;
+
+	rte_memcpy(&ring->buf[ring->head], &mask_id, NFP_FLOWER_MASK_ELEMENT_RS);
+	ring->head = (ring->head + NFP_FLOWER_MASK_ELEMENT_RS) %
+			(NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS);
+
+	return 0;
+}
+
+static int
+nfp_mask_table_add(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *id)
+{
+	int ret;
+	uint8_t mask_id;
+	uint32_t hash_key;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = rte_zmalloc("mask_entry", sizeof(struct nfp_mask_id_entry), 0);
+	if (mask_entry == NULL) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = nfp_mask_id_alloc(priv, &mask_id);
+	if (ret != 0)
+		goto mask_entry_free;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	mask_entry->mask_id  = mask_id;
+	mask_entry->hash_key = hash_key;
+	mask_entry->ref_cnt  = 1;
+	PMD_DRV_LOG(DEBUG, "hash_key=%#x id=%u ref=%u", hash_key,
+			mask_id, mask_entry->ref_cnt);
+
+	ret = rte_hash_add_key_data(priv->mask_table, &hash_key, mask_entry);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Add to mask table failed.");
+		goto mask_id_free;
+	}
+
+	*id = mask_id;
+	return 0;
+
+mask_id_free:
+	nfp_mask_id_free(priv, mask_id);
+mask_entry_free:
+	rte_free(mask_entry);
+exit:
+	return ret;
+}
+
+static int
+nfp_mask_table_del(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t id)
+{
+	int ret;
+	uint32_t hash_key;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	ret = rte_hash_del_key(priv->mask_table, &hash_key);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Delete from mask table failed.");
+		return ret;
+	}
+
+	ret = nfp_mask_id_free(priv, id);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Free mask id failed.");
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct nfp_mask_id_entry *
+nfp_mask_table_search(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len)
+{
+	int index;
+	uint32_t hash_key;
+	struct nfp_mask_id_entry *entry;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	index = rte_hash_lookup_data(priv->mask_table, &hash_key, (void **)&entry);
+	if (index < 0) {
+		PMD_DRV_LOG(DEBUG, "Data NOT found in the mask table.");
+		return NULL;
+	}
+
+	return entry;
+}
+
+__rte_unused static bool
+nfp_check_mask_add(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *meta_flags,
+		uint8_t *mask_id)
+{
+	int ret;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = nfp_mask_table_search(priv, mask_data, mask_len);
+	if (mask_entry == NULL) {
+		/* mask entry does not exist, let's create one */
+		ret = nfp_mask_table_add(priv, mask_data, mask_len, mask_id);
+		if (ret != 0)
+			return false;
+
+		*meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK;
+	} else {
+		/* mask entry already exist */
+		mask_entry->ref_cnt++;
+		*mask_id = mask_entry->mask_id;
+	}
+
+	return true;
+}
+
+__rte_unused static bool
+nfp_check_mask_remove(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *meta_flags)
+{
+	int ret;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = nfp_mask_table_search(priv, mask_data, mask_len);
+	if (mask_entry == NULL)
+		return false;
+
+	mask_entry->ref_cnt--;
+	if (mask_entry->ref_cnt == 0) {
+		ret = nfp_mask_table_del(priv, mask_data, mask_len,
+				mask_entry->mask_id);
+		if (ret != 0)
+			return false;
+
+		rte_free(mask_entry);
+		if (meta_flags)
+			*meta_flags &= ~NFP_FL_META_FLAG_MANAGE_MASK;
+	}
+
+	return true;
+}
+
+__rte_unused static int
+nfp_flow_table_add(struct nfp_flow_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+	char *hash_data;
+	uint32_t hash_key;
+
+	hash_data = (char *)(nfp_flow->payload.unmasked_data);
+	hash_key = rte_jhash(hash_data, nfp_flow->length, priv->hash_seed);
+	ret = rte_hash_add_key_data(priv->flow_table, &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_flow_table_delete(struct nfp_flow_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+	char *hash_data;
+	uint32_t hash_key;
+
+	hash_data = (char *)(nfp_flow->payload.unmasked_data);
+	hash_key = rte_jhash(hash_data, nfp_flow->length, priv->hash_seed);
+	ret = rte_hash_del_key(priv->flow_table, &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_flow_table_search(struct nfp_flow_priv *priv,
+		struct rte_flow *nfp_flow)
+{
+	int index;
+	char *hash_data;
+	uint32_t hash_key;
+	struct rte_flow *flow_find;
+
+	hash_data = (char *)(nfp_flow->payload.unmasked_data);
+	hash_key = rte_jhash(hash_data, nfp_flow->length, priv->hash_seed);
+	index = rte_hash_lookup_data(priv->flow_table, &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_flow_alloc(struct nfp_fl_key_ls *key_layer)
+{
+	char *tmp;
+	size_t len;
+	struct rte_flow *nfp_flow;
+	struct nfp_fl_payload *payload;
+
+	nfp_flow = rte_zmalloc("nfp_flow", sizeof(struct rte_flow), 0);
+	if (nfp_flow == NULL)
+		goto exit;
+
+	len = key_layer->key_size + key_layer->key_size + key_layer->act_size;
+	tmp = rte_zmalloc("nfp_flow_payload", len + sizeof(struct nfp_fl_rule_metadata), 0);
+	if (tmp == NULL)
+		goto free_flow;
+
+	nfp_flow->length = len;
+
+	payload                = &nfp_flow->payload;
+	payload->meta          = (struct nfp_fl_rule_metadata *)tmp;
+	payload->unmasked_data = tmp + sizeof(struct nfp_fl_rule_metadata);
+	payload->mask_data     = payload->unmasked_data + key_layer->key_size;
+	payload->action_data   = payload->mask_data + key_layer->key_size;
+
+	return nfp_flow;
+
+free_flow:
+	rte_free(nfp_flow);
+exit:
+	return NULL;
+}
+
+__rte_unused static void
+nfp_flow_free(struct rte_flow *nfp_flow)
+{
+	rte_free(nfp_flow->payload.meta);
+	rte_free(nfp_flow);
+}
+
+__rte_unused static int
+nfp_stats_id_alloc(struct nfp_flow_priv *priv, uint32_t *ctx)
+{
+	struct circ_buf *ring;
+	uint32_t freed_stats_id;
+	uint32_t temp_stats_id;
+
+	/* Check for unallocated entries first. */
+	if (priv->stats_ids.init_unallocated > 0) {
+		*ctx = ((priv->stats_ids.init_unallocated - 1) & NFP_FL_STAT_ID_STAT) |
+				(priv->active_mem_unit & NFP_FL_STAT_ID_MU_NUM);
+		if (++priv->active_mem_unit == priv->total_mem_units) {
+			priv->stats_ids.init_unallocated--;
+			priv->active_mem_unit = 0;
+		}
+		return 0;
+	}
+
+	/* Check if buffer is empty */
+	ring = &priv->stats_ids.free_list;
+	freed_stats_id = priv->stats_ring_size;
+	if (ring->head == ring->tail) {
+		*ctx = freed_stats_id;
+		return -ENOENT;
+	}
+
+	memcpy(&temp_stats_id, &ring->buf[ring->tail], NFP_FL_STATS_ELEM_RS);
+	*ctx = temp_stats_id;
+	memcpy(&ring->buf[ring->tail], &freed_stats_id, NFP_FL_STATS_ELEM_RS);
+	ring->tail = (ring->tail + NFP_FL_STATS_ELEM_RS) %
+			(priv->stats_ring_size * NFP_FL_STATS_ELEM_RS);
+
+	return 0;
+}
+
+__rte_unused static int
+nfp_stats_id_free(struct nfp_flow_priv *priv, uint32_t ctx)
+{
+	struct circ_buf *ring;
+
+	/* Check if buffer is full */
+	ring = &priv->stats_ids.free_list;
+	if (!CIRC_SPACE(ring->head, ring->tail, priv->stats_ring_size *
+			NFP_FL_STATS_ELEM_RS - NFP_FL_STATS_ELEM_RS + 1))
+		return -ENOBUFS;
+
+	memcpy(&ring->buf[ring->head], &ctx, NFP_FL_STATS_ELEM_RS);
+	ring->head = (ring->head + NFP_FL_STATS_ELEM_RS) %
+			(priv->stats_ring_size * NFP_FL_STATS_ELEM_RS);
+
+	return 0;
+}
+
+int
+nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)
+{
+	int ret = 0;
+	uint64_t ctx_count;
+	uint64_t ctx_split;
+	size_t stats_size;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+
+	struct rte_hash_parameters mask_hash_params = {
+		.name       = "mask_hash_table",
+		.entries    = NFP_MASK_TABLE_ENTRIES,
+		.hash_func  = rte_jhash,
+		.socket_id  = rte_socket_id(),
+		.key_len    = sizeof(uint32_t),
+		.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,
+	};
+
+	struct rte_hash_parameters flow_hash_params = {
+		.name       = "flow_hash_table",
+		.hash_func  = rte_jhash,
+		.socket_id  = rte_socket_id(),
+		.key_len    = sizeof(uint32_t),
+		.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,
+	};
+
+	ctx_count = nfp_rtsym_read_le(pf_dev->sym_tbl,
+			"CONFIG_FC_HOST_CTX_COUNT", &ret);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "Read CTX_COUNT from symbol table failed");
+		goto exit;
+	}
+
+	ctx_split = nfp_rtsym_read_le(pf_dev->sym_tbl,
+			"CONFIG_FC_HOST_CTX_SPLIT", &ret);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "Read CTX_SPLIT from symbol table failed");
+		goto exit;
+	}
+
+	priv = rte_zmalloc("nfp_app_flow_priv", sizeof(struct nfp_flow_priv), 0);
+	if (priv == NULL) {
+		PMD_INIT_LOG(ERR, "nfp app flow priv creation failed");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+	app_fw_flower->flow_priv = priv;
+	priv->hash_seed = (uint32_t)rte_rand();
+	priv->stats_ring_size = ctx_count;
+	priv->total_mem_units = ctx_split;
+
+	/* Init ring buffer and unallocated mask_ids. */
+	priv->mask_ids.init_unallocated = NFP_FLOWER_MASK_ENTRY_RS - 1;
+	priv->mask_ids.free_list.buf = rte_zmalloc("nfp_app_mask_ids",
+			NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS, 0);
+	if (priv->mask_ids.free_list.buf == NULL) {
+		PMD_INIT_LOG(ERR, "mask id free list creation failed");
+		ret = -ENOMEM;
+		goto free_priv;
+	}
+
+	/* Init ring buffer and unallocated stats_ids. */
+	priv->stats_ids.init_unallocated = ctx_count / ctx_split;
+	priv->stats_ids.free_list.buf = rte_zmalloc("nfp_app_stats_ids",
+			priv->stats_ring_size * NFP_FL_STATS_ELEM_RS, 0);
+	if (priv->stats_ids.free_list.buf == NULL) {
+		PMD_INIT_LOG(ERR, "stats id free list creation failed");
+		ret = -ENOMEM;
+		goto free_mask_id;
+	}
+
+	/* flow stats */
+	rte_spinlock_init(&priv->stats_lock);
+	stats_size = (ctx_count & NFP_FL_STAT_ID_STAT) |
+			((ctx_split - 1) & NFP_FL_STAT_ID_MU_NUM);
+	PMD_INIT_LOG(INFO, "ctx_count:%0lx, ctx_split:%0lx, stats_size:%0lx ",
+			ctx_count, ctx_split, stats_size);
+	priv->stats = rte_zmalloc("nfp_flow_stats",
+			stats_size * sizeof(struct nfp_fl_stats), 0);
+	if (priv->stats == NULL) {
+		PMD_INIT_LOG(ERR, "flow stats creation failed");
+		ret = -ENOMEM;
+		goto free_stats_id;
+	}
+
+	/* mask table */
+	mask_hash_params.hash_func_init_val = priv->hash_seed;
+	priv->mask_table = rte_hash_create(&mask_hash_params);
+	if (priv->mask_table == NULL) {
+		PMD_INIT_LOG(ERR, "mask hash table creation failed");
+		ret = -ENOMEM;
+		goto free_stats;
+	}
+
+	/* flow table */
+	flow_hash_params.hash_func_init_val = priv->hash_seed;
+	flow_hash_params.entries = ctx_count;
+	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_mask_table;
+	}
+
+	return 0;
+
+free_mask_table:
+	rte_free(priv->mask_table);
+free_stats:
+	rte_free(priv->stats);
+free_stats_id:
+	rte_free(priv->stats_ids.free_list.buf);
+free_mask_id:
+	rte_free(priv->mask_ids.free_list.buf);
+free_priv:
+	rte_free(priv);
+exit:
+	return ret;
+}
+
+void
+nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev)
+{
+	struct nfp_app_fw_flower *app_fw_flower;
+	struct nfp_flow_priv *priv;
+
+	app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+	priv = app_fw_flower->flow_priv;
+
+	rte_hash_free(priv->flow_table);
+	rte_hash_free(priv->mask_table);
+	rte_free(priv->stats);
+	rte_free(priv->stats_ids.free_list.buf);
+	rte_free(priv->mask_ids.free_list.buf);
+	rte_free(priv);
+}
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
new file mode 100644
index 0000000..142d7d5
--- /dev/null
+++ b/drivers/net/nfp/nfp_flow.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _NFP_FLOW_H_
+#define _NFP_FLOW_H_
+
+#define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)
+
+#define NFP_MASK_TABLE_ENTRIES          1024
+
+enum nfp_flower_tun_type {
+	NFP_FL_TUN_NONE   = 0,
+	NFP_FL_TUN_GRE    = 1,
+	NFP_FL_TUN_VXLAN  = 2,
+	NFP_FL_TUN_GENEVE = 4,
+};
+
+struct nfp_fl_key_ls {
+	uint32_t key_layer_two;
+	uint8_t key_layer;
+	int key_size;
+	int act_size;
+	uint32_t port;
+	uint16_t vlan;
+	enum nfp_flower_tun_type tun_type;
+};
+
+struct nfp_fl_rule_metadata {
+	uint8_t key_len;
+	uint8_t mask_len;
+	uint8_t act_len;
+	uint8_t flags;
+	rte_be32_t host_ctx_id;
+	rte_be64_t host_cookie __rte_packed;
+	rte_be64_t flow_version __rte_packed;
+	rte_be32_t shortcut;
+};
+
+struct nfp_fl_payload {
+	struct nfp_fl_rule_metadata *meta;
+	char *unmasked_data;
+	char *mask_data;
+	char *action_data;
+};
+
+#define CIRC_CNT(head, tail, size)     (((head) - (tail)) & ((size) - 1))
+#define CIRC_SPACE(head, tail, size)   CIRC_CNT((tail), ((head) + 1), (size))
+struct circ_buf {
+	uint32_t head;
+	uint32_t tail;
+	char *buf;
+};
+
+#define NFP_FLOWER_MASK_ENTRY_RS        256
+#define NFP_FLOWER_MASK_ELEMENT_RS      sizeof(uint8_t)
+struct nfp_fl_mask_id {
+	struct circ_buf free_list;
+	uint8_t init_unallocated;
+};
+
+#define NFP_FL_STATS_ELEM_RS            sizeof(uint32_t)
+struct nfp_fl_stats_id {
+	struct circ_buf free_list;
+	uint32_t init_unallocated;
+};
+
+#define NFP_FL_STAT_ID_MU_NUM           0xffc00000
+#define NFP_FL_STAT_ID_STAT             0x003fffff
+struct nfp_fl_stats {
+	uint64_t pkts;
+	uint64_t bytes;
+};
+
+struct nfp_flow_priv {
+	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
+	/* mask hash table */
+	struct nfp_fl_mask_id mask_ids; /**< Entry for mask hash table */
+	struct rte_hash *mask_table; /**< Hash table to store mask ids. */
+	/* flow hash table */
+	struct rte_hash *flow_table; /**< Hash table to store flow rules. */
+	/* flow stats */
+	uint32_t active_mem_unit; /**< The size of active mem units. */
+	uint32_t total_mem_units; /**< The size of total mem units. */
+	uint32_t stats_ring_size; /**< The size of stats id ring. */
+	struct nfp_fl_stats_id stats_ids; /**< The stats id ring. */
+	struct nfp_fl_stats *stats; /**< Store stats of flow. */
+	rte_spinlock_t stats_lock; /** < Lock the update of 'stats' field. */
+};
+
+struct rte_flow {
+	struct nfp_fl_payload payload;
+	size_t length;
+	bool install_flag;
+};
+
+int nfp_flow_priv_init(struct nfp_pf_dev *pf_dev);
+void nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev);
+
+#endif /* _NFP_FLOW_H_ */
-- 
1.8.3.1


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

* [PATCH v4 03/25] net/nfp: add the stats process logic in ctrl VNIC service
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 01/25] net/nfp: fix the requirement of cpp bridge service Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 02/25] net/nfp: add the structures and functions for flow offload Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 04/25] net/nfp: add the flow APIs of nfp PMD Chaoyong He
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the flow stats process logic in the ctrl VNIC service.
The flower firmware pass the flow stats to nfp driver through
control message, we store them in the flow_priv structure.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 25 +++++++++++
 drivers/net/nfp/flower/nfp_flower_ctrl.c | 73 ++++++++++++++++++++++++++++++--
 2 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 0bf8fc8..5c28363 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -129,6 +129,31 @@ struct nfp_flower_cmsg_port_mod {
 	rte_be16_t mtu;
 };
 
+/*
+ * NFP_FLOWER_CMSG_TYPE_FLOW_STATS
+ *    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  |    Reserved   |               Host Context                    |
+ *          +---------------+-----------------------------------------------+
+ *       1  |                          Packet Count                         |
+ *          +---------------------------------------------------------------+
+ *       2  |                          Byte Count                           |
+ *          +---------------------------------------------------------------+
+ *       2  |                          Byte Count                           |
+ *          +---------------------------------------------------------------+
+ *       3  |                          Host Cookie                          |
+ *          +---------------------------------------------------------------+
+ *       4  |                          Host Cookie                          |
+ *          +---------------------------------------------------------------+
+ */
+struct nfp_flower_stats_frame {
+	rte_be32_t stats_con_id;
+	rte_be32_t pkt_count;
+	rte_be64_t byte_count;
+	rte_be64_t stats_cookie;
+};
+
 enum nfp_flower_cmsg_port_type {
 	NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC,
 	NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT,
diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c
index df908ef..bb9efe1 100644
--- a/drivers/net/nfp/flower/nfp_flower_ctrl.c
+++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c
@@ -10,8 +10,10 @@
 #include "../nfp_logs.h"
 #include "../nfp_ctrl.h"
 #include "../nfp_rxtx.h"
+#include "nfp_flow.h"
 #include "nfp_flower.h"
 #include "nfp_flower_ctrl.h"
+#include "nfp_flower_cmsg.h"
 
 #define MAX_PKT_BURST 32
 
@@ -222,10 +224,74 @@
 	return cnt;
 }
 
+static void
+nfp_flower_cmsg_rx_stats(struct nfp_flow_priv *flow_priv,
+		struct rte_mbuf *mbuf)
+{
+	char *msg;
+	uint16_t i;
+	uint16_t count;
+	uint16_t msg_len;
+	uint32_t ctx_id;
+	struct nfp_flower_stats_frame *stats;
+
+	msg = rte_pktmbuf_mtod(mbuf, char *) + NFP_FLOWER_CMSG_HLEN;
+	msg_len = mbuf->data_len - NFP_FLOWER_CMSG_HLEN;
+	count = msg_len / sizeof(struct nfp_flower_stats_frame);
+
+	rte_spinlock_lock(&flow_priv->stats_lock);
+	for (i = 0; i < count; i++) {
+		stats = (struct nfp_flower_stats_frame *)msg + i;
+		ctx_id = rte_be_to_cpu_32(stats->stats_con_id);
+		flow_priv->stats[ctx_id].pkts  += rte_be_to_cpu_32(stats->pkt_count);
+		flow_priv->stats[ctx_id].bytes += rte_be_to_cpu_64(stats->byte_count);
+	}
+	rte_spinlock_unlock(&flow_priv->stats_lock);
+}
+
+static void
+nfp_flower_cmsg_rx(struct nfp_flow_priv *flow_priv,
+		struct rte_mbuf **pkts_burst,
+		uint16_t count)
+{
+	uint16_t i;
+	char *meta;
+	uint32_t meta_type;
+	uint32_t meta_info;
+	struct nfp_flower_cmsg_hdr *cmsg_hdr;
+
+	for (i = 0; i < count; i++) {
+		meta = rte_pktmbuf_mtod(pkts_burst[i], char *);
+
+		/* Free the unsupported ctrl packet */
+		meta_type = rte_be_to_cpu_32(*(uint32_t *)(meta - 8));
+		meta_info = rte_be_to_cpu_32(*(uint32_t *)(meta - 4));
+		if (meta_type != NFP_NET_META_PORTID ||
+				meta_info != NFP_META_PORT_ID_CTRL) {
+			PMD_DRV_LOG(ERR, "Incorrect metadata for ctrl packet!");
+			rte_pktmbuf_free(pkts_burst[i]);
+			continue;
+		}
+
+		cmsg_hdr = (struct nfp_flower_cmsg_hdr *)meta;
+		if (unlikely(cmsg_hdr->version != NFP_FLOWER_CMSG_VER1)) {
+			PMD_DRV_LOG(ERR, "Incorrect repr control version!");
+			rte_pktmbuf_free(pkts_burst[i]);
+			continue;
+		}
+
+		if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_FLOW_STATS) {
+			/* We need to deal with stats updates from HW asap */
+			nfp_flower_cmsg_rx_stats(flow_priv, pkts_burst[i]);
+		}
+
+		rte_pktmbuf_free(pkts_burst[i]);
+	}
+}
+
 void
 nfp_flower_ctrl_vnic_poll(struct nfp_app_fw_flower *app_fw_flower)
 {
-	uint16_t i;
 	uint16_t count;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *ctrl_hw;
@@ -242,9 +308,8 @@
 		count = nfp_flower_ctrl_vnic_recv(rxq, pkts_burst, MAX_PKT_BURST);
 		if (count != 0) {
 			app_fw_flower->ctrl_vnic_rx_count += count;
-			/* Process cmsgs here, only free for now */
-			for (i = 0; i < count; i++)
-				rte_pktmbuf_free(pkts_burst[i]);
+			/* Process cmsgs here */
+			nfp_flower_cmsg_rx(app_fw_flower->flow_priv, pkts_burst, count);
 		}
 	}
 }
-- 
1.8.3.1


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

* [PATCH v4 04/25] net/nfp: add the flow APIs of nfp PMD
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (2 preceding siblings ...)
  2022-10-18 11:26 ` [PATCH v4 03/25] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 05/25] net/nfp: support basic flow items Chaoyong He
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the flow validate/create/query/destroy/flush API of nfp PMD.

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

The flow query API get flow stats from the flow_priv structure.
Note there exist an rte_spin_lock to prevent the update and query
action occur at the same time.

The flow destroy API construct a control cmsg and send it to
firmware, then adelete 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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower_cmsg.c        |  69 +++
 drivers/net/nfp/flower/nfp_flower_cmsg.h        |  48 ++
 drivers/net/nfp/flower/nfp_flower_representor.c |   3 +
 drivers/net/nfp/nfp_flow.c                      | 580 +++++++++++++++++++++++-
 drivers/net/nfp/nfp_flow.h                      |  28 ++
 5 files changed, 719 insertions(+), 9 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c
index 750a629..15d8381 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c
@@ -6,6 +6,7 @@
 #include "../nfpcore/nfp_nsp.h"
 #include "../nfp_logs.h"
 #include "../nfp_common.h"
+#include "../nfp_flow.h"
 #include "nfp_flower.h"
 #include "nfp_flower_cmsg.h"
 #include "nfp_flower_ctrl.h"
@@ -177,3 +178,71 @@
 
 	return 0;
 }
+
+int
+nfp_flower_cmsg_flow_delete(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow)
+{
+	char *msg;
+	uint16_t cnt;
+	uint32_t msg_len;
+	struct rte_mbuf *mbuf;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+	if (mbuf == NULL) {
+		PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for flow delete.");
+		return -ENOMEM;
+	}
+
+	/* Copy the flow to mbuf */
+	nfp_flow_meta = flow->payload.meta;
+	msg_len = (nfp_flow_meta->key_len + nfp_flow_meta->mask_len +
+			nfp_flow_meta->act_len) << NFP_FL_LW_SIZ;
+	msg_len += sizeof(struct nfp_fl_rule_metadata);
+	msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_FLOW_DEL, msg_len);
+	rte_memcpy(msg, flow->payload.meta, msg_len);
+
+	cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+	if (cnt == 0) {
+		PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+		rte_pktmbuf_free(mbuf);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+nfp_flower_cmsg_flow_add(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow)
+{
+	char *msg;
+	uint16_t cnt;
+	uint32_t msg_len;
+	struct rte_mbuf *mbuf;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+	if (mbuf == NULL) {
+		PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for flow add.");
+		return -ENOMEM;
+	}
+
+	/* copy the flow to mbuf */
+	nfp_flow_meta = flow->payload.meta;
+	msg_len = (nfp_flow_meta->key_len + nfp_flow_meta->mask_len +
+			nfp_flow_meta->act_len) << NFP_FL_LW_SIZ;
+	msg_len += sizeof(struct nfp_fl_rule_metadata);
+	msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_FLOW_ADD, msg_len);
+	rte_memcpy(msg, flow->payload.meta, msg_len);
+
+	cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+	if (cnt == 0) {
+		PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+		rte_pktmbuf_free(mbuf);
+		return -EIO;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 5c28363..6045bb0 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -189,10 +189,58 @@ enum nfp_flower_cmsg_port_vnic_type {
 	return rte_pktmbuf_mtod(m, char *) + 4 + 4 + NFP_FLOWER_CMSG_HLEN;
 }
 
+/*
+ * Metadata with L2 (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    key_type   |    mask_id    | PCP |p|   vlan outermost VID  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *                                 ^                               ^
+ *                           NOTE: |             TCI               |
+ *                                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_meta_tci {
+	uint8_t nfp_flow_key_layer;
+	uint8_t mask_id;
+	rte_be16_t tci;
+};
+
+/*
+ * Extended metadata for additional key_layers (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                      nfp_flow_key_layer2                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ext_meta {
+	rte_be32_t nfp_flow_key_layer2;
+};
+
+/*
+ * L1 Port details (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                         port_ingress                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_in_port {
+	rte_be32_t in_port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
 int nfp_flower_cmsg_port_mod(struct nfp_app_fw_flower *app_fw_flower,
 		uint32_t port_id, bool carrier_ok);
+int nfp_flower_cmsg_flow_delete(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow);
+int nfp_flower_cmsg_flow_add(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow);
 
 #endif /* _NFP_CMSG_H_ */
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index 0e60f50..f1cd298 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -10,6 +10,7 @@
 #include "../nfp_logs.h"
 #include "../nfp_ctrl.h"
 #include "../nfp_rxtx.h"
+#include "../nfp_flow.h"
 #include "../nfpcore/nfp_mip.h"
 #include "../nfpcore/nfp_rtsym.h"
 #include "../nfpcore/nfp_nsp.h"
@@ -590,6 +591,8 @@
 	.promiscuous_disable  = nfp_flower_repr_promiscuous_disable,
 
 	.mac_addr_set         = nfp_flower_repr_mac_addr_set,
+
+	.flow_ops_get         = nfp_net_flow_ops_get,
 };
 
 static uint32_t
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 97f5d1b..64ebffe 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -7,11 +7,15 @@
 #include <rte_hash.h>
 #include <rte_jhash.h>
 #include <bus_pci_driver.h>
+#include <rte_malloc.h>
 
 #include "nfp_common.h"
 #include "nfp_flow.h"
 #include "nfp_logs.h"
 #include "flower/nfp_flower.h"
+#include "flower/nfp_flower_cmsg.h"
+#include "flower/nfp_flower_ctrl.h"
+#include "flower/nfp_flower_representor.h"
 #include "nfpcore/nfp_mip.h"
 #include "nfpcore/nfp_rtsym.h"
 
@@ -21,6 +25,15 @@ struct nfp_mask_id_entry {
 	uint8_t mask_id;
 };
 
+static inline struct nfp_flow_priv *
+nfp_flow_dev_to_priv(struct rte_eth_dev *dev)
+{
+	struct nfp_flower_representor *repr;
+
+	repr = (struct nfp_flower_representor *)dev->data->dev_private;
+	return repr->app_fw_flower->flow_priv;
+}
+
 static int
 nfp_mask_id_alloc(struct nfp_flow_priv *priv, uint8_t *mask_id)
 {
@@ -160,7 +173,7 @@ struct nfp_mask_id_entry {
 	return entry;
 }
 
-__rte_unused static bool
+static bool
 nfp_check_mask_add(struct nfp_flow_priv *priv,
 		char *mask_data,
 		uint32_t mask_len,
@@ -187,7 +200,7 @@ struct nfp_mask_id_entry {
 	return true;
 }
 
-__rte_unused static bool
+static bool
 nfp_check_mask_remove(struct nfp_flow_priv *priv,
 		char *mask_data,
 		uint32_t mask_len,
@@ -215,7 +228,7 @@ struct nfp_mask_id_entry {
 	return true;
 }
 
-__rte_unused static int
+static int
 nfp_flow_table_add(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -234,7 +247,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static int
+static int
 nfp_flow_table_delete(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -253,7 +266,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static struct rte_flow *
+static struct rte_flow *
 nfp_flow_table_search(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -273,7 +286,7 @@ struct nfp_mask_id_entry {
 	return flow_find;
 }
 
-__rte_unused static struct rte_flow *
+static struct rte_flow *
 nfp_flow_alloc(struct nfp_fl_key_ls *key_layer)
 {
 	char *tmp;
@@ -306,14 +319,14 @@ struct nfp_mask_id_entry {
 	return NULL;
 }
 
-__rte_unused static void
+static void
 nfp_flow_free(struct rte_flow *nfp_flow)
 {
 	rte_free(nfp_flow->payload.meta);
 	rte_free(nfp_flow);
 }
 
-__rte_unused static int
+static int
 nfp_stats_id_alloc(struct nfp_flow_priv *priv, uint32_t *ctx)
 {
 	struct circ_buf *ring;
@@ -348,7 +361,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static int
+static int
 nfp_stats_id_free(struct nfp_flow_priv *priv, uint32_t ctx)
 {
 	struct circ_buf *ring;
@@ -366,6 +379,555 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flower_compile_meta_tci(char *mbuf_off, struct nfp_fl_key_ls *key_layer)
+{
+	struct nfp_flower_meta_tci *tci_meta;
+
+	tci_meta = (struct nfp_flower_meta_tci *)mbuf_off;
+	tci_meta->nfp_flow_key_layer = key_layer->key_layer;
+	tci_meta->mask_id = ~0;
+	tci_meta->tci = rte_cpu_to_be_16(key_layer->vlan);
+}
+
+static void
+nfp_flower_update_meta_tci(char *exact, uint8_t mask_id)
+{
+	struct nfp_flower_meta_tci *meta_tci;
+
+	meta_tci = (struct nfp_flower_meta_tci *)exact;
+	meta_tci->mask_id = mask_id;
+}
+
+static void
+nfp_flower_compile_ext_meta(char *mbuf_off, struct nfp_fl_key_ls *key_layer)
+{
+	struct nfp_flower_ext_meta *ext_meta;
+
+	ext_meta = (struct nfp_flower_ext_meta *)mbuf_off;
+	ext_meta->nfp_flow_key_layer2 = rte_cpu_to_be_32(key_layer->key_layer_two);
+}
+
+static void
+nfp_compile_meta_port(char *mbuf_off,
+		struct nfp_fl_key_ls *key_layer,
+		bool is_mask)
+{
+	struct nfp_flower_in_port *port_meta;
+
+	port_meta = (struct nfp_flower_in_port *)mbuf_off;
+
+	if (is_mask)
+		port_meta->in_port = rte_cpu_to_be_32(~0);
+	else if (key_layer->tun_type)
+		port_meta->in_port = rte_cpu_to_be_32(NFP_FL_PORT_TYPE_TUN |
+				key_layer->tun_type);
+	else
+		port_meta->in_port = rte_cpu_to_be_32(key_layer->port);
+}
+
+static void
+nfp_flow_compile_metadata(struct nfp_flow_priv *priv,
+		struct rte_flow *nfp_flow,
+		struct nfp_fl_key_ls *key_layer,
+		uint32_t stats_ctx)
+{
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+	char *mbuf_off_exact;
+	char *mbuf_off_mask;
+
+	/*
+	 * Convert to long words as firmware expects
+	 * lengths in units of NFP_FL_LW_SIZ.
+	 */
+	nfp_flow_meta               = nfp_flow->payload.meta;
+	nfp_flow_meta->key_len      = key_layer->key_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->mask_len     = key_layer->key_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->act_len      = key_layer->act_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->flags        = 0;
+	nfp_flow_meta->host_ctx_id  = rte_cpu_to_be_32(stats_ctx);
+	nfp_flow_meta->host_cookie  = rte_rand();
+	nfp_flow_meta->flow_version = rte_cpu_to_be_64(priv->flower_version);
+	priv->flower_version++;
+
+	mbuf_off_exact = nfp_flow->payload.unmasked_data;
+	mbuf_off_mask  = nfp_flow->payload.mask_data;
+
+	/* Populate Metadata */
+	nfp_flower_compile_meta_tci(mbuf_off_exact, key_layer);
+	nfp_flower_compile_meta_tci(mbuf_off_mask, key_layer);
+	mbuf_off_exact += sizeof(struct nfp_flower_meta_tci);
+	mbuf_off_mask  += sizeof(struct nfp_flower_meta_tci);
+
+	/* Populate Extended Metadata if required */
+	if (key_layer->key_layer & NFP_FLOWER_LAYER_EXT_META) {
+		nfp_flower_compile_ext_meta(mbuf_off_exact, key_layer);
+		nfp_flower_compile_ext_meta(mbuf_off_mask, key_layer);
+		mbuf_off_exact += sizeof(struct nfp_flower_ext_meta);
+		mbuf_off_mask  += sizeof(struct nfp_flower_ext_meta);
+	}
+
+	/* Populate Port Data */
+	nfp_compile_meta_port(mbuf_off_exact, key_layer, false);
+	nfp_compile_meta_port(mbuf_off_mask, key_layer, true);
+	mbuf_off_exact += sizeof(struct nfp_flower_in_port);
+	mbuf_off_mask  += sizeof(struct nfp_flower_in_port);
+}
+
+static int
+nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[],
+		__rte_unused struct nfp_fl_key_ls *key_ls)
+{
+	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, "Item type %d not supported.", item->type);
+			return -ENOTSUP;
+		}
+	}
+
+	return 0;
+}
+
+static int
+nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
+		struct nfp_fl_key_ls *key_ls)
+{
+	int ret = 0;
+	const struct rte_flow_action *action;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+		/* Make sure actions length no longer than NFP_FL_MAX_A_SIZ */
+		if (key_ls->act_size > NFP_FL_MAX_A_SIZ) {
+			PMD_DRV_LOG(ERR, "The action list is too long.");
+			ret = -ERANGE;
+			break;
+		}
+
+		switch (action->type) {
+		case RTE_FLOW_ACTION_TYPE_VOID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VOID detected");
+			break;
+		default:
+			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
+			return -ENOTSUP;
+		}
+	}
+
+	return ret;
+}
+
+static int
+nfp_flow_key_layers_calculate(const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct nfp_fl_key_ls *key_ls)
+{
+	int ret = 0;
+
+	key_ls->key_layer_two = 0;
+	key_ls->key_layer = NFP_FLOWER_LAYER_PORT;
+	key_ls->key_size = sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+	key_ls->act_size = 0;
+	key_ls->port = ~0;
+	key_ls->vlan = 0;
+	key_ls->tun_type = NFP_FL_TUN_NONE;
+
+	ret |= nfp_flow_key_layers_calculate_items(items, key_ls);
+	ret |= nfp_flow_key_layers_calculate_actions(actions, key_ls);
+
+	return ret;
+}
+
+static struct rte_flow *
+nfp_flow_process(struct nfp_flower_representor *representor,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[])
+{
+	int ret;
+	char *mask_data;
+	uint32_t mask_len;
+	uint32_t stats_ctx = 0;
+	uint8_t new_mask_id = 0;
+	struct rte_flow *nfp_flow;
+	struct rte_flow *flow_find;
+	struct nfp_flow_priv *priv;
+	struct nfp_fl_key_ls key_layer;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	ret = nfp_flow_key_layers_calculate(items, actions, &key_layer);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Key layers calculate failed.");
+		return NULL;
+	}
+
+	if (key_layer.port == (uint32_t)~0)
+		key_layer.port = representor->port_id;
+
+	priv = representor->app_fw_flower->flow_priv;
+	ret = nfp_stats_id_alloc(priv, &stats_ctx);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp stats id alloc failed.");
+		return NULL;
+	}
+
+	nfp_flow = nfp_flow_alloc(&key_layer);
+	if (nfp_flow == NULL) {
+		PMD_DRV_LOG(ERR, "Alloc nfp flow failed.");
+		goto free_stats;
+	}
+
+	nfp_flow->install_flag = true;
+
+	nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx);
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	mask_data = nfp_flow->payload.mask_data;
+	mask_len = key_layer.key_size;
+	if (!nfp_check_mask_add(priv, mask_data, mask_len,
+			&nfp_flow_meta->flags, &new_mask_id)) {
+		PMD_DRV_LOG(ERR, "nfp mask add check failed.");
+		goto free_flow;
+	}
+
+	/* Once we have a mask_id, update the meta tci */
+	nfp_flower_update_meta_tci(nfp_flow->payload.unmasked_data, new_mask_id);
+
+	/* Find the flow in hash table */
+	flow_find = nfp_flow_table_search(priv, nfp_flow);
+	if (flow_find != NULL) {
+		PMD_DRV_LOG(ERR, "This flow is already exist.");
+		if (!nfp_check_mask_remove(priv, mask_data, mask_len,
+				&nfp_flow_meta->flags)) {
+			PMD_DRV_LOG(ERR, "nfp mask del check failed.");
+		}
+		goto free_flow;
+	}
+
+	return nfp_flow;
+
+free_flow:
+	nfp_flow_free(nfp_flow);
+free_stats:
+	nfp_stats_id_free(priv, stats_ctx);
+
+	return NULL;
+}
+
+static struct rte_flow *
+nfp_flow_setup(struct nfp_flower_representor *representor,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error)
+{
+	if (attr->group != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support group attribute.");
+
+	if (attr->priority != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support priority attribute.");
+
+	if (attr->transfer != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support transfer attribute.");
+
+	if (attr->egress != 0) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
+				NULL, "Egress is not supported.");
+		return NULL;
+	}
+
+	if (attr->ingress == 0) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
+				NULL, "Only ingress is supported.");
+		return NULL;
+	}
+
+	return nfp_flow_process(representor, items, actions);
+}
+
+static int
+nfp_flow_teardown(struct nfp_flow_priv *priv, struct rte_flow *nfp_flow)
+{
+	char *mask_data;
+	uint32_t mask_len;
+	uint32_t stats_ctx;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	mask_data = nfp_flow->payload.mask_data;
+	mask_len = nfp_flow_meta->mask_len << NFP_FL_LW_SIZ;
+	if (!nfp_check_mask_remove(priv, mask_data, mask_len,
+			&nfp_flow_meta->flags)) {
+		PMD_DRV_LOG(ERR, "nfp mask del check failed.");
+		return -EINVAL;
+	}
+
+	nfp_flow_meta->flow_version = rte_cpu_to_be_64(priv->flower_version);
+	priv->flower_version++;
+
+	stats_ctx = rte_be_to_cpu_32(nfp_flow_meta->host_ctx_id);
+	return nfp_stats_id_free(priv, stats_ctx);
+}
+
+static int
+nfp_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 rte_flow *nfp_flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	priv = representor->app_fw_flower->flow_priv;
+
+	nfp_flow = nfp_flow_setup(representor, attr, items, actions, error);
+	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_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_flow_free(nfp_flow);
+
+	return 0;
+}
+
+static struct rte_flow *
+nfp_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 rte_flow *nfp_flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	app_fw_flower = representor->app_fw_flower;
+	priv = app_fw_flower->flow_priv;
+
+	nfp_flow = nfp_flow_setup(representor, attr, items, actions, error);
+	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 hardware */
+	if (nfp_flow->install_flag) {
+		ret = nfp_flower_cmsg_flow_add(app_fw_flower, nfp_flow);
+		if (ret != 0) {
+			rte_flow_error_set(error, EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL, "Add flow to firmware failed.");
+			goto flow_teardown;
+		}
+	}
+
+	/* Add the flow to flow hash table */
+	ret = nfp_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;
+	}
+
+	return nfp_flow;
+
+flow_teardown:
+	nfp_flow_teardown(priv, nfp_flow);
+	nfp_flow_free(nfp_flow);
+
+	return NULL;
+}
+
+static int
+nfp_flow_destroy(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct rte_flow *flow_find;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	app_fw_flower = representor->app_fw_flower;
+	priv = app_fw_flower->flow_priv;
+
+	/* Find the flow in flow hash table */
+	flow_find = nfp_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;
+	}
+
+	/* Update flow */
+	ret = nfp_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;
+	}
+
+	/* Delete the flow from hardware */
+	if (nfp_flow->install_flag) {
+		ret = nfp_flower_cmsg_flow_delete(app_fw_flower, nfp_flow);
+		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_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;
+	}
+
+exit:
+	nfp_flow_free(nfp_flow);
+
+	return ret;
+}
+
+static int
+nfp_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_flow_priv *priv;
+
+	priv = nfp_flow_dev_to_priv(dev);
+
+	while (rte_hash_iterate(priv->flow_table, &next_key, &next_data, &iter) >= 0) {
+		ret = nfp_flow_destroy(dev, (struct rte_flow *)next_data, error);
+		if (ret != 0)
+			break;
+	}
+
+	return ret;
+}
+
+static void
+nfp_flow_stats_get(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		void *data)
+{
+	uint32_t ctx_id;
+	struct rte_flow *flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_fl_stats *stats;
+	struct rte_flow_query_count *query;
+
+	priv = nfp_flow_dev_to_priv(dev);
+	flow = nfp_flow_table_search(priv, nfp_flow);
+	if (flow == NULL) {
+		PMD_DRV_LOG(ERR, "Can not find statistics for this flow.");
+		return;
+	}
+
+	query = (struct rte_flow_query_count *)data;
+	if (query->reserved != 0) {
+		PMD_DRV_LOG(ERR, "The reserved field should always be 0!");
+		return;
+	}
+
+	ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id);
+	stats = &priv->stats[ctx_id];
+
+	rte_spinlock_lock(&priv->stats_lock);
+	if (stats->pkts != 0 && stats->bytes != 0) {
+		query->hits = stats->pkts;
+		query->bytes = stats->bytes;
+		query->hits_set = 1;
+		query->bytes_set = 1;
+		if (query->reset != 0) {
+			stats->pkts = 0;
+			stats->bytes = 0;
+		}
+	}
+	rte_spinlock_unlock(&priv->stats_lock);
+}
+
+static int
+nfp_flow_query(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		const struct rte_flow_action *actions,
+		void *data,
+		struct rte_flow_error *error)
+{
+	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_VOID:
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			nfp_flow_stats_get(dev, nfp_flow, data);
+			break;
+		default:
+			rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL, "Unsupported action type for flow query.");
+			return -ENOTSUP;
+		}
+	}
+
+	return 0;
+}
+
+static const struct rte_flow_ops nfp_flow_ops = {
+	.validate                    = nfp_flow_validate,
+	.create                      = nfp_flow_create,
+	.destroy                     = nfp_flow_destroy,
+	.flush                       = nfp_flow_flush,
+	.query                       = nfp_flow_query,
+};
+
+int
+nfp_net_flow_ops_get(struct rte_eth_dev *dev,
+		const struct rte_flow_ops **ops)
+{
+	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0) {
+		*ops = NULL;
+		PMD_DRV_LOG(ERR, "Port is not a representor.");
+		return -EINVAL;
+	}
+
+	*ops = &nfp_flow_ops;
+
+	return 0;
+}
+
 int
 nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)
 {
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 142d7d5..83f9f29 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -6,10 +6,36 @@
 #ifndef _NFP_FLOW_H_
 #define _NFP_FLOW_H_
 
+#include <ethdev_driver.h>
+
+#define NFP_FLOWER_LAYER_EXT_META   (1 << 0)
+#define NFP_FLOWER_LAYER_PORT       (1 << 1)
+#define NFP_FLOWER_LAYER_MAC        (1 << 2)
+#define NFP_FLOWER_LAYER_TP         (1 << 3)
+#define NFP_FLOWER_LAYER_IPV4       (1 << 4)
+#define NFP_FLOWER_LAYER_IPV6       (1 << 5)
+#define NFP_FLOWER_LAYER_CT         (1 << 6)
+#define NFP_FLOWER_LAYER_VXLAN      (1 << 7)
+
+#define NFP_FLOWER_LAYER2_GRE       (1 << 0)
+#define NFP_FLOWER_LAYER2_QINQ      (1 << 4)
+#define NFP_FLOWER_LAYER2_GENEVE    (1 << 5)
+#define NFP_FLOWER_LAYER2_GENEVE_OP (1 << 6)
+#define NFP_FLOWER_LAYER2_TUN_IPV6  (1 << 7)
+
 #define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)
 
 #define NFP_MASK_TABLE_ENTRIES          1024
 
+/* The maximum action list size (in bytes) supported by the NFP. */
+#define NFP_FL_MAX_A_SIZ                1216
+
+/* The firmware expects lengths in units of long words */
+#define NFP_FL_LW_SIZ                   2
+
+/* Tunnel ports */
+#define NFP_FL_PORT_TYPE_TUN            0x50000000
+
 enum nfp_flower_tun_type {
 	NFP_FL_TUN_NONE   = 0,
 	NFP_FL_TUN_GRE    = 1,
@@ -75,6 +101,7 @@ struct nfp_fl_stats {
 
 struct nfp_flow_priv {
 	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
+	uint64_t flower_version; /**< Flow version, always increase. */
 	/* mask hash table */
 	struct nfp_fl_mask_id mask_ids; /**< Entry for mask hash table */
 	struct rte_hash *mask_table; /**< Hash table to store mask ids. */
@@ -97,5 +124,6 @@ struct rte_flow {
 
 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);
 
 #endif /* _NFP_FLOW_H_ */
-- 
1.8.3.1


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

* [PATCH v4 05/25] net/nfp: support basic flow items
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (3 preceding siblings ...)
  2022-10-18 11:26 ` [PATCH v4 04/25] net/nfp: add the flow APIs of nfp PMD Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 06/25] net/nfp: support basic flow actions Chaoyong He
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the offload support of very basic items: ethernet and
port id.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |   4 +
 doc/guides/rel_notes/release_22_11.rst   |   2 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  20 +++
 drivers/net/nfp/nfp_flow.c               | 252 ++++++++++++++++++++++++++++++-
 4 files changed, 277 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f7a0362..4460cf0 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -25,3 +25,7 @@ Linux                = Y
 Multiprocess aware   = Y
 x86-64               = Y
 Usage doc            = Y
+
+[rte_flow items]
+eth                  = Y
+port_id              = Y
diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index a3700bb..6d421a2 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -163,6 +163,8 @@ New Features
   * Added the control message interactive channels between PMD and firmware.
   * Added the support of representor port.
 
+  Add the support of rte_flow pattern items.
+
 * **Updated NXP dpaa2 driver.**
 
   * Added support for flow action REPRESENTED_PORT.
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 6045bb0..75a3b91 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -233,6 +233,26 @@ struct nfp_flower_in_port {
 	rte_be32_t in_port;
 };
 
+/*
+ * L2 details (4W/16B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     mac_addr_dst, 31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      mac_addr_dst, 47 - 32    |     mac_addr_src, 15 - 0      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     mac_addr_src, 47 - 16                     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |       mpls outermost label            |  TC |B|   reserved  |q|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_mac_mpls {
+	uint8_t mac_dst[6];
+	uint8_t mac_src[6];
+	rte_be32_t mpls_lse;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 64ebffe..56cbfb7 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -19,6 +19,30 @@
 #include "nfpcore/nfp_mip.h"
 #include "nfpcore/nfp_rtsym.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_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 unsigned int mask_sz;
+	/* Merge a pattern item into a flow rule handle. */
+	int (*merge)(struct rte_flow *nfp_flow,
+			char **mbuf_off,
+			const struct rte_flow_item *item,
+			const struct nfp_flow_item_proc *proc,
+			bool is_mask);
+	/* List of possible subsequent items. */
+	const enum rte_flow_item_type *const next_item;
+};
+
 struct nfp_mask_id_entry {
 	uint32_t hash_key;
 	uint32_t ref_cnt;
@@ -476,12 +500,36 @@ struct nfp_mask_id_entry {
 
 static int
 nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[],
-		__rte_unused struct nfp_fl_key_ls *key_ls)
+		struct nfp_fl_key_ls *key_ls)
 {
+	struct rte_eth_dev *ethdev;
 	const struct rte_flow_item *item;
+	struct nfp_flower_representor *representor;
+	const struct rte_flow_item_port_id *port_id;
 
 	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");
+			/*
+			 * eth is set with no specific params.
+			 * NFP does not need this.
+			 */
+			if (item->spec == NULL)
+				continue;
+			key_ls->key_layer |= NFP_FLOWER_LAYER_MAC;
+			key_ls->key_size += sizeof(struct nfp_flower_mac_mpls);
+			break;
+		case RTE_FLOW_ITEM_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_PORT_ID detected");
+			port_id = item->spec;
+			if (port_id->id >= RTE_MAX_ETHPORTS)
+				return -ERANGE;
+			ethdev = &rte_eth_devices[port_id->id];
+			representor = (struct nfp_flower_representor *)
+					ethdev->data->dev_private;
+			key_ls->port = rte_cpu_to_be_32(representor->port_id);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -541,6 +589,202 @@ struct nfp_mask_id_entry {
 	return ret;
 }
 
+static int
+nfp_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_mac_mpls *eth;
+	const struct rte_flow_item_eth *spec;
+	const struct rte_flow_item_eth *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge eth: no item->spec!");
+		goto eth_end;
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	eth = (void *)*mbuf_off;
+
+	if (is_mask) {
+		memcpy(eth->mac_src, mask->src.addr_bytes, RTE_ETHER_ADDR_LEN);
+		memcpy(eth->mac_dst, mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN);
+	} else {
+		memcpy(eth->mac_src, spec->src.addr_bytes, RTE_ETHER_ADDR_LEN);
+		memcpy(eth->mac_dst, spec->dst.addr_bytes, RTE_ETHER_ADDR_LEN);
+	}
+
+	eth->mpls_lse = 0;
+
+eth_end:
+	*mbuf_off += sizeof(struct nfp_flower_mac_mpls);
+
+	return 0;
+}
+
+/* Graph of supported items and associated process function */
+static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
+	[RTE_FLOW_ITEM_TYPE_END] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+	},
+	[RTE_FLOW_ITEM_TYPE_ETH] = {
+		.mask_support = &(const struct rte_flow_item_eth){
+			.hdr = {
+				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+				.src_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+				.ether_type          = RTE_BE16(0xffff),
+			},
+			.has_vlan = 1,
+		},
+		.mask_default = &rte_flow_item_eth_mask,
+		.mask_sz = sizeof(struct rte_flow_item_eth),
+		.merge = nfp_flow_merge_eth,
+	},
+};
+
+static int
+nfp_flow_item_check(const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc)
+{
+	int ret = 0;
+	unsigned int i;
+	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 ?
+		(const uint8_t *)item->mask :
+		(const uint8_t *)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 && (((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_flow_compile_item_proc(const struct rte_flow_item items[],
+		struct rte_flow *nfp_flow,
+		char **mbuf_off_exact,
+		char **mbuf_off_mask)
+{
+	int i;
+	int ret = 0;
+	const struct rte_flow_item *item;
+	const struct nfp_flow_item_proc *proc_list;
+
+	proc_list = nfp_flow_item_proc_list;
+	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
+		const struct nfp_flow_item_proc *proc = NULL;
+
+		for (i = 0; proc_list->next_item && proc_list->next_item[i]; ++i) {
+			if (proc_list->next_item[i] == item->type) {
+				proc = &nfp_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_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, mbuf_off_exact, item,
+				proc, false);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "nfp flow item %d exact merge failed", item->type);
+			break;
+		}
+
+		ret = proc->merge(nfp_flow, mbuf_off_mask, item,
+				proc, true);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "nfp flow item %d mask merge failed", item->type);
+			break;
+		}
+
+		proc_list = proc;
+	}
+
+	return ret;
+}
+
+static int
+nfp_flow_compile_items(__rte_unused struct nfp_flower_representor *representor,
+		const struct rte_flow_item items[],
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+	char *mbuf_off_mask;
+	char *mbuf_off_exact;
+
+	mbuf_off_exact = nfp_flow->payload.unmasked_data +
+			sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+	mbuf_off_mask  = nfp_flow->payload.mask_data +
+			sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+
+	/* Go over items */
+	ret = nfp_flow_compile_item_proc(items, nfp_flow,
+			&mbuf_off_exact, &mbuf_off_mask);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow item compile failed.");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static struct rte_flow *
 nfp_flow_process(struct nfp_flower_representor *representor,
 		const struct rte_flow_item items[],
@@ -583,6 +827,12 @@ struct nfp_mask_id_entry {
 
 	nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx);
 
+	ret = nfp_flow_compile_items(representor, items, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow item process failed.");
+		goto free_flow;
+	}
+
 	nfp_flow_meta = nfp_flow->payload.meta;
 	mask_data = nfp_flow->payload.mask_data;
 	mask_len = key_layer.key_size;
-- 
1.8.3.1


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

* [PATCH v4 06/25] net/nfp: support basic flow actions
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (4 preceding siblings ...)
  2022-10-18 11:26 ` [PATCH v4 05/25] net/nfp: support basic flow items Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 07/25] net/nfp: support VLAN flow item Chaoyong He
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the offload support of very basic actions: mark, rss,
count, drop and output.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |   5 ++
 doc/guides/rel_notes/release_22_11.rst   |   2 +-
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  11 +++
 drivers/net/nfp/nfp_flow.c               | 112 +++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h               |  37 ++++++++++
 5 files changed, 166 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 4460cf0..f91da82 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,3 +29,8 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 port_id              = Y
+
+[rte_flow actions]
+count                = Y
+drop                 = Y
+port_id              = Y
diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index 6d421a2..471f300 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -163,7 +163,7 @@ New Features
   * Added the control message interactive channels between PMD and firmware.
   * Added the support of representor port.
 
-  Add the support of rte_flow pattern items.
+  Add the support of rte_flow pattern items and actions.
 
 * **Updated NXP dpaa2 driver.**
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 75a3b91..d776e37 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -253,6 +253,17 @@ struct nfp_flower_mac_mpls {
 	rte_be32_t mpls_lse;
 };
 
+struct nfp_fl_act_head {
+	uint8_t jump_id;
+	uint8_t len_lw;
+};
+
+struct nfp_fl_act_output {
+	struct nfp_fl_act_head head;
+	rte_be16_t flags;
+	rte_be32_t port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 56cbfb7..dcc0942 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -558,6 +558,22 @@ struct nfp_mask_id_entry {
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VOID detected");
 			break;
+		case RTE_FLOW_ACTION_TYPE_MARK:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_MARK detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_DROP detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_COUNT detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_RSS detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_PORT_ID detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_output);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -785,6 +801,96 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_action_output(char *act_data,
+		const struct rte_flow_action *action,
+		struct nfp_fl_rule_metadata *nfp_flow_meta)
+{
+	size_t act_size;
+	struct rte_eth_dev *ethdev;
+	struct nfp_fl_act_output *output;
+	struct nfp_flower_representor *representor;
+	const struct rte_flow_action_port_id *port_id;
+
+	port_id = action->conf;
+	if (port_id == NULL || port_id->id >= RTE_MAX_ETHPORTS)
+		return -ERANGE;
+
+	ethdev = &rte_eth_devices[port_id->id];
+	representor = (struct nfp_flower_representor *)ethdev->data->dev_private;
+	act_size = sizeof(struct nfp_fl_act_output);
+
+	output = (struct nfp_fl_act_output *)act_data;
+	output->head.jump_id = NFP_FL_ACTION_OPCODE_OUTPUT;
+	output->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	output->flags        = rte_cpu_to_be_16(NFP_FL_OUT_FLAGS_LAST);
+	output->port         = rte_cpu_to_be_32(representor->port_id);
+
+	nfp_flow_meta->shortcut = rte_cpu_to_be_32(representor->port_id);
+
+	return 0;
+}
+
+static int
+nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
+		const struct rte_flow_action actions[],
+		struct rte_flow *nfp_flow)
+{
+	int ret = 0;
+	char *position;
+	char *action_data;
+	bool drop_flag = false;
+	uint32_t total_actions = 0;
+	const struct rte_flow_action *action;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	action_data   = nfp_flow->payload.action_data;
+	position      = action_data;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+		switch (action->type) {
+		case RTE_FLOW_ACTION_TYPE_VOID:
+			break;
+		case RTE_FLOW_ACTION_TYPE_MARK:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_MARK");
+			break;
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_DROP");
+			drop_flag = true;
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_COUNT");
+			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_RSS");
+			break;
+		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_PORT_ID");
+			ret = nfp_flow_action_output(position, action, nfp_flow_meta);
+			if (ret != 0) {
+				PMD_DRV_LOG(ERR, "Failed when process"
+						" RTE_FLOW_ACTION_TYPE_PORT_ID");
+				return ret;
+			}
+
+			position += sizeof(struct nfp_fl_act_output);
+			break;
+		default:
+			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
+			return -ENOTSUP;
+		}
+		total_actions++;
+	}
+
+	if (drop_flag)
+		nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_DROP);
+	else if (total_actions > 1)
+		nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_NULL);
+
+	return 0;
+}
+
 static struct rte_flow *
 nfp_flow_process(struct nfp_flower_representor *representor,
 		const struct rte_flow_item items[],
@@ -833,6 +939,12 @@ struct nfp_mask_id_entry {
 		goto free_flow;
 	}
 
+	ret = nfp_flow_compile_action(representor, actions, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow action process failed.");
+		goto free_flow;
+	}
+
 	nfp_flow_meta = nfp_flow->payload.meta;
 	mask_data = nfp_flow->payload.mask_data;
 	mask_len = key_layer.key_size;
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 83f9f29..f1fbada 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -33,6 +33,43 @@
 /* The firmware expects lengths in units of long words */
 #define NFP_FL_LW_SIZ                   2
 
+#define NFP_FL_SC_ACT_DROP      0x80000000
+#define NFP_FL_SC_ACT_USER      0x7D000000
+#define NFP_FL_SC_ACT_POPV      0x6A000000
+#define NFP_FL_SC_ACT_NULL      0x00000000
+
+/* Action opcodes */
+#define NFP_FL_ACTION_OPCODE_OUTPUT             0
+#define NFP_FL_ACTION_OPCODE_PUSH_VLAN          1
+#define NFP_FL_ACTION_OPCODE_POP_VLAN           2
+#define NFP_FL_ACTION_OPCODE_PUSH_MPLS          3
+#define NFP_FL_ACTION_OPCODE_POP_MPLS           4
+#define NFP_FL_ACTION_OPCODE_USERSPACE          5
+#define NFP_FL_ACTION_OPCODE_SET_TUNNEL         6
+#define NFP_FL_ACTION_OPCODE_SET_ETHERNET       7
+#define NFP_FL_ACTION_OPCODE_SET_MPLS           8
+#define NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS     9
+#define NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS   10
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_SRC       11
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_DST       12
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL  13
+#define NFP_FL_ACTION_OPCODE_SET_UDP            14
+#define NFP_FL_ACTION_OPCODE_SET_TCP            15
+#define NFP_FL_ACTION_OPCODE_PRE_LAG            16
+#define NFP_FL_ACTION_OPCODE_PRE_TUNNEL         17
+#define NFP_FL_ACTION_OPCODE_PRE_GS             18
+#define NFP_FL_ACTION_OPCODE_GS                 19
+#define NFP_FL_ACTION_OPCODE_PUSH_NSH           20
+#define NFP_FL_ACTION_OPCODE_POP_NSH            21
+#define NFP_FL_ACTION_OPCODE_SET_QUEUE          22
+#define NFP_FL_ACTION_OPCODE_CONNTRACK          23
+#define NFP_FL_ACTION_OPCODE_METER              24
+#define NFP_FL_ACTION_OPCODE_CT_NAT_EXT         25
+#define NFP_FL_ACTION_OPCODE_PUSH_GENEVE        26
+#define NFP_FL_ACTION_OPCODE_NUM                32
+
+#define NFP_FL_OUT_FLAGS_LAST            (1 << 15)
+
 /* Tunnel ports */
 #define NFP_FL_PORT_TYPE_TUN            0x50000000
 
-- 
1.8.3.1


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

* [PATCH v4 07/25] net/nfp: support VLAN flow item
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (5 preceding siblings ...)
  2022-10-18 11:26 ` [PATCH v4 06/25] net/nfp: support basic flow actions Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 08/25] net/nfp: support IPv4 " Chaoyong He
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 46 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h       |  2 ++
 3 files changed, 49 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f91da82..b0af2a0 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,6 +29,7 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 port_id              = Y
+vlan                 = Y
 
 [rte_flow actions]
 count                = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index dcc0942..72e642c 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -530,6 +530,10 @@ struct nfp_mask_id_entry {
 					ethdev->data->dev_private;
 			key_ls->port = rte_cpu_to_be_32(representor->port_id);
 			break;
+		case RTE_FLOW_ITEM_TYPE_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_VLAN detected");
+			key_ls->vlan = NFP_FLOWER_MASK_VLAN_CFI;
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -641,12 +645,42 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_vlan(struct rte_flow *nfp_flow,
+		__rte_unused char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_vlan *spec;
+	const struct rte_flow_item_vlan *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge vlan: no item->spec!");
+		return 0;
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.mask_data;
+		meta_tci->tci |= mask->tci;
+	} else {
+		meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+		meta_tci->tci |= spec->tci;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -659,6 +693,18 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_eth),
 		.merge = nfp_flow_merge_eth,
 	},
+	[RTE_FLOW_ITEM_TYPE_VLAN] = {
+		.mask_support = &(const struct rte_flow_item_vlan){
+			.hdr = {
+				.vlan_tci  = RTE_BE16(0xefff),
+				.eth_proto = RTE_BE16(0xffff),
+			},
+			.has_more_vlan = 1,
+		},
+		.mask_default = &rte_flow_item_vlan_mask,
+		.mask_sz = sizeof(struct rte_flow_item_vlan),
+		.merge = nfp_flow_merge_vlan,
+	},
 };
 
 static int
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index f1fbada..f6bd3e4 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -25,6 +25,8 @@
 
 #define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)
 
+#define NFP_FLOWER_MASK_VLAN_CFI        (1 << 12)
+
 #define NFP_MASK_TABLE_ENTRIES          1024
 
 /* The maximum action list size (in bytes) supported by the NFP. */
-- 
1.8.3.1


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

* [PATCH v4 08/25] net/nfp: support IPv4 flow item
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (6 preceding siblings ...)
  2022-10-18 11:26 ` [PATCH v4 07/25] net/nfp: support VLAN flow item Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 09/25] net/nfp: support IPv6 " Chaoyong He
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 38 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 68 +++++++++++++++++++++++++++++++-
 3 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index b0af2a0..bf59123 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -28,6 +28,7 @@ Usage doc            = Y
 
 [rte_flow items]
 eth                  = Y
+ipv4                 = Y
 port_id              = Y
 vlan                 = Y
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index d776e37..5964ecf 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -253,6 +253,44 @@ struct nfp_flower_mac_mpls {
 	rte_be32_t mpls_lse;
 };
 
+/*
+ * L4 ports (for UDP, TCP, SCTP) (1W/4B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |            port_src           |           port_dst            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_tp_ports {
+	rte_be16_t port_src;
+	rte_be16_t port_dst;
+};
+
+struct nfp_flower_ip_ext {
+	uint8_t tos;
+	uint8_t proto;
+	uint8_t ttl;
+	uint8_t flags;
+};
+
+/*
+ * L3 IPv4 details (3W/12B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    DSCP   |ECN|   protocol    |      ttl      |     flags     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                        ipv4_addr_src                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                        ipv4_addr_dst                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ipv4 {
+	struct nfp_flower_ip_ext ip_ext;
+	rte_be32_t ipv4_src;
+	rte_be32_t ipv4_dst;
+};
+
 struct nfp_fl_act_head {
 	uint8_t jump_id;
 	uint8_t len_lw;
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 72e642c..08c6ef8 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -534,6 +534,11 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_VLAN detected");
 			key_ls->vlan = NFP_FLOWER_MASK_VLAN_CFI;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV4:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV4;
+			key_ls->key_size += sizeof(struct nfp_flower_ipv4);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -674,13 +679,58 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_ipv4(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_ipv4 *ipv4;
+	const struct rte_ipv4_hdr *hdr;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_ipv4 *spec;
+	const struct rte_flow_item_ipv4 *mask;
+
+	spec = item->spec;
+	mask = item->mask ? item->mask : proc->mask_default;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge ipv4: no item->spec!");
+		goto ipv4_end;
+	}
+
+	/*
+	 * reserve space for L4 info.
+	 * rte_flow has ipv4 before L4 but NFP flower fw requires L4 before ipv4
+	 */
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP)
+		*mbuf_off += sizeof(struct nfp_flower_tp_ports);
+
+	hdr = is_mask ? &mask->hdr : &spec->hdr;
+	ipv4 = (struct nfp_flower_ipv4 *)*mbuf_off;
+
+	ipv4->ip_ext.tos   = hdr->type_of_service;
+	ipv4->ip_ext.proto = hdr->next_proto_id;
+	ipv4->ip_ext.ttl   = hdr->time_to_live;
+	ipv4->ipv4_src     = hdr->src_addr;
+	ipv4->ipv4_dst     = hdr->dst_addr;
+
+ipv4_end:
+	*mbuf_off += sizeof(struct nfp_flower_ipv4);
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN,
+			RTE_FLOW_ITEM_TYPE_IPV4),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -694,6 +744,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_eth,
 	},
 	[RTE_FLOW_ITEM_TYPE_VLAN] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4),
 		.mask_support = &(const struct rte_flow_item_vlan){
 			.hdr = {
 				.vlan_tci  = RTE_BE16(0xefff),
@@ -705,6 +756,21 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_vlan),
 		.merge = nfp_flow_merge_vlan,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.mask_support = &(const struct rte_flow_item_ipv4){
+			.hdr = {
+				.type_of_service = 0xff,
+				.fragment_offset = RTE_BE16(0xffff),
+				.time_to_live    = 0xff,
+				.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_flow_merge_ipv4,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v4 09/25] net/nfp: support IPv6 flow item
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (7 preceding siblings ...)
  2022-10-18 11:26 ` [PATCH v4 08/25] net/nfp: support IPv4 " Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:26 ` [PATCH v4 10/25] net/nfp: support TCP " Chaoyong He
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  2 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 33 +++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 73 +++++++++++++++++++++++++++++++-
 3 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index bf59123..fb40473 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,6 +29,8 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 ipv4                 = Y
+ipv6                 = Y
+ipv6_frag_ext        = Y
 port_id              = Y
 vlan                 = Y
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 5964ecf..36d406f 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -291,6 +291,39 @@ struct nfp_flower_ipv4 {
 	rte_be32_t ipv4_dst;
 };
 
+/*
+ * L3 IPv6 details (10W/40B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    DSCP   |ECN|   protocol    |      ttl      |     flags     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   ipv6_exthdr   | res |            ipv6_flow_label            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,   31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,  63 - 32                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,  95 - 64                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src, 127 - 96                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,   31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,  63 - 32                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,  95 - 64                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst, 127 - 96                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ipv6 {
+	struct nfp_flower_ip_ext ip_ext;
+	rte_be32_t ipv6_flow_label_exthdr;
+	uint8_t ipv6_src[16];
+	uint8_t ipv6_dst[16];
+};
+
 struct nfp_fl_act_head {
 	uint8_t jump_id;
 	uint8_t len_lw;
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 08c6ef8..043e5f8 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -539,6 +539,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV4;
 			key_ls->key_size += sizeof(struct nfp_flower_ipv4);
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV6 detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV6;
+			key_ls->key_size += sizeof(struct nfp_flower_ipv6);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -723,6 +728,51 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_ipv6(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_ipv6 *ipv6;
+	const struct rte_ipv6_hdr *hdr;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_ipv6 *spec;
+	const struct rte_flow_item_ipv6 *mask;
+
+	spec = item->spec;
+	mask = item->mask ? item->mask : proc->mask_default;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge ipv6: no item->spec!");
+		goto ipv6_end;
+	}
+
+	/*
+	 * reserve space for L4 info.
+	 * rte_flow has ipv4 before L4 but NFP flower fw requires L4 before ipv4
+	 */
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP)
+		*mbuf_off += sizeof(struct nfp_flower_tp_ports);
+
+	hdr = is_mask ? &mask->hdr : &spec->hdr;
+	ipv6 = (struct nfp_flower_ipv6 *)*mbuf_off;
+
+	ipv6->ip_ext.tos   = (hdr->vtc_flow & RTE_IPV6_HDR_TC_MASK) >>
+			RTE_IPV6_HDR_TC_SHIFT;
+	ipv6->ip_ext.proto = hdr->proto;
+	ipv6->ip_ext.ttl   = hdr->hop_limits;
+	memcpy(ipv6->ipv6_src, hdr->src_addr, sizeof(ipv6->ipv6_src));
+	memcpy(ipv6->ipv6_dst, hdr->dst_addr, sizeof(ipv6->ipv6_dst));
+
+ipv6_end:
+	*mbuf_off += sizeof(struct nfp_flower_ipv6);
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -730,7 +780,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN,
-			RTE_FLOW_ITEM_TYPE_IPV4),
+			RTE_FLOW_ITEM_TYPE_IPV4,
+			RTE_FLOW_ITEM_TYPE_IPV6),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -744,7 +795,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_eth,
 	},
 	[RTE_FLOW_ITEM_TYPE_VLAN] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4,
+			RTE_FLOW_ITEM_TYPE_IPV6),
 		.mask_support = &(const struct rte_flow_item_vlan){
 			.hdr = {
 				.vlan_tci  = RTE_BE16(0xefff),
@@ -771,6 +823,23 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_ipv4),
 		.merge = nfp_flow_merge_ipv4,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.mask_support = &(const struct rte_flow_item_ipv6){
+			.hdr = {
+				.vtc_flow   = RTE_BE32(0x0ff00000),
+				.proto      = 0xff,
+				.hop_limits = 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",
+			},
+			.has_frag_ext = 1,
+		},
+		.mask_default = &rte_flow_item_ipv6_mask,
+		.mask_sz = sizeof(struct rte_flow_item_ipv6),
+		.merge = nfp_flow_merge_ipv6,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v4 10/25] net/nfp: support TCP flow item
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (8 preceding siblings ...)
  2022-10-18 11:26 ` [PATCH v4 09/25] net/nfp: support IPv6 " Chaoyong He
@ 2022-10-18 11:26 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 11/25] net/nfp: support UDP " Chaoyong He
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 91 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h       |  7 ++++
 3 files changed, 99 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index fb40473..108f47d 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -32,6 +32,7 @@ ipv4                 = Y
 ipv6                 = Y
 ipv6_frag_ext        = Y
 port_id              = Y
+tcp                  = Y
 vlan                 = Y
 
 [rte_flow actions]
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 043e5f8..7727c32 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -544,6 +544,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV6;
 			key_ls->key_size += sizeof(struct nfp_flower_ipv6);
 			break;
+		case RTE_FLOW_ITEM_TYPE_TCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_TCP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -773,6 +778,78 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_tcp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	uint8_t tcp_flags;
+	struct nfp_flower_tp_ports *ports;
+	struct nfp_flower_ipv4 *ipv4 = NULL;
+	struct nfp_flower_ipv6 *ipv6 = NULL;
+	const struct rte_flow_item_tcp *spec;
+	const struct rte_flow_item_tcp *mask;
+	struct nfp_flower_meta_tci *meta_tci;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge tcp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ipv4  = (struct nfp_flower_ipv4 *)
+			(*mbuf_off - sizeof(struct nfp_flower_ipv4));
+		ports = (struct nfp_flower_tp_ports *)
+			((char *)ipv4 - sizeof(struct nfp_flower_tp_ports));
+	} else { /* IPv6 */
+		ipv6  = (struct nfp_flower_ipv6 *)
+			(*mbuf_off - sizeof(struct nfp_flower_ipv6));
+		ports = (struct nfp_flower_tp_ports *)
+			((char *)ipv6 - sizeof(struct nfp_flower_tp_ports));
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+		tcp_flags       = mask->hdr.tcp_flags;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+		tcp_flags       = spec->hdr.tcp_flags;
+	}
+
+	if (ipv4) {
+		if (tcp_flags & RTE_TCP_FIN_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_FIN;
+		if (tcp_flags & RTE_TCP_SYN_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_SYN;
+		if (tcp_flags & RTE_TCP_RST_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_RST;
+		if (tcp_flags & RTE_TCP_PSH_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_PSH;
+		if (tcp_flags & RTE_TCP_URG_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_URG;
+	} else {  /* IPv6 */
+		if (tcp_flags & RTE_TCP_FIN_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_FIN;
+		if (tcp_flags & RTE_TCP_SYN_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_SYN;
+		if (tcp_flags & RTE_TCP_RST_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_RST;
+		if (tcp_flags & RTE_TCP_PSH_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_PSH;
+		if (tcp_flags & RTE_TCP_URG_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_URG;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -809,6 +886,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_vlan,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -824,6 +902,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_ipv4,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -840,6 +919,18 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_ipv6),
 		.merge = nfp_flow_merge_ipv6,
 	},
+	[RTE_FLOW_ITEM_TYPE_TCP] = {
+		.mask_support = &(const struct rte_flow_item_tcp){
+			.hdr = {
+				.tcp_flags = 0xff,
+				.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_tcp,
+	},
 };
 
 static int
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index f6bd3e4..b3bd949 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -23,6 +23,13 @@
 #define NFP_FLOWER_LAYER2_GENEVE_OP (1 << 6)
 #define NFP_FLOWER_LAYER2_TUN_IPV6  (1 << 7)
 
+/* Compressed HW representation of TCP Flags */
+#define NFP_FL_TCP_FLAG_FIN         (1 << 0)
+#define NFP_FL_TCP_FLAG_SYN         (1 << 1)
+#define NFP_FL_TCP_FLAG_RST         (1 << 2)
+#define NFP_FL_TCP_FLAG_PSH         (1 << 3)
+#define NFP_FL_TCP_FLAG_URG         (1 << 4)
+
 #define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)
 
 #define NFP_FLOWER_MASK_VLAN_CFI        (1 << 12)
-- 
1.8.3.1


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

* [PATCH v4 11/25] net/nfp: support UDP flow item
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (9 preceding siblings ...)
  2022-10-18 11:26 ` [PATCH v4 10/25] net/nfp: support TCP " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 12/25] net/nfp: support SCTP " Chaoyong He
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload
of UDP item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 63 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 108f47d..3f3aaa9 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -33,6 +33,7 @@ ipv6                 = Y
 ipv6_frag_ext        = Y
 port_id              = Y
 tcp                  = Y
+udp                  = Y
 vlan                 = Y
 
 [rte_flow actions]
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 7727c32..afc7099 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -549,6 +549,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
 			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
 			break;
+		case RTE_FLOW_ITEM_TYPE_UDP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_UDP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -850,6 +855,47 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_udp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	char *ports_off;
+	struct nfp_flower_tp_ports *ports;
+	const struct rte_flow_item_udp *spec;
+	const struct rte_flow_item_udp *mask;
+	struct nfp_flower_meta_tci *meta_tci;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge udp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv4) -
+			sizeof(struct nfp_flower_tp_ports);
+	} else {/* IPv6 */
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv6) -
+			sizeof(struct nfp_flower_tp_ports);
+	}
+	ports = (struct nfp_flower_tp_ports *)ports_off;
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -886,7 +932,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_vlan,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+			RTE_FLOW_ITEM_TYPE_UDP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -902,7 +949,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_ipv4,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+			RTE_FLOW_ITEM_TYPE_UDP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -931,6 +979,17 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_tcp),
 		.merge = nfp_flow_merge_tcp,
 	},
+	[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_udp,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v4 12/25] net/nfp: support SCTP flow item
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (10 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 11/25] net/nfp: support UDP " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 13/25] net/nfp: support SRC MAC flow action Chaoyong He
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload
of SCTP item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 63 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 3f3aaa9..79a175b 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -32,6 +32,7 @@ ipv4                 = Y
 ipv6                 = Y
 ipv6_frag_ext        = Y
 port_id              = Y
+sctp                 = Y
 tcp                  = Y
 udp                  = Y
 vlan                 = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index afc7099..6b0d9ae 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -554,6 +554,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
 			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
 			break;
+		case RTE_FLOW_ITEM_TYPE_SCTP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_SCTP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -896,6 +901,47 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_sctp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	char *ports_off;
+	struct nfp_flower_tp_ports *ports;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_sctp *spec;
+	const struct rte_flow_item_sctp *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge sctp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv4) -
+			sizeof(struct nfp_flower_tp_ports);
+	} else { /* IPv6 */
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv6) -
+			sizeof(struct nfp_flower_tp_ports);
+	}
+	ports = (struct nfp_flower_tp_ports *)ports_off;
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -933,7 +979,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
-			RTE_FLOW_ITEM_TYPE_UDP),
+			RTE_FLOW_ITEM_TYPE_UDP,
+			RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -950,7 +997,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
-			RTE_FLOW_ITEM_TYPE_UDP),
+			RTE_FLOW_ITEM_TYPE_UDP,
+			RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -990,6 +1038,17 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_udp),
 		.merge = nfp_flow_merge_udp,
 	},
+	[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_sctp,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v4 13/25] net/nfp: support SRC MAC flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (11 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 12/25] net/nfp: support SCTP " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 14/25] net/nfp: support DST " Chaoyong He
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source MAC action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 27 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 47 ++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 79a175b..ed43b1f 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -41,3 +41,4 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 port_id              = Y
+set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 36d406f..b61342e 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -335,6 +335,33 @@ struct nfp_fl_act_output {
 	rte_be32_t port;
 };
 
+/*
+ * ETH
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |   -   |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_dst_47_16_mask                        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      eth_dst_15_0_mask        |      eth_src_47_32_mask       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_src_31_0_mask                         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_dst_47_16                             |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      eth_dst_15_0             |      eth_src_47_32            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_src_31_0                              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_eth {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	uint8_t eth_addr_mask[RTE_ETHER_ADDR_LEN * 2];
+	uint8_t eth_addr[RTE_ETHER_ADDR_LEN * 2];
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 6b0d9ae..a0a8c7b 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -573,6 +573,7 @@ struct nfp_mask_id_entry {
 		struct nfp_fl_key_ls *key_ls)
 {
 	int ret = 0;
+	bool mac_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -603,6 +604,13 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_PORT_ID detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_output);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_MAC_SRC detected");
+			if (!mac_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1221,6 +1229,36 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flow_action_set_mac(char *act_data,
+		const struct rte_flow_action *action,
+		bool mac_src_flag,
+		bool mac_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_eth *set_eth;
+	const struct rte_flow_action_set_mac *set_mac;
+
+	if (mac_set_flag)
+		set_eth = (struct nfp_fl_act_set_eth *)act_data - 1;
+	else
+		set_eth = (struct nfp_fl_act_set_eth *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_eth);
+	set_eth->head.jump_id = NFP_FL_ACTION_OPCODE_SET_ETHERNET;
+	set_eth->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_eth->reserved     = 0;
+
+	set_mac = (const struct rte_flow_action_set_mac *)action->conf;
+	if (mac_src_flag) {
+		rte_memcpy(&set_eth->eth_addr[RTE_ETHER_ADDR_LEN],
+				set_mac->mac_addr, RTE_ETHER_ADDR_LEN);
+	} else {
+		rte_memcpy(&set_eth->eth_addr[0],
+				set_mac->mac_addr, RTE_ETHER_ADDR_LEN);
+	}
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1230,6 +1268,7 @@ struct nfp_mask_id_entry {
 	char *position;
 	char *action_data;
 	bool drop_flag = false;
+	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
 	struct nfp_fl_rule_metadata *nfp_flow_meta;
@@ -1266,6 +1305,14 @@ struct nfp_mask_id_entry {
 
 			position += sizeof(struct nfp_fl_act_output);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_MAC_SRC");
+			nfp_flow_action_set_mac(position, action, true, mac_set_flag);
+			if (!mac_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 14/25] net/nfp: support DST MAC flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (12 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 13/25] net/nfp: support SRC MAC flow action Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 15/25] net/nfp: support pop VLAN " Chaoyong He
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest MAC action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index ed43b1f..9948d42 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -41,4 +41,5 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 port_id              = Y
+set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index a0a8c7b..46a9732 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -611,6 +611,13 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_MAC_DST detected");
+			if (!mac_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1313,6 +1320,14 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_MAC_DST");
+			nfp_flow_action_set_mac(position, action, false, mac_set_flag);
+			if (!mac_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 15/25] net/nfp: support pop VLAN flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (13 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 14/25] net/nfp: support DST " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 16/25] net/nfp: support push " Chaoyong He
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of pop_vlan action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  5 +++++
 drivers/net/nfp/nfp_flow.c               | 25 +++++++++++++++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 9948d42..ef089fb 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -40,6 +40,7 @@ vlan                 = Y
 [rte_flow actions]
 count                = Y
 drop                 = Y
+of_pop_vlan          = Y
 port_id              = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index b61342e..4ce03da 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -362,6 +362,11 @@ struct nfp_fl_act_set_eth {
 	uint8_t eth_addr[RTE_ETHER_ADDR_LEN * 2];
 };
 
+struct nfp_fl_act_pop_vlan {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 46a9732..18867fd 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -618,6 +618,10 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_POP_VLAN detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_pop_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1266,6 +1270,22 @@ struct nfp_mask_id_entry {
 	}
 }
 
+static void
+nfp_flow_action_pop_vlan(char *act_data,
+		struct nfp_fl_rule_metadata *nfp_flow_meta)
+{
+	size_t act_size;
+	struct nfp_fl_act_pop_vlan *pop_vlan;
+
+	act_size = sizeof(struct nfp_fl_act_pop_vlan);
+	pop_vlan = (struct nfp_fl_act_pop_vlan *)act_data;
+	pop_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_POP_VLAN;
+	pop_vlan->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	pop_vlan->reserved     = 0;
+
+	nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_POPV);
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1328,6 +1348,11 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_OF_POP_VLAN");
+			nfp_flow_action_pop_vlan(position, nfp_flow_meta);
+			position += sizeof(struct nfp_fl_act_pop_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 16/25] net/nfp: support push VLAN flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (14 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 15/25] net/nfp: support pop VLAN " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 17/25] net/nfp: support SRC IPv4 " Chaoyong He
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of push_vlan action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  3 ++
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  7 ++++
 drivers/net/nfp/nfp_flow.c               | 60 ++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index ef089fb..ba3455c 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -41,6 +41,9 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 of_pop_vlan          = Y
+of_push_vlan         = Y
+of_set_vlan_pcp      = Y
+of_set_vlan_vid      = Y
 port_id              = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 4ce03da..30a9ff5 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -367,6 +367,13 @@ struct nfp_fl_act_pop_vlan {
 	rte_be16_t reserved;
 };
 
+struct nfp_fl_act_push_vlan {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be16_t vlan_tpid;
+	rte_be16_t vlan_tci;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 18867fd..fecc97a 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -622,6 +622,16 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_POP_VLAN detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_pop_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_push_vlan);
+			break;
+		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP detected");
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1287,6 +1297,39 @@ struct nfp_mask_id_entry {
 }
 
 static int
+nfp_flow_action_push_vlan(char *act_data,
+		const struct rte_flow_action *action)
+{
+	size_t act_size;
+	struct nfp_fl_act_push_vlan *push_vlan;
+	const struct rte_flow_action_of_push_vlan *push_vlan_conf;
+	const struct rte_flow_action_of_set_vlan_pcp *vlan_pcp_conf;
+	const struct rte_flow_action_of_set_vlan_vid *vlan_vid_conf;
+
+	if (((action + 1)->type != RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP) ||
+			((action + 2)->type != RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID))
+		return -EINVAL;
+
+	act_size = sizeof(struct nfp_fl_act_push_vlan);
+	push_vlan = (struct nfp_fl_act_push_vlan *)act_data;
+	push_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_PUSH_VLAN;
+	push_vlan->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	push_vlan->reserved     = 0;
+
+	push_vlan_conf = (const struct rte_flow_action_of_push_vlan *)
+			action->conf;
+	vlan_pcp_conf  = (const struct rte_flow_action_of_set_vlan_pcp *)
+			(action + 1)->conf;
+	vlan_vid_conf  = (const struct rte_flow_action_of_set_vlan_vid *)
+			(action + 2)->conf;
+	push_vlan->vlan_tpid = push_vlan_conf->ethertype;
+	push_vlan->vlan_tci = ((vlan_pcp_conf->vlan_pcp & 0x07) << 13) |
+			(vlan_vid_conf->vlan_vid & 0x0fff);
+
+	return 0;
+}
+
+static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
 		struct rte_flow *nfp_flow)
@@ -1353,6 +1396,23 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_pop_vlan(position, nfp_flow_meta);
 			position += sizeof(struct nfp_fl_act_pop_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN");
+			ret = nfp_flow_action_push_vlan(position, action);
+			if (ret != 0) {
+				PMD_DRV_LOG(ERR, "Failed when process"
+						" RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN");
+				return ret;
+			}
+
+			/*
+			 * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP and
+			 * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID
+			 * have also been processed.
+			 */
+			action += 2;
+			position += sizeof(struct nfp_fl_act_push_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 17/25] net/nfp: support SRC IPv4 flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (15 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 16/25] net/nfp: support push " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 18/25] net/nfp: support DST " Chaoyong He
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source IPv4 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 25 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 45 ++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index ba3455c..dc5c676 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -45,5 +45,6 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 30a9ff5..77cb51d 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -374,6 +374,31 @@ struct nfp_fl_act_push_vlan {
 	rte_be16_t vlan_tci;
 };
 
+/*
+ * IPv4 addrs
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_saddr_mask                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_saddr                                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_daddr_mask                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_daddr                                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ip4_addrs {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be32_t ipv4_src_mask;
+	rte_be32_t ipv4_src;
+	rte_be32_t ipv4_dst_mask;
+	rte_be32_t ipv4_dst;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index fecc97a..c0df617 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -574,6 +574,7 @@ struct nfp_mask_id_entry {
 {
 	int ret = 0;
 	bool mac_set_flag = false;
+	bool ip_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -632,6 +633,14 @@ struct nfp_mask_id_entry {
 		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP detected");
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC detected");
+			if (!ip_set_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1296,6 +1305,33 @@ struct nfp_mask_id_entry {
 	nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_POPV);
 }
 
+static void
+nfp_flow_action_set_ip(char *act_data,
+		const struct rte_flow_action *action,
+		bool ip_src_flag,
+		bool ip_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_addrs *set_ip;
+	const struct rte_flow_action_set_ipv4 *set_ipv4;
+
+	if (ip_set_flag)
+		set_ip = (struct nfp_fl_act_set_ip4_addrs *)act_data - 1;
+	else
+		set_ip = (struct nfp_fl_act_set_ip4_addrs *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_addrs);
+	set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS;
+	set_ip->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_ip->reserved     = 0;
+
+	set_ipv4 = (const struct rte_flow_action_set_ipv4 *)action->conf;
+	if (ip_src_flag)
+		set_ip->ipv4_src = set_ipv4->ipv4_addr;
+	else
+		set_ip->ipv4_dst = set_ipv4->ipv4_addr;
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1338,6 +1374,7 @@ struct nfp_mask_id_entry {
 	char *position;
 	char *action_data;
 	bool drop_flag = false;
+	bool ip_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
@@ -1413,6 +1450,14 @@ struct nfp_mask_id_entry {
 			action += 2;
 			position += sizeof(struct nfp_fl_act_push_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC");
+			nfp_flow_action_set_ip(position, action, true, ip_set_flag);
+			if (!ip_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 18/25] net/nfp: support DST IPv4 flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (16 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 17/25] net/nfp: support SRC IPv4 " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 19/25] net/nfp: support SRC IPv6 " Chaoyong He
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest IPv4 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index dc5c676..9bcc8d6 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -45,6 +45,7 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_dst         = Y
 set_ipv4_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index c0df617..19fc8ca 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -641,6 +641,14 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_DST detected");
+			if (!ip_set_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1458,6 +1466,14 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_DST");
+			nfp_flow_action_set_ip(position, action, false, ip_set_flag);
+			if (!ip_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 19/25] net/nfp: support SRC IPv6 flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (17 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 18/25] net/nfp: support DST " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 20/25] net/nfp: support DST " Chaoyong He
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source IPv6 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 33 ++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 35 ++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 9bcc8d6..d841782 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -47,5 +47,6 @@ of_set_vlan_vid      = Y
 port_id              = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 77cb51d..45e50dd 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -399,6 +399,39 @@ struct nfp_fl_act_set_ip4_addrs {
 	rte_be32_t ipv4_dst;
 };
 
+/*
+ * IPv6 addr
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_127_96_mask                     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_127_96                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_95_64_mask                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_95_64                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_63_32_mask                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_63_32                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_31_0_mask                       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_31_0                            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ipv6_addr {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	struct {
+		rte_be32_t mask;
+		rte_be32_t exact;
+	} ipv6[4];
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 19fc8ca..839f559 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -649,6 +649,10 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1340,6 +1344,32 @@ struct nfp_mask_id_entry {
 		set_ip->ipv4_dst = set_ipv4->ipv4_addr;
 }
 
+static void
+nfp_flow_action_set_ipv6(char *act_data,
+		const struct rte_flow_action *action,
+		bool ip_src_flag)
+{
+	int i;
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_addr *set_ip;
+	const struct rte_flow_action_set_ipv6 *set_ipv6;
+
+	set_ip = (struct nfp_fl_act_set_ipv6_addr *)act_data;
+	set_ipv6 = (const struct rte_flow_action_set_ipv6 *)action->conf;
+
+	if (ip_src_flag)
+		set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_SRC;
+	else
+		set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_DST;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_addr);
+	set_ip->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+	set_ip->reserved = 0;
+
+	for (i = 0; i < 4; i++)
+		set_ip->ipv6[i].exact = set_ipv6->ipv6_addr[i];
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1474,6 +1504,11 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC");
+			nfp_flow_action_set_ipv6(position, action, true);
+			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 20/25] net/nfp: support DST IPv6 flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (18 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 19/25] net/nfp: support SRC IPv6 " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 21/25] net/nfp: support TP SRC " Chaoyong He
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest IPv6 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini | 1 +
 drivers/net/nfp/nfp_flow.c       | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index d841782..67c3ebe 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -47,6 +47,7 @@ of_set_vlan_vid      = Y
 port_id              = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 839f559..2cf82ce 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -653,6 +653,10 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DST detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1509,6 +1513,11 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_set_ipv6(position, action, true);
 			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_DST");
+			nfp_flow_action_set_ipv6(position, action, false);
+			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 21/25] net/nfp: support TP SRC flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (19 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 20/25] net/nfp: support DST " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 22/25] net/nfp: support TP DST " Chaoyong He
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set TP source port action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 21 +++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 44 ++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 67c3ebe..f40a995 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -51,3 +51,4 @@ set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
+set_tp_src           = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 45e50dd..26de8b1 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -432,6 +432,27 @@ struct nfp_fl_act_set_ipv6_addr {
 	} ipv6[4];
 };
 
+/*
+ * TCP/UDP/SCTP
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |          src_mask             |         dst_mask              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |          src                  |         dst                   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_tport {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be16_t src_port_mask;
+	rte_be16_t dst_port_mask;
+	rte_be16_t src_port;
+	rte_be16_t dst_port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 2cf82ce..dc37769 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -575,6 +575,7 @@ struct nfp_mask_id_entry {
 	int ret = 0;
 	bool mac_set_flag = false;
 	bool ip_set_flag = false;
+	bool tp_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -657,6 +658,13 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DST detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TP_SRC detected");
+			if (!tp_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1374,6 +1382,33 @@ struct nfp_mask_id_entry {
 		set_ip->ipv6[i].exact = set_ipv6->ipv6_addr[i];
 }
 
+static void
+nfp_flow_action_set_tp(char *act_data,
+		const struct rte_flow_action *action,
+		bool tp_src_flag,
+		bool tp_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_tport *set_tp;
+	const struct rte_flow_action_set_tp *set_tp_conf;
+
+	if (tp_set_flag)
+		set_tp = (struct nfp_fl_act_set_tport *)act_data - 1;
+	else
+		set_tp = (struct nfp_fl_act_set_tport *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_tport);
+	set_tp->head.jump_id = NFP_FL_ACTION_OPCODE_SET_TCP;
+	set_tp->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_tp->reserved     = 0;
+
+	set_tp_conf = (const struct rte_flow_action_set_tp *)action->conf;
+	if (tp_src_flag)
+		set_tp->src_port = set_tp_conf->port;
+	else
+		set_tp->dst_port = set_tp_conf->port;
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1417,6 +1452,7 @@ struct nfp_mask_id_entry {
 	char *action_data;
 	bool drop_flag = false;
 	bool ip_set_flag = false;
+	bool tp_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
@@ -1518,6 +1554,14 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_set_ipv6(position, action, false);
 			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TP_SRC");
+			nfp_flow_action_set_tp(position, action, true, tp_set_flag);
+			if (!tp_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 22/25] net/nfp: support TP DST flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (20 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 21/25] net/nfp: support TP SRC " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 23/25] net/nfp: support TTL " Chaoyong He
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of set
TP dest port action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f40a995..eb7fb15 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -51,4 +51,5 @@ set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
+set_tp_dst           = Y
 set_tp_src           = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index dc37769..6fe4e6c 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -665,6 +665,13 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TP_DST detected");
+			if (!tp_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1562,6 +1569,14 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TP_DST");
+			nfp_flow_action_set_tp(position, action, false, tp_set_flag);
+			if (!tp_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 23/25] net/nfp: support TTL flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (21 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 22/25] net/nfp: support TP DST " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 24/25] net/nfp: support IPv4 DSCP " Chaoyong He
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set TTL action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 44 +++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 84 ++++++++++++++++++++++++++++++++
 3 files changed, 129 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index eb7fb15..2e79935 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -53,3 +53,4 @@ set_mac_dst          = Y
 set_mac_src          = Y
 set_tp_dst           = Y
 set_tp_src           = Y
+set_ttl              = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 26de8b1..6bf8ff7 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -400,6 +400,25 @@ struct nfp_fl_act_set_ip4_addrs {
 };
 
 /*
+ * IPv4 ttl tos
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|    ttl_mask   |   tos_mask    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |       ttl     |      tos      |               0               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ip4_ttl_tos {
+	struct nfp_fl_act_head head;
+	uint8_t ipv4_ttl_mask;
+	uint8_t ipv4_tos_mask;
+	uint8_t ipv4_ttl;
+	uint8_t ipv4_tos;
+	rte_be16_t reserved;
+};
+
+/*
  * IPv6 addr
  *    3                   2                   1
  *  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
@@ -433,6 +452,31 @@ struct nfp_fl_act_set_ipv6_addr {
 };
 
 /*
+ * ipv6 tc hl fl
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|  tclass_mask  |  hlimit_mask  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |               0               |  tclass       |  hlimit       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           0           |             flabel_mask               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           0           |             flabel                    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ipv6_tc_hl_fl {
+	struct nfp_fl_act_head head;
+	uint8_t ipv6_tc_mask;
+	uint8_t ipv6_hop_limit_mask;
+	rte_be16_t reserved;
+	uint8_t ipv6_tc;
+	uint8_t ipv6_hop_limit;
+	rte_be32_t ipv6_label_mask;
+	rte_be32_t ipv6_label;
+};
+
+/*
  * TCP/UDP/SCTP
  *    3                   2                   1
  *  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
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 6fe4e6c..2f737b3 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -573,9 +573,11 @@ struct nfp_mask_id_entry {
 		struct nfp_fl_key_ls *key_ls)
 {
 	int ret = 0;
+	bool tc_hl_flag = false;
 	bool mac_set_flag = false;
 	bool ip_set_flag = false;
 	bool tp_set_flag = false;
+	bool ttl_tos_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -672,6 +674,22 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TTL:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TTL detected");
+			if (key_ls->key_layer & NFP_FLOWER_LAYER_IPV4) {
+				if (!ttl_tos_flag) {
+					key_ls->act_size +=
+						sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+					ttl_tos_flag = true;
+				}
+			} else {
+				if (!tc_hl_flag) {
+					key_ls->act_size +=
+						sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+					tc_hl_flag = true;
+				}
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1449,6 +1467,52 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flow_action_set_ttl(char *act_data,
+		const struct rte_flow_action *action,
+		bool ttl_tos_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_ttl_tos *ttl_tos;
+	const struct rte_flow_action_set_ttl *ttl_conf;
+
+	if (ttl_tos_flag)
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data - 1;
+	else
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+	ttl_tos->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS;
+	ttl_tos->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	ttl_conf = (const struct rte_flow_action_set_ttl *)action->conf;
+	ttl_tos->ipv4_ttl = ttl_conf->ttl_value;
+	ttl_tos->reserved = 0;
+}
+
+static void
+nfp_flow_action_set_hl(char *act_data,
+		const struct rte_flow_action *action,
+		bool tc_hl_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_tc_hl_fl *tc_hl;
+	const struct rte_flow_action_set_ttl *ttl_conf;
+
+	if (tc_hl_flag)
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data - 1;
+	else
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+	tc_hl->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL;
+	tc_hl->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	ttl_conf = (const struct rte_flow_action_set_ttl *)action->conf;
+	tc_hl->ipv6_hop_limit = ttl_conf->ttl_value;
+	tc_hl->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1457,17 +1521,21 @@ struct nfp_mask_id_entry {
 	int ret = 0;
 	char *position;
 	char *action_data;
+	bool ttl_tos_flag = false;
+	bool tc_hl_flag = false;
 	bool drop_flag = false;
 	bool ip_set_flag = false;
 	bool tp_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
+	struct nfp_flower_meta_tci *meta_tci;
 	struct nfp_fl_rule_metadata *nfp_flow_meta;
 
 	nfp_flow_meta = nfp_flow->payload.meta;
 	action_data   = nfp_flow->payload.action_data;
 	position      = action_data;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
 		switch (action->type) {
@@ -1577,6 +1645,22 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TTL:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TTL");
+			if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+				nfp_flow_action_set_ttl(position, action, ttl_tos_flag);
+				if (!ttl_tos_flag) {
+					position += sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+					ttl_tos_flag = true;
+				}
+			} else {
+				nfp_flow_action_set_hl(position, action, ttl_tos_flag);
+				if (!tc_hl_flag) {
+					position += sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+					tc_hl_flag = true;
+				}
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 24/25] net/nfp: support IPv4 DSCP flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (22 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 23/25] net/nfp: support TTL " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 11:27 ` [PATCH v4 25/25] net/nfp: support IPv6 " Chaoyong He
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set IPv4 DSCP action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 2e79935..d2b4188 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -45,6 +45,7 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_dscp        = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
 set_ipv6_dst         = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 2f737b3..6dff973 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -690,6 +690,14 @@ struct nfp_mask_id_entry {
 				}
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP detected");
+			if (!ttl_tos_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+				ttl_tos_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1513,6 +1521,29 @@ struct nfp_mask_id_entry {
 	tc_hl->reserved = 0;
 }
 
+static void
+nfp_flow_action_set_tos(char *act_data,
+		const struct rte_flow_action *action,
+		bool ttl_tos_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_ttl_tos *ttl_tos;
+	const struct rte_flow_action_set_dscp *tos_conf;
+
+	if (ttl_tos_flag)
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data - 1;
+	else
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+	ttl_tos->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS;
+	ttl_tos->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	tos_conf = (const struct rte_flow_action_set_dscp *)action->conf;
+	ttl_tos->ipv4_tos = tos_conf->dscp;
+	ttl_tos->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1661,6 +1692,14 @@ struct nfp_mask_id_entry {
 				}
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP");
+			nfp_flow_action_set_tos(position, action, ttl_tos_flag);
+			if (!ttl_tos_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+				ttl_tos_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v4 25/25] net/nfp: support IPv6 DSCP flow action
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (23 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 24/25] net/nfp: support IPv4 DSCP " Chaoyong He
@ 2022-10-18 11:27 ` Chaoyong He
  2022-10-18 12:27 ` [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Ferruh Yigit
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
  26 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-18 11:27 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set IPv6 DSCP action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index d2b4188..e547774 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -48,6 +48,7 @@ port_id              = Y
 set_ipv4_dscp        = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_dscp        = Y
 set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 6dff973..ceb61bf 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -698,6 +698,14 @@ struct nfp_mask_id_entry {
 				ttl_tos_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP detected");
+			if (!tc_hl_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+				tc_hl_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1544,6 +1552,29 @@ struct nfp_mask_id_entry {
 	ttl_tos->reserved = 0;
 }
 
+static void
+nfp_flow_action_set_tc(char *act_data,
+		const struct rte_flow_action *action,
+		bool tc_hl_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_tc_hl_fl *tc_hl;
+	const struct rte_flow_action_set_dscp *tos_conf;
+
+	if (tc_hl_flag)
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data - 1;
+	else
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+	tc_hl->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL;
+	tc_hl->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	tos_conf = (const struct rte_flow_action_set_dscp *)action->conf;
+	tc_hl->ipv6_tc = tos_conf->dscp;
+	tc_hl->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1700,6 +1731,14 @@ struct nfp_mask_id_entry {
 				ttl_tos_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP");
+			nfp_flow_action_set_tc(position, action, ttl_tos_flag);
+			if (!tc_hl_flag) {
+				position += sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+				tc_hl_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* Re: [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (24 preceding siblings ...)
  2022-10-18 11:27 ` [PATCH v4 25/25] net/nfp: support IPv6 " Chaoyong He
@ 2022-10-18 12:27 ` Ferruh Yigit
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
  26 siblings, 0 replies; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-18 12:27 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers, niklas.soderlund

On 10/18/2022 12:26 PM, Chaoyong He wrote:
> This is the second patch series to add the support of rte_flow offload for
> nfp PMD, includes:
> Implement the rte_flow related API
> Implement the offload framework of nfp card
> Add the offload support of common rte_flow pattern items
> Add the offload support of common rte_flow actions
> 
> * Changes since v2
> - Change the release note.
> - Change the headline of commit message.
> - Adjust the order of commits to prevent the memory problem.
> 
> * Changes since v2
> - Fix one problem import by the first patch series
> 
> * Changes since v1
> - Add the 'Depends-on' tag
> 
> Chaoyong He (25):
>    net/nfp: fix the requirement of cpp bridge service
>    net/nfp: add the structures and functions for flow offload
>    net/nfp: add the stats process logic in ctrl VNIC service
>    net/nfp: add the flow APIs of nfp PMD
>    net/nfp: support basic flow items
>    net/nfp: support basic flow actions
>    net/nfp: support VLAN flow item
>    net/nfp: support IPv4 flow item
>    net/nfp: support IPv6 flow item
>    net/nfp: support TCP flow item
>    net/nfp: support UDP flow item
>    net/nfp: support SCTP flow item
>    net/nfp: support SRC MAC flow action
>    net/nfp: support DST MAC flow action
>    net/nfp: support pop VLAN flow action
>    net/nfp: support push VLAN flow action
>    net/nfp: support SRC IPv4 flow action
>    net/nfp: support DST IPv4 flow action
>    net/nfp: support SRC IPv6 flow action
>    net/nfp: support DST IPv6 flow action
>    net/nfp: support TP SRC flow action
>    net/nfp: support TP DST flow action
>    net/nfp: support TTL flow action
>    net/nfp: support IPv4 DSCP flow action
>    net/nfp: support IPv6 DSCP flow action
> 

Hi Chaoyong,

It seems comment to first patch (v2 1/24) applied and rest ignored again.

Please check all comments [1]. Also there are some questions, can you 
please response to them?


And when you send new version can you please use '--in-reply-to' and 
reply to previous version to keep all versions in same email thread, 
otherwise it is too hard to find previous versions and comments to 
previous versions.
More details can be found in the documentation:
https://doc.dpdk.org/guides/contributing/patches.html#sending-patches


[1]
https://inbox.dpdk.org/dev/1665382142-21684-1-git-send-email-chaoyong.he@corigine.com/


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

* Re: [PATCH v4 01/25] net/nfp: fix the requirement of cpp bridge service
  2022-10-18 11:26 ` [PATCH v4 01/25] net/nfp: fix the requirement of cpp bridge service Chaoyong He
@ 2022-10-18 12:39   ` Ferruh Yigit
  0 siblings, 0 replies; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-18 12:39 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers, niklas.soderlund

On 10/18/2022 12:26 PM, Chaoyong He wrote:
> The cpp bridge service is needed for some debug tools, and should be
> optional, so remove the mandatory requirement of service lcore parameter.
> 

I assume cpp is 'Command Push Pull', if so please describe it in the 
commit log (unless it is a common abbreviation),
like "The CPP (Command Pull Push) bridge ..."

Also in patch title please use abbreviations as upper case, like:
net/nfp: fix CPP bridge service requirement

> Fixes: b18804219537 ("net/nfp: add initial flower firmware support")
> 
> Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> ---
>   drivers/net/nfp/nfp_ethdev.c | 7 ++-----
>   1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
> index f11a1b6..b105edb 100644
> --- a/drivers/net/nfp/nfp_ethdev.c
> +++ b/drivers/net/nfp/nfp_ethdev.c
> @@ -1066,11 +1066,8 @@
>   
>   	/* register the CPP bridge service here for primary use */
>   	ret = nfp_enable_cpp_service(pf_dev->cpp);
> -	if (ret != 0) {
> -		PMD_INIT_LOG(ERR, "Enable cpp service failed.");
> -		ret = -EINVAL;
> -		goto hwqueues_cleanup;
> -	}
> +	if (ret != 0)
> +		PMD_INIT_LOG(INFO, "Enable cpp service failed.");

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

* [PATCH v5 00/25] add the basic rte_flow offload support of nfp PMD
  2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
                   ` (25 preceding siblings ...)
  2022-10-18 12:27 ` [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Ferruh Yigit
@ 2022-10-20  2:19 ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 01/25] net/nfp: fix CPP bridge service requirement Chaoyong He
                     ` (25 more replies)
  26 siblings, 26 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

This is the second patch series to add the support of rte_flow offload for
nfp PMD, includes:
Implement the rte_flow related API
Implement the offload framework of nfp card
Add the offload support of common rte_flow pattern items
Add the offload support of common rte_flow actions

* Changes since v4
- Store the hash_key to avoid the uncessary repeat calculation.
- Make sure '.validate' don't update 'flower_version'.
- Guarante 'query' is zeroed out.
- Use the 'rest' field of query action to decide if reset the stats.
- Modify the 'nfp.ini' document.

* Changes since v3
- Change the release note.
- Change the headline of commit message.
- Adjust the order of commits to prevent the memory problem.

* Changes since v2
- Fix one problem import by the first patch series

* Changes since v1
- Add the 'Depends-on' tag

Chaoyong He (25):
  net/nfp: fix CPP bridge service requirement
  net/nfp: add the structures and functions for flow offload
  net/nfp: add the stats process logic in ctrl VNIC service
  net/nfp: add the flow APIs of nfp PMD
  net/nfp: support basic flow items
  net/nfp: support basic flow actions
  net/nfp: support VLAN flow item
  net/nfp: support IPv4 flow item
  net/nfp: support IPv6 flow item
  net/nfp: support TCP flow item
  net/nfp: support UDP flow item
  net/nfp: support SCTP flow item
  net/nfp: support SRC MAC flow action
  net/nfp: support DST MAC flow action
  net/nfp: support pop VLAN flow action
  net/nfp: support push VLAN flow action
  net/nfp: support SRC IPv4 flow action
  net/nfp: support DST IPv4 flow action
  net/nfp: support SRC IPv6 flow action
  net/nfp: support DST IPv6 flow action
  net/nfp: support TP SRC flow action
  net/nfp: support TP DST flow action
  net/nfp: support TTL flow action
  net/nfp: support IPv4 DSCP flow action
  net/nfp: support IPv6 DSCP flow action

 doc/guides/nics/features/nfp.ini                |   30 +
 doc/guides/rel_notes/release_22_11.rst          |    2 +
 drivers/net/nfp/flower/nfp_flower.c             |   11 +-
 drivers/net/nfp/flower/nfp_flower.h             |    2 +
 drivers/net/nfp/flower/nfp_flower_cmsg.c        |   69 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h        |  337 ++++
 drivers/net/nfp/flower/nfp_flower_ctrl.c        |   73 +-
 drivers/net/nfp/flower/nfp_flower_representor.c |    3 +
 drivers/net/nfp/meson.build                     |    3 +
 drivers/net/nfp/nfp_ethdev.c                    |   13 +-
 drivers/net/nfp/nfp_flow.c                      | 2295 +++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h                      |  176 ++
 12 files changed, 3000 insertions(+), 14 deletions(-)
 create mode 100644 drivers/net/nfp/nfp_flow.c
 create mode 100644 drivers/net/nfp/nfp_flow.h

-- 
1.8.3.1


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

* [PATCH v5 01/25] net/nfp: fix CPP bridge service requirement
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 02/25] net/nfp: add the structures and functions for flow offload Chaoyong He
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

The CPP(Command Pull Push) bridge service is needed for some debug tools,
and should be optional, so remove the mandatory requirement of service
lcore parameter.

Fixes: b18804219537 ("net/nfp: add initial flower firmware support")

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/nfp_ethdev.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index f11a1b6..78c5c0f 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -1066,11 +1066,8 @@
 
 	/* register the CPP bridge service here for primary use */
 	ret = nfp_enable_cpp_service(pf_dev->cpp);
-	if (ret != 0) {
-		PMD_INIT_LOG(ERR, "Enable cpp service failed.");
-		ret = -EINVAL;
-		goto hwqueues_cleanup;
-	}
+	if (ret != 0)
+		PMD_INIT_LOG(INFO, "Enable cpp service failed.");
 
 	return 0;
 
@@ -1210,10 +1207,8 @@
 
 	/* Register the CPP bridge service for the secondary too */
 	ret = nfp_enable_cpp_service(cpp);
-	if (ret != 0) {
-		PMD_INIT_LOG(ERR, "Enable cpp service failed.");
-		ret = -EINVAL;
-	}
+	if (ret != 0)
+		PMD_INIT_LOG(INFO, "Enable cpp service failed.");
 
 sym_tbl_cleanup:
 	free(sym_tbl);
-- 
1.8.3.1


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

* [PATCH v5 02/25] net/nfp: add the structures and functions for flow offload
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 01/25] net/nfp: fix CPP bridge service requirement Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 03/25] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
                     ` (23 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the structures and functions to process mask table, flow
table, and flow stats id, which are used in the rte_flow
offload logics.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower.c |  11 +-
 drivers/net/nfp/flower/nfp_flower.h |   2 +
 drivers/net/nfp/meson.build         |   3 +
 drivers/net/nfp/nfp_flow.c          | 496 ++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h          | 102 ++++++++
 5 files changed, 613 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/nfp/nfp_flow.c
 create mode 100644 drivers/net/nfp/nfp_flow.h

diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index 3e97f5c..168bf0c 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -15,6 +15,7 @@
 #include "../nfp_ctrl.h"
 #include "../nfp_cpp_bridge.h"
 #include "../nfp_rxtx.h"
+#include "../nfp_flow.h"
 #include "../nfpcore/nfp_mip.h"
 #include "../nfpcore/nfp_rtsym.h"
 #include "../nfpcore/nfp_nsp.h"
@@ -1089,13 +1090,19 @@
 
 	pf_dev->app_fw_priv = app_fw_flower;
 
+	ret = nfp_flow_priv_init(pf_dev);
+	if (ret != 0) {
+		PMD_INIT_LOG(ERR, "init flow priv failed");
+		goto app_cleanup;
+	}
+
 	/* Allocate memory for the PF AND ctrl vNIC here (hence the * 2) */
 	pf_hw = rte_zmalloc_socket("nfp_pf_vnic", 2 * sizeof(struct nfp_net_adapter),
 			RTE_CACHE_LINE_SIZE, numa_node);
 	if (pf_hw == NULL) {
 		PMD_INIT_LOG(ERR, "Could not malloc nfp pf vnic");
 		ret = -ENOMEM;
-		goto app_cleanup;
+		goto flow_priv_cleanup;
 	}
 
 	/* Map the PF ctrl bar */
@@ -1173,6 +1180,8 @@
 	nfp_cpp_area_free(pf_dev->ctrl_area);
 vnic_cleanup:
 	rte_free(pf_hw);
+flow_priv_cleanup:
+	nfp_flow_priv_uninit(pf_dev);
 app_cleanup:
 	rte_free(app_fw_flower);
 
diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index 48f597a..b90391c 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -51,6 +51,8 @@ struct nfp_app_fw_flower {
 
 	/* PF representor */
 	struct nfp_flower_representor *pf_repr;
+
+	struct nfp_flow_priv *flow_priv;
 };
 
 int nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev);
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 8a63979..7416fd3 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -27,4 +27,7 @@ sources = files(
         'nfp_cpp_bridge.c',
         'nfp_ethdev_vf.c',
         'nfp_ethdev.c',
+        'nfp_flow.c',
 )
+
+deps += ['hash']
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
new file mode 100644
index 0000000..8c36e97
--- /dev/null
+++ b/drivers/net/nfp/nfp_flow.c
@@ -0,0 +1,496 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include <rte_flow_driver.h>
+#include <rte_hash.h>
+#include <rte_jhash.h>
+#include <bus_pci_driver.h>
+
+#include "nfp_common.h"
+#include "nfp_flow.h"
+#include "nfp_logs.h"
+#include "flower/nfp_flower.h"
+#include "nfpcore/nfp_mip.h"
+#include "nfpcore/nfp_rtsym.h"
+
+struct nfp_mask_id_entry {
+	uint32_t hash_key;
+	uint32_t ref_cnt;
+	uint8_t mask_id;
+};
+
+static int
+nfp_mask_id_alloc(struct nfp_flow_priv *priv, uint8_t *mask_id)
+{
+	uint8_t temp_id;
+	uint8_t freed_id;
+	struct circ_buf *ring;
+
+	/* Checking for unallocated entries first. */
+	if (priv->mask_ids.init_unallocated > 0) {
+		*mask_id = priv->mask_ids.init_unallocated;
+		priv->mask_ids.init_unallocated--;
+		return 0;
+	}
+
+	/* Checking if buffer is empty. */
+	freed_id = NFP_FLOWER_MASK_ENTRY_RS - 1;
+	ring = &priv->mask_ids.free_list;
+	if (ring->head == ring->tail) {
+		*mask_id = freed_id;
+		return -ENOENT;
+	}
+
+	rte_memcpy(&temp_id, &ring->buf[ring->tail], NFP_FLOWER_MASK_ELEMENT_RS);
+	*mask_id = temp_id;
+
+	rte_memcpy(&ring->buf[ring->tail], &freed_id, NFP_FLOWER_MASK_ELEMENT_RS);
+	ring->tail = (ring->tail + NFP_FLOWER_MASK_ELEMENT_RS) %
+			(NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS);
+
+	return 0;
+}
+
+static int
+nfp_mask_id_free(struct nfp_flow_priv *priv, uint8_t mask_id)
+{
+	struct circ_buf *ring;
+
+	ring = &priv->mask_ids.free_list;
+
+	/* Checking if buffer is full. */
+	if (CIRC_SPACE(ring->head, ring->tail, NFP_FLOWER_MASK_ENTRY_RS) == 0)
+		return -ENOBUFS;
+
+	rte_memcpy(&ring->buf[ring->head], &mask_id, NFP_FLOWER_MASK_ELEMENT_RS);
+	ring->head = (ring->head + NFP_FLOWER_MASK_ELEMENT_RS) %
+			(NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS);
+
+	return 0;
+}
+
+static int
+nfp_mask_table_add(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *id)
+{
+	int ret;
+	uint8_t mask_id;
+	uint32_t hash_key;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = rte_zmalloc("mask_entry", sizeof(struct nfp_mask_id_entry), 0);
+	if (mask_entry == NULL) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = nfp_mask_id_alloc(priv, &mask_id);
+	if (ret != 0)
+		goto mask_entry_free;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	mask_entry->mask_id  = mask_id;
+	mask_entry->hash_key = hash_key;
+	mask_entry->ref_cnt  = 1;
+	PMD_DRV_LOG(DEBUG, "hash_key=%#x id=%u ref=%u", hash_key,
+			mask_id, mask_entry->ref_cnt);
+
+	ret = rte_hash_add_key_data(priv->mask_table, &hash_key, mask_entry);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Add to mask table failed.");
+		goto mask_id_free;
+	}
+
+	*id = mask_id;
+	return 0;
+
+mask_id_free:
+	nfp_mask_id_free(priv, mask_id);
+mask_entry_free:
+	rte_free(mask_entry);
+exit:
+	return ret;
+}
+
+static int
+nfp_mask_table_del(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t id)
+{
+	int ret;
+	uint32_t hash_key;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	ret = rte_hash_del_key(priv->mask_table, &hash_key);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Delete from mask table failed.");
+		return ret;
+	}
+
+	ret = nfp_mask_id_free(priv, id);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Free mask id failed.");
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct nfp_mask_id_entry *
+nfp_mask_table_search(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len)
+{
+	int index;
+	uint32_t hash_key;
+	struct nfp_mask_id_entry *entry;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	index = rte_hash_lookup_data(priv->mask_table, &hash_key, (void **)&entry);
+	if (index < 0) {
+		PMD_DRV_LOG(DEBUG, "Data NOT found in the mask table.");
+		return NULL;
+	}
+
+	return entry;
+}
+
+__rte_unused static bool
+nfp_check_mask_add(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *meta_flags,
+		uint8_t *mask_id)
+{
+	int ret;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = nfp_mask_table_search(priv, mask_data, mask_len);
+	if (mask_entry == NULL) {
+		/* mask entry does not exist, let's create one */
+		ret = nfp_mask_table_add(priv, mask_data, mask_len, mask_id);
+		if (ret != 0)
+			return false;
+
+		*meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK;
+	} else {
+		/* mask entry already exist */
+		mask_entry->ref_cnt++;
+		*mask_id = mask_entry->mask_id;
+	}
+
+	return true;
+}
+
+__rte_unused static bool
+nfp_check_mask_remove(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *meta_flags)
+{
+	int ret;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = nfp_mask_table_search(priv, mask_data, mask_len);
+	if (mask_entry == NULL)
+		return false;
+
+	mask_entry->ref_cnt--;
+	if (mask_entry->ref_cnt == 0) {
+		ret = nfp_mask_table_del(priv, mask_data, mask_len,
+				mask_entry->mask_id);
+		if (ret != 0)
+			return false;
+
+		rte_free(mask_entry);
+		if (meta_flags)
+			*meta_flags &= ~NFP_FL_META_FLAG_MANAGE_MASK;
+	}
+
+	return true;
+}
+
+__rte_unused static int
+nfp_flow_table_add(struct nfp_flow_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_flow_table_delete(struct nfp_flow_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_flow_table_search(struct nfp_flow_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_flow_alloc(struct nfp_fl_key_ls *key_layer)
+{
+	char *tmp;
+	size_t len;
+	struct rte_flow *nfp_flow;
+	struct nfp_fl_payload *payload;
+
+	nfp_flow = rte_zmalloc("nfp_flow", sizeof(struct rte_flow), 0);
+	if (nfp_flow == NULL)
+		goto exit;
+
+	len = key_layer->key_size + key_layer->key_size + key_layer->act_size;
+	tmp = rte_zmalloc("nfp_flow_payload", len + sizeof(struct nfp_fl_rule_metadata), 0);
+	if (tmp == NULL)
+		goto free_flow;
+
+	nfp_flow->length = len;
+
+	payload                = &nfp_flow->payload;
+	payload->meta          = (struct nfp_fl_rule_metadata *)tmp;
+	payload->unmasked_data = tmp + sizeof(struct nfp_fl_rule_metadata);
+	payload->mask_data     = payload->unmasked_data + key_layer->key_size;
+	payload->action_data   = payload->mask_data + key_layer->key_size;
+
+	return nfp_flow;
+
+free_flow:
+	rte_free(nfp_flow);
+exit:
+	return NULL;
+}
+
+__rte_unused static void
+nfp_flow_free(struct rte_flow *nfp_flow)
+{
+	rte_free(nfp_flow->payload.meta);
+	rte_free(nfp_flow);
+}
+
+__rte_unused static int
+nfp_stats_id_alloc(struct nfp_flow_priv *priv, uint32_t *ctx)
+{
+	struct circ_buf *ring;
+	uint32_t freed_stats_id;
+	uint32_t temp_stats_id;
+
+	/* Check for unallocated entries first. */
+	if (priv->stats_ids.init_unallocated > 0) {
+		*ctx = ((priv->stats_ids.init_unallocated - 1) & NFP_FL_STAT_ID_STAT) |
+				(priv->active_mem_unit & NFP_FL_STAT_ID_MU_NUM);
+		if (++priv->active_mem_unit == priv->total_mem_units) {
+			priv->stats_ids.init_unallocated--;
+			priv->active_mem_unit = 0;
+		}
+		return 0;
+	}
+
+	/* Check if buffer is empty */
+	ring = &priv->stats_ids.free_list;
+	freed_stats_id = priv->stats_ring_size;
+	if (ring->head == ring->tail) {
+		*ctx = freed_stats_id;
+		return -ENOENT;
+	}
+
+	memcpy(&temp_stats_id, &ring->buf[ring->tail], NFP_FL_STATS_ELEM_RS);
+	*ctx = temp_stats_id;
+	memcpy(&ring->buf[ring->tail], &freed_stats_id, NFP_FL_STATS_ELEM_RS);
+	ring->tail = (ring->tail + NFP_FL_STATS_ELEM_RS) %
+			(priv->stats_ring_size * NFP_FL_STATS_ELEM_RS);
+
+	return 0;
+}
+
+__rte_unused static int
+nfp_stats_id_free(struct nfp_flow_priv *priv, uint32_t ctx)
+{
+	struct circ_buf *ring;
+
+	/* Check if buffer is full */
+	ring = &priv->stats_ids.free_list;
+	if (!CIRC_SPACE(ring->head, ring->tail, priv->stats_ring_size *
+			NFP_FL_STATS_ELEM_RS - NFP_FL_STATS_ELEM_RS + 1))
+		return -ENOBUFS;
+
+	memcpy(&ring->buf[ring->head], &ctx, NFP_FL_STATS_ELEM_RS);
+	ring->head = (ring->head + NFP_FL_STATS_ELEM_RS) %
+			(priv->stats_ring_size * NFP_FL_STATS_ELEM_RS);
+
+	return 0;
+}
+
+int
+nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)
+{
+	int ret = 0;
+	uint64_t ctx_count;
+	uint64_t ctx_split;
+	size_t stats_size;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+
+	struct rte_hash_parameters mask_hash_params = {
+		.name       = "mask_hash_table",
+		.entries    = NFP_MASK_TABLE_ENTRIES,
+		.hash_func  = rte_jhash,
+		.socket_id  = rte_socket_id(),
+		.key_len    = sizeof(uint32_t),
+		.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,
+	};
+
+	struct rte_hash_parameters flow_hash_params = {
+		.name       = "flow_hash_table",
+		.hash_func  = rte_jhash,
+		.socket_id  = rte_socket_id(),
+		.key_len    = sizeof(uint32_t),
+		.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,
+	};
+
+	ctx_count = nfp_rtsym_read_le(pf_dev->sym_tbl,
+			"CONFIG_FC_HOST_CTX_COUNT", &ret);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "Read CTX_COUNT from symbol table failed");
+		goto exit;
+	}
+
+	ctx_split = nfp_rtsym_read_le(pf_dev->sym_tbl,
+			"CONFIG_FC_HOST_CTX_SPLIT", &ret);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "Read CTX_SPLIT from symbol table failed");
+		goto exit;
+	}
+
+	priv = rte_zmalloc("nfp_app_flow_priv", sizeof(struct nfp_flow_priv), 0);
+	if (priv == NULL) {
+		PMD_INIT_LOG(ERR, "nfp app flow priv creation failed");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+	app_fw_flower->flow_priv = priv;
+	priv->hash_seed = (uint32_t)rte_rand();
+	priv->stats_ring_size = ctx_count;
+	priv->total_mem_units = ctx_split;
+
+	/* Init ring buffer and unallocated mask_ids. */
+	priv->mask_ids.init_unallocated = NFP_FLOWER_MASK_ENTRY_RS - 1;
+	priv->mask_ids.free_list.buf = rte_zmalloc("nfp_app_mask_ids",
+			NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS, 0);
+	if (priv->mask_ids.free_list.buf == NULL) {
+		PMD_INIT_LOG(ERR, "mask id free list creation failed");
+		ret = -ENOMEM;
+		goto free_priv;
+	}
+
+	/* Init ring buffer and unallocated stats_ids. */
+	priv->stats_ids.init_unallocated = ctx_count / ctx_split;
+	priv->stats_ids.free_list.buf = rte_zmalloc("nfp_app_stats_ids",
+			priv->stats_ring_size * NFP_FL_STATS_ELEM_RS, 0);
+	if (priv->stats_ids.free_list.buf == NULL) {
+		PMD_INIT_LOG(ERR, "stats id free list creation failed");
+		ret = -ENOMEM;
+		goto free_mask_id;
+	}
+
+	/* flow stats */
+	rte_spinlock_init(&priv->stats_lock);
+	stats_size = (ctx_count & NFP_FL_STAT_ID_STAT) |
+			((ctx_split - 1) & NFP_FL_STAT_ID_MU_NUM);
+	PMD_INIT_LOG(INFO, "ctx_count:%0lx, ctx_split:%0lx, stats_size:%0lx ",
+			ctx_count, ctx_split, stats_size);
+	priv->stats = rte_zmalloc("nfp_flow_stats",
+			stats_size * sizeof(struct nfp_fl_stats), 0);
+	if (priv->stats == NULL) {
+		PMD_INIT_LOG(ERR, "flow stats creation failed");
+		ret = -ENOMEM;
+		goto free_stats_id;
+	}
+
+	/* mask table */
+	mask_hash_params.hash_func_init_val = priv->hash_seed;
+	priv->mask_table = rte_hash_create(&mask_hash_params);
+	if (priv->mask_table == NULL) {
+		PMD_INIT_LOG(ERR, "mask hash table creation failed");
+		ret = -ENOMEM;
+		goto free_stats;
+	}
+
+	/* flow table */
+	flow_hash_params.hash_func_init_val = priv->hash_seed;
+	flow_hash_params.entries = ctx_count;
+	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_mask_table;
+	}
+
+	return 0;
+
+free_mask_table:
+	rte_free(priv->mask_table);
+free_stats:
+	rte_free(priv->stats);
+free_stats_id:
+	rte_free(priv->stats_ids.free_list.buf);
+free_mask_id:
+	rte_free(priv->mask_ids.free_list.buf);
+free_priv:
+	rte_free(priv);
+exit:
+	return ret;
+}
+
+void
+nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev)
+{
+	struct nfp_app_fw_flower *app_fw_flower;
+	struct nfp_flow_priv *priv;
+
+	app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+	priv = app_fw_flower->flow_priv;
+
+	rte_hash_free(priv->flow_table);
+	rte_hash_free(priv->mask_table);
+	rte_free(priv->stats);
+	rte_free(priv->stats_ids.free_list.buf);
+	rte_free(priv->mask_ids.free_list.buf);
+	rte_free(priv);
+}
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
new file mode 100644
index 0000000..e8fd22a
--- /dev/null
+++ b/drivers/net/nfp/nfp_flow.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _NFP_FLOW_H_
+#define _NFP_FLOW_H_
+
+#define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)
+
+#define NFP_MASK_TABLE_ENTRIES          1024
+
+enum nfp_flower_tun_type {
+	NFP_FL_TUN_NONE   = 0,
+	NFP_FL_TUN_GRE    = 1,
+	NFP_FL_TUN_VXLAN  = 2,
+	NFP_FL_TUN_GENEVE = 4,
+};
+
+struct nfp_fl_key_ls {
+	uint32_t key_layer_two;
+	uint8_t key_layer;
+	int key_size;
+	int act_size;
+	uint32_t port;
+	uint16_t vlan;
+	enum nfp_flower_tun_type tun_type;
+};
+
+struct nfp_fl_rule_metadata {
+	uint8_t key_len;
+	uint8_t mask_len;
+	uint8_t act_len;
+	uint8_t flags;
+	rte_be32_t host_ctx_id;
+	rte_be64_t host_cookie __rte_packed;
+	rte_be64_t flow_version __rte_packed;
+	rte_be32_t shortcut;
+};
+
+struct nfp_fl_payload {
+	struct nfp_fl_rule_metadata *meta;
+	char *unmasked_data;
+	char *mask_data;
+	char *action_data;
+};
+
+#define CIRC_CNT(head, tail, size)     (((head) - (tail)) & ((size) - 1))
+#define CIRC_SPACE(head, tail, size)   CIRC_CNT((tail), ((head) + 1), (size))
+struct circ_buf {
+	uint32_t head;
+	uint32_t tail;
+	char *buf;
+};
+
+#define NFP_FLOWER_MASK_ENTRY_RS        256
+#define NFP_FLOWER_MASK_ELEMENT_RS      sizeof(uint8_t)
+struct nfp_fl_mask_id {
+	struct circ_buf free_list;
+	uint8_t init_unallocated;
+};
+
+#define NFP_FL_STATS_ELEM_RS            sizeof(uint32_t)
+struct nfp_fl_stats_id {
+	struct circ_buf free_list;
+	uint32_t init_unallocated;
+};
+
+#define NFP_FL_STAT_ID_MU_NUM           0xffc00000
+#define NFP_FL_STAT_ID_STAT             0x003fffff
+struct nfp_fl_stats {
+	uint64_t pkts;
+	uint64_t bytes;
+};
+
+struct nfp_flow_priv {
+	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
+	/* mask hash table */
+	struct nfp_fl_mask_id mask_ids; /**< Entry for mask hash table */
+	struct rte_hash *mask_table; /**< Hash table to store mask ids. */
+	/* flow hash table */
+	struct rte_hash *flow_table; /**< Hash table to store flow rules. */
+	/* flow stats */
+	uint32_t active_mem_unit; /**< The size of active mem units. */
+	uint32_t total_mem_units; /**< The size of total mem units. */
+	uint32_t stats_ring_size; /**< The size of stats id ring. */
+	struct nfp_fl_stats_id stats_ids; /**< The stats id ring. */
+	struct nfp_fl_stats *stats; /**< Store stats of flow. */
+	rte_spinlock_t stats_lock; /** < Lock the update of 'stats' field. */
+};
+
+struct rte_flow {
+	struct nfp_fl_payload payload;
+	size_t length;
+	uint32_t hash_key;
+	bool install_flag;
+};
+
+int nfp_flow_priv_init(struct nfp_pf_dev *pf_dev);
+void nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev);
+
+#endif /* _NFP_FLOW_H_ */
-- 
1.8.3.1


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

* [PATCH v5 03/25] net/nfp: add the stats process logic in ctrl VNIC service
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 01/25] net/nfp: fix CPP bridge service requirement Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 02/25] net/nfp: add the structures and functions for flow offload Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 04/25] net/nfp: add the flow APIs of nfp PMD Chaoyong He
                     ` (22 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the flow stats process logic in the ctrl VNIC service.
The flower firmware pass the flow stats to nfp driver through
control message, we store them in the flow_priv structure.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 25 +++++++++++
 drivers/net/nfp/flower/nfp_flower_ctrl.c | 73 ++++++++++++++++++++++++++++++--
 2 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 0bf8fc8..5c28363 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -129,6 +129,31 @@ struct nfp_flower_cmsg_port_mod {
 	rte_be16_t mtu;
 };
 
+/*
+ * NFP_FLOWER_CMSG_TYPE_FLOW_STATS
+ *    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  |    Reserved   |               Host Context                    |
+ *          +---------------+-----------------------------------------------+
+ *       1  |                          Packet Count                         |
+ *          +---------------------------------------------------------------+
+ *       2  |                          Byte Count                           |
+ *          +---------------------------------------------------------------+
+ *       2  |                          Byte Count                           |
+ *          +---------------------------------------------------------------+
+ *       3  |                          Host Cookie                          |
+ *          +---------------------------------------------------------------+
+ *       4  |                          Host Cookie                          |
+ *          +---------------------------------------------------------------+
+ */
+struct nfp_flower_stats_frame {
+	rte_be32_t stats_con_id;
+	rte_be32_t pkt_count;
+	rte_be64_t byte_count;
+	rte_be64_t stats_cookie;
+};
+
 enum nfp_flower_cmsg_port_type {
 	NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC,
 	NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT,
diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c
index df908ef..bb9efe1 100644
--- a/drivers/net/nfp/flower/nfp_flower_ctrl.c
+++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c
@@ -10,8 +10,10 @@
 #include "../nfp_logs.h"
 #include "../nfp_ctrl.h"
 #include "../nfp_rxtx.h"
+#include "nfp_flow.h"
 #include "nfp_flower.h"
 #include "nfp_flower_ctrl.h"
+#include "nfp_flower_cmsg.h"
 
 #define MAX_PKT_BURST 32
 
@@ -222,10 +224,74 @@
 	return cnt;
 }
 
+static void
+nfp_flower_cmsg_rx_stats(struct nfp_flow_priv *flow_priv,
+		struct rte_mbuf *mbuf)
+{
+	char *msg;
+	uint16_t i;
+	uint16_t count;
+	uint16_t msg_len;
+	uint32_t ctx_id;
+	struct nfp_flower_stats_frame *stats;
+
+	msg = rte_pktmbuf_mtod(mbuf, char *) + NFP_FLOWER_CMSG_HLEN;
+	msg_len = mbuf->data_len - NFP_FLOWER_CMSG_HLEN;
+	count = msg_len / sizeof(struct nfp_flower_stats_frame);
+
+	rte_spinlock_lock(&flow_priv->stats_lock);
+	for (i = 0; i < count; i++) {
+		stats = (struct nfp_flower_stats_frame *)msg + i;
+		ctx_id = rte_be_to_cpu_32(stats->stats_con_id);
+		flow_priv->stats[ctx_id].pkts  += rte_be_to_cpu_32(stats->pkt_count);
+		flow_priv->stats[ctx_id].bytes += rte_be_to_cpu_64(stats->byte_count);
+	}
+	rte_spinlock_unlock(&flow_priv->stats_lock);
+}
+
+static void
+nfp_flower_cmsg_rx(struct nfp_flow_priv *flow_priv,
+		struct rte_mbuf **pkts_burst,
+		uint16_t count)
+{
+	uint16_t i;
+	char *meta;
+	uint32_t meta_type;
+	uint32_t meta_info;
+	struct nfp_flower_cmsg_hdr *cmsg_hdr;
+
+	for (i = 0; i < count; i++) {
+		meta = rte_pktmbuf_mtod(pkts_burst[i], char *);
+
+		/* Free the unsupported ctrl packet */
+		meta_type = rte_be_to_cpu_32(*(uint32_t *)(meta - 8));
+		meta_info = rte_be_to_cpu_32(*(uint32_t *)(meta - 4));
+		if (meta_type != NFP_NET_META_PORTID ||
+				meta_info != NFP_META_PORT_ID_CTRL) {
+			PMD_DRV_LOG(ERR, "Incorrect metadata for ctrl packet!");
+			rte_pktmbuf_free(pkts_burst[i]);
+			continue;
+		}
+
+		cmsg_hdr = (struct nfp_flower_cmsg_hdr *)meta;
+		if (unlikely(cmsg_hdr->version != NFP_FLOWER_CMSG_VER1)) {
+			PMD_DRV_LOG(ERR, "Incorrect repr control version!");
+			rte_pktmbuf_free(pkts_burst[i]);
+			continue;
+		}
+
+		if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_FLOW_STATS) {
+			/* We need to deal with stats updates from HW asap */
+			nfp_flower_cmsg_rx_stats(flow_priv, pkts_burst[i]);
+		}
+
+		rte_pktmbuf_free(pkts_burst[i]);
+	}
+}
+
 void
 nfp_flower_ctrl_vnic_poll(struct nfp_app_fw_flower *app_fw_flower)
 {
-	uint16_t i;
 	uint16_t count;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *ctrl_hw;
@@ -242,9 +308,8 @@
 		count = nfp_flower_ctrl_vnic_recv(rxq, pkts_burst, MAX_PKT_BURST);
 		if (count != 0) {
 			app_fw_flower->ctrl_vnic_rx_count += count;
-			/* Process cmsgs here, only free for now */
-			for (i = 0; i < count; i++)
-				rte_pktmbuf_free(pkts_burst[i]);
+			/* Process cmsgs here */
+			nfp_flower_cmsg_rx(app_fw_flower->flow_priv, pkts_burst, count);
 		}
 	}
 }
-- 
1.8.3.1


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

* [PATCH v5 04/25] net/nfp: add the flow APIs of nfp PMD
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (2 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 03/25] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20 11:09     ` Ferruh Yigit
  2022-10-20  2:19   ` [PATCH v5 05/25] net/nfp: support basic flow items Chaoyong He
                     ` (21 subsequent siblings)
  25 siblings, 1 reply; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the flow validate/create/query/destroy/flush API of nfp PMD.

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

The flow query API get flow stats from the flow_priv structure.
Note there exist an rte_spin_lock to prevent the update and query
action occur at the same time.

The flow destroy API construct a control cmsg and send it to
firmware, then adelete 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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower_cmsg.c        |  69 +++
 drivers/net/nfp/flower/nfp_flower_cmsg.h        |  48 ++
 drivers/net/nfp/flower/nfp_flower_representor.c |   3 +
 drivers/net/nfp/nfp_flow.c                      | 592 +++++++++++++++++++++++-
 drivers/net/nfp/nfp_flow.h                      |  28 ++
 5 files changed, 731 insertions(+), 9 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c
index 750a629..15d8381 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c
@@ -6,6 +6,7 @@
 #include "../nfpcore/nfp_nsp.h"
 #include "../nfp_logs.h"
 #include "../nfp_common.h"
+#include "../nfp_flow.h"
 #include "nfp_flower.h"
 #include "nfp_flower_cmsg.h"
 #include "nfp_flower_ctrl.h"
@@ -177,3 +178,71 @@
 
 	return 0;
 }
+
+int
+nfp_flower_cmsg_flow_delete(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow)
+{
+	char *msg;
+	uint16_t cnt;
+	uint32_t msg_len;
+	struct rte_mbuf *mbuf;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+	if (mbuf == NULL) {
+		PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for flow delete.");
+		return -ENOMEM;
+	}
+
+	/* Copy the flow to mbuf */
+	nfp_flow_meta = flow->payload.meta;
+	msg_len = (nfp_flow_meta->key_len + nfp_flow_meta->mask_len +
+			nfp_flow_meta->act_len) << NFP_FL_LW_SIZ;
+	msg_len += sizeof(struct nfp_fl_rule_metadata);
+	msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_FLOW_DEL, msg_len);
+	rte_memcpy(msg, flow->payload.meta, msg_len);
+
+	cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+	if (cnt == 0) {
+		PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+		rte_pktmbuf_free(mbuf);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+nfp_flower_cmsg_flow_add(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow)
+{
+	char *msg;
+	uint16_t cnt;
+	uint32_t msg_len;
+	struct rte_mbuf *mbuf;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+	if (mbuf == NULL) {
+		PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for flow add.");
+		return -ENOMEM;
+	}
+
+	/* copy the flow to mbuf */
+	nfp_flow_meta = flow->payload.meta;
+	msg_len = (nfp_flow_meta->key_len + nfp_flow_meta->mask_len +
+			nfp_flow_meta->act_len) << NFP_FL_LW_SIZ;
+	msg_len += sizeof(struct nfp_fl_rule_metadata);
+	msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_FLOW_ADD, msg_len);
+	rte_memcpy(msg, flow->payload.meta, msg_len);
+
+	cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+	if (cnt == 0) {
+		PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+		rte_pktmbuf_free(mbuf);
+		return -EIO;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 5c28363..6045bb0 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -189,10 +189,58 @@ enum nfp_flower_cmsg_port_vnic_type {
 	return rte_pktmbuf_mtod(m, char *) + 4 + 4 + NFP_FLOWER_CMSG_HLEN;
 }
 
+/*
+ * Metadata with L2 (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    key_type   |    mask_id    | PCP |p|   vlan outermost VID  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *                                 ^                               ^
+ *                           NOTE: |             TCI               |
+ *                                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_meta_tci {
+	uint8_t nfp_flow_key_layer;
+	uint8_t mask_id;
+	rte_be16_t tci;
+};
+
+/*
+ * Extended metadata for additional key_layers (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                      nfp_flow_key_layer2                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ext_meta {
+	rte_be32_t nfp_flow_key_layer2;
+};
+
+/*
+ * L1 Port details (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                         port_ingress                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_in_port {
+	rte_be32_t in_port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
 int nfp_flower_cmsg_port_mod(struct nfp_app_fw_flower *app_fw_flower,
 		uint32_t port_id, bool carrier_ok);
+int nfp_flower_cmsg_flow_delete(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow);
+int nfp_flower_cmsg_flow_add(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow);
 
 #endif /* _NFP_CMSG_H_ */
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index 0e60f50..f1cd298 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -10,6 +10,7 @@
 #include "../nfp_logs.h"
 #include "../nfp_ctrl.h"
 #include "../nfp_rxtx.h"
+#include "../nfp_flow.h"
 #include "../nfpcore/nfp_mip.h"
 #include "../nfpcore/nfp_rtsym.h"
 #include "../nfpcore/nfp_nsp.h"
@@ -590,6 +591,8 @@
 	.promiscuous_disable  = nfp_flower_repr_promiscuous_disable,
 
 	.mac_addr_set         = nfp_flower_repr_mac_addr_set,
+
+	.flow_ops_get         = nfp_net_flow_ops_get,
 };
 
 static uint32_t
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 8c36e97..eb1e42c 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -7,11 +7,15 @@
 #include <rte_hash.h>
 #include <rte_jhash.h>
 #include <bus_pci_driver.h>
+#include <rte_malloc.h>
 
 #include "nfp_common.h"
 #include "nfp_flow.h"
 #include "nfp_logs.h"
 #include "flower/nfp_flower.h"
+#include "flower/nfp_flower_cmsg.h"
+#include "flower/nfp_flower_ctrl.h"
+#include "flower/nfp_flower_representor.h"
 #include "nfpcore/nfp_mip.h"
 #include "nfpcore/nfp_rtsym.h"
 
@@ -21,6 +25,15 @@ struct nfp_mask_id_entry {
 	uint8_t mask_id;
 };
 
+static inline struct nfp_flow_priv *
+nfp_flow_dev_to_priv(struct rte_eth_dev *dev)
+{
+	struct nfp_flower_representor *repr;
+
+	repr = (struct nfp_flower_representor *)dev->data->dev_private;
+	return repr->app_fw_flower->flow_priv;
+}
+
 static int
 nfp_mask_id_alloc(struct nfp_flow_priv *priv, uint8_t *mask_id)
 {
@@ -160,7 +173,7 @@ struct nfp_mask_id_entry {
 	return entry;
 }
 
-__rte_unused static bool
+static bool
 nfp_check_mask_add(struct nfp_flow_priv *priv,
 		char *mask_data,
 		uint32_t mask_len,
@@ -187,7 +200,7 @@ struct nfp_mask_id_entry {
 	return true;
 }
 
-__rte_unused static bool
+static bool
 nfp_check_mask_remove(struct nfp_flow_priv *priv,
 		char *mask_data,
 		uint32_t mask_len,
@@ -215,7 +228,7 @@ struct nfp_mask_id_entry {
 	return true;
 }
 
-__rte_unused static int
+static int
 nfp_flow_table_add(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -230,7 +243,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static int
+static int
 nfp_flow_table_delete(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -245,7 +258,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static struct rte_flow *
+static struct rte_flow *
 nfp_flow_table_search(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -262,7 +275,7 @@ struct nfp_mask_id_entry {
 	return flow_find;
 }
 
-__rte_unused static struct rte_flow *
+static struct rte_flow *
 nfp_flow_alloc(struct nfp_fl_key_ls *key_layer)
 {
 	char *tmp;
@@ -295,14 +308,14 @@ struct nfp_mask_id_entry {
 	return NULL;
 }
 
-__rte_unused static void
+static void
 nfp_flow_free(struct rte_flow *nfp_flow)
 {
 	rte_free(nfp_flow->payload.meta);
 	rte_free(nfp_flow);
 }
 
-__rte_unused static int
+static int
 nfp_stats_id_alloc(struct nfp_flow_priv *priv, uint32_t *ctx)
 {
 	struct circ_buf *ring;
@@ -337,7 +350,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static int
+static int
 nfp_stats_id_free(struct nfp_flow_priv *priv, uint32_t ctx)
 {
 	struct circ_buf *ring;
@@ -355,6 +368,567 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flower_compile_meta_tci(char *mbuf_off, struct nfp_fl_key_ls *key_layer)
+{
+	struct nfp_flower_meta_tci *tci_meta;
+
+	tci_meta = (struct nfp_flower_meta_tci *)mbuf_off;
+	tci_meta->nfp_flow_key_layer = key_layer->key_layer;
+	tci_meta->mask_id = ~0;
+	tci_meta->tci = rte_cpu_to_be_16(key_layer->vlan);
+}
+
+static void
+nfp_flower_update_meta_tci(char *exact, uint8_t mask_id)
+{
+	struct nfp_flower_meta_tci *meta_tci;
+
+	meta_tci = (struct nfp_flower_meta_tci *)exact;
+	meta_tci->mask_id = mask_id;
+}
+
+static void
+nfp_flower_compile_ext_meta(char *mbuf_off, struct nfp_fl_key_ls *key_layer)
+{
+	struct nfp_flower_ext_meta *ext_meta;
+
+	ext_meta = (struct nfp_flower_ext_meta *)mbuf_off;
+	ext_meta->nfp_flow_key_layer2 = rte_cpu_to_be_32(key_layer->key_layer_two);
+}
+
+static void
+nfp_compile_meta_port(char *mbuf_off,
+		struct nfp_fl_key_ls *key_layer,
+		bool is_mask)
+{
+	struct nfp_flower_in_port *port_meta;
+
+	port_meta = (struct nfp_flower_in_port *)mbuf_off;
+
+	if (is_mask)
+		port_meta->in_port = rte_cpu_to_be_32(~0);
+	else if (key_layer->tun_type)
+		port_meta->in_port = rte_cpu_to_be_32(NFP_FL_PORT_TYPE_TUN |
+				key_layer->tun_type);
+	else
+		port_meta->in_port = rte_cpu_to_be_32(key_layer->port);
+}
+
+static void
+nfp_flow_compile_metadata(struct nfp_flow_priv *priv,
+		struct rte_flow *nfp_flow,
+		struct nfp_fl_key_ls *key_layer,
+		uint32_t stats_ctx)
+{
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+	char *mbuf_off_exact;
+	char *mbuf_off_mask;
+
+	/*
+	 * Convert to long words as firmware expects
+	 * lengths in units of NFP_FL_LW_SIZ.
+	 */
+	nfp_flow_meta               = nfp_flow->payload.meta;
+	nfp_flow_meta->key_len      = key_layer->key_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->mask_len     = key_layer->key_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->act_len      = key_layer->act_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->flags        = 0;
+	nfp_flow_meta->host_ctx_id  = rte_cpu_to_be_32(stats_ctx);
+	nfp_flow_meta->host_cookie  = rte_rand();
+	nfp_flow_meta->flow_version = rte_cpu_to_be_64(priv->flower_version);
+
+	mbuf_off_exact = nfp_flow->payload.unmasked_data;
+	mbuf_off_mask  = nfp_flow->payload.mask_data;
+
+	/* Populate Metadata */
+	nfp_flower_compile_meta_tci(mbuf_off_exact, key_layer);
+	nfp_flower_compile_meta_tci(mbuf_off_mask, key_layer);
+	mbuf_off_exact += sizeof(struct nfp_flower_meta_tci);
+	mbuf_off_mask  += sizeof(struct nfp_flower_meta_tci);
+
+	/* Populate Extended Metadata if required */
+	if (key_layer->key_layer & NFP_FLOWER_LAYER_EXT_META) {
+		nfp_flower_compile_ext_meta(mbuf_off_exact, key_layer);
+		nfp_flower_compile_ext_meta(mbuf_off_mask, key_layer);
+		mbuf_off_exact += sizeof(struct nfp_flower_ext_meta);
+		mbuf_off_mask  += sizeof(struct nfp_flower_ext_meta);
+	}
+
+	/* Populate Port Data */
+	nfp_compile_meta_port(mbuf_off_exact, key_layer, false);
+	nfp_compile_meta_port(mbuf_off_mask, key_layer, true);
+	mbuf_off_exact += sizeof(struct nfp_flower_in_port);
+	mbuf_off_mask  += sizeof(struct nfp_flower_in_port);
+}
+
+static int
+nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[],
+		__rte_unused struct nfp_fl_key_ls *key_ls)
+{
+	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, "Item type %d not supported.", item->type);
+			return -ENOTSUP;
+		}
+	}
+
+	return 0;
+}
+
+static int
+nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
+		struct nfp_fl_key_ls *key_ls)
+{
+	int ret = 0;
+	const struct rte_flow_action *action;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+		/* Make sure actions length no longer than NFP_FL_MAX_A_SIZ */
+		if (key_ls->act_size > NFP_FL_MAX_A_SIZ) {
+			PMD_DRV_LOG(ERR, "The action list is too long.");
+			ret = -ERANGE;
+			break;
+		}
+
+		switch (action->type) {
+		case RTE_FLOW_ACTION_TYPE_VOID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VOID detected");
+			break;
+		default:
+			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
+			return -ENOTSUP;
+		}
+	}
+
+	return ret;
+}
+
+static int
+nfp_flow_key_layers_calculate(const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct nfp_fl_key_ls *key_ls)
+{
+	int ret = 0;
+
+	key_ls->key_layer_two = 0;
+	key_ls->key_layer = NFP_FLOWER_LAYER_PORT;
+	key_ls->key_size = sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+	key_ls->act_size = 0;
+	key_ls->port = ~0;
+	key_ls->vlan = 0;
+	key_ls->tun_type = NFP_FL_TUN_NONE;
+
+	ret |= nfp_flow_key_layers_calculate_items(items, key_ls);
+	ret |= nfp_flow_key_layers_calculate_actions(actions, key_ls);
+
+	return ret;
+}
+
+static struct rte_flow *
+nfp_flow_process(struct nfp_flower_representor *representor,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		bool validate_flag)
+{
+	int ret;
+	char *hash_data;
+	char *mask_data;
+	uint32_t mask_len;
+	uint32_t stats_ctx = 0;
+	uint8_t new_mask_id = 0;
+	struct rte_flow *nfp_flow;
+	struct rte_flow *flow_find;
+	struct nfp_flow_priv *priv;
+	struct nfp_fl_key_ls key_layer;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	ret = nfp_flow_key_layers_calculate(items, actions, &key_layer);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Key layers calculate failed.");
+		return NULL;
+	}
+
+	if (key_layer.port == (uint32_t)~0)
+		key_layer.port = representor->port_id;
+
+	priv = representor->app_fw_flower->flow_priv;
+	ret = nfp_stats_id_alloc(priv, &stats_ctx);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp stats id alloc failed.");
+		return NULL;
+	}
+
+	nfp_flow = nfp_flow_alloc(&key_layer);
+	if (nfp_flow == NULL) {
+		PMD_DRV_LOG(ERR, "Alloc nfp flow failed.");
+		goto free_stats;
+	}
+
+	nfp_flow->install_flag = true;
+
+	nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx);
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	mask_data = nfp_flow->payload.mask_data;
+	mask_len = key_layer.key_size;
+	if (!nfp_check_mask_add(priv, mask_data, mask_len,
+			&nfp_flow_meta->flags, &new_mask_id)) {
+		PMD_DRV_LOG(ERR, "nfp mask add check failed.");
+		goto free_flow;
+	}
+
+	/* Once we have a mask_id, update the meta tci */
+	nfp_flower_update_meta_tci(nfp_flow->payload.unmasked_data, new_mask_id);
+
+	/* Calculate and store the hask_key for later use */
+	hash_data = (char *)(nfp_flow->payload.unmasked_data);
+	nfp_flow->hash_key = rte_jhash(hash_data, nfp_flow->length, priv->hash_seed);
+
+	/* Find the flow in hash table */
+	flow_find = nfp_flow_table_search(priv, nfp_flow);
+	if (flow_find != NULL) {
+		PMD_DRV_LOG(ERR, "This flow is already exist.");
+		if (!nfp_check_mask_remove(priv, mask_data, mask_len,
+				&nfp_flow_meta->flags)) {
+			PMD_DRV_LOG(ERR, "nfp mask del check failed.");
+		}
+		goto free_flow;
+	}
+
+	/* Flow validate should not update the flower version */
+	if (!validate_flag)
+		priv->flower_version++;
+
+	return nfp_flow;
+
+free_flow:
+	nfp_flow_free(nfp_flow);
+free_stats:
+	nfp_stats_id_free(priv, stats_ctx);
+
+	return NULL;
+}
+
+static struct rte_flow *
+nfp_flow_setup(struct nfp_flower_representor *representor,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error,
+		bool validate_flag)
+{
+	if (attr->group != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support group attribute.");
+
+	if (attr->priority != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support priority attribute.");
+
+	if (attr->transfer != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support transfer attribute.");
+
+	if (attr->egress != 0) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
+				NULL, "Egress is not supported.");
+		return NULL;
+	}
+
+	if (attr->ingress == 0) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
+				NULL, "Only ingress is supported.");
+		return NULL;
+	}
+
+	return nfp_flow_process(representor, items, actions, validate_flag);
+}
+
+static int
+nfp_flow_teardown(struct nfp_flow_priv *priv,
+		struct rte_flow *nfp_flow,
+		bool validate_flag)
+{
+	char *mask_data;
+	uint32_t mask_len;
+	uint32_t stats_ctx;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	mask_data = nfp_flow->payload.mask_data;
+	mask_len = nfp_flow_meta->mask_len << NFP_FL_LW_SIZ;
+	if (!nfp_check_mask_remove(priv, mask_data, mask_len,
+			&nfp_flow_meta->flags)) {
+		PMD_DRV_LOG(ERR, "nfp mask del check failed.");
+		return -EINVAL;
+	}
+
+	nfp_flow_meta->flow_version = rte_cpu_to_be_64(priv->flower_version);
+
+	/* Flow validate should not update the flower version */
+	if (!validate_flag)
+		priv->flower_version++;
+
+	stats_ctx = rte_be_to_cpu_32(nfp_flow_meta->host_ctx_id);
+	return nfp_stats_id_free(priv, stats_ctx);
+}
+
+static int
+nfp_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 rte_flow *nfp_flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	priv = representor->app_fw_flower->flow_priv;
+
+	nfp_flow = nfp_flow_setup(representor, attr, items, actions, error, true);
+	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_flow_teardown(priv, nfp_flow, true);
+	if (ret != 0) {
+		return rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow resource free failed.");
+	}
+
+	nfp_flow_free(nfp_flow);
+
+	return 0;
+}
+
+static struct rte_flow *
+nfp_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 rte_flow *nfp_flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	app_fw_flower = representor->app_fw_flower;
+	priv = app_fw_flower->flow_priv;
+
+	nfp_flow = nfp_flow_setup(representor, attr, items, actions, error, false);
+	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 hardware */
+	if (nfp_flow->install_flag) {
+		ret = nfp_flower_cmsg_flow_add(app_fw_flower, nfp_flow);
+		if (ret != 0) {
+			rte_flow_error_set(error, EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL, "Add flow to firmware failed.");
+			goto flow_teardown;
+		}
+	}
+
+	/* Add the flow to flow hash table */
+	ret = nfp_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;
+	}
+
+	return nfp_flow;
+
+flow_teardown:
+	nfp_flow_teardown(priv, nfp_flow, false);
+	nfp_flow_free(nfp_flow);
+
+	return NULL;
+}
+
+static int
+nfp_flow_destroy(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct rte_flow *flow_find;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	app_fw_flower = representor->app_fw_flower;
+	priv = app_fw_flower->flow_priv;
+
+	/* Find the flow in flow hash table */
+	flow_find = nfp_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;
+	}
+
+	/* Update flow */
+	ret = nfp_flow_teardown(priv, nfp_flow, false);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow teardown failed.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Delete the flow from hardware */
+	if (nfp_flow->install_flag) {
+		ret = nfp_flower_cmsg_flow_delete(app_fw_flower, nfp_flow);
+		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_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;
+	}
+
+exit:
+	nfp_flow_free(nfp_flow);
+
+	return ret;
+}
+
+static int
+nfp_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_flow_priv *priv;
+
+	priv = nfp_flow_dev_to_priv(dev);
+
+	while (rte_hash_iterate(priv->flow_table, &next_key, &next_data, &iter) >= 0) {
+		ret = nfp_flow_destroy(dev, (struct rte_flow *)next_data, error);
+		if (ret != 0)
+			break;
+	}
+
+	return ret;
+}
+
+static void
+nfp_flow_stats_get(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		void *data)
+{
+	uint32_t ctx_id;
+	struct rte_flow *flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_fl_stats *stats;
+	struct rte_flow_query_count *query;
+
+	priv = nfp_flow_dev_to_priv(dev);
+	flow = nfp_flow_table_search(priv, nfp_flow);
+	if (flow == NULL) {
+		PMD_DRV_LOG(ERR, "Can not find statistics for this flow.");
+		return;
+	}
+
+	query = (struct rte_flow_query_count *)data;
+	memset(query, 0, sizeof(*query));
+
+	ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id);
+	stats = &priv->stats[ctx_id];
+
+	rte_spinlock_lock(&priv->stats_lock);
+	if (stats->pkts != 0 && stats->bytes != 0) {
+		query->hits = stats->pkts;
+		query->bytes = stats->bytes;
+		query->hits_set = 1;
+		query->bytes_set = 1;
+		if (query->reset != 0) {
+			stats->pkts = 0;
+			stats->bytes = 0;
+		}
+	}
+	rte_spinlock_unlock(&priv->stats_lock);
+}
+
+static int
+nfp_flow_query(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		const struct rte_flow_action *actions,
+		void *data,
+		struct rte_flow_error *error)
+{
+	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_VOID:
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			nfp_flow_stats_get(dev, nfp_flow, data);
+			break;
+		default:
+			rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL, "Unsupported action type for flow query.");
+			return -ENOTSUP;
+		}
+	}
+
+	return 0;
+}
+
+static const struct rte_flow_ops nfp_flow_ops = {
+	.validate                    = nfp_flow_validate,
+	.create                      = nfp_flow_create,
+	.destroy                     = nfp_flow_destroy,
+	.flush                       = nfp_flow_flush,
+	.query                       = nfp_flow_query,
+};
+
+int
+nfp_net_flow_ops_get(struct rte_eth_dev *dev,
+		const struct rte_flow_ops **ops)
+{
+	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0) {
+		*ops = NULL;
+		PMD_DRV_LOG(ERR, "Port is not a representor.");
+		return -EINVAL;
+	}
+
+	*ops = &nfp_flow_ops;
+
+	return 0;
+}
+
 int
 nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)
 {
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index e8fd22a..6fa1b3e 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -6,10 +6,36 @@
 #ifndef _NFP_FLOW_H_
 #define _NFP_FLOW_H_
 
+#include <ethdev_driver.h>
+
+#define NFP_FLOWER_LAYER_EXT_META   (1 << 0)
+#define NFP_FLOWER_LAYER_PORT       (1 << 1)
+#define NFP_FLOWER_LAYER_MAC        (1 << 2)
+#define NFP_FLOWER_LAYER_TP         (1 << 3)
+#define NFP_FLOWER_LAYER_IPV4       (1 << 4)
+#define NFP_FLOWER_LAYER_IPV6       (1 << 5)
+#define NFP_FLOWER_LAYER_CT         (1 << 6)
+#define NFP_FLOWER_LAYER_VXLAN      (1 << 7)
+
+#define NFP_FLOWER_LAYER2_GRE       (1 << 0)
+#define NFP_FLOWER_LAYER2_QINQ      (1 << 4)
+#define NFP_FLOWER_LAYER2_GENEVE    (1 << 5)
+#define NFP_FLOWER_LAYER2_GENEVE_OP (1 << 6)
+#define NFP_FLOWER_LAYER2_TUN_IPV6  (1 << 7)
+
 #define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)
 
 #define NFP_MASK_TABLE_ENTRIES          1024
 
+/* The maximum action list size (in bytes) supported by the NFP. */
+#define NFP_FL_MAX_A_SIZ                1216
+
+/* The firmware expects lengths in units of long words */
+#define NFP_FL_LW_SIZ                   2
+
+/* Tunnel ports */
+#define NFP_FL_PORT_TYPE_TUN            0x50000000
+
 enum nfp_flower_tun_type {
 	NFP_FL_TUN_NONE   = 0,
 	NFP_FL_TUN_GRE    = 1,
@@ -75,6 +101,7 @@ struct nfp_fl_stats {
 
 struct nfp_flow_priv {
 	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
+	uint64_t flower_version; /**< Flow version, always increase. */
 	/* mask hash table */
 	struct nfp_fl_mask_id mask_ids; /**< Entry for mask hash table */
 	struct rte_hash *mask_table; /**< Hash table to store mask ids. */
@@ -98,5 +125,6 @@ struct rte_flow {
 
 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);
 
 #endif /* _NFP_FLOW_H_ */
-- 
1.8.3.1


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

* [PATCH v5 05/25] net/nfp: support basic flow items
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (3 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 04/25] net/nfp: add the flow APIs of nfp PMD Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20 11:11     ` Ferruh Yigit
  2022-10-20  2:19   ` [PATCH v5 06/25] net/nfp: support basic flow actions Chaoyong He
                     ` (20 subsequent siblings)
  25 siblings, 1 reply; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the offload support of very basic items: ethernet and
port id.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |   4 +
 doc/guides/rel_notes/release_22_11.rst   |   2 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  20 +++
 drivers/net/nfp/nfp_flow.c               | 252 ++++++++++++++++++++++++++++++-
 4 files changed, 277 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f7a0362..4460cf0 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -25,3 +25,7 @@ Linux                = Y
 Multiprocess aware   = Y
 x86-64               = Y
 Usage doc            = Y
+
+[rte_flow items]
+eth                  = Y
+port_id              = Y
diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index a3700bb..6d421a2 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -163,6 +163,8 @@ New Features
   * Added the control message interactive channels between PMD and firmware.
   * Added the support of representor port.
 
+  Add the support of rte_flow pattern items.
+
 * **Updated NXP dpaa2 driver.**
 
   * Added support for flow action REPRESENTED_PORT.
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 6045bb0..75a3b91 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -233,6 +233,26 @@ struct nfp_flower_in_port {
 	rte_be32_t in_port;
 };
 
+/*
+ * L2 details (4W/16B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     mac_addr_dst, 31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      mac_addr_dst, 47 - 32    |     mac_addr_src, 15 - 0      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     mac_addr_src, 47 - 16                     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |       mpls outermost label            |  TC |B|   reserved  |q|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_mac_mpls {
+	uint8_t mac_dst[6];
+	uint8_t mac_src[6];
+	rte_be32_t mpls_lse;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index eb1e42c..1af0acd 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -19,6 +19,30 @@
 #include "nfpcore/nfp_mip.h"
 #include "nfpcore/nfp_rtsym.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_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 unsigned int mask_sz;
+	/* Merge a pattern item into a flow rule handle. */
+	int (*merge)(struct rte_flow *nfp_flow,
+			char **mbuf_off,
+			const struct rte_flow_item *item,
+			const struct nfp_flow_item_proc *proc,
+			bool is_mask);
+	/* List of possible subsequent items. */
+	const enum rte_flow_item_type *const next_item;
+};
+
 struct nfp_mask_id_entry {
 	uint32_t hash_key;
 	uint32_t ref_cnt;
@@ -464,12 +488,36 @@ struct nfp_mask_id_entry {
 
 static int
 nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[],
-		__rte_unused struct nfp_fl_key_ls *key_ls)
+		struct nfp_fl_key_ls *key_ls)
 {
+	struct rte_eth_dev *ethdev;
 	const struct rte_flow_item *item;
+	struct nfp_flower_representor *representor;
+	const struct rte_flow_item_port_id *port_id;
 
 	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");
+			/*
+			 * eth is set with no specific params.
+			 * NFP does not need this.
+			 */
+			if (item->spec == NULL)
+				continue;
+			key_ls->key_layer |= NFP_FLOWER_LAYER_MAC;
+			key_ls->key_size += sizeof(struct nfp_flower_mac_mpls);
+			break;
+		case RTE_FLOW_ITEM_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_PORT_ID detected");
+			port_id = item->spec;
+			if (port_id->id >= RTE_MAX_ETHPORTS)
+				return -ERANGE;
+			ethdev = &rte_eth_devices[port_id->id];
+			representor = (struct nfp_flower_representor *)
+					ethdev->data->dev_private;
+			key_ls->port = rte_cpu_to_be_32(representor->port_id);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -529,6 +577,202 @@ struct nfp_mask_id_entry {
 	return ret;
 }
 
+static int
+nfp_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_mac_mpls *eth;
+	const struct rte_flow_item_eth *spec;
+	const struct rte_flow_item_eth *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge eth: no item->spec!");
+		goto eth_end;
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	eth = (void *)*mbuf_off;
+
+	if (is_mask) {
+		memcpy(eth->mac_src, mask->src.addr_bytes, RTE_ETHER_ADDR_LEN);
+		memcpy(eth->mac_dst, mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN);
+	} else {
+		memcpy(eth->mac_src, spec->src.addr_bytes, RTE_ETHER_ADDR_LEN);
+		memcpy(eth->mac_dst, spec->dst.addr_bytes, RTE_ETHER_ADDR_LEN);
+	}
+
+	eth->mpls_lse = 0;
+
+eth_end:
+	*mbuf_off += sizeof(struct nfp_flower_mac_mpls);
+
+	return 0;
+}
+
+/* Graph of supported items and associated process function */
+static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
+	[RTE_FLOW_ITEM_TYPE_END] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+	},
+	[RTE_FLOW_ITEM_TYPE_ETH] = {
+		.mask_support = &(const struct rte_flow_item_eth){
+			.hdr = {
+				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+				.src_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+				.ether_type          = RTE_BE16(0xffff),
+			},
+			.has_vlan = 1,
+		},
+		.mask_default = &rte_flow_item_eth_mask,
+		.mask_sz = sizeof(struct rte_flow_item_eth),
+		.merge = nfp_flow_merge_eth,
+	},
+};
+
+static int
+nfp_flow_item_check(const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc)
+{
+	int ret = 0;
+	unsigned int i;
+	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 ?
+		(const uint8_t *)item->mask :
+		(const uint8_t *)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 && (((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_flow_compile_item_proc(const struct rte_flow_item items[],
+		struct rte_flow *nfp_flow,
+		char **mbuf_off_exact,
+		char **mbuf_off_mask)
+{
+	int i;
+	int ret = 0;
+	const struct rte_flow_item *item;
+	const struct nfp_flow_item_proc *proc_list;
+
+	proc_list = nfp_flow_item_proc_list;
+	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
+		const struct nfp_flow_item_proc *proc = NULL;
+
+		for (i = 0; proc_list->next_item && proc_list->next_item[i]; ++i) {
+			if (proc_list->next_item[i] == item->type) {
+				proc = &nfp_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_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, mbuf_off_exact, item,
+				proc, false);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "nfp flow item %d exact merge failed", item->type);
+			break;
+		}
+
+		ret = proc->merge(nfp_flow, mbuf_off_mask, item,
+				proc, true);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "nfp flow item %d mask merge failed", item->type);
+			break;
+		}
+
+		proc_list = proc;
+	}
+
+	return ret;
+}
+
+static int
+nfp_flow_compile_items(__rte_unused struct nfp_flower_representor *representor,
+		const struct rte_flow_item items[],
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+	char *mbuf_off_mask;
+	char *mbuf_off_exact;
+
+	mbuf_off_exact = nfp_flow->payload.unmasked_data +
+			sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+	mbuf_off_mask  = nfp_flow->payload.mask_data +
+			sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+
+	/* Go over items */
+	ret = nfp_flow_compile_item_proc(items, nfp_flow,
+			&mbuf_off_exact, &mbuf_off_mask);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow item compile failed.");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static struct rte_flow *
 nfp_flow_process(struct nfp_flower_representor *representor,
 		const struct rte_flow_item items[],
@@ -573,6 +817,12 @@ struct nfp_mask_id_entry {
 
 	nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx);
 
+	ret = nfp_flow_compile_items(representor, items, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow item process failed.");
+		goto free_flow;
+	}
+
 	nfp_flow_meta = nfp_flow->payload.meta;
 	mask_data = nfp_flow->payload.mask_data;
 	mask_len = key_layer.key_size;
-- 
1.8.3.1


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

* [PATCH v5 06/25] net/nfp: support basic flow actions
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (4 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 05/25] net/nfp: support basic flow items Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20 11:12     ` Ferruh Yigit
  2022-10-20  2:19   ` [PATCH v5 07/25] net/nfp: support VLAN flow item Chaoyong He
                     ` (19 subsequent siblings)
  25 siblings, 1 reply; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the offload support of very basic actions: mark, rss,
count, drop and output.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |   5 ++
 doc/guides/rel_notes/release_22_11.rst   |   2 +-
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  11 +++
 drivers/net/nfp/nfp_flow.c               | 112 +++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h               |  37 ++++++++++
 5 files changed, 166 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 4460cf0..f91da82 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,3 +29,8 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 port_id              = Y
+
+[rte_flow actions]
+count                = Y
+drop                 = Y
+port_id              = Y
diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index 6d421a2..471f300 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -163,7 +163,7 @@ New Features
   * Added the control message interactive channels between PMD and firmware.
   * Added the support of representor port.
 
-  Add the support of rte_flow pattern items.
+  Add the support of rte_flow pattern items and actions.
 
 * **Updated NXP dpaa2 driver.**
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 75a3b91..d776e37 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -253,6 +253,17 @@ struct nfp_flower_mac_mpls {
 	rte_be32_t mpls_lse;
 };
 
+struct nfp_fl_act_head {
+	uint8_t jump_id;
+	uint8_t len_lw;
+};
+
+struct nfp_fl_act_output {
+	struct nfp_fl_act_head head;
+	rte_be16_t flags;
+	rte_be32_t port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 1af0acd..be522ad 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -546,6 +546,22 @@ struct nfp_mask_id_entry {
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VOID detected");
 			break;
+		case RTE_FLOW_ACTION_TYPE_MARK:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_MARK detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_DROP detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_COUNT detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_RSS detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_PORT_ID detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_output);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -773,6 +789,96 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_action_output(char *act_data,
+		const struct rte_flow_action *action,
+		struct nfp_fl_rule_metadata *nfp_flow_meta)
+{
+	size_t act_size;
+	struct rte_eth_dev *ethdev;
+	struct nfp_fl_act_output *output;
+	struct nfp_flower_representor *representor;
+	const struct rte_flow_action_port_id *port_id;
+
+	port_id = action->conf;
+	if (port_id == NULL || port_id->id >= RTE_MAX_ETHPORTS)
+		return -ERANGE;
+
+	ethdev = &rte_eth_devices[port_id->id];
+	representor = (struct nfp_flower_representor *)ethdev->data->dev_private;
+	act_size = sizeof(struct nfp_fl_act_output);
+
+	output = (struct nfp_fl_act_output *)act_data;
+	output->head.jump_id = NFP_FL_ACTION_OPCODE_OUTPUT;
+	output->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	output->flags        = rte_cpu_to_be_16(NFP_FL_OUT_FLAGS_LAST);
+	output->port         = rte_cpu_to_be_32(representor->port_id);
+
+	nfp_flow_meta->shortcut = rte_cpu_to_be_32(representor->port_id);
+
+	return 0;
+}
+
+static int
+nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
+		const struct rte_flow_action actions[],
+		struct rte_flow *nfp_flow)
+{
+	int ret = 0;
+	char *position;
+	char *action_data;
+	bool drop_flag = false;
+	uint32_t total_actions = 0;
+	const struct rte_flow_action *action;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	action_data   = nfp_flow->payload.action_data;
+	position      = action_data;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+		switch (action->type) {
+		case RTE_FLOW_ACTION_TYPE_VOID:
+			break;
+		case RTE_FLOW_ACTION_TYPE_MARK:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_MARK");
+			break;
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_DROP");
+			drop_flag = true;
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_COUNT");
+			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_RSS");
+			break;
+		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_PORT_ID");
+			ret = nfp_flow_action_output(position, action, nfp_flow_meta);
+			if (ret != 0) {
+				PMD_DRV_LOG(ERR, "Failed when process"
+						" RTE_FLOW_ACTION_TYPE_PORT_ID");
+				return ret;
+			}
+
+			position += sizeof(struct nfp_fl_act_output);
+			break;
+		default:
+			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
+			return -ENOTSUP;
+		}
+		total_actions++;
+	}
+
+	if (drop_flag)
+		nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_DROP);
+	else if (total_actions > 1)
+		nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_NULL);
+
+	return 0;
+}
+
 static struct rte_flow *
 nfp_flow_process(struct nfp_flower_representor *representor,
 		const struct rte_flow_item items[],
@@ -823,6 +929,12 @@ struct nfp_mask_id_entry {
 		goto free_flow;
 	}
 
+	ret = nfp_flow_compile_action(representor, actions, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow action process failed.");
+		goto free_flow;
+	}
+
 	nfp_flow_meta = nfp_flow->payload.meta;
 	mask_data = nfp_flow->payload.mask_data;
 	mask_len = key_layer.key_size;
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 6fa1b3e..2ad6d0a 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -33,6 +33,43 @@
 /* The firmware expects lengths in units of long words */
 #define NFP_FL_LW_SIZ                   2
 
+#define NFP_FL_SC_ACT_DROP      0x80000000
+#define NFP_FL_SC_ACT_USER      0x7D000000
+#define NFP_FL_SC_ACT_POPV      0x6A000000
+#define NFP_FL_SC_ACT_NULL      0x00000000
+
+/* Action opcodes */
+#define NFP_FL_ACTION_OPCODE_OUTPUT             0
+#define NFP_FL_ACTION_OPCODE_PUSH_VLAN          1
+#define NFP_FL_ACTION_OPCODE_POP_VLAN           2
+#define NFP_FL_ACTION_OPCODE_PUSH_MPLS          3
+#define NFP_FL_ACTION_OPCODE_POP_MPLS           4
+#define NFP_FL_ACTION_OPCODE_USERSPACE          5
+#define NFP_FL_ACTION_OPCODE_SET_TUNNEL         6
+#define NFP_FL_ACTION_OPCODE_SET_ETHERNET       7
+#define NFP_FL_ACTION_OPCODE_SET_MPLS           8
+#define NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS     9
+#define NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS   10
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_SRC       11
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_DST       12
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL  13
+#define NFP_FL_ACTION_OPCODE_SET_UDP            14
+#define NFP_FL_ACTION_OPCODE_SET_TCP            15
+#define NFP_FL_ACTION_OPCODE_PRE_LAG            16
+#define NFP_FL_ACTION_OPCODE_PRE_TUNNEL         17
+#define NFP_FL_ACTION_OPCODE_PRE_GS             18
+#define NFP_FL_ACTION_OPCODE_GS                 19
+#define NFP_FL_ACTION_OPCODE_PUSH_NSH           20
+#define NFP_FL_ACTION_OPCODE_POP_NSH            21
+#define NFP_FL_ACTION_OPCODE_SET_QUEUE          22
+#define NFP_FL_ACTION_OPCODE_CONNTRACK          23
+#define NFP_FL_ACTION_OPCODE_METER              24
+#define NFP_FL_ACTION_OPCODE_CT_NAT_EXT         25
+#define NFP_FL_ACTION_OPCODE_PUSH_GENEVE        26
+#define NFP_FL_ACTION_OPCODE_NUM                32
+
+#define NFP_FL_OUT_FLAGS_LAST            (1 << 15)
+
 /* Tunnel ports */
 #define NFP_FL_PORT_TYPE_TUN            0x50000000
 
-- 
1.8.3.1


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

* [PATCH v5 07/25] net/nfp: support VLAN flow item
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (5 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 06/25] net/nfp: support basic flow actions Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 08/25] net/nfp: support IPv4 " Chaoyong He
                     ` (18 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 46 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h       |  2 ++
 3 files changed, 49 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f91da82..b0af2a0 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,6 +29,7 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 port_id              = Y
+vlan                 = Y
 
 [rte_flow actions]
 count                = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index be522ad..107cd5b 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -518,6 +518,10 @@ struct nfp_mask_id_entry {
 					ethdev->data->dev_private;
 			key_ls->port = rte_cpu_to_be_32(representor->port_id);
 			break;
+		case RTE_FLOW_ITEM_TYPE_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_VLAN detected");
+			key_ls->vlan = NFP_FLOWER_MASK_VLAN_CFI;
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -629,12 +633,42 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_vlan(struct rte_flow *nfp_flow,
+		__rte_unused char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_vlan *spec;
+	const struct rte_flow_item_vlan *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge vlan: no item->spec!");
+		return 0;
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.mask_data;
+		meta_tci->tci |= mask->tci;
+	} else {
+		meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+		meta_tci->tci |= spec->tci;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -647,6 +681,18 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_eth),
 		.merge = nfp_flow_merge_eth,
 	},
+	[RTE_FLOW_ITEM_TYPE_VLAN] = {
+		.mask_support = &(const struct rte_flow_item_vlan){
+			.hdr = {
+				.vlan_tci  = RTE_BE16(0xefff),
+				.eth_proto = RTE_BE16(0xffff),
+			},
+			.has_more_vlan = 1,
+		},
+		.mask_default = &rte_flow_item_vlan_mask,
+		.mask_sz = sizeof(struct rte_flow_item_vlan),
+		.merge = nfp_flow_merge_vlan,
+	},
 };
 
 static int
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 2ad6d0a..6e5b0fa 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -25,6 +25,8 @@
 
 #define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)
 
+#define NFP_FLOWER_MASK_VLAN_CFI        (1 << 12)
+
 #define NFP_MASK_TABLE_ENTRIES          1024
 
 /* The maximum action list size (in bytes) supported by the NFP. */
-- 
1.8.3.1


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

* [PATCH v5 08/25] net/nfp: support IPv4 flow item
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (6 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 07/25] net/nfp: support VLAN flow item Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 09/25] net/nfp: support IPv6 " Chaoyong He
                     ` (17 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 38 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 68 +++++++++++++++++++++++++++++++-
 3 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index b0af2a0..bf59123 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -28,6 +28,7 @@ Usage doc            = Y
 
 [rte_flow items]
 eth                  = Y
+ipv4                 = Y
 port_id              = Y
 vlan                 = Y
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index d776e37..5964ecf 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -253,6 +253,44 @@ struct nfp_flower_mac_mpls {
 	rte_be32_t mpls_lse;
 };
 
+/*
+ * L4 ports (for UDP, TCP, SCTP) (1W/4B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |            port_src           |           port_dst            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_tp_ports {
+	rte_be16_t port_src;
+	rte_be16_t port_dst;
+};
+
+struct nfp_flower_ip_ext {
+	uint8_t tos;
+	uint8_t proto;
+	uint8_t ttl;
+	uint8_t flags;
+};
+
+/*
+ * L3 IPv4 details (3W/12B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    DSCP   |ECN|   protocol    |      ttl      |     flags     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                        ipv4_addr_src                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                        ipv4_addr_dst                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ipv4 {
+	struct nfp_flower_ip_ext ip_ext;
+	rte_be32_t ipv4_src;
+	rte_be32_t ipv4_dst;
+};
+
 struct nfp_fl_act_head {
 	uint8_t jump_id;
 	uint8_t len_lw;
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 107cd5b..928f149 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -522,6 +522,11 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_VLAN detected");
 			key_ls->vlan = NFP_FLOWER_MASK_VLAN_CFI;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV4:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV4;
+			key_ls->key_size += sizeof(struct nfp_flower_ipv4);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -662,13 +667,58 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_ipv4(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_ipv4 *ipv4;
+	const struct rte_ipv4_hdr *hdr;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_ipv4 *spec;
+	const struct rte_flow_item_ipv4 *mask;
+
+	spec = item->spec;
+	mask = item->mask ? item->mask : proc->mask_default;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge ipv4: no item->spec!");
+		goto ipv4_end;
+	}
+
+	/*
+	 * reserve space for L4 info.
+	 * rte_flow has ipv4 before L4 but NFP flower fw requires L4 before ipv4
+	 */
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP)
+		*mbuf_off += sizeof(struct nfp_flower_tp_ports);
+
+	hdr = is_mask ? &mask->hdr : &spec->hdr;
+	ipv4 = (struct nfp_flower_ipv4 *)*mbuf_off;
+
+	ipv4->ip_ext.tos   = hdr->type_of_service;
+	ipv4->ip_ext.proto = hdr->next_proto_id;
+	ipv4->ip_ext.ttl   = hdr->time_to_live;
+	ipv4->ipv4_src     = hdr->src_addr;
+	ipv4->ipv4_dst     = hdr->dst_addr;
+
+ipv4_end:
+	*mbuf_off += sizeof(struct nfp_flower_ipv4);
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN,
+			RTE_FLOW_ITEM_TYPE_IPV4),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -682,6 +732,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_eth,
 	},
 	[RTE_FLOW_ITEM_TYPE_VLAN] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4),
 		.mask_support = &(const struct rte_flow_item_vlan){
 			.hdr = {
 				.vlan_tci  = RTE_BE16(0xefff),
@@ -693,6 +744,21 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_vlan),
 		.merge = nfp_flow_merge_vlan,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.mask_support = &(const struct rte_flow_item_ipv4){
+			.hdr = {
+				.type_of_service = 0xff,
+				.fragment_offset = RTE_BE16(0xffff),
+				.time_to_live    = 0xff,
+				.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_flow_merge_ipv4,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v5 09/25] net/nfp: support IPv6 flow item
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (7 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 08/25] net/nfp: support IPv4 " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 10/25] net/nfp: support TCP " Chaoyong He
                     ` (16 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 33 +++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 73 +++++++++++++++++++++++++++++++-
 3 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index bf59123..4869b45 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,6 +29,7 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 ipv4                 = Y
+ipv6                 = Y
 port_id              = Y
 vlan                 = Y
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 5964ecf..36d406f 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -291,6 +291,39 @@ struct nfp_flower_ipv4 {
 	rte_be32_t ipv4_dst;
 };
 
+/*
+ * L3 IPv6 details (10W/40B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    DSCP   |ECN|   protocol    |      ttl      |     flags     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   ipv6_exthdr   | res |            ipv6_flow_label            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,   31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,  63 - 32                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,  95 - 64                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src, 127 - 96                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,   31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,  63 - 32                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,  95 - 64                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst, 127 - 96                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ipv6 {
+	struct nfp_flower_ip_ext ip_ext;
+	rte_be32_t ipv6_flow_label_exthdr;
+	uint8_t ipv6_src[16];
+	uint8_t ipv6_dst[16];
+};
+
 struct nfp_fl_act_head {
 	uint8_t jump_id;
 	uint8_t len_lw;
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 928f149..b2360fd 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -527,6 +527,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV4;
 			key_ls->key_size += sizeof(struct nfp_flower_ipv4);
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV6 detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV6;
+			key_ls->key_size += sizeof(struct nfp_flower_ipv6);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -711,6 +716,51 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_ipv6(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_ipv6 *ipv6;
+	const struct rte_ipv6_hdr *hdr;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_ipv6 *spec;
+	const struct rte_flow_item_ipv6 *mask;
+
+	spec = item->spec;
+	mask = item->mask ? item->mask : proc->mask_default;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge ipv6: no item->spec!");
+		goto ipv6_end;
+	}
+
+	/*
+	 * reserve space for L4 info.
+	 * rte_flow has ipv4 before L4 but NFP flower fw requires L4 before ipv4
+	 */
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP)
+		*mbuf_off += sizeof(struct nfp_flower_tp_ports);
+
+	hdr = is_mask ? &mask->hdr : &spec->hdr;
+	ipv6 = (struct nfp_flower_ipv6 *)*mbuf_off;
+
+	ipv6->ip_ext.tos   = (hdr->vtc_flow & RTE_IPV6_HDR_TC_MASK) >>
+			RTE_IPV6_HDR_TC_SHIFT;
+	ipv6->ip_ext.proto = hdr->proto;
+	ipv6->ip_ext.ttl   = hdr->hop_limits;
+	memcpy(ipv6->ipv6_src, hdr->src_addr, sizeof(ipv6->ipv6_src));
+	memcpy(ipv6->ipv6_dst, hdr->dst_addr, sizeof(ipv6->ipv6_dst));
+
+ipv6_end:
+	*mbuf_off += sizeof(struct nfp_flower_ipv6);
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -718,7 +768,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN,
-			RTE_FLOW_ITEM_TYPE_IPV4),
+			RTE_FLOW_ITEM_TYPE_IPV4,
+			RTE_FLOW_ITEM_TYPE_IPV6),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -732,7 +783,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_eth,
 	},
 	[RTE_FLOW_ITEM_TYPE_VLAN] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4,
+			RTE_FLOW_ITEM_TYPE_IPV6),
 		.mask_support = &(const struct rte_flow_item_vlan){
 			.hdr = {
 				.vlan_tci  = RTE_BE16(0xefff),
@@ -759,6 +811,23 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_ipv4),
 		.merge = nfp_flow_merge_ipv4,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.mask_support = &(const struct rte_flow_item_ipv6){
+			.hdr = {
+				.vtc_flow   = RTE_BE32(0x0ff00000),
+				.proto      = 0xff,
+				.hop_limits = 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",
+			},
+			.has_frag_ext = 1,
+		},
+		.mask_default = &rte_flow_item_ipv6_mask,
+		.mask_sz = sizeof(struct rte_flow_item_ipv6),
+		.merge = nfp_flow_merge_ipv6,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v5 10/25] net/nfp: support TCP flow item
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (8 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 09/25] net/nfp: support IPv6 " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 11/25] net/nfp: support UDP " Chaoyong He
                     ` (15 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 91 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h       |  7 ++++
 3 files changed, 99 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 4869b45..670c12f 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -31,6 +31,7 @@ eth                  = Y
 ipv4                 = Y
 ipv6                 = Y
 port_id              = Y
+tcp                  = Y
 vlan                 = Y
 
 [rte_flow actions]
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index b2360fd..2e89a22 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -532,6 +532,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV6;
 			key_ls->key_size += sizeof(struct nfp_flower_ipv6);
 			break;
+		case RTE_FLOW_ITEM_TYPE_TCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_TCP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -761,6 +766,78 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_tcp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	uint8_t tcp_flags;
+	struct nfp_flower_tp_ports *ports;
+	struct nfp_flower_ipv4 *ipv4 = NULL;
+	struct nfp_flower_ipv6 *ipv6 = NULL;
+	const struct rte_flow_item_tcp *spec;
+	const struct rte_flow_item_tcp *mask;
+	struct nfp_flower_meta_tci *meta_tci;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge tcp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ipv4  = (struct nfp_flower_ipv4 *)
+			(*mbuf_off - sizeof(struct nfp_flower_ipv4));
+		ports = (struct nfp_flower_tp_ports *)
+			((char *)ipv4 - sizeof(struct nfp_flower_tp_ports));
+	} else { /* IPv6 */
+		ipv6  = (struct nfp_flower_ipv6 *)
+			(*mbuf_off - sizeof(struct nfp_flower_ipv6));
+		ports = (struct nfp_flower_tp_ports *)
+			((char *)ipv6 - sizeof(struct nfp_flower_tp_ports));
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+		tcp_flags       = mask->hdr.tcp_flags;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+		tcp_flags       = spec->hdr.tcp_flags;
+	}
+
+	if (ipv4) {
+		if (tcp_flags & RTE_TCP_FIN_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_FIN;
+		if (tcp_flags & RTE_TCP_SYN_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_SYN;
+		if (tcp_flags & RTE_TCP_RST_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_RST;
+		if (tcp_flags & RTE_TCP_PSH_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_PSH;
+		if (tcp_flags & RTE_TCP_URG_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_URG;
+	} else {  /* IPv6 */
+		if (tcp_flags & RTE_TCP_FIN_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_FIN;
+		if (tcp_flags & RTE_TCP_SYN_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_SYN;
+		if (tcp_flags & RTE_TCP_RST_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_RST;
+		if (tcp_flags & RTE_TCP_PSH_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_PSH;
+		if (tcp_flags & RTE_TCP_URG_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_URG;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -797,6 +874,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_vlan,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -812,6 +890,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_ipv4,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -828,6 +907,18 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_ipv6),
 		.merge = nfp_flow_merge_ipv6,
 	},
+	[RTE_FLOW_ITEM_TYPE_TCP] = {
+		.mask_support = &(const struct rte_flow_item_tcp){
+			.hdr = {
+				.tcp_flags = 0xff,
+				.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_tcp,
+	},
 };
 
 static int
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 6e5b0fa..ebea1cf 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -23,6 +23,13 @@
 #define NFP_FLOWER_LAYER2_GENEVE_OP (1 << 6)
 #define NFP_FLOWER_LAYER2_TUN_IPV6  (1 << 7)
 
+/* Compressed HW representation of TCP Flags */
+#define NFP_FL_TCP_FLAG_FIN         (1 << 0)
+#define NFP_FL_TCP_FLAG_SYN         (1 << 1)
+#define NFP_FL_TCP_FLAG_RST         (1 << 2)
+#define NFP_FL_TCP_FLAG_PSH         (1 << 3)
+#define NFP_FL_TCP_FLAG_URG         (1 << 4)
+
 #define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)
 
 #define NFP_FLOWER_MASK_VLAN_CFI        (1 << 12)
-- 
1.8.3.1


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

* [PATCH v5 11/25] net/nfp: support UDP flow item
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (9 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 10/25] net/nfp: support TCP " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 12/25] net/nfp: support SCTP " Chaoyong He
                     ` (14 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload
of UDP item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 63 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 670c12f..0af740a 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -32,6 +32,7 @@ ipv4                 = Y
 ipv6                 = Y
 port_id              = Y
 tcp                  = Y
+udp                  = Y
 vlan                 = Y
 
 [rte_flow actions]
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 2e89a22..5dcdbc6 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -537,6 +537,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
 			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
 			break;
+		case RTE_FLOW_ITEM_TYPE_UDP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_UDP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -838,6 +843,47 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_udp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	char *ports_off;
+	struct nfp_flower_tp_ports *ports;
+	const struct rte_flow_item_udp *spec;
+	const struct rte_flow_item_udp *mask;
+	struct nfp_flower_meta_tci *meta_tci;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge udp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv4) -
+			sizeof(struct nfp_flower_tp_ports);
+	} else {/* IPv6 */
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv6) -
+			sizeof(struct nfp_flower_tp_ports);
+	}
+	ports = (struct nfp_flower_tp_ports *)ports_off;
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -874,7 +920,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_vlan,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+			RTE_FLOW_ITEM_TYPE_UDP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -890,7 +937,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_ipv4,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+			RTE_FLOW_ITEM_TYPE_UDP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -919,6 +967,17 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_tcp),
 		.merge = nfp_flow_merge_tcp,
 	},
+	[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_udp,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v5 12/25] net/nfp: support SCTP flow item
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (10 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 11/25] net/nfp: support UDP " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 13/25] net/nfp: support SRC MAC flow action Chaoyong He
                     ` (13 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload
of SCTP item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 63 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 0af740a..27575d1 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -31,6 +31,7 @@ eth                  = Y
 ipv4                 = Y
 ipv6                 = Y
 port_id              = Y
+sctp                 = Y
 tcp                  = Y
 udp                  = Y
 vlan                 = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 5dcdbc6..35456a5 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -542,6 +542,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
 			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
 			break;
+		case RTE_FLOW_ITEM_TYPE_SCTP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_SCTP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -884,6 +889,47 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_sctp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	char *ports_off;
+	struct nfp_flower_tp_ports *ports;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_sctp *spec;
+	const struct rte_flow_item_sctp *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge sctp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv4) -
+			sizeof(struct nfp_flower_tp_ports);
+	} else { /* IPv6 */
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv6) -
+			sizeof(struct nfp_flower_tp_ports);
+	}
+	ports = (struct nfp_flower_tp_ports *)ports_off;
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -921,7 +967,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
-			RTE_FLOW_ITEM_TYPE_UDP),
+			RTE_FLOW_ITEM_TYPE_UDP,
+			RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -938,7 +985,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
-			RTE_FLOW_ITEM_TYPE_UDP),
+			RTE_FLOW_ITEM_TYPE_UDP,
+			RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -978,6 +1026,17 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_udp),
 		.merge = nfp_flow_merge_udp,
 	},
+	[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_sctp,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v5 13/25] net/nfp: support SRC MAC flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (11 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 12/25] net/nfp: support SCTP " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20 11:12     ` Ferruh Yigit
  2022-10-20  2:19   ` [PATCH v5 14/25] net/nfp: support DST " Chaoyong He
                     ` (12 subsequent siblings)
  25 siblings, 1 reply; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source MAC action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 27 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 47 ++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 27575d1..f7cd070 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -40,3 +40,4 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 port_id              = Y
+set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 36d406f..b61342e 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -335,6 +335,33 @@ struct nfp_fl_act_output {
 	rte_be32_t port;
 };
 
+/*
+ * ETH
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |   -   |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_dst_47_16_mask                        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      eth_dst_15_0_mask        |      eth_src_47_32_mask       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_src_31_0_mask                         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_dst_47_16                             |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      eth_dst_15_0             |      eth_src_47_32            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_src_31_0                              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_eth {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	uint8_t eth_addr_mask[RTE_ETHER_ADDR_LEN * 2];
+	uint8_t eth_addr[RTE_ETHER_ADDR_LEN * 2];
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 35456a5..f40d777 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -561,6 +561,7 @@ struct nfp_mask_id_entry {
 		struct nfp_fl_key_ls *key_ls)
 {
 	int ret = 0;
+	bool mac_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -591,6 +592,13 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_PORT_ID detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_output);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_MAC_SRC detected");
+			if (!mac_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1209,6 +1217,36 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flow_action_set_mac(char *act_data,
+		const struct rte_flow_action *action,
+		bool mac_src_flag,
+		bool mac_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_eth *set_eth;
+	const struct rte_flow_action_set_mac *set_mac;
+
+	if (mac_set_flag)
+		set_eth = (struct nfp_fl_act_set_eth *)act_data - 1;
+	else
+		set_eth = (struct nfp_fl_act_set_eth *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_eth);
+	set_eth->head.jump_id = NFP_FL_ACTION_OPCODE_SET_ETHERNET;
+	set_eth->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_eth->reserved     = 0;
+
+	set_mac = (const struct rte_flow_action_set_mac *)action->conf;
+	if (mac_src_flag) {
+		rte_memcpy(&set_eth->eth_addr[RTE_ETHER_ADDR_LEN],
+				set_mac->mac_addr, RTE_ETHER_ADDR_LEN);
+	} else {
+		rte_memcpy(&set_eth->eth_addr[0],
+				set_mac->mac_addr, RTE_ETHER_ADDR_LEN);
+	}
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1218,6 +1256,7 @@ struct nfp_mask_id_entry {
 	char *position;
 	char *action_data;
 	bool drop_flag = false;
+	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
 	struct nfp_fl_rule_metadata *nfp_flow_meta;
@@ -1254,6 +1293,14 @@ struct nfp_mask_id_entry {
 
 			position += sizeof(struct nfp_fl_act_output);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_MAC_SRC");
+			nfp_flow_action_set_mac(position, action, true, mac_set_flag);
+			if (!mac_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 14/25] net/nfp: support DST MAC flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (12 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 13/25] net/nfp: support SRC MAC flow action Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 15/25] net/nfp: support pop VLAN " Chaoyong He
                     ` (11 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest MAC action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f7cd070..9e86164 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -40,4 +40,5 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 port_id              = Y
+set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index f40d777..7348574 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -599,6 +599,13 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_MAC_DST detected");
+			if (!mac_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1301,6 +1308,14 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_MAC_DST");
+			nfp_flow_action_set_mac(position, action, false, mac_set_flag);
+			if (!mac_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 15/25] net/nfp: support pop VLAN flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (13 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 14/25] net/nfp: support DST " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 16/25] net/nfp: support push " Chaoyong He
                     ` (10 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of pop_vlan action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  5 +++++
 drivers/net/nfp/nfp_flow.c               | 25 +++++++++++++++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 9e86164..2c5d173 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -39,6 +39,7 @@ vlan                 = Y
 [rte_flow actions]
 count                = Y
 drop                 = Y
+of_pop_vlan          = Y
 port_id              = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index b61342e..4ce03da 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -362,6 +362,11 @@ struct nfp_fl_act_set_eth {
 	uint8_t eth_addr[RTE_ETHER_ADDR_LEN * 2];
 };
 
+struct nfp_fl_act_pop_vlan {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 7348574..3a63239 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -606,6 +606,10 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_POP_VLAN detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_pop_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1254,6 +1258,22 @@ struct nfp_mask_id_entry {
 	}
 }
 
+static void
+nfp_flow_action_pop_vlan(char *act_data,
+		struct nfp_fl_rule_metadata *nfp_flow_meta)
+{
+	size_t act_size;
+	struct nfp_fl_act_pop_vlan *pop_vlan;
+
+	act_size = sizeof(struct nfp_fl_act_pop_vlan);
+	pop_vlan = (struct nfp_fl_act_pop_vlan *)act_data;
+	pop_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_POP_VLAN;
+	pop_vlan->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	pop_vlan->reserved     = 0;
+
+	nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_POPV);
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1316,6 +1336,11 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_OF_POP_VLAN");
+			nfp_flow_action_pop_vlan(position, nfp_flow_meta);
+			position += sizeof(struct nfp_fl_act_pop_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 16/25] net/nfp: support push VLAN flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (14 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 15/25] net/nfp: support pop VLAN " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 17/25] net/nfp: support SRC IPv4 " Chaoyong He
                     ` (9 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of push_vlan action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  3 ++
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  7 ++++
 drivers/net/nfp/nfp_flow.c               | 60 ++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 2c5d173..005129d 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -40,6 +40,9 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 of_pop_vlan          = Y
+of_push_vlan         = Y
+of_set_vlan_pcp      = Y
+of_set_vlan_vid      = Y
 port_id              = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 4ce03da..30a9ff5 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -367,6 +367,13 @@ struct nfp_fl_act_pop_vlan {
 	rte_be16_t reserved;
 };
 
+struct nfp_fl_act_push_vlan {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be16_t vlan_tpid;
+	rte_be16_t vlan_tci;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 3a63239..686a1c0 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -610,6 +610,16 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_POP_VLAN detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_pop_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_push_vlan);
+			break;
+		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP detected");
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1275,6 +1285,39 @@ struct nfp_mask_id_entry {
 }
 
 static int
+nfp_flow_action_push_vlan(char *act_data,
+		const struct rte_flow_action *action)
+{
+	size_t act_size;
+	struct nfp_fl_act_push_vlan *push_vlan;
+	const struct rte_flow_action_of_push_vlan *push_vlan_conf;
+	const struct rte_flow_action_of_set_vlan_pcp *vlan_pcp_conf;
+	const struct rte_flow_action_of_set_vlan_vid *vlan_vid_conf;
+
+	if (((action + 1)->type != RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP) ||
+			((action + 2)->type != RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID))
+		return -EINVAL;
+
+	act_size = sizeof(struct nfp_fl_act_push_vlan);
+	push_vlan = (struct nfp_fl_act_push_vlan *)act_data;
+	push_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_PUSH_VLAN;
+	push_vlan->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	push_vlan->reserved     = 0;
+
+	push_vlan_conf = (const struct rte_flow_action_of_push_vlan *)
+			action->conf;
+	vlan_pcp_conf  = (const struct rte_flow_action_of_set_vlan_pcp *)
+			(action + 1)->conf;
+	vlan_vid_conf  = (const struct rte_flow_action_of_set_vlan_vid *)
+			(action + 2)->conf;
+	push_vlan->vlan_tpid = push_vlan_conf->ethertype;
+	push_vlan->vlan_tci = ((vlan_pcp_conf->vlan_pcp & 0x07) << 13) |
+			(vlan_vid_conf->vlan_vid & 0x0fff);
+
+	return 0;
+}
+
+static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
 		struct rte_flow *nfp_flow)
@@ -1341,6 +1384,23 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_pop_vlan(position, nfp_flow_meta);
 			position += sizeof(struct nfp_fl_act_pop_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN");
+			ret = nfp_flow_action_push_vlan(position, action);
+			if (ret != 0) {
+				PMD_DRV_LOG(ERR, "Failed when process"
+						" RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN");
+				return ret;
+			}
+
+			/*
+			 * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP and
+			 * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID
+			 * have also been processed.
+			 */
+			action += 2;
+			position += sizeof(struct nfp_fl_act_push_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 17/25] net/nfp: support SRC IPv4 flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (15 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 16/25] net/nfp: support push " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 18/25] net/nfp: support DST " Chaoyong He
                     ` (8 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source IPv4 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 25 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 45 ++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 005129d..e62b3f7 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -44,5 +44,6 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 30a9ff5..77cb51d 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -374,6 +374,31 @@ struct nfp_fl_act_push_vlan {
 	rte_be16_t vlan_tci;
 };
 
+/*
+ * IPv4 addrs
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_saddr_mask                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_saddr                                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_daddr_mask                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_daddr                                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ip4_addrs {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be32_t ipv4_src_mask;
+	rte_be32_t ipv4_src;
+	rte_be32_t ipv4_dst_mask;
+	rte_be32_t ipv4_dst;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 686a1c0..8b9e153 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -562,6 +562,7 @@ struct nfp_mask_id_entry {
 {
 	int ret = 0;
 	bool mac_set_flag = false;
+	bool ip_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -620,6 +621,14 @@ struct nfp_mask_id_entry {
 		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP detected");
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC detected");
+			if (!ip_set_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1284,6 +1293,33 @@ struct nfp_mask_id_entry {
 	nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_POPV);
 }
 
+static void
+nfp_flow_action_set_ip(char *act_data,
+		const struct rte_flow_action *action,
+		bool ip_src_flag,
+		bool ip_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_addrs *set_ip;
+	const struct rte_flow_action_set_ipv4 *set_ipv4;
+
+	if (ip_set_flag)
+		set_ip = (struct nfp_fl_act_set_ip4_addrs *)act_data - 1;
+	else
+		set_ip = (struct nfp_fl_act_set_ip4_addrs *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_addrs);
+	set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS;
+	set_ip->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_ip->reserved     = 0;
+
+	set_ipv4 = (const struct rte_flow_action_set_ipv4 *)action->conf;
+	if (ip_src_flag)
+		set_ip->ipv4_src = set_ipv4->ipv4_addr;
+	else
+		set_ip->ipv4_dst = set_ipv4->ipv4_addr;
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1326,6 +1362,7 @@ struct nfp_mask_id_entry {
 	char *position;
 	char *action_data;
 	bool drop_flag = false;
+	bool ip_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
@@ -1401,6 +1438,14 @@ struct nfp_mask_id_entry {
 			action += 2;
 			position += sizeof(struct nfp_fl_act_push_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC");
+			nfp_flow_action_set_ip(position, action, true, ip_set_flag);
+			if (!ip_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 18/25] net/nfp: support DST IPv4 flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (16 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 17/25] net/nfp: support SRC IPv4 " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 19/25] net/nfp: support SRC IPv6 " Chaoyong He
                     ` (7 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest IPv4 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index e62b3f7..ddc457f 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -44,6 +44,7 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_dst         = Y
 set_ipv4_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 8b9e153..5bd1eec 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -629,6 +629,14 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_DST detected");
+			if (!ip_set_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1446,6 +1454,14 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_DST");
+			nfp_flow_action_set_ip(position, action, false, ip_set_flag);
+			if (!ip_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 19/25] net/nfp: support SRC IPv6 flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (17 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 18/25] net/nfp: support DST " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 20/25] net/nfp: support DST " Chaoyong He
                     ` (6 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source IPv6 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 33 ++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 35 ++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index ddc457f..b17c701 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -46,5 +46,6 @@ of_set_vlan_vid      = Y
 port_id              = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 77cb51d..45e50dd 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -399,6 +399,39 @@ struct nfp_fl_act_set_ip4_addrs {
 	rte_be32_t ipv4_dst;
 };
 
+/*
+ * IPv6 addr
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_127_96_mask                     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_127_96                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_95_64_mask                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_95_64                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_63_32_mask                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_63_32                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_31_0_mask                       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_31_0                            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ipv6_addr {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	struct {
+		rte_be32_t mask;
+		rte_be32_t exact;
+	} ipv6[4];
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 5bd1eec..21a7168 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -637,6 +637,10 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1328,6 +1332,32 @@ struct nfp_mask_id_entry {
 		set_ip->ipv4_dst = set_ipv4->ipv4_addr;
 }
 
+static void
+nfp_flow_action_set_ipv6(char *act_data,
+		const struct rte_flow_action *action,
+		bool ip_src_flag)
+{
+	int i;
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_addr *set_ip;
+	const struct rte_flow_action_set_ipv6 *set_ipv6;
+
+	set_ip = (struct nfp_fl_act_set_ipv6_addr *)act_data;
+	set_ipv6 = (const struct rte_flow_action_set_ipv6 *)action->conf;
+
+	if (ip_src_flag)
+		set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_SRC;
+	else
+		set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_DST;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_addr);
+	set_ip->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+	set_ip->reserved = 0;
+
+	for (i = 0; i < 4; i++)
+		set_ip->ipv6[i].exact = set_ipv6->ipv6_addr[i];
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1462,6 +1492,11 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC");
+			nfp_flow_action_set_ipv6(position, action, true);
+			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 20/25] net/nfp: support DST IPv6 flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (18 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 19/25] net/nfp: support SRC IPv6 " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 21/25] net/nfp: support TP SRC " Chaoyong He
                     ` (5 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest IPv6 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini | 1 +
 drivers/net/nfp/nfp_flow.c       | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index b17c701..5fcece7 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -46,6 +46,7 @@ of_set_vlan_vid      = Y
 port_id              = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 21a7168..29e7b99 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -641,6 +641,10 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DST detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1497,6 +1501,11 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_set_ipv6(position, action, true);
 			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_DST");
+			nfp_flow_action_set_ipv6(position, action, false);
+			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 21/25] net/nfp: support TP SRC flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (19 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 20/25] net/nfp: support DST " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 22/25] net/nfp: support TP DST " Chaoyong He
                     ` (4 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set TP source port action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 21 +++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 44 ++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 5fcece7..f3ac51c 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -50,3 +50,4 @@ set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
+set_tp_src           = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 45e50dd..26de8b1 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -432,6 +432,27 @@ struct nfp_fl_act_set_ipv6_addr {
 	} ipv6[4];
 };
 
+/*
+ * TCP/UDP/SCTP
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |          src_mask             |         dst_mask              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |          src                  |         dst                   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_tport {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be16_t src_port_mask;
+	rte_be16_t dst_port_mask;
+	rte_be16_t src_port;
+	rte_be16_t dst_port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 29e7b99..db05a5e 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -563,6 +563,7 @@ struct nfp_mask_id_entry {
 	int ret = 0;
 	bool mac_set_flag = false;
 	bool ip_set_flag = false;
+	bool tp_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -645,6 +646,13 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DST detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TP_SRC detected");
+			if (!tp_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1362,6 +1370,33 @@ struct nfp_mask_id_entry {
 		set_ip->ipv6[i].exact = set_ipv6->ipv6_addr[i];
 }
 
+static void
+nfp_flow_action_set_tp(char *act_data,
+		const struct rte_flow_action *action,
+		bool tp_src_flag,
+		bool tp_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_tport *set_tp;
+	const struct rte_flow_action_set_tp *set_tp_conf;
+
+	if (tp_set_flag)
+		set_tp = (struct nfp_fl_act_set_tport *)act_data - 1;
+	else
+		set_tp = (struct nfp_fl_act_set_tport *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_tport);
+	set_tp->head.jump_id = NFP_FL_ACTION_OPCODE_SET_TCP;
+	set_tp->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_tp->reserved     = 0;
+
+	set_tp_conf = (const struct rte_flow_action_set_tp *)action->conf;
+	if (tp_src_flag)
+		set_tp->src_port = set_tp_conf->port;
+	else
+		set_tp->dst_port = set_tp_conf->port;
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1405,6 +1440,7 @@ struct nfp_mask_id_entry {
 	char *action_data;
 	bool drop_flag = false;
 	bool ip_set_flag = false;
+	bool tp_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
@@ -1506,6 +1542,14 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_set_ipv6(position, action, false);
 			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TP_SRC");
+			nfp_flow_action_set_tp(position, action, true, tp_set_flag);
+			if (!tp_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 22/25] net/nfp: support TP DST flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (20 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 21/25] net/nfp: support TP SRC " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 23/25] net/nfp: support TTL " Chaoyong He
                     ` (3 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of set
TP dest port action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f3ac51c..e8ccd6a 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -50,4 +50,5 @@ set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
+set_tp_dst           = Y
 set_tp_src           = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index db05a5e..93f4c04 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -653,6 +653,13 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TP_DST detected");
+			if (!tp_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1550,6 +1557,14 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TP_DST");
+			nfp_flow_action_set_tp(position, action, false, tp_set_flag);
+			if (!tp_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 23/25] net/nfp: support TTL flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (21 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 22/25] net/nfp: support TP DST " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 24/25] net/nfp: support IPv4 DSCP " Chaoyong He
                     ` (2 subsequent siblings)
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set TTL action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 44 +++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 84 ++++++++++++++++++++++++++++++++
 3 files changed, 129 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index e8ccd6a..1283583 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -52,3 +52,4 @@ set_mac_dst          = Y
 set_mac_src          = Y
 set_tp_dst           = Y
 set_tp_src           = Y
+set_ttl              = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 26de8b1..6bf8ff7 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -400,6 +400,25 @@ struct nfp_fl_act_set_ip4_addrs {
 };
 
 /*
+ * IPv4 ttl tos
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|    ttl_mask   |   tos_mask    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |       ttl     |      tos      |               0               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ip4_ttl_tos {
+	struct nfp_fl_act_head head;
+	uint8_t ipv4_ttl_mask;
+	uint8_t ipv4_tos_mask;
+	uint8_t ipv4_ttl;
+	uint8_t ipv4_tos;
+	rte_be16_t reserved;
+};
+
+/*
  * IPv6 addr
  *    3                   2                   1
  *  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
@@ -433,6 +452,31 @@ struct nfp_fl_act_set_ipv6_addr {
 };
 
 /*
+ * ipv6 tc hl fl
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|  tclass_mask  |  hlimit_mask  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |               0               |  tclass       |  hlimit       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           0           |             flabel_mask               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           0           |             flabel                    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ipv6_tc_hl_fl {
+	struct nfp_fl_act_head head;
+	uint8_t ipv6_tc_mask;
+	uint8_t ipv6_hop_limit_mask;
+	rte_be16_t reserved;
+	uint8_t ipv6_tc;
+	uint8_t ipv6_hop_limit;
+	rte_be32_t ipv6_label_mask;
+	rte_be32_t ipv6_label;
+};
+
+/*
  * TCP/UDP/SCTP
  *    3                   2                   1
  *  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
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 93f4c04..9b1e8dd 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -561,9 +561,11 @@ struct nfp_mask_id_entry {
 		struct nfp_fl_key_ls *key_ls)
 {
 	int ret = 0;
+	bool tc_hl_flag = false;
 	bool mac_set_flag = false;
 	bool ip_set_flag = false;
 	bool tp_set_flag = false;
+	bool ttl_tos_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -660,6 +662,22 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TTL:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TTL detected");
+			if (key_ls->key_layer & NFP_FLOWER_LAYER_IPV4) {
+				if (!ttl_tos_flag) {
+					key_ls->act_size +=
+						sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+					ttl_tos_flag = true;
+				}
+			} else {
+				if (!tc_hl_flag) {
+					key_ls->act_size +=
+						sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+					tc_hl_flag = true;
+				}
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1437,6 +1455,52 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flow_action_set_ttl(char *act_data,
+		const struct rte_flow_action *action,
+		bool ttl_tos_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_ttl_tos *ttl_tos;
+	const struct rte_flow_action_set_ttl *ttl_conf;
+
+	if (ttl_tos_flag)
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data - 1;
+	else
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+	ttl_tos->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS;
+	ttl_tos->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	ttl_conf = (const struct rte_flow_action_set_ttl *)action->conf;
+	ttl_tos->ipv4_ttl = ttl_conf->ttl_value;
+	ttl_tos->reserved = 0;
+}
+
+static void
+nfp_flow_action_set_hl(char *act_data,
+		const struct rte_flow_action *action,
+		bool tc_hl_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_tc_hl_fl *tc_hl;
+	const struct rte_flow_action_set_ttl *ttl_conf;
+
+	if (tc_hl_flag)
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data - 1;
+	else
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+	tc_hl->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL;
+	tc_hl->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	ttl_conf = (const struct rte_flow_action_set_ttl *)action->conf;
+	tc_hl->ipv6_hop_limit = ttl_conf->ttl_value;
+	tc_hl->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1445,17 +1509,21 @@ struct nfp_mask_id_entry {
 	int ret = 0;
 	char *position;
 	char *action_data;
+	bool ttl_tos_flag = false;
+	bool tc_hl_flag = false;
 	bool drop_flag = false;
 	bool ip_set_flag = false;
 	bool tp_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
+	struct nfp_flower_meta_tci *meta_tci;
 	struct nfp_fl_rule_metadata *nfp_flow_meta;
 
 	nfp_flow_meta = nfp_flow->payload.meta;
 	action_data   = nfp_flow->payload.action_data;
 	position      = action_data;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
 		switch (action->type) {
@@ -1565,6 +1633,22 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TTL:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TTL");
+			if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+				nfp_flow_action_set_ttl(position, action, ttl_tos_flag);
+				if (!ttl_tos_flag) {
+					position += sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+					ttl_tos_flag = true;
+				}
+			} else {
+				nfp_flow_action_set_hl(position, action, ttl_tos_flag);
+				if (!tc_hl_flag) {
+					position += sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+					tc_hl_flag = true;
+				}
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 24/25] net/nfp: support IPv4 DSCP flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (22 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 23/25] net/nfp: support TTL " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-20  2:19   ` [PATCH v5 25/25] net/nfp: support IPv6 " Chaoyong He
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set IPv4 DSCP action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 1283583..596589f 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -44,6 +44,7 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_dscp        = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
 set_ipv6_dst         = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 9b1e8dd..dfcd784 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -678,6 +678,14 @@ struct nfp_mask_id_entry {
 				}
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP detected");
+			if (!ttl_tos_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+				ttl_tos_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1501,6 +1509,29 @@ struct nfp_mask_id_entry {
 	tc_hl->reserved = 0;
 }
 
+static void
+nfp_flow_action_set_tos(char *act_data,
+		const struct rte_flow_action *action,
+		bool ttl_tos_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_ttl_tos *ttl_tos;
+	const struct rte_flow_action_set_dscp *tos_conf;
+
+	if (ttl_tos_flag)
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data - 1;
+	else
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+	ttl_tos->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS;
+	ttl_tos->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	tos_conf = (const struct rte_flow_action_set_dscp *)action->conf;
+	ttl_tos->ipv4_tos = tos_conf->dscp;
+	ttl_tos->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1649,6 +1680,14 @@ struct nfp_mask_id_entry {
 				}
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP");
+			nfp_flow_action_set_tos(position, action, ttl_tos_flag);
+			if (!ttl_tos_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+				ttl_tos_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v5 25/25] net/nfp: support IPv6 DSCP flow action
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (23 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 24/25] net/nfp: support IPv4 DSCP " Chaoyong He
@ 2022-10-20  2:19   ` Chaoyong He
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
  25 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20  2:19 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set IPv6 DSCP action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 596589f..0184980 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -47,6 +47,7 @@ port_id              = Y
 set_ipv4_dscp        = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_dscp        = Y
 set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index dfcd784..23b7802 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -686,6 +686,14 @@ struct nfp_mask_id_entry {
 				ttl_tos_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP detected");
+			if (!tc_hl_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+				tc_hl_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1532,6 +1540,29 @@ struct nfp_mask_id_entry {
 	ttl_tos->reserved = 0;
 }
 
+static void
+nfp_flow_action_set_tc(char *act_data,
+		const struct rte_flow_action *action,
+		bool tc_hl_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_tc_hl_fl *tc_hl;
+	const struct rte_flow_action_set_dscp *tos_conf;
+
+	if (tc_hl_flag)
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data - 1;
+	else
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+	tc_hl->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL;
+	tc_hl->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	tos_conf = (const struct rte_flow_action_set_dscp *)action->conf;
+	tc_hl->ipv6_tc = tos_conf->dscp;
+	tc_hl->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1688,6 +1719,14 @@ struct nfp_mask_id_entry {
 				ttl_tos_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP");
+			nfp_flow_action_set_tc(position, action, ttl_tos_flag);
+			if (!tc_hl_flag) {
+				position += sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+				tc_hl_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* Re: [PATCH v5 04/25] net/nfp: add the flow APIs of nfp PMD
  2022-10-20  2:19   ` [PATCH v5 04/25] net/nfp: add the flow APIs of nfp PMD Chaoyong He
@ 2022-10-20 11:09     ` Ferruh Yigit
  2022-10-20 11:42       ` Chaoyong He
  0 siblings, 1 reply; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-20 11:09 UTC (permalink / raw)
  To: Chaoyong He; +Cc: oss-drivers, niklas.soderlund, dev

On 10/20/2022 3:19 AM, Chaoyong He wrote:
> Add the flow validate/create/query/destroy/flush API of nfp PMD.
> 
> The flow create API construct a control cmsg and send it to
> firmware, then add this flow  to the hash table.
> 
> The flow query API get flow stats from the flow_priv structure.
> Note there exist an rte_spin_lock to prevent the update and query
> action occur at the same time.
> 
> The flow destroy API construct a control cmsg and send it to
> firmware, then adelete 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: Niklas Söderlund <niklas.soderlund@corigine.com>

<...>

> diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
> index e8fd22a..6fa1b3e 100644
> --- a/drivers/net/nfp/nfp_flow.h
> +++ b/drivers/net/nfp/nfp_flow.h
> @@ -6,10 +6,36 @@
>   #ifndef _NFP_FLOW_H_
>   #define _NFP_FLOW_H_
>   
> +#include <ethdev_driver.h>
> +
> +#define NFP_FLOWER_LAYER_EXT_META   (1 << 0)
> +#define NFP_FLOWER_LAYER_PORT       (1 << 1)
> +#define NFP_FLOWER_LAYER_MAC        (1 << 2)
> +#define NFP_FLOWER_LAYER_TP         (1 << 3)
> +#define NFP_FLOWER_LAYER_IPV4       (1 << 4)
> +#define NFP_FLOWER_LAYER_IPV6       (1 << 5)
> +#define NFP_FLOWER_LAYER_CT         (1 << 6)
> +#define NFP_FLOWER_LAYER_VXLAN      (1 << 7)
> +
> +#define NFP_FLOWER_LAYER2_GRE       (1 << 0)
> +#define NFP_FLOWER_LAYER2_QINQ      (1 << 4)
> +#define NFP_FLOWER_LAYER2_GENEVE    (1 << 5)
> +#define NFP_FLOWER_LAYER2_GENEVE_OP (1 << 6)
> +#define NFP_FLOWER_LAYER2_TUN_IPV6  (1 << 7)
> +

RTE_BIT32() may be used, up to you.

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

* Re: [PATCH v5 05/25] net/nfp: support basic flow items
  2022-10-20  2:19   ` [PATCH v5 05/25] net/nfp: support basic flow items Chaoyong He
@ 2022-10-20 11:11     ` Ferruh Yigit
  2022-10-20 11:43       ` Chaoyong He
  0 siblings, 1 reply; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-20 11:11 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers, niklas.soderlund

On 10/20/2022 3:19 AM, Chaoyong He wrote:
> Add the offload support of very basic items: ethernet and
> port id.
> 
> Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
> ---
>   doc/guides/nics/features/nfp.ini         |   4 +
>   doc/guides/rel_notes/release_22_11.rst   |   2 +
>   drivers/net/nfp/flower/nfp_flower_cmsg.h |  20 +++
>   drivers/net/nfp/nfp_flow.c               | 252 ++++++++++++++++++++++++++++++-
>   4 files changed, 277 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
> index f7a0362..4460cf0 100644
> --- a/doc/guides/nics/features/nfp.ini
> +++ b/doc/guides/nics/features/nfp.ini
> @@ -25,3 +25,7 @@ Linux                = Y
>   Multiprocess aware   = Y
>   x86-64               = Y
>   Usage doc            = Y
> +
> +[rte_flow items]
> +eth                  = Y
> +port_id              = Y
> diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
> index a3700bb..6d421a2 100644
> --- a/doc/guides/rel_notes/release_22_11.rst
> +++ b/doc/guides/rel_notes/release_22_11.rst
> @@ -163,6 +163,8 @@ New Features
>     * Added the control message interactive channels between PMD and firmware.
>     * Added the support of representor port.
>   
> +  Add the support of rte_flow pattern items.
> +

I remember previously this was listing supported patterns one by one, it 
is changed to brief entry now but instead of saying added "pattern items 
and actions" and what do you think on a generic wording someting like:
"Added support for flow API"


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

* Re: [PATCH v5 06/25] net/nfp: support basic flow actions
  2022-10-20  2:19   ` [PATCH v5 06/25] net/nfp: support basic flow actions Chaoyong He
@ 2022-10-20 11:12     ` Ferruh Yigit
  2022-10-20 11:41       ` Chaoyong He
  0 siblings, 1 reply; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-20 11:12 UTC (permalink / raw)
  To: Chaoyong He; +Cc: oss-drivers, niklas.soderlund, dev

On 10/20/2022 3:19 AM, Chaoyong He wrote:
> Add the offload support of very basic actions: mark, rss,
> count, drop and output.
> 
> Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>

<...>

> +static int
> +nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
> +		const struct rte_flow_action actions[],
> +		struct rte_flow *nfp_flow)
> +{
> +	int ret = 0;
> +	char *position;
> +	char *action_data;
> +	bool drop_flag = false;
> +	uint32_t total_actions = 0;
> +	const struct rte_flow_action *action;
> +	struct nfp_fl_rule_metadata *nfp_flow_meta;
> +
> +	nfp_flow_meta = nfp_flow->payload.meta;
> +	action_data   = nfp_flow->payload.action_data;
> +	position      = action_data;
> +
> +	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
> +		switch (action->type) {
> +		case RTE_FLOW_ACTION_TYPE_VOID:
> +			break;
> +		case RTE_FLOW_ACTION_TYPE_MARK:
> +			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_MARK");
> +			break;
> +		case RTE_FLOW_ACTION_TYPE_DROP:
> +			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_DROP");
> +			drop_flag = true;
> +			break;
> +		case RTE_FLOW_ACTION_TYPE_COUNT:
> +			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_COUNT");
> +			break;
> +		case RTE_FLOW_ACTION_TYPE_RSS:
> +			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_RSS");
> +			break;

Above MARK and RSS actions not doing anything but not returning error as 
if it is supported.

Not sure about COUNT, since driver is keeping stats may be it is 
supported by default, but if not it also needs to return error.

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

* Re: [PATCH v5 13/25] net/nfp: support SRC MAC flow action
  2022-10-20  2:19   ` [PATCH v5 13/25] net/nfp: support SRC MAC flow action Chaoyong He
@ 2022-10-20 11:12     ` Ferruh Yigit
  2022-10-20 11:48       ` Chaoyong He
  0 siblings, 1 reply; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-20 11:12 UTC (permalink / raw)
  To: Chaoyong He, Andrew Rybchenko, Ori Kam; +Cc: oss-drivers, niklas.soderlund, dev

On 10/20/2022 3:19 AM, Chaoyong He wrote:
> Add the corresponding data structure and logics, to support
> the offload of set source MAC action.
> 
> Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>

<...>

> +		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
> +			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_MAC_SRC");
> +			nfp_flow_action_set_mac(position, action, true, mac_set_flag);
> +			if (!mac_set_flag) {
> +				position += sizeof(struct nfp_fl_act_set_eth);
> +				mac_set_flag = true;
> +			}

Hi Andrew, Ori,

I can see 'RTE_FLOW_ACTION_TYPE_SET_MAC_SRC' and many  other marked as 
legacy and reference to 'RTE_FLOW_ACTION_TYPE_MODIFY_FIELD'.

What is the expectation from PMD developers for this?

User still can provide these legacy actions, right? So should PMD 
implement both legacy and new ones?


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

* RE: [PATCH v5 06/25] net/nfp: support basic flow actions
  2022-10-20 11:12     ` Ferruh Yigit
@ 2022-10-20 11:41       ` Chaoyong He
  0 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20 11:41 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: oss-drivers, Niklas Soderlund, dev

> On 10/20/2022 3:19 AM, Chaoyong He wrote:
> > Add the offload support of very basic actions: mark, rss, count, drop
> > and output.
> >
> > Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> > Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
> 
> <...>
> 
> > +static int
> > +nfp_flow_compile_action(__rte_unused struct nfp_flower_representor
> *representor,
> > +		const struct rte_flow_action actions[],
> > +		struct rte_flow *nfp_flow)
> > +{
> > +	int ret = 0;
> > +	char *position;
> > +	char *action_data;
> > +	bool drop_flag = false;
> > +	uint32_t total_actions = 0;
> > +	const struct rte_flow_action *action;
> > +	struct nfp_fl_rule_metadata *nfp_flow_meta;
> > +
> > +	nfp_flow_meta = nfp_flow->payload.meta;
> > +	action_data   = nfp_flow->payload.action_data;
> > +	position      = action_data;
> > +
> > +	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END;
> ++action) {
> > +		switch (action->type) {
> > +		case RTE_FLOW_ACTION_TYPE_VOID:
> > +			break;
> > +		case RTE_FLOW_ACTION_TYPE_MARK:
> > +			PMD_DRV_LOG(DEBUG, "Process
> RTE_FLOW_ACTION_TYPE_MARK");
> > +			break;
> > +		case RTE_FLOW_ACTION_TYPE_DROP:
> > +			PMD_DRV_LOG(DEBUG, "Process
> RTE_FLOW_ACTION_TYPE_DROP");
> > +			drop_flag = true;
> > +			break;
> > +		case RTE_FLOW_ACTION_TYPE_COUNT:
> > +			PMD_DRV_LOG(DEBUG, "Process
> RTE_FLOW_ACTION_TYPE_COUNT");
> > +			break;
> > +		case RTE_FLOW_ACTION_TYPE_RSS:
> > +			PMD_DRV_LOG(DEBUG, "Process
> RTE_FLOW_ACTION_TYPE_RSS");
> > +			break;
> 
> Above MARK and RSS actions not doing anything but not returning error as if
> it is supported.
> 
> Not sure about COUNT, since driver is keeping stats may be it is supported by
> default, but if not it also needs to return error.

Yes, COUNT is supported by default.
I will remove MARK and RSS here and add them when we really support the partial offload.
Thanks.

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

* RE: [PATCH v5 04/25] net/nfp: add the flow APIs of nfp PMD
  2022-10-20 11:09     ` Ferruh Yigit
@ 2022-10-20 11:42       ` Chaoyong He
  0 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20 11:42 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: oss-drivers, Niklas Soderlund, dev

> On 10/20/2022 3:19 AM, Chaoyong He wrote:
> > Add the flow validate/create/query/destroy/flush API of nfp PMD.
> >
> > The flow create API construct a control cmsg and send it to firmware,
> > then add this flow  to the hash table.
> >
> > The flow query API get flow stats from the flow_priv structure.
> > Note there exist an rte_spin_lock to prevent the update and query
> > action occur at the same time.
> >
> > The flow destroy API construct a control cmsg and send it to firmware,
> > then adelete 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: Niklas Söderlund <niklas.soderlund@corigine.com>
> 
> <...>
> 
> > diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
> > index e8fd22a..6fa1b3e 100644
> > --- a/drivers/net/nfp/nfp_flow.h
> > +++ b/drivers/net/nfp/nfp_flow.h
> > @@ -6,10 +6,36 @@
> >   #ifndef _NFP_FLOW_H_
> >   #define _NFP_FLOW_H_
> >
> > +#include <ethdev_driver.h>
> > +
> > +#define NFP_FLOWER_LAYER_EXT_META   (1 << 0)
> > +#define NFP_FLOWER_LAYER_PORT       (1 << 1)
> > +#define NFP_FLOWER_LAYER_MAC        (1 << 2)
> > +#define NFP_FLOWER_LAYER_TP         (1 << 3)
> > +#define NFP_FLOWER_LAYER_IPV4       (1 << 4)
> > +#define NFP_FLOWER_LAYER_IPV6       (1 << 5)
> > +#define NFP_FLOWER_LAYER_CT         (1 << 6)
> > +#define NFP_FLOWER_LAYER_VXLAN      (1 << 7)
> > +
> > +#define NFP_FLOWER_LAYER2_GRE       (1 << 0)
> > +#define NFP_FLOWER_LAYER2_QINQ      (1 << 4)
> > +#define NFP_FLOWER_LAYER2_GENEVE    (1 << 5)
> > +#define NFP_FLOWER_LAYER2_GENEVE_OP (1 << 6) #define
> > +NFP_FLOWER_LAYER2_TUN_IPV6  (1 << 7)
> > +
> 
> RTE_BIT32() may be used, up to you.

Okay, I will try to use RTE_BIT32() as you wish, need some check and test.
Thanks.

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

* RE: [PATCH v5 05/25] net/nfp: support basic flow items
  2022-10-20 11:11     ` Ferruh Yigit
@ 2022-10-20 11:43       ` Chaoyong He
  0 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-20 11:43 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: oss-drivers, Niklas Soderlund

> On 10/20/2022 3:19 AM, Chaoyong He wrote:
> > Add the offload support of very basic items: ethernet and port id.
> >
> > Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> > Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
> > ---
> >   doc/guides/nics/features/nfp.ini         |   4 +
> >   doc/guides/rel_notes/release_22_11.rst   |   2 +
> >   drivers/net/nfp/flower/nfp_flower_cmsg.h |  20 +++
> >   drivers/net/nfp/nfp_flow.c               | 252
> ++++++++++++++++++++++++++++++-
> >   4 files changed, 277 insertions(+), 1 deletion(-)
> >
> > diff --git a/doc/guides/nics/features/nfp.ini
> > b/doc/guides/nics/features/nfp.ini
> > index f7a0362..4460cf0 100644
> > --- a/doc/guides/nics/features/nfp.ini
> > +++ b/doc/guides/nics/features/nfp.ini
> > @@ -25,3 +25,7 @@ Linux                = Y
> >   Multiprocess aware   = Y
> >   x86-64               = Y
> >   Usage doc            = Y
> > +
> > +[rte_flow items]
> > +eth                  = Y
> > +port_id              = Y
> > diff --git a/doc/guides/rel_notes/release_22_11.rst
> > b/doc/guides/rel_notes/release_22_11.rst
> > index a3700bb..6d421a2 100644
> > --- a/doc/guides/rel_notes/release_22_11.rst
> > +++ b/doc/guides/rel_notes/release_22_11.rst
> > @@ -163,6 +163,8 @@ New Features
> >     * Added the control message interactive channels between PMD and
> firmware.
> >     * Added the support of representor port.
> >
> > +  Add the support of rte_flow pattern items.
> > +
> 
> I remember previously this was listing supported patterns one by one, it is
> changed to brief entry now but instead of saying added "pattern items and
> actions" and what do you think on a generic wording someting like:
> "Added support for flow API"

Sure, I will revise in the next version patch, thanks.

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

* RE: [PATCH v5 13/25] net/nfp: support SRC MAC flow action
  2022-10-20 11:12     ` Ferruh Yigit
@ 2022-10-20 11:48       ` Chaoyong He
  2022-10-20 11:55         ` Ferruh Yigit
  0 siblings, 1 reply; 96+ messages in thread
From: Chaoyong He @ 2022-10-20 11:48 UTC (permalink / raw)
  To: Ferruh Yigit, Andrew Rybchenko, Ori Kam
  Cc: oss-drivers, Niklas Soderlund, dev

> On 10/20/2022 3:19 AM, Chaoyong He wrote:
> > Add the corresponding data structure and logics, to support the
> > offload of set source MAC action.
> >
> > Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> > Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
> 
> <...>
> 
> > +		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
> > +			PMD_DRV_LOG(DEBUG, "Process
> RTE_FLOW_ACTION_TYPE_SET_MAC_SRC");
> > +			nfp_flow_action_set_mac(position, action, true,
> mac_set_flag);
> > +			if (!mac_set_flag) {
> > +				position += sizeof(struct nfp_fl_act_set_eth);
> > +				mac_set_flag = true;
> > +			}
> 
> Hi Andrew, Ori,
> 
> I can see 'RTE_FLOW_ACTION_TYPE_SET_MAC_SRC' and many  other
> marked as legacy and reference to
> 'RTE_FLOW_ACTION_TYPE_MODIFY_FIELD'.
> 
> What is the expectation from PMD developers for this?
> 
> User still can provide these legacy actions, right? So should PMD implement
> both legacy and new ones?

From my side, we trying to implement the basic offload in this DPDK release, and complete
the missing pieces in the next few DPDK releases.

The support of 'RTE_FLOW_ACTION_TYPE_MODIFY_FIELD' is in the very next project after
this series.

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

* Re: [PATCH v5 13/25] net/nfp: support SRC MAC flow action
  2022-10-20 11:48       ` Chaoyong He
@ 2022-10-20 11:55         ` Ferruh Yigit
  0 siblings, 0 replies; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-20 11:55 UTC (permalink / raw)
  To: Chaoyong He, Andrew Rybchenko, Ori Kam; +Cc: oss-drivers, Niklas Soderlund, dev

On 10/20/2022 12:48 PM, Chaoyong He wrote:
>> On 10/20/2022 3:19 AM, Chaoyong He wrote:
>>> Add the corresponding data structure and logics, to support the
>>> offload of set source MAC action.
>>>
>>> Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
>>> Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
>>
>> <...>
>>
>>> +		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
>>> +			PMD_DRV_LOG(DEBUG, "Process
>> RTE_FLOW_ACTION_TYPE_SET_MAC_SRC");
>>> +			nfp_flow_action_set_mac(position, action, true,
>> mac_set_flag);
>>> +			if (!mac_set_flag) {
>>> +				position += sizeof(struct nfp_fl_act_set_eth);
>>> +				mac_set_flag = true;
>>> +			}
>>
>> Hi Andrew, Ori,
>>
>> I can see 'RTE_FLOW_ACTION_TYPE_SET_MAC_SRC' and many  other
>> marked as legacy and reference to
>> 'RTE_FLOW_ACTION_TYPE_MODIFY_FIELD'.
>>
>> What is the expectation from PMD developers for this?
>>
>> User still can provide these legacy actions, right? So should PMD implement
>> both legacy and new ones?
> 
>  From my side, we trying to implement the basic offload in this DPDK release, and complete
> the missing pieces in the next few DPDK releases.
> 
> The support of 'RTE_FLOW_ACTION_TYPE_MODIFY_FIELD' is in the very next project after
> this series.

Sounds reasonable to me, but also I am not aware of the long term plan 
there, so I need input from Andrew and Ori.

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

* [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD
  2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
                     ` (24 preceding siblings ...)
  2022-10-20  2:19   ` [PATCH v5 25/25] net/nfp: support IPv6 " Chaoyong He
@ 2022-10-21  8:01   ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 01/27] net/nfp: fix CPP bridge service requirement Chaoyong He
                       ` (27 more replies)
  25 siblings, 28 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

This is the second patch series to add the support of rte_flow offload for
nfp PMD, includes:
Implement the rte_flow related API
Implement the offload framework of nfp card
Add the offload support of common rte_flow pattern items
Add the offload support of common rte_flow actions

* Changes since v5
- Fix two problems import by the first patch series.
- Use RTE_BIT32 for bit.
- Modify the release note.
- Remove the incompletement logic about 'MARK' and 'RSS'.

* Changes since v4
- Store the hash_key to avoid the uncessary repeat calculation.
- Make sure '.validate' don't update 'flower_version'.
- Guarante 'query' is zeroed out.
- Use the 'rest' field of query action to decide if reset the stats.
- Modify the 'nfp.ini' document.

* Changes since v3
- Change the release note.
- Change the headline of commit message.
- Adjust the order of commits to prevent the memory problem.

* Changes since v2
- Fix one problem import by the first patch series

* Changes since v1
- Add the 'Depends-on' tag

Chaoyong He (27):
  net/nfp: fix CPP bridge service requirement
  net/nfp: fix the promiscuous mode control functions
  net/nfp: fix the service stuck the app end
  net/nfp: add the structures and functions for flow offload
  net/nfp: add the stats process logic in ctrl VNIC service
  net/nfp: add the flow APIs of nfp PMD
  net/nfp: support basic flow items
  net/nfp: support basic flow actions
  net/nfp: support VLAN flow item
  net/nfp: support IPv4 flow item
  net/nfp: support IPv6 flow item
  net/nfp: support TCP flow item
  net/nfp: support UDP flow item
  net/nfp: support SCTP flow item
  net/nfp: support SRC MAC flow action
  net/nfp: support DST MAC flow action
  net/nfp: support pop VLAN flow action
  net/nfp: support push VLAN flow action
  net/nfp: support SRC IPv4 flow action
  net/nfp: support DST IPv4 flow action
  net/nfp: support SRC IPv6 flow action
  net/nfp: support DST IPv6 flow action
  net/nfp: support TP SRC flow action
  net/nfp: support TP DST flow action
  net/nfp: support TTL flow action
  net/nfp: support IPv4 DSCP flow action
  net/nfp: support IPv6 DSCP flow action

 doc/guides/nics/features/nfp.ini                |   30 +
 doc/guides/rel_notes/release_22_11.rst          |    2 +
 drivers/net/nfp/flower/nfp_flower.c             |   12 +-
 drivers/net/nfp/flower/nfp_flower.h             |    5 +
 drivers/net/nfp/flower/nfp_flower_cmsg.c        |   69 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h        |  337 ++++
 drivers/net/nfp/flower/nfp_flower_ctrl.c        |   76 +-
 drivers/net/nfp/flower/nfp_flower_representor.c |   29 +-
 drivers/net/nfp/meson.build                     |    3 +
 drivers/net/nfp/nfp_common.h                    |    3 +
 drivers/net/nfp/nfp_cpp_bridge.c                |   12 +-
 drivers/net/nfp/nfp_cpp_bridge.h                |    2 +-
 drivers/net/nfp/nfp_ethdev.c                    |   16 +-
 drivers/net/nfp/nfp_flow.c                      | 2283 +++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h                      |  177 ++
 15 files changed, 3030 insertions(+), 26 deletions(-)
 create mode 100644 drivers/net/nfp/nfp_flow.c
 create mode 100644 drivers/net/nfp/nfp_flow.h

-- 
1.8.3.1


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

* [PATCH v6 01/27] net/nfp: fix CPP bridge service requirement
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 02/27] net/nfp: fix the promiscuous mode control functions Chaoyong He
                       ` (26 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

The CPP(Command Pull Push) bridge service is needed for some debug tools,
and should be optional, so remove the mandatory requirement of service
lcore parameter.

Fixes: b18804219537 ("net/nfp: add initial flower firmware support")

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/nfp_ethdev.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index f11a1b6..f25d6a1 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -1066,11 +1066,8 @@
 
 	/* register the CPP bridge service here for primary use */
 	ret = nfp_enable_cpp_service(pf_dev->cpp);
-	if (ret != 0) {
-		PMD_INIT_LOG(ERR, "Enable cpp service failed.");
-		ret = -EINVAL;
-		goto hwqueues_cleanup;
-	}
+	if (ret != 0)
+		PMD_INIT_LOG(INFO, "Enable cpp service failed.");
 
 	return 0;
 
@@ -1208,13 +1205,6 @@
 		goto sym_tbl_cleanup;
 	}
 
-	/* Register the CPP bridge service for the secondary too */
-	ret = nfp_enable_cpp_service(cpp);
-	if (ret != 0) {
-		PMD_INIT_LOG(ERR, "Enable cpp service failed.");
-		ret = -EINVAL;
-	}
-
 sym_tbl_cleanup:
 	free(sym_tbl);
 
-- 
1.8.3.1


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

* [PATCH v6 02/27] net/nfp: fix the promiscuous mode control functions
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 01/27] net/nfp: fix CPP bridge service requirement Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21 13:03       ` Ferruh Yigit
  2022-10-22  8:11       ` [PATCH v7] net/nfp: fix the promiscuous mode functions Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 03/27] net/nfp: fix the service stuck the app end Chaoyong He
                       ` (25 subsequent siblings)
  27 siblings, 2 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

The original functions of promiscuous mode can't process the
representor port rightly, revise the logic to do that.

Fixes: e1124c4f8a45 ("net/nfp: add flower representor framework")

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower_representor.c | 26 +++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index 0e60f50..cecdf46 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -415,6 +415,9 @@
 static int
 nfp_flower_repr_promiscuous_enable(struct rte_eth_dev *dev)
 {
+	int ret;
+	uint32_t update;
+	uint32_t new_ctrl;
 	struct nfp_net_hw *pf_hw;
 	struct nfp_flower_representor *repr;
 
@@ -431,12 +434,23 @@
 		return 0;
 	}
 
-	return nfp_net_promisc_enable(pf_hw->eth_dev);
+	new_ctrl = pf_hw->ctrl | NFP_NET_CFG_CTRL_PROMISC;
+	update = NFP_NET_CFG_UPDATE_GEN;
+	ret = nfp_net_reconfig(pf_hw, new_ctrl, update);
+	if (ret < 0)
+		return ret;
+
+	pf_hw->ctrl = new_ctrl;
+
+	return 0;
 }
 
 static int
 nfp_flower_repr_promiscuous_disable(struct rte_eth_dev *dev)
 {
+	int ret;
+	uint32_t update;
+	uint32_t new_ctrl;
 	struct nfp_net_hw *pf_hw;
 	struct nfp_flower_representor *repr;
 
@@ -448,7 +462,15 @@
 		return 0;
 	}
 
-	return nfp_net_promisc_disable(pf_hw->eth_dev);
+	new_ctrl = pf_hw->ctrl & ~NFP_NET_CFG_CTRL_PROMISC;
+	update = NFP_NET_CFG_UPDATE_GEN;
+	ret = nfp_net_reconfig(pf_hw, new_ctrl, update);
+	if (ret < 0)
+		return ret;
+
+	pf_hw->ctrl = new_ctrl;
+
+	return 0;
 }
 
 static int
-- 
1.8.3.1


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

* [PATCH v6 03/27] net/nfp: fix the service stuck the app end
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 01/27] net/nfp: fix CPP bridge service requirement Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 02/27] net/nfp: fix the promiscuous mode control functions Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 04/27] net/nfp: add the structures and functions for flow offload Chaoyong He
                       ` (24 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

The services don't have a method to break the infinite loop, and
this will cause the DPDK app can't end normally.

Fixes: a36634e87e16 ("net/nfp: add flower ctrl VNIC Rx/Tx")

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower.c      |  1 +
 drivers/net/nfp/flower/nfp_flower.h      |  3 +++
 drivers/net/nfp/flower/nfp_flower_ctrl.c |  3 ++-
 drivers/net/nfp/nfp_common.h             |  3 +++
 drivers/net/nfp/nfp_cpp_bridge.c         | 12 ++++++++----
 drivers/net/nfp/nfp_cpp_bridge.h         |  2 +-
 drivers/net/nfp/nfp_ethdev.c             |  2 +-
 7 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index 3e97f5c..1db085e 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -1056,6 +1056,7 @@
 		return -EINVAL;
 	}
 
+	app_fw_flower->ctrl_vnic_id = service_id;
 	PMD_INIT_LOG(INFO, "%s registered", flower_service.name);
 
 	/* Map them to available service cores*/
diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index 48f597a..8521ae4 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -51,6 +51,9 @@ struct nfp_app_fw_flower {
 
 	/* PF representor */
 	struct nfp_flower_representor *pf_repr;
+
+	/* service id of ctrl vnic service */
+	uint32_t ctrl_vnic_id;
 };
 
 int nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev);
diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c
index df908ef..53ca710 100644
--- a/drivers/net/nfp/flower/nfp_flower_ctrl.c
+++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c
@@ -4,6 +4,7 @@
  */
 
 #include <rte_common.h>
+#include <rte_service.h>
 #include <ethdev_pci.h>
 
 #include "../nfp_common.h"
@@ -238,7 +239,7 @@
 	/* ctrl vNIC only has a single Rx queue */
 	rxq = ctrl_eth_dev->data->rx_queues[0];
 
-	while (true) {
+	while (rte_service_runstate_get(app_fw_flower->ctrl_vnic_id) != 0) {
 		count = nfp_flower_ctrl_vnic_recv(rxq, pkts_burst, MAX_PKT_BURST);
 		if (count != 0) {
 			app_fw_flower->ctrl_vnic_rx_count += count;
diff --git a/drivers/net/nfp/nfp_common.h b/drivers/net/nfp/nfp_common.h
index d7861a2..36c19b4 100644
--- a/drivers/net/nfp/nfp_common.h
+++ b/drivers/net/nfp/nfp_common.h
@@ -171,6 +171,9 @@ struct nfp_pf_dev {
 
 	struct nfp_hwinfo *hwinfo;
 	struct nfp_rtsym_table *sym_tbl;
+
+	/* service id of cpp bridge service */
+	uint32_t cpp_bridge_id;
 };
 
 struct nfp_app_fw_nic {
diff --git a/drivers/net/nfp/nfp_cpp_bridge.c b/drivers/net/nfp/nfp_cpp_bridge.c
index 155628d..db4b781 100644
--- a/drivers/net/nfp/nfp_cpp_bridge.c
+++ b/drivers/net/nfp/nfp_cpp_bridge.c
@@ -80,7 +80,7 @@
 }
 
 int
-nfp_enable_cpp_service(struct nfp_cpp *cpp)
+nfp_enable_cpp_service(struct nfp_pf_dev *pf_dev)
 {
 	int ret;
 	uint32_t service_id = 0;
@@ -89,7 +89,7 @@
 		.callback     = nfp_cpp_bridge_service_func,
 	};
 
-	cpp_service.callback_userdata = (void *)cpp;
+	cpp_service.callback_userdata = (void *)pf_dev;
 
 	/* Register the cpp service */
 	ret = rte_service_component_register(&cpp_service, &service_id);
@@ -98,6 +98,7 @@
 		return -EINVAL;
 	}
 
+	pf_dev->cpp_bridge_id = service_id;
 	PMD_INIT_LOG(INFO, "NFP cpp service registered");
 
 	/* Map it to available service core*/
@@ -375,7 +376,8 @@
 nfp_cpp_bridge_service_func(void *args)
 {
 	struct sockaddr address;
-	struct nfp_cpp *cpp = args;
+	struct nfp_cpp *cpp;
+	struct nfp_pf_dev *pf_dev;
 	int sockfd, datafd, op, ret;
 
 	unlink("/tmp/nfp_cpp");
@@ -408,7 +410,9 @@
 		return ret;
 	}
 
-	for (;;) {
+	pf_dev = args;
+	cpp = pf_dev->cpp;
+	while (rte_service_runstate_get(pf_dev->cpp_bridge_id) != 0) {
 		datafd = accept(sockfd, NULL, NULL);
 		if (datafd < 0) {
 			RTE_LOG(ERR, PMD, "%s: accept call error (%d)\n",
diff --git a/drivers/net/nfp/nfp_cpp_bridge.h b/drivers/net/nfp/nfp_cpp_bridge.h
index 7fee3a9..8ff7a22 100644
--- a/drivers/net/nfp/nfp_cpp_bridge.h
+++ b/drivers/net/nfp/nfp_cpp_bridge.h
@@ -26,7 +26,7 @@
 #define NFP_IOCTL 'n'
 #define NFP_IOCTL_CPP_IDENTIFICATION _IOW(NFP_IOCTL, 0x8f, uint32_t)
 
-int nfp_enable_cpp_service(struct nfp_cpp *cpp);
+int nfp_enable_cpp_service(struct nfp_pf_dev *pf_dev);
 int nfp_map_service(uint32_t service_id);
 
 #endif /* _NFP_CPP_BRIDGE_H_ */
diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index f25d6a1..77aac2e 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -1065,7 +1065,7 @@
 	}
 
 	/* register the CPP bridge service here for primary use */
-	ret = nfp_enable_cpp_service(pf_dev->cpp);
+	ret = nfp_enable_cpp_service(pf_dev);
 	if (ret != 0)
 		PMD_INIT_LOG(INFO, "Enable cpp service failed.");
 
-- 
1.8.3.1


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

* [PATCH v6 04/27] net/nfp: add the structures and functions for flow offload
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (2 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 03/27] net/nfp: fix the service stuck the app end Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 05/27] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
                       ` (23 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the structures and functions to process mask table, flow
table, and flow stats id, which are used in the rte_flow
offload logics.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower.c |  11 +-
 drivers/net/nfp/flower/nfp_flower.h |   2 +
 drivers/net/nfp/meson.build         |   3 +
 drivers/net/nfp/nfp_flow.c          | 496 ++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h          | 104 ++++++++
 5 files changed, 615 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/nfp/nfp_flow.c
 create mode 100644 drivers/net/nfp/nfp_flow.h

diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index 1db085e..41b0fe2 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -15,6 +15,7 @@
 #include "../nfp_ctrl.h"
 #include "../nfp_cpp_bridge.h"
 #include "../nfp_rxtx.h"
+#include "../nfp_flow.h"
 #include "../nfpcore/nfp_mip.h"
 #include "../nfpcore/nfp_rtsym.h"
 #include "../nfpcore/nfp_nsp.h"
@@ -1090,13 +1091,19 @@
 
 	pf_dev->app_fw_priv = app_fw_flower;
 
+	ret = nfp_flow_priv_init(pf_dev);
+	if (ret != 0) {
+		PMD_INIT_LOG(ERR, "init flow priv failed");
+		goto app_cleanup;
+	}
+
 	/* Allocate memory for the PF AND ctrl vNIC here (hence the * 2) */
 	pf_hw = rte_zmalloc_socket("nfp_pf_vnic", 2 * sizeof(struct nfp_net_adapter),
 			RTE_CACHE_LINE_SIZE, numa_node);
 	if (pf_hw == NULL) {
 		PMD_INIT_LOG(ERR, "Could not malloc nfp pf vnic");
 		ret = -ENOMEM;
-		goto app_cleanup;
+		goto flow_priv_cleanup;
 	}
 
 	/* Map the PF ctrl bar */
@@ -1174,6 +1181,8 @@
 	nfp_cpp_area_free(pf_dev->ctrl_area);
 vnic_cleanup:
 	rte_free(pf_hw);
+flow_priv_cleanup:
+	nfp_flow_priv_uninit(pf_dev);
 app_cleanup:
 	rte_free(app_fw_flower);
 
diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index 8521ae4..12a0fb5 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -54,6 +54,8 @@ struct nfp_app_fw_flower {
 
 	/* service id of ctrl vnic service */
 	uint32_t ctrl_vnic_id;
+
+	struct nfp_flow_priv *flow_priv;
 };
 
 int nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev);
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 8a63979..7416fd3 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -27,4 +27,7 @@ sources = files(
         'nfp_cpp_bridge.c',
         'nfp_ethdev_vf.c',
         'nfp_ethdev.c',
+        'nfp_flow.c',
 )
+
+deps += ['hash']
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
new file mode 100644
index 0000000..dd690cd
--- /dev/null
+++ b/drivers/net/nfp/nfp_flow.c
@@ -0,0 +1,496 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include <rte_flow_driver.h>
+#include <rte_hash.h>
+#include <rte_jhash.h>
+#include <bus_pci_driver.h>
+
+#include "nfp_common.h"
+#include "nfp_flow.h"
+#include "nfp_logs.h"
+#include "flower/nfp_flower.h"
+#include "nfpcore/nfp_mip.h"
+#include "nfpcore/nfp_rtsym.h"
+
+struct nfp_mask_id_entry {
+	uint32_t hash_key;
+	uint32_t ref_cnt;
+	uint8_t mask_id;
+};
+
+static int
+nfp_mask_id_alloc(struct nfp_flow_priv *priv, uint8_t *mask_id)
+{
+	uint8_t temp_id;
+	uint8_t freed_id;
+	struct circ_buf *ring;
+
+	/* Checking for unallocated entries first. */
+	if (priv->mask_ids.init_unallocated > 0) {
+		*mask_id = priv->mask_ids.init_unallocated;
+		priv->mask_ids.init_unallocated--;
+		return 0;
+	}
+
+	/* Checking if buffer is empty. */
+	freed_id = NFP_FLOWER_MASK_ENTRY_RS - 1;
+	ring = &priv->mask_ids.free_list;
+	if (ring->head == ring->tail) {
+		*mask_id = freed_id;
+		return -ENOENT;
+	}
+
+	rte_memcpy(&temp_id, &ring->buf[ring->tail], NFP_FLOWER_MASK_ELEMENT_RS);
+	*mask_id = temp_id;
+
+	rte_memcpy(&ring->buf[ring->tail], &freed_id, NFP_FLOWER_MASK_ELEMENT_RS);
+	ring->tail = (ring->tail + NFP_FLOWER_MASK_ELEMENT_RS) %
+			(NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS);
+
+	return 0;
+}
+
+static int
+nfp_mask_id_free(struct nfp_flow_priv *priv, uint8_t mask_id)
+{
+	struct circ_buf *ring;
+
+	ring = &priv->mask_ids.free_list;
+
+	/* Checking if buffer is full. */
+	if (CIRC_SPACE(ring->head, ring->tail, NFP_FLOWER_MASK_ENTRY_RS) == 0)
+		return -ENOBUFS;
+
+	rte_memcpy(&ring->buf[ring->head], &mask_id, NFP_FLOWER_MASK_ELEMENT_RS);
+	ring->head = (ring->head + NFP_FLOWER_MASK_ELEMENT_RS) %
+			(NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS);
+
+	return 0;
+}
+
+static int
+nfp_mask_table_add(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *id)
+{
+	int ret;
+	uint8_t mask_id;
+	uint32_t hash_key;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = rte_zmalloc("mask_entry", sizeof(struct nfp_mask_id_entry), 0);
+	if (mask_entry == NULL) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = nfp_mask_id_alloc(priv, &mask_id);
+	if (ret != 0)
+		goto mask_entry_free;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	mask_entry->mask_id  = mask_id;
+	mask_entry->hash_key = hash_key;
+	mask_entry->ref_cnt  = 1;
+	PMD_DRV_LOG(DEBUG, "hash_key=%#x id=%u ref=%u", hash_key,
+			mask_id, mask_entry->ref_cnt);
+
+	ret = rte_hash_add_key_data(priv->mask_table, &hash_key, mask_entry);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Add to mask table failed.");
+		goto mask_id_free;
+	}
+
+	*id = mask_id;
+	return 0;
+
+mask_id_free:
+	nfp_mask_id_free(priv, mask_id);
+mask_entry_free:
+	rte_free(mask_entry);
+exit:
+	return ret;
+}
+
+static int
+nfp_mask_table_del(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t id)
+{
+	int ret;
+	uint32_t hash_key;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	ret = rte_hash_del_key(priv->mask_table, &hash_key);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Delete from mask table failed.");
+		return ret;
+	}
+
+	ret = nfp_mask_id_free(priv, id);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Free mask id failed.");
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct nfp_mask_id_entry *
+nfp_mask_table_search(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len)
+{
+	int index;
+	uint32_t hash_key;
+	struct nfp_mask_id_entry *entry;
+
+	hash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);
+	index = rte_hash_lookup_data(priv->mask_table, &hash_key, (void **)&entry);
+	if (index < 0) {
+		PMD_DRV_LOG(DEBUG, "Data NOT found in the mask table.");
+		return NULL;
+	}
+
+	return entry;
+}
+
+__rte_unused static bool
+nfp_check_mask_add(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *meta_flags,
+		uint8_t *mask_id)
+{
+	int ret;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = nfp_mask_table_search(priv, mask_data, mask_len);
+	if (mask_entry == NULL) {
+		/* mask entry does not exist, let's create one */
+		ret = nfp_mask_table_add(priv, mask_data, mask_len, mask_id);
+		if (ret != 0)
+			return false;
+
+		*meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK;
+	} else {
+		/* mask entry already exist */
+		mask_entry->ref_cnt++;
+		*mask_id = mask_entry->mask_id;
+	}
+
+	return true;
+}
+
+__rte_unused static bool
+nfp_check_mask_remove(struct nfp_flow_priv *priv,
+		char *mask_data,
+		uint32_t mask_len,
+		uint8_t *meta_flags)
+{
+	int ret;
+	struct nfp_mask_id_entry *mask_entry;
+
+	mask_entry = nfp_mask_table_search(priv, mask_data, mask_len);
+	if (mask_entry == NULL)
+		return false;
+
+	mask_entry->ref_cnt--;
+	if (mask_entry->ref_cnt == 0) {
+		ret = nfp_mask_table_del(priv, mask_data, mask_len,
+				mask_entry->mask_id);
+		if (ret != 0)
+			return false;
+
+		rte_free(mask_entry);
+		if (meta_flags)
+			*meta_flags &= ~NFP_FL_META_FLAG_MANAGE_MASK;
+	}
+
+	return true;
+}
+
+__rte_unused static int
+nfp_flow_table_add(struct nfp_flow_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_flow_table_delete(struct nfp_flow_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_flow_table_search(struct nfp_flow_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_flow_alloc(struct nfp_fl_key_ls *key_layer)
+{
+	char *tmp;
+	size_t len;
+	struct rte_flow *nfp_flow;
+	struct nfp_fl_payload *payload;
+
+	nfp_flow = rte_zmalloc("nfp_flow", sizeof(struct rte_flow), 0);
+	if (nfp_flow == NULL)
+		goto exit;
+
+	len = key_layer->key_size + key_layer->key_size + key_layer->act_size;
+	tmp = rte_zmalloc("nfp_flow_payload", len + sizeof(struct nfp_fl_rule_metadata), 0);
+	if (tmp == NULL)
+		goto free_flow;
+
+	nfp_flow->length = len;
+
+	payload                = &nfp_flow->payload;
+	payload->meta          = (struct nfp_fl_rule_metadata *)tmp;
+	payload->unmasked_data = tmp + sizeof(struct nfp_fl_rule_metadata);
+	payload->mask_data     = payload->unmasked_data + key_layer->key_size;
+	payload->action_data   = payload->mask_data + key_layer->key_size;
+
+	return nfp_flow;
+
+free_flow:
+	rte_free(nfp_flow);
+exit:
+	return NULL;
+}
+
+__rte_unused static void
+nfp_flow_free(struct rte_flow *nfp_flow)
+{
+	rte_free(nfp_flow->payload.meta);
+	rte_free(nfp_flow);
+}
+
+__rte_unused static int
+nfp_stats_id_alloc(struct nfp_flow_priv *priv, uint32_t *ctx)
+{
+	struct circ_buf *ring;
+	uint32_t temp_stats_id;
+	uint32_t freed_stats_id;
+
+	/* Check for unallocated entries first. */
+	if (priv->stats_ids.init_unallocated > 0) {
+		*ctx = ((priv->stats_ids.init_unallocated - 1) & NFP_FL_STAT_ID_STAT) |
+				(priv->active_mem_unit & NFP_FL_STAT_ID_MU_NUM);
+		if (++priv->active_mem_unit == priv->total_mem_units) {
+			priv->stats_ids.init_unallocated--;
+			priv->active_mem_unit = 0;
+		}
+		return 0;
+	}
+
+	/* Check if buffer is empty */
+	ring = &priv->stats_ids.free_list;
+	freed_stats_id = priv->stats_ring_size;
+	if (ring->head == ring->tail) {
+		*ctx = freed_stats_id;
+		return -ENOENT;
+	}
+
+	memcpy(&temp_stats_id, &ring->buf[ring->tail], NFP_FL_STATS_ELEM_RS);
+	*ctx = temp_stats_id;
+	memcpy(&ring->buf[ring->tail], &freed_stats_id, NFP_FL_STATS_ELEM_RS);
+	ring->tail = (ring->tail + NFP_FL_STATS_ELEM_RS) %
+			(priv->stats_ring_size * NFP_FL_STATS_ELEM_RS);
+
+	return 0;
+}
+
+__rte_unused static int
+nfp_stats_id_free(struct nfp_flow_priv *priv, uint32_t ctx)
+{
+	struct circ_buf *ring;
+
+	/* Check if buffer is full */
+	ring = &priv->stats_ids.free_list;
+	if (!CIRC_SPACE(ring->head, ring->tail, priv->stats_ring_size *
+			NFP_FL_STATS_ELEM_RS - NFP_FL_STATS_ELEM_RS + 1))
+		return -ENOBUFS;
+
+	memcpy(&ring->buf[ring->head], &ctx, NFP_FL_STATS_ELEM_RS);
+	ring->head = (ring->head + NFP_FL_STATS_ELEM_RS) %
+			(priv->stats_ring_size * NFP_FL_STATS_ELEM_RS);
+
+	return 0;
+}
+
+int
+nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)
+{
+	int ret = 0;
+	size_t stats_size;
+	uint64_t ctx_count;
+	uint64_t ctx_split;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+
+	struct rte_hash_parameters mask_hash_params = {
+		.name       = "mask_hash_table",
+		.entries    = NFP_MASK_TABLE_ENTRIES,
+		.hash_func  = rte_jhash,
+		.socket_id  = rte_socket_id(),
+		.key_len    = sizeof(uint32_t),
+		.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,
+	};
+
+	struct rte_hash_parameters flow_hash_params = {
+		.name       = "flow_hash_table",
+		.hash_func  = rte_jhash,
+		.socket_id  = rte_socket_id(),
+		.key_len    = sizeof(uint32_t),
+		.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,
+	};
+
+	ctx_count = nfp_rtsym_read_le(pf_dev->sym_tbl,
+			"CONFIG_FC_HOST_CTX_COUNT", &ret);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "Read CTX_COUNT from symbol table failed");
+		goto exit;
+	}
+
+	ctx_split = nfp_rtsym_read_le(pf_dev->sym_tbl,
+			"CONFIG_FC_HOST_CTX_SPLIT", &ret);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "Read CTX_SPLIT from symbol table failed");
+		goto exit;
+	}
+
+	priv = rte_zmalloc("nfp_app_flow_priv", sizeof(struct nfp_flow_priv), 0);
+	if (priv == NULL) {
+		PMD_INIT_LOG(ERR, "nfp app flow priv creation failed");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+	app_fw_flower->flow_priv = priv;
+	priv->hash_seed = (uint32_t)rte_rand();
+	priv->stats_ring_size = ctx_count;
+	priv->total_mem_units = ctx_split;
+
+	/* Init ring buffer and unallocated mask_ids. */
+	priv->mask_ids.init_unallocated = NFP_FLOWER_MASK_ENTRY_RS - 1;
+	priv->mask_ids.free_list.buf = rte_zmalloc("nfp_app_mask_ids",
+			NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS, 0);
+	if (priv->mask_ids.free_list.buf == NULL) {
+		PMD_INIT_LOG(ERR, "mask id free list creation failed");
+		ret = -ENOMEM;
+		goto free_priv;
+	}
+
+	/* Init ring buffer and unallocated stats_ids. */
+	priv->stats_ids.init_unallocated = ctx_count / ctx_split;
+	priv->stats_ids.free_list.buf = rte_zmalloc("nfp_app_stats_ids",
+			priv->stats_ring_size * NFP_FL_STATS_ELEM_RS, 0);
+	if (priv->stats_ids.free_list.buf == NULL) {
+		PMD_INIT_LOG(ERR, "stats id free list creation failed");
+		ret = -ENOMEM;
+		goto free_mask_id;
+	}
+
+	/* flow stats */
+	rte_spinlock_init(&priv->stats_lock);
+	stats_size = (ctx_count & NFP_FL_STAT_ID_STAT) |
+			((ctx_split - 1) & NFP_FL_STAT_ID_MU_NUM);
+	PMD_INIT_LOG(INFO, "ctx_count:%0lx, ctx_split:%0lx, stats_size:%0lx ",
+			ctx_count, ctx_split, stats_size);
+	priv->stats = rte_zmalloc("nfp_flow_stats",
+			stats_size * sizeof(struct nfp_fl_stats), 0);
+	if (priv->stats == NULL) {
+		PMD_INIT_LOG(ERR, "flow stats creation failed");
+		ret = -ENOMEM;
+		goto free_stats_id;
+	}
+
+	/* mask table */
+	mask_hash_params.hash_func_init_val = priv->hash_seed;
+	priv->mask_table = rte_hash_create(&mask_hash_params);
+	if (priv->mask_table == NULL) {
+		PMD_INIT_LOG(ERR, "mask hash table creation failed");
+		ret = -ENOMEM;
+		goto free_stats;
+	}
+
+	/* flow table */
+	flow_hash_params.hash_func_init_val = priv->hash_seed;
+	flow_hash_params.entries = ctx_count;
+	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_mask_table;
+	}
+
+	return 0;
+
+free_mask_table:
+	rte_free(priv->mask_table);
+free_stats:
+	rte_free(priv->stats);
+free_stats_id:
+	rte_free(priv->stats_ids.free_list.buf);
+free_mask_id:
+	rte_free(priv->mask_ids.free_list.buf);
+free_priv:
+	rte_free(priv);
+exit:
+	return ret;
+}
+
+void
+nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev)
+{
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+
+	app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+	priv = app_fw_flower->flow_priv;
+
+	rte_hash_free(priv->flow_table);
+	rte_hash_free(priv->mask_table);
+	rte_free(priv->stats);
+	rte_free(priv->stats_ids.free_list.buf);
+	rte_free(priv->mask_ids.free_list.buf);
+	rte_free(priv);
+}
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
new file mode 100644
index 0000000..8eec84c
--- /dev/null
+++ b/drivers/net/nfp/nfp_flow.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _NFP_FLOW_H_
+#define _NFP_FLOW_H_
+
+#include <rte_bitops.h>
+
+#define NFP_FL_META_FLAG_MANAGE_MASK    RTE_BIT32(7)
+
+#define NFP_MASK_TABLE_ENTRIES          1024
+
+enum nfp_flower_tun_type {
+	NFP_FL_TUN_NONE   = 0,
+	NFP_FL_TUN_GRE    = 1,
+	NFP_FL_TUN_VXLAN  = 2,
+	NFP_FL_TUN_GENEVE = 4,
+};
+
+struct nfp_fl_key_ls {
+	uint32_t key_layer_two;
+	uint8_t key_layer;
+	int key_size;
+	int act_size;
+	uint32_t port;
+	uint16_t vlan;
+	enum nfp_flower_tun_type tun_type;
+};
+
+struct nfp_fl_rule_metadata {
+	uint8_t key_len;
+	uint8_t mask_len;
+	uint8_t act_len;
+	uint8_t flags;
+	rte_be32_t host_ctx_id;
+	rte_be64_t host_cookie __rte_packed;
+	rte_be64_t flow_version __rte_packed;
+	rte_be32_t shortcut;
+};
+
+struct nfp_fl_payload {
+	struct nfp_fl_rule_metadata *meta;
+	char *unmasked_data;
+	char *mask_data;
+	char *action_data;
+};
+
+#define CIRC_CNT(head, tail, size)     (((head) - (tail)) & ((size) - 1))
+#define CIRC_SPACE(head, tail, size)   CIRC_CNT((tail), ((head) + 1), (size))
+struct circ_buf {
+	uint32_t head;
+	uint32_t tail;
+	char *buf;
+};
+
+#define NFP_FLOWER_MASK_ENTRY_RS        256
+#define NFP_FLOWER_MASK_ELEMENT_RS      sizeof(uint8_t)
+struct nfp_fl_mask_id {
+	struct circ_buf free_list;
+	uint8_t init_unallocated;
+};
+
+#define NFP_FL_STATS_ELEM_RS            sizeof(uint32_t)
+struct nfp_fl_stats_id {
+	struct circ_buf free_list;
+	uint32_t init_unallocated;
+};
+
+#define NFP_FL_STAT_ID_MU_NUM           0xffc00000
+#define NFP_FL_STAT_ID_STAT             0x003fffff
+struct nfp_fl_stats {
+	uint64_t pkts;
+	uint64_t bytes;
+};
+
+struct nfp_flow_priv {
+	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
+	/* mask hash table */
+	struct nfp_fl_mask_id mask_ids; /**< Entry for mask hash table */
+	struct rte_hash *mask_table; /**< Hash table to store mask ids. */
+	/* flow hash table */
+	struct rte_hash *flow_table; /**< Hash table to store flow rules. */
+	/* flow stats */
+	uint32_t active_mem_unit; /**< The size of active mem units. */
+	uint32_t total_mem_units; /**< The size of total mem units. */
+	uint32_t stats_ring_size; /**< The size of stats id ring. */
+	struct nfp_fl_stats_id stats_ids; /**< The stats id ring. */
+	struct nfp_fl_stats *stats; /**< Store stats of flow. */
+	rte_spinlock_t stats_lock; /** < Lock the update of 'stats' field. */
+};
+
+struct rte_flow {
+	struct nfp_fl_payload payload;
+	size_t length;
+	uint32_t hash_key;
+	bool install_flag;
+};
+
+int nfp_flow_priv_init(struct nfp_pf_dev *pf_dev);
+void nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev);
+
+#endif /* _NFP_FLOW_H_ */
-- 
1.8.3.1


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

* [PATCH v6 05/27] net/nfp: add the stats process logic in ctrl VNIC service
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (3 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 04/27] net/nfp: add the structures and functions for flow offload Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 06/27] net/nfp: add the flow APIs of nfp PMD Chaoyong He
                       ` (22 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the flow stats process logic in the ctrl VNIC service.
The flower firmware pass the flow stats to nfp driver through
control message, we store them in the flow_priv structure.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 25 +++++++++++
 drivers/net/nfp/flower/nfp_flower_ctrl.c | 73 ++++++++++++++++++++++++++++++--
 2 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 0bf8fc8..5c28363 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -129,6 +129,31 @@ struct nfp_flower_cmsg_port_mod {
 	rte_be16_t mtu;
 };
 
+/*
+ * NFP_FLOWER_CMSG_TYPE_FLOW_STATS
+ *    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  |    Reserved   |               Host Context                    |
+ *          +---------------+-----------------------------------------------+
+ *       1  |                          Packet Count                         |
+ *          +---------------------------------------------------------------+
+ *       2  |                          Byte Count                           |
+ *          +---------------------------------------------------------------+
+ *       2  |                          Byte Count                           |
+ *          +---------------------------------------------------------------+
+ *       3  |                          Host Cookie                          |
+ *          +---------------------------------------------------------------+
+ *       4  |                          Host Cookie                          |
+ *          +---------------------------------------------------------------+
+ */
+struct nfp_flower_stats_frame {
+	rte_be32_t stats_con_id;
+	rte_be32_t pkt_count;
+	rte_be64_t byte_count;
+	rte_be64_t stats_cookie;
+};
+
 enum nfp_flower_cmsg_port_type {
 	NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC,
 	NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT,
diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c
index 53ca710..953ab6e 100644
--- a/drivers/net/nfp/flower/nfp_flower_ctrl.c
+++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c
@@ -11,8 +11,10 @@
 #include "../nfp_logs.h"
 #include "../nfp_ctrl.h"
 #include "../nfp_rxtx.h"
+#include "nfp_flow.h"
 #include "nfp_flower.h"
 #include "nfp_flower_ctrl.h"
+#include "nfp_flower_cmsg.h"
 
 #define MAX_PKT_BURST 32
 
@@ -223,10 +225,74 @@
 	return cnt;
 }
 
+static void
+nfp_flower_cmsg_rx_stats(struct nfp_flow_priv *flow_priv,
+		struct rte_mbuf *mbuf)
+{
+	char *msg;
+	uint16_t i;
+	uint16_t count;
+	uint16_t msg_len;
+	uint32_t ctx_id;
+	struct nfp_flower_stats_frame *stats;
+
+	msg = rte_pktmbuf_mtod(mbuf, char *) + NFP_FLOWER_CMSG_HLEN;
+	msg_len = mbuf->data_len - NFP_FLOWER_CMSG_HLEN;
+	count = msg_len / sizeof(struct nfp_flower_stats_frame);
+
+	rte_spinlock_lock(&flow_priv->stats_lock);
+	for (i = 0; i < count; i++) {
+		stats = (struct nfp_flower_stats_frame *)msg + i;
+		ctx_id = rte_be_to_cpu_32(stats->stats_con_id);
+		flow_priv->stats[ctx_id].pkts  += rte_be_to_cpu_32(stats->pkt_count);
+		flow_priv->stats[ctx_id].bytes += rte_be_to_cpu_64(stats->byte_count);
+	}
+	rte_spinlock_unlock(&flow_priv->stats_lock);
+}
+
+static void
+nfp_flower_cmsg_rx(struct nfp_flow_priv *flow_priv,
+		struct rte_mbuf **pkts_burst,
+		uint16_t count)
+{
+	uint16_t i;
+	char *meta;
+	uint32_t meta_type;
+	uint32_t meta_info;
+	struct nfp_flower_cmsg_hdr *cmsg_hdr;
+
+	for (i = 0; i < count; i++) {
+		meta = rte_pktmbuf_mtod(pkts_burst[i], char *);
+
+		/* Free the unsupported ctrl packet */
+		meta_type = rte_be_to_cpu_32(*(uint32_t *)(meta - 8));
+		meta_info = rte_be_to_cpu_32(*(uint32_t *)(meta - 4));
+		if (meta_type != NFP_NET_META_PORTID ||
+				meta_info != NFP_META_PORT_ID_CTRL) {
+			PMD_DRV_LOG(ERR, "Incorrect metadata for ctrl packet!");
+			rte_pktmbuf_free(pkts_burst[i]);
+			continue;
+		}
+
+		cmsg_hdr = (struct nfp_flower_cmsg_hdr *)meta;
+		if (unlikely(cmsg_hdr->version != NFP_FLOWER_CMSG_VER1)) {
+			PMD_DRV_LOG(ERR, "Incorrect repr control version!");
+			rte_pktmbuf_free(pkts_burst[i]);
+			continue;
+		}
+
+		if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_FLOW_STATS) {
+			/* We need to deal with stats updates from HW asap */
+			nfp_flower_cmsg_rx_stats(flow_priv, pkts_burst[i]);
+		}
+
+		rte_pktmbuf_free(pkts_burst[i]);
+	}
+}
+
 void
 nfp_flower_ctrl_vnic_poll(struct nfp_app_fw_flower *app_fw_flower)
 {
-	uint16_t i;
 	uint16_t count;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *ctrl_hw;
@@ -243,9 +309,8 @@
 		count = nfp_flower_ctrl_vnic_recv(rxq, pkts_burst, MAX_PKT_BURST);
 		if (count != 0) {
 			app_fw_flower->ctrl_vnic_rx_count += count;
-			/* Process cmsgs here, only free for now */
-			for (i = 0; i < count; i++)
-				rte_pktmbuf_free(pkts_burst[i]);
+			/* Process cmsgs here */
+			nfp_flower_cmsg_rx(app_fw_flower->flow_priv, pkts_burst, count);
 		}
 	}
 }
-- 
1.8.3.1


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

* [PATCH v6 06/27] net/nfp: add the flow APIs of nfp PMD
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (4 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 05/27] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 07/27] net/nfp: support basic flow items Chaoyong He
                       ` (21 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the flow validate/create/query/destroy/flush API of nfp PMD.

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

The flow query API get flow stats from the flow_priv structure.
Note there exist an rte_spin_lock to prevent the update and query
action occur at the same time.

The flow destroy API construct a control cmsg and send it to
firmware, then adelete 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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower_cmsg.c        |  69 +++
 drivers/net/nfp/flower/nfp_flower_cmsg.h        |  48 ++
 drivers/net/nfp/flower/nfp_flower_representor.c |   3 +
 drivers/net/nfp/nfp_flow.c                      | 592 +++++++++++++++++++++++-
 drivers/net/nfp/nfp_flow.h                      |  27 ++
 5 files changed, 730 insertions(+), 9 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c
index 750a629..15d8381 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c
@@ -6,6 +6,7 @@
 #include "../nfpcore/nfp_nsp.h"
 #include "../nfp_logs.h"
 #include "../nfp_common.h"
+#include "../nfp_flow.h"
 #include "nfp_flower.h"
 #include "nfp_flower_cmsg.h"
 #include "nfp_flower_ctrl.h"
@@ -177,3 +178,71 @@
 
 	return 0;
 }
+
+int
+nfp_flower_cmsg_flow_delete(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow)
+{
+	char *msg;
+	uint16_t cnt;
+	uint32_t msg_len;
+	struct rte_mbuf *mbuf;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+	if (mbuf == NULL) {
+		PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for flow delete.");
+		return -ENOMEM;
+	}
+
+	/* Copy the flow to mbuf */
+	nfp_flow_meta = flow->payload.meta;
+	msg_len = (nfp_flow_meta->key_len + nfp_flow_meta->mask_len +
+			nfp_flow_meta->act_len) << NFP_FL_LW_SIZ;
+	msg_len += sizeof(struct nfp_fl_rule_metadata);
+	msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_FLOW_DEL, msg_len);
+	rte_memcpy(msg, flow->payload.meta, msg_len);
+
+	cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+	if (cnt == 0) {
+		PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+		rte_pktmbuf_free(mbuf);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+nfp_flower_cmsg_flow_add(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow)
+{
+	char *msg;
+	uint16_t cnt;
+	uint32_t msg_len;
+	struct rte_mbuf *mbuf;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+	if (mbuf == NULL) {
+		PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for flow add.");
+		return -ENOMEM;
+	}
+
+	/* copy the flow to mbuf */
+	nfp_flow_meta = flow->payload.meta;
+	msg_len = (nfp_flow_meta->key_len + nfp_flow_meta->mask_len +
+			nfp_flow_meta->act_len) << NFP_FL_LW_SIZ;
+	msg_len += sizeof(struct nfp_fl_rule_metadata);
+	msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_FLOW_ADD, msg_len);
+	rte_memcpy(msg, flow->payload.meta, msg_len);
+
+	cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+	if (cnt == 0) {
+		PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+		rte_pktmbuf_free(mbuf);
+		return -EIO;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 5c28363..6045bb0 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -189,10 +189,58 @@ enum nfp_flower_cmsg_port_vnic_type {
 	return rte_pktmbuf_mtod(m, char *) + 4 + 4 + NFP_FLOWER_CMSG_HLEN;
 }
 
+/*
+ * Metadata with L2 (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    key_type   |    mask_id    | PCP |p|   vlan outermost VID  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *                                 ^                               ^
+ *                           NOTE: |             TCI               |
+ *                                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_meta_tci {
+	uint8_t nfp_flow_key_layer;
+	uint8_t mask_id;
+	rte_be16_t tci;
+};
+
+/*
+ * Extended metadata for additional key_layers (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                      nfp_flow_key_layer2                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ext_meta {
+	rte_be32_t nfp_flow_key_layer2;
+};
+
+/*
+ * L1 Port details (1W/4B)
+ * ----------------------------------------------------------------
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                         port_ingress                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_in_port {
+	rte_be32_t in_port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
 int nfp_flower_cmsg_port_mod(struct nfp_app_fw_flower *app_fw_flower,
 		uint32_t port_id, bool carrier_ok);
+int nfp_flower_cmsg_flow_delete(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow);
+int nfp_flower_cmsg_flow_add(struct nfp_app_fw_flower *app_fw_flower,
+		struct rte_flow *flow);
 
 #endif /* _NFP_CMSG_H_ */
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index cecdf46..07f4045 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -10,6 +10,7 @@
 #include "../nfp_logs.h"
 #include "../nfp_ctrl.h"
 #include "../nfp_rxtx.h"
+#include "../nfp_flow.h"
 #include "../nfpcore/nfp_mip.h"
 #include "../nfpcore/nfp_rtsym.h"
 #include "../nfpcore/nfp_nsp.h"
@@ -612,6 +613,8 @@
 	.promiscuous_disable  = nfp_flower_repr_promiscuous_disable,
 
 	.mac_addr_set         = nfp_flower_repr_mac_addr_set,
+
+	.flow_ops_get         = nfp_net_flow_ops_get,
 };
 
 static uint32_t
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index dd690cd..e302165 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -7,11 +7,15 @@
 #include <rte_hash.h>
 #include <rte_jhash.h>
 #include <bus_pci_driver.h>
+#include <rte_malloc.h>
 
 #include "nfp_common.h"
 #include "nfp_flow.h"
 #include "nfp_logs.h"
 #include "flower/nfp_flower.h"
+#include "flower/nfp_flower_cmsg.h"
+#include "flower/nfp_flower_ctrl.h"
+#include "flower/nfp_flower_representor.h"
 #include "nfpcore/nfp_mip.h"
 #include "nfpcore/nfp_rtsym.h"
 
@@ -21,6 +25,15 @@ struct nfp_mask_id_entry {
 	uint8_t mask_id;
 };
 
+static inline struct nfp_flow_priv *
+nfp_flow_dev_to_priv(struct rte_eth_dev *dev)
+{
+	struct nfp_flower_representor *repr;
+
+	repr = (struct nfp_flower_representor *)dev->data->dev_private;
+	return repr->app_fw_flower->flow_priv;
+}
+
 static int
 nfp_mask_id_alloc(struct nfp_flow_priv *priv, uint8_t *mask_id)
 {
@@ -160,7 +173,7 @@ struct nfp_mask_id_entry {
 	return entry;
 }
 
-__rte_unused static bool
+static bool
 nfp_check_mask_add(struct nfp_flow_priv *priv,
 		char *mask_data,
 		uint32_t mask_len,
@@ -187,7 +200,7 @@ struct nfp_mask_id_entry {
 	return true;
 }
 
-__rte_unused static bool
+static bool
 nfp_check_mask_remove(struct nfp_flow_priv *priv,
 		char *mask_data,
 		uint32_t mask_len,
@@ -215,7 +228,7 @@ struct nfp_mask_id_entry {
 	return true;
 }
 
-__rte_unused static int
+static int
 nfp_flow_table_add(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -230,7 +243,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static int
+static int
 nfp_flow_table_delete(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -245,7 +258,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static struct rte_flow *
+static struct rte_flow *
 nfp_flow_table_search(struct nfp_flow_priv *priv,
 		struct rte_flow *nfp_flow)
 {
@@ -262,7 +275,7 @@ struct nfp_mask_id_entry {
 	return flow_find;
 }
 
-__rte_unused static struct rte_flow *
+static struct rte_flow *
 nfp_flow_alloc(struct nfp_fl_key_ls *key_layer)
 {
 	char *tmp;
@@ -295,14 +308,14 @@ struct nfp_mask_id_entry {
 	return NULL;
 }
 
-__rte_unused static void
+static void
 nfp_flow_free(struct rte_flow *nfp_flow)
 {
 	rte_free(nfp_flow->payload.meta);
 	rte_free(nfp_flow);
 }
 
-__rte_unused static int
+static int
 nfp_stats_id_alloc(struct nfp_flow_priv *priv, uint32_t *ctx)
 {
 	struct circ_buf *ring;
@@ -337,7 +350,7 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
-__rte_unused static int
+static int
 nfp_stats_id_free(struct nfp_flow_priv *priv, uint32_t ctx)
 {
 	struct circ_buf *ring;
@@ -355,6 +368,567 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flower_compile_meta_tci(char *mbuf_off, struct nfp_fl_key_ls *key_layer)
+{
+	struct nfp_flower_meta_tci *tci_meta;
+
+	tci_meta = (struct nfp_flower_meta_tci *)mbuf_off;
+	tci_meta->nfp_flow_key_layer = key_layer->key_layer;
+	tci_meta->mask_id = ~0;
+	tci_meta->tci = rte_cpu_to_be_16(key_layer->vlan);
+}
+
+static void
+nfp_flower_update_meta_tci(char *exact, uint8_t mask_id)
+{
+	struct nfp_flower_meta_tci *meta_tci;
+
+	meta_tci = (struct nfp_flower_meta_tci *)exact;
+	meta_tci->mask_id = mask_id;
+}
+
+static void
+nfp_flower_compile_ext_meta(char *mbuf_off, struct nfp_fl_key_ls *key_layer)
+{
+	struct nfp_flower_ext_meta *ext_meta;
+
+	ext_meta = (struct nfp_flower_ext_meta *)mbuf_off;
+	ext_meta->nfp_flow_key_layer2 = rte_cpu_to_be_32(key_layer->key_layer_two);
+}
+
+static void
+nfp_compile_meta_port(char *mbuf_off,
+		struct nfp_fl_key_ls *key_layer,
+		bool is_mask)
+{
+	struct nfp_flower_in_port *port_meta;
+
+	port_meta = (struct nfp_flower_in_port *)mbuf_off;
+
+	if (is_mask)
+		port_meta->in_port = rte_cpu_to_be_32(~0);
+	else if (key_layer->tun_type)
+		port_meta->in_port = rte_cpu_to_be_32(NFP_FL_PORT_TYPE_TUN |
+				key_layer->tun_type);
+	else
+		port_meta->in_port = rte_cpu_to_be_32(key_layer->port);
+}
+
+static void
+nfp_flow_compile_metadata(struct nfp_flow_priv *priv,
+		struct rte_flow *nfp_flow,
+		struct nfp_fl_key_ls *key_layer,
+		uint32_t stats_ctx)
+{
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+	char *mbuf_off_exact;
+	char *mbuf_off_mask;
+
+	/*
+	 * Convert to long words as firmware expects
+	 * lengths in units of NFP_FL_LW_SIZ.
+	 */
+	nfp_flow_meta               = nfp_flow->payload.meta;
+	nfp_flow_meta->key_len      = key_layer->key_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->mask_len     = key_layer->key_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->act_len      = key_layer->act_size >> NFP_FL_LW_SIZ;
+	nfp_flow_meta->flags        = 0;
+	nfp_flow_meta->host_ctx_id  = rte_cpu_to_be_32(stats_ctx);
+	nfp_flow_meta->host_cookie  = rte_rand();
+	nfp_flow_meta->flow_version = rte_cpu_to_be_64(priv->flower_version);
+
+	mbuf_off_exact = nfp_flow->payload.unmasked_data;
+	mbuf_off_mask  = nfp_flow->payload.mask_data;
+
+	/* Populate Metadata */
+	nfp_flower_compile_meta_tci(mbuf_off_exact, key_layer);
+	nfp_flower_compile_meta_tci(mbuf_off_mask, key_layer);
+	mbuf_off_exact += sizeof(struct nfp_flower_meta_tci);
+	mbuf_off_mask  += sizeof(struct nfp_flower_meta_tci);
+
+	/* Populate Extended Metadata if required */
+	if (key_layer->key_layer & NFP_FLOWER_LAYER_EXT_META) {
+		nfp_flower_compile_ext_meta(mbuf_off_exact, key_layer);
+		nfp_flower_compile_ext_meta(mbuf_off_mask, key_layer);
+		mbuf_off_exact += sizeof(struct nfp_flower_ext_meta);
+		mbuf_off_mask  += sizeof(struct nfp_flower_ext_meta);
+	}
+
+	/* Populate Port Data */
+	nfp_compile_meta_port(mbuf_off_exact, key_layer, false);
+	nfp_compile_meta_port(mbuf_off_mask, key_layer, true);
+	mbuf_off_exact += sizeof(struct nfp_flower_in_port);
+	mbuf_off_mask  += sizeof(struct nfp_flower_in_port);
+}
+
+static int
+nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[],
+		__rte_unused struct nfp_fl_key_ls *key_ls)
+{
+	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, "Item type %d not supported.", item->type);
+			return -ENOTSUP;
+		}
+	}
+
+	return 0;
+}
+
+static int
+nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
+		struct nfp_fl_key_ls *key_ls)
+{
+	int ret = 0;
+	const struct rte_flow_action *action;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+		/* Make sure actions length no longer than NFP_FL_MAX_A_SIZ */
+		if (key_ls->act_size > NFP_FL_MAX_A_SIZ) {
+			PMD_DRV_LOG(ERR, "The action list is too long.");
+			ret = -ERANGE;
+			break;
+		}
+
+		switch (action->type) {
+		case RTE_FLOW_ACTION_TYPE_VOID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VOID detected");
+			break;
+		default:
+			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
+			return -ENOTSUP;
+		}
+	}
+
+	return ret;
+}
+
+static int
+nfp_flow_key_layers_calculate(const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct nfp_fl_key_ls *key_ls)
+{
+	int ret = 0;
+
+	key_ls->key_layer_two = 0;
+	key_ls->key_layer = NFP_FLOWER_LAYER_PORT;
+	key_ls->key_size = sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+	key_ls->act_size = 0;
+	key_ls->port = ~0;
+	key_ls->vlan = 0;
+	key_ls->tun_type = NFP_FL_TUN_NONE;
+
+	ret |= nfp_flow_key_layers_calculate_items(items, key_ls);
+	ret |= nfp_flow_key_layers_calculate_actions(actions, key_ls);
+
+	return ret;
+}
+
+static struct rte_flow *
+nfp_flow_process(struct nfp_flower_representor *representor,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		bool validate_flag)
+{
+	int ret;
+	char *hash_data;
+	char *mask_data;
+	uint32_t mask_len;
+	uint32_t stats_ctx = 0;
+	uint8_t new_mask_id = 0;
+	struct rte_flow *nfp_flow;
+	struct rte_flow *flow_find;
+	struct nfp_flow_priv *priv;
+	struct nfp_fl_key_ls key_layer;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	ret = nfp_flow_key_layers_calculate(items, actions, &key_layer);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Key layers calculate failed.");
+		return NULL;
+	}
+
+	if (key_layer.port == (uint32_t)~0)
+		key_layer.port = representor->port_id;
+
+	priv = representor->app_fw_flower->flow_priv;
+	ret = nfp_stats_id_alloc(priv, &stats_ctx);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp stats id alloc failed.");
+		return NULL;
+	}
+
+	nfp_flow = nfp_flow_alloc(&key_layer);
+	if (nfp_flow == NULL) {
+		PMD_DRV_LOG(ERR, "Alloc nfp flow failed.");
+		goto free_stats;
+	}
+
+	nfp_flow->install_flag = true;
+
+	nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx);
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	mask_data = nfp_flow->payload.mask_data;
+	mask_len = key_layer.key_size;
+	if (!nfp_check_mask_add(priv, mask_data, mask_len,
+			&nfp_flow_meta->flags, &new_mask_id)) {
+		PMD_DRV_LOG(ERR, "nfp mask add check failed.");
+		goto free_flow;
+	}
+
+	/* Once we have a mask_id, update the meta tci */
+	nfp_flower_update_meta_tci(nfp_flow->payload.unmasked_data, new_mask_id);
+
+	/* Calculate and store the hash_key for later use */
+	hash_data = (char *)(nfp_flow->payload.unmasked_data);
+	nfp_flow->hash_key = rte_jhash(hash_data, nfp_flow->length, priv->hash_seed);
+
+	/* Find the flow in hash table */
+	flow_find = nfp_flow_table_search(priv, nfp_flow);
+	if (flow_find != NULL) {
+		PMD_DRV_LOG(ERR, "This flow is already exist.");
+		if (!nfp_check_mask_remove(priv, mask_data, mask_len,
+				&nfp_flow_meta->flags)) {
+			PMD_DRV_LOG(ERR, "nfp mask del check failed.");
+		}
+		goto free_flow;
+	}
+
+	/* Flow validate should not update the flower version */
+	if (!validate_flag)
+		priv->flower_version++;
+
+	return nfp_flow;
+
+free_flow:
+	nfp_flow_free(nfp_flow);
+free_stats:
+	nfp_stats_id_free(priv, stats_ctx);
+
+	return NULL;
+}
+
+static struct rte_flow *
+nfp_flow_setup(struct nfp_flower_representor *representor,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item items[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error,
+		bool validate_flag)
+{
+	if (attr->group != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support group attribute.");
+
+	if (attr->priority != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support priority attribute.");
+
+	if (attr->transfer != 0)
+		PMD_DRV_LOG(INFO, "Pretend we support transfer attribute.");
+
+	if (attr->egress != 0) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
+				NULL, "Egress is not supported.");
+		return NULL;
+	}
+
+	if (attr->ingress == 0) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
+				NULL, "Only ingress is supported.");
+		return NULL;
+	}
+
+	return nfp_flow_process(representor, items, actions, validate_flag);
+}
+
+static int
+nfp_flow_teardown(struct nfp_flow_priv *priv,
+		struct rte_flow *nfp_flow,
+		bool validate_flag)
+{
+	char *mask_data;
+	uint32_t mask_len;
+	uint32_t stats_ctx;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	mask_data = nfp_flow->payload.mask_data;
+	mask_len = nfp_flow_meta->mask_len << NFP_FL_LW_SIZ;
+	if (!nfp_check_mask_remove(priv, mask_data, mask_len,
+			&nfp_flow_meta->flags)) {
+		PMD_DRV_LOG(ERR, "nfp mask del check failed.");
+		return -EINVAL;
+	}
+
+	nfp_flow_meta->flow_version = rte_cpu_to_be_64(priv->flower_version);
+
+	/* Flow validate should not update the flower version */
+	if (!validate_flag)
+		priv->flower_version++;
+
+	stats_ctx = rte_be_to_cpu_32(nfp_flow_meta->host_ctx_id);
+	return nfp_stats_id_free(priv, stats_ctx);
+}
+
+static int
+nfp_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 rte_flow *nfp_flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	priv = representor->app_fw_flower->flow_priv;
+
+	nfp_flow = nfp_flow_setup(representor, attr, items, actions, error, true);
+	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_flow_teardown(priv, nfp_flow, true);
+	if (ret != 0) {
+		return rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow resource free failed.");
+	}
+
+	nfp_flow_free(nfp_flow);
+
+	return 0;
+}
+
+static struct rte_flow *
+nfp_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 rte_flow *nfp_flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	app_fw_flower = representor->app_fw_flower;
+	priv = app_fw_flower->flow_priv;
+
+	nfp_flow = nfp_flow_setup(representor, attr, items, actions, error, false);
+	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 hardware */
+	if (nfp_flow->install_flag) {
+		ret = nfp_flower_cmsg_flow_add(app_fw_flower, nfp_flow);
+		if (ret != 0) {
+			rte_flow_error_set(error, EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL, "Add flow to firmware failed.");
+			goto flow_teardown;
+		}
+	}
+
+	/* Add the flow to flow hash table */
+	ret = nfp_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;
+	}
+
+	return nfp_flow;
+
+flow_teardown:
+	nfp_flow_teardown(priv, nfp_flow, false);
+	nfp_flow_free(nfp_flow);
+
+	return NULL;
+}
+
+static int
+nfp_flow_destroy(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct rte_flow *flow_find;
+	struct nfp_flow_priv *priv;
+	struct nfp_app_fw_flower *app_fw_flower;
+	struct nfp_flower_representor *representor;
+
+	representor = (struct nfp_flower_representor *)dev->data->dev_private;
+	app_fw_flower = representor->app_fw_flower;
+	priv = app_fw_flower->flow_priv;
+
+	/* Find the flow in flow hash table */
+	flow_find = nfp_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;
+	}
+
+	/* Update flow */
+	ret = nfp_flow_teardown(priv, nfp_flow, false);
+	if (ret != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL, "Flow teardown failed.");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Delete the flow from hardware */
+	if (nfp_flow->install_flag) {
+		ret = nfp_flower_cmsg_flow_delete(app_fw_flower, nfp_flow);
+		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_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;
+	}
+
+exit:
+	nfp_flow_free(nfp_flow);
+
+	return ret;
+}
+
+static int
+nfp_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_flow_priv *priv;
+
+	priv = nfp_flow_dev_to_priv(dev);
+
+	while (rte_hash_iterate(priv->flow_table, &next_key, &next_data, &iter) >= 0) {
+		ret = nfp_flow_destroy(dev, (struct rte_flow *)next_data, error);
+		if (ret != 0)
+			break;
+	}
+
+	return ret;
+}
+
+static void
+nfp_flow_stats_get(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		void *data)
+{
+	uint32_t ctx_id;
+	struct rte_flow *flow;
+	struct nfp_flow_priv *priv;
+	struct nfp_fl_stats *stats;
+	struct rte_flow_query_count *query;
+
+	priv = nfp_flow_dev_to_priv(dev);
+	flow = nfp_flow_table_search(priv, nfp_flow);
+	if (flow == NULL) {
+		PMD_DRV_LOG(ERR, "Can not find statistics for this flow.");
+		return;
+	}
+
+	query = (struct rte_flow_query_count *)data;
+	memset(query, 0, sizeof(*query));
+
+	ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id);
+	stats = &priv->stats[ctx_id];
+
+	rte_spinlock_lock(&priv->stats_lock);
+	if (stats->pkts != 0 && stats->bytes != 0) {
+		query->hits = stats->pkts;
+		query->bytes = stats->bytes;
+		query->hits_set = 1;
+		query->bytes_set = 1;
+		if (query->reset != 0) {
+			stats->pkts = 0;
+			stats->bytes = 0;
+		}
+	}
+	rte_spinlock_unlock(&priv->stats_lock);
+}
+
+static int
+nfp_flow_query(struct rte_eth_dev *dev,
+		struct rte_flow *nfp_flow,
+		const struct rte_flow_action *actions,
+		void *data,
+		struct rte_flow_error *error)
+{
+	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_VOID:
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			nfp_flow_stats_get(dev, nfp_flow, data);
+			break;
+		default:
+			rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL, "Unsupported action type for flow query.");
+			return -ENOTSUP;
+		}
+	}
+
+	return 0;
+}
+
+static const struct rte_flow_ops nfp_flow_ops = {
+	.validate                    = nfp_flow_validate,
+	.create                      = nfp_flow_create,
+	.destroy                     = nfp_flow_destroy,
+	.flush                       = nfp_flow_flush,
+	.query                       = nfp_flow_query,
+};
+
+int
+nfp_net_flow_ops_get(struct rte_eth_dev *dev,
+		const struct rte_flow_ops **ops)
+{
+	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0) {
+		*ops = NULL;
+		PMD_DRV_LOG(ERR, "Port is not a representor.");
+		return -EINVAL;
+	}
+
+	*ops = &nfp_flow_ops;
+
+	return 0;
+}
+
 int
 nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)
 {
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 8eec84c..4adcc36 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -7,11 +7,36 @@
 #define _NFP_FLOW_H_
 
 #include <rte_bitops.h>
+#include <ethdev_driver.h>
+
+#define NFP_FLOWER_LAYER_EXT_META       RTE_BIT32(0)
+#define NFP_FLOWER_LAYER_PORT           RTE_BIT32(1)
+#define NFP_FLOWER_LAYER_MAC            RTE_BIT32(2)
+#define NFP_FLOWER_LAYER_TP             RTE_BIT32(3)
+#define NFP_FLOWER_LAYER_IPV4           RTE_BIT32(4)
+#define NFP_FLOWER_LAYER_IPV6           RTE_BIT32(5)
+#define NFP_FLOWER_LAYER_CT             RTE_BIT32(6)
+#define NFP_FLOWER_LAYER_VXLAN          RTE_BIT32(7)
+
+#define NFP_FLOWER_LAYER2_GRE           RTE_BIT32(0)
+#define NFP_FLOWER_LAYER2_QINQ          RTE_BIT32(4)
+#define NFP_FLOWER_LAYER2_GENEVE        RTE_BIT32(5)
+#define NFP_FLOWER_LAYER2_GENEVE_OP     RTE_BIT32(6)
+#define NFP_FLOWER_LAYER2_TUN_IPV6      RTE_BIT32(7)
 
 #define NFP_FL_META_FLAG_MANAGE_MASK    RTE_BIT32(7)
 
 #define NFP_MASK_TABLE_ENTRIES          1024
 
+/* The maximum action list size (in bytes) supported by the NFP. */
+#define NFP_FL_MAX_A_SIZ                1216
+
+/* The firmware expects lengths in units of long words */
+#define NFP_FL_LW_SIZ                   2
+
+/* Tunnel ports */
+#define NFP_FL_PORT_TYPE_TUN            0x50000000
+
 enum nfp_flower_tun_type {
 	NFP_FL_TUN_NONE   = 0,
 	NFP_FL_TUN_GRE    = 1,
@@ -77,6 +102,7 @@ struct nfp_fl_stats {
 
 struct nfp_flow_priv {
 	uint32_t hash_seed; /**< Hash seed for hash tables in this structure. */
+	uint64_t flower_version; /**< Flow version, always increase. */
 	/* mask hash table */
 	struct nfp_fl_mask_id mask_ids; /**< Entry for mask hash table */
 	struct rte_hash *mask_table; /**< Hash table to store mask ids. */
@@ -100,5 +126,6 @@ struct rte_flow {
 
 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);
 
 #endif /* _NFP_FLOW_H_ */
-- 
1.8.3.1


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

* [PATCH v6 07/27] net/nfp: support basic flow items
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (5 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 06/27] net/nfp: add the flow APIs of nfp PMD Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 08/27] net/nfp: support basic flow actions Chaoyong He
                       ` (20 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the offload support of very basic items: ethernet and
port id.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |   4 +
 doc/guides/rel_notes/release_22_11.rst   |   2 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  20 +++
 drivers/net/nfp/nfp_flow.c               | 252 ++++++++++++++++++++++++++++++-
 4 files changed, 277 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f7a0362..4460cf0 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -25,3 +25,7 @@ Linux                = Y
 Multiprocess aware   = Y
 x86-64               = Y
 Usage doc            = Y
+
+[rte_flow items]
+eth                  = Y
+port_id              = Y
diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index a3700bb..bab3833 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -163,6 +163,8 @@ New Features
   * Added the control message interactive channels between PMD and firmware.
   * Added the support of representor port.
 
+  Added support for flow API.
+
 * **Updated NXP dpaa2 driver.**
 
   * Added support for flow action REPRESENTED_PORT.
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 6045bb0..75a3b91 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -233,6 +233,26 @@ struct nfp_flower_in_port {
 	rte_be32_t in_port;
 };
 
+/*
+ * L2 details (4W/16B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     mac_addr_dst, 31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      mac_addr_dst, 47 - 32    |     mac_addr_src, 15 - 0      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     mac_addr_src, 47 - 16                     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |       mpls outermost label            |  TC |B|   reserved  |q|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_mac_mpls {
+	uint8_t mac_dst[6];
+	uint8_t mac_src[6];
+	rte_be32_t mpls_lse;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index e302165..ea5b359 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -19,6 +19,30 @@
 #include "nfpcore/nfp_mip.h"
 #include "nfpcore/nfp_rtsym.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_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 unsigned int mask_sz;
+	/* Merge a pattern item into a flow rule handle. */
+	int (*merge)(struct rte_flow *nfp_flow,
+			char **mbuf_off,
+			const struct rte_flow_item *item,
+			const struct nfp_flow_item_proc *proc,
+			bool is_mask);
+	/* List of possible subsequent items. */
+	const enum rte_flow_item_type *const next_item;
+};
+
 struct nfp_mask_id_entry {
 	uint32_t hash_key;
 	uint32_t ref_cnt;
@@ -464,12 +488,36 @@ struct nfp_mask_id_entry {
 
 static int
 nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[],
-		__rte_unused struct nfp_fl_key_ls *key_ls)
+		struct nfp_fl_key_ls *key_ls)
 {
+	struct rte_eth_dev *ethdev;
 	const struct rte_flow_item *item;
+	struct nfp_flower_representor *representor;
+	const struct rte_flow_item_port_id *port_id;
 
 	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");
+			/*
+			 * eth is set with no specific params.
+			 * NFP does not need this.
+			 */
+			if (item->spec == NULL)
+				continue;
+			key_ls->key_layer |= NFP_FLOWER_LAYER_MAC;
+			key_ls->key_size += sizeof(struct nfp_flower_mac_mpls);
+			break;
+		case RTE_FLOW_ITEM_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_PORT_ID detected");
+			port_id = item->spec;
+			if (port_id->id >= RTE_MAX_ETHPORTS)
+				return -ERANGE;
+			ethdev = &rte_eth_devices[port_id->id];
+			representor = (struct nfp_flower_representor *)
+					ethdev->data->dev_private;
+			key_ls->port = rte_cpu_to_be_32(representor->port_id);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -529,6 +577,202 @@ struct nfp_mask_id_entry {
 	return ret;
 }
 
+static int
+nfp_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_mac_mpls *eth;
+	const struct rte_flow_item_eth *spec;
+	const struct rte_flow_item_eth *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge eth: no item->spec!");
+		goto eth_end;
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	eth = (void *)*mbuf_off;
+
+	if (is_mask) {
+		memcpy(eth->mac_src, mask->src.addr_bytes, RTE_ETHER_ADDR_LEN);
+		memcpy(eth->mac_dst, mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN);
+	} else {
+		memcpy(eth->mac_src, spec->src.addr_bytes, RTE_ETHER_ADDR_LEN);
+		memcpy(eth->mac_dst, spec->dst.addr_bytes, RTE_ETHER_ADDR_LEN);
+	}
+
+	eth->mpls_lse = 0;
+
+eth_end:
+	*mbuf_off += sizeof(struct nfp_flower_mac_mpls);
+
+	return 0;
+}
+
+/* Graph of supported items and associated process function */
+static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
+	[RTE_FLOW_ITEM_TYPE_END] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+	},
+	[RTE_FLOW_ITEM_TYPE_ETH] = {
+		.mask_support = &(const struct rte_flow_item_eth){
+			.hdr = {
+				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+				.src_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+				.ether_type          = RTE_BE16(0xffff),
+			},
+			.has_vlan = 1,
+		},
+		.mask_default = &rte_flow_item_eth_mask,
+		.mask_sz = sizeof(struct rte_flow_item_eth),
+		.merge = nfp_flow_merge_eth,
+	},
+};
+
+static int
+nfp_flow_item_check(const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc)
+{
+	int ret = 0;
+	unsigned int i;
+	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 ?
+		(const uint8_t *)item->mask :
+		(const uint8_t *)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 && (((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_flow_compile_item_proc(const struct rte_flow_item items[],
+		struct rte_flow *nfp_flow,
+		char **mbuf_off_exact,
+		char **mbuf_off_mask)
+{
+	int i;
+	int ret = 0;
+	const struct rte_flow_item *item;
+	const struct nfp_flow_item_proc *proc_list;
+
+	proc_list = nfp_flow_item_proc_list;
+	for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {
+		const struct nfp_flow_item_proc *proc = NULL;
+
+		for (i = 0; proc_list->next_item && proc_list->next_item[i]; ++i) {
+			if (proc_list->next_item[i] == item->type) {
+				proc = &nfp_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_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, mbuf_off_exact, item,
+				proc, false);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "nfp flow item %d exact merge failed", item->type);
+			break;
+		}
+
+		ret = proc->merge(nfp_flow, mbuf_off_mask, item,
+				proc, true);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "nfp flow item %d mask merge failed", item->type);
+			break;
+		}
+
+		proc_list = proc;
+	}
+
+	return ret;
+}
+
+static int
+nfp_flow_compile_items(__rte_unused struct nfp_flower_representor *representor,
+		const struct rte_flow_item items[],
+		struct rte_flow *nfp_flow)
+{
+	int ret;
+	char *mbuf_off_mask;
+	char *mbuf_off_exact;
+
+	mbuf_off_exact = nfp_flow->payload.unmasked_data +
+			sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+	mbuf_off_mask  = nfp_flow->payload.mask_data +
+			sizeof(struct nfp_flower_meta_tci) +
+			sizeof(struct nfp_flower_in_port);
+
+	/* Go over items */
+	ret = nfp_flow_compile_item_proc(items, nfp_flow,
+			&mbuf_off_exact, &mbuf_off_mask);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow item compile failed.");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static struct rte_flow *
 nfp_flow_process(struct nfp_flower_representor *representor,
 		const struct rte_flow_item items[],
@@ -573,6 +817,12 @@ struct nfp_mask_id_entry {
 
 	nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx);
 
+	ret = nfp_flow_compile_items(representor, items, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow item process failed.");
+		goto free_flow;
+	}
+
 	nfp_flow_meta = nfp_flow->payload.meta;
 	mask_data = nfp_flow->payload.mask_data;
 	mask_len = key_layer.key_size;
-- 
1.8.3.1


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

* [PATCH v6 08/27] net/nfp: support basic flow actions
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (6 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 07/27] net/nfp: support basic flow items Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 09/27] net/nfp: support VLAN flow item Chaoyong He
                       ` (19 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the offload support of very basic actions: count, drop
and output.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |   5 ++
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  11 ++++
 drivers/net/nfp/nfp_flow.c               | 100 +++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h               |  37 ++++++++++++
 4 files changed, 153 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 4460cf0..f91da82 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,3 +29,8 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 port_id              = Y
+
+[rte_flow actions]
+count                = Y
+drop                 = Y
+port_id              = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 75a3b91..d776e37 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -253,6 +253,17 @@ struct nfp_flower_mac_mpls {
 	rte_be32_t mpls_lse;
 };
 
+struct nfp_fl_act_head {
+	uint8_t jump_id;
+	uint8_t len_lw;
+};
+
+struct nfp_fl_act_output {
+	struct nfp_fl_act_head head;
+	rte_be16_t flags;
+	rte_be32_t port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index ea5b359..36b1221 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -546,6 +546,16 @@ struct nfp_mask_id_entry {
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VOID detected");
 			break;
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_DROP detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_COUNT detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_PORT_ID detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_output);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -773,6 +783,90 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_action_output(char *act_data,
+		const struct rte_flow_action *action,
+		struct nfp_fl_rule_metadata *nfp_flow_meta)
+{
+	size_t act_size;
+	struct rte_eth_dev *ethdev;
+	struct nfp_fl_act_output *output;
+	struct nfp_flower_representor *representor;
+	const struct rte_flow_action_port_id *port_id;
+
+	port_id = action->conf;
+	if (port_id == NULL || port_id->id >= RTE_MAX_ETHPORTS)
+		return -ERANGE;
+
+	ethdev = &rte_eth_devices[port_id->id];
+	representor = (struct nfp_flower_representor *)ethdev->data->dev_private;
+	act_size = sizeof(struct nfp_fl_act_output);
+
+	output = (struct nfp_fl_act_output *)act_data;
+	output->head.jump_id = NFP_FL_ACTION_OPCODE_OUTPUT;
+	output->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	output->flags        = rte_cpu_to_be_16(NFP_FL_OUT_FLAGS_LAST);
+	output->port         = rte_cpu_to_be_32(representor->port_id);
+
+	nfp_flow_meta->shortcut = rte_cpu_to_be_32(representor->port_id);
+
+	return 0;
+}
+
+static int
+nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
+		const struct rte_flow_action actions[],
+		struct rte_flow *nfp_flow)
+{
+	int ret = 0;
+	char *position;
+	char *action_data;
+	bool drop_flag = false;
+	uint32_t total_actions = 0;
+	const struct rte_flow_action *action;
+	struct nfp_fl_rule_metadata *nfp_flow_meta;
+
+	nfp_flow_meta = nfp_flow->payload.meta;
+	action_data   = nfp_flow->payload.action_data;
+	position      = action_data;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+		switch (action->type) {
+		case RTE_FLOW_ACTION_TYPE_VOID:
+			break;
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_DROP");
+			drop_flag = true;
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_COUNT");
+			break;
+		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_PORT_ID");
+			ret = nfp_flow_action_output(position, action, nfp_flow_meta);
+			if (ret != 0) {
+				PMD_DRV_LOG(ERR, "Failed when process"
+						" RTE_FLOW_ACTION_TYPE_PORT_ID");
+				return ret;
+			}
+
+			position += sizeof(struct nfp_fl_act_output);
+			break;
+		default:
+			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
+			return -ENOTSUP;
+		}
+		total_actions++;
+	}
+
+	if (drop_flag)
+		nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_DROP);
+	else if (total_actions > 1)
+		nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_NULL);
+
+	return 0;
+}
+
 static struct rte_flow *
 nfp_flow_process(struct nfp_flower_representor *representor,
 		const struct rte_flow_item items[],
@@ -823,6 +917,12 @@ struct nfp_mask_id_entry {
 		goto free_flow;
 	}
 
+	ret = nfp_flow_compile_action(representor, actions, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "nfp flow action process failed.");
+		goto free_flow;
+	}
+
 	nfp_flow_meta = nfp_flow->payload.meta;
 	mask_data = nfp_flow->payload.mask_data;
 	mask_len = key_layer.key_size;
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 4adcc36..2fdffa1 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -34,6 +34,43 @@
 /* The firmware expects lengths in units of long words */
 #define NFP_FL_LW_SIZ                   2
 
+#define NFP_FL_SC_ACT_DROP      0x80000000
+#define NFP_FL_SC_ACT_USER      0x7D000000
+#define NFP_FL_SC_ACT_POPV      0x6A000000
+#define NFP_FL_SC_ACT_NULL      0x00000000
+
+/* Action opcodes */
+#define NFP_FL_ACTION_OPCODE_OUTPUT             0
+#define NFP_FL_ACTION_OPCODE_PUSH_VLAN          1
+#define NFP_FL_ACTION_OPCODE_POP_VLAN           2
+#define NFP_FL_ACTION_OPCODE_PUSH_MPLS          3
+#define NFP_FL_ACTION_OPCODE_POP_MPLS           4
+#define NFP_FL_ACTION_OPCODE_USERSPACE          5
+#define NFP_FL_ACTION_OPCODE_SET_TUNNEL         6
+#define NFP_FL_ACTION_OPCODE_SET_ETHERNET       7
+#define NFP_FL_ACTION_OPCODE_SET_MPLS           8
+#define NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS     9
+#define NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS   10
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_SRC       11
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_DST       12
+#define NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL  13
+#define NFP_FL_ACTION_OPCODE_SET_UDP            14
+#define NFP_FL_ACTION_OPCODE_SET_TCP            15
+#define NFP_FL_ACTION_OPCODE_PRE_LAG            16
+#define NFP_FL_ACTION_OPCODE_PRE_TUNNEL         17
+#define NFP_FL_ACTION_OPCODE_PRE_GS             18
+#define NFP_FL_ACTION_OPCODE_GS                 19
+#define NFP_FL_ACTION_OPCODE_PUSH_NSH           20
+#define NFP_FL_ACTION_OPCODE_POP_NSH            21
+#define NFP_FL_ACTION_OPCODE_SET_QUEUE          22
+#define NFP_FL_ACTION_OPCODE_CONNTRACK          23
+#define NFP_FL_ACTION_OPCODE_METER              24
+#define NFP_FL_ACTION_OPCODE_CT_NAT_EXT         25
+#define NFP_FL_ACTION_OPCODE_PUSH_GENEVE        26
+#define NFP_FL_ACTION_OPCODE_NUM                32
+
+#define NFP_FL_OUT_FLAGS_LAST            RTE_BIT32(15)
+
 /* Tunnel ports */
 #define NFP_FL_PORT_TYPE_TUN            0x50000000
 
-- 
1.8.3.1


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

* [PATCH v6 09/27] net/nfp: support VLAN flow item
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (7 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 08/27] net/nfp: support basic flow actions Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 10/27] net/nfp: support IPv4 " Chaoyong He
                       ` (18 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 46 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h       |  2 ++
 3 files changed, 49 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f91da82..b0af2a0 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,6 +29,7 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 port_id              = Y
+vlan                 = Y
 
 [rte_flow actions]
 count                = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 36b1221..802fa6a 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -518,6 +518,10 @@ struct nfp_mask_id_entry {
 					ethdev->data->dev_private;
 			key_ls->port = rte_cpu_to_be_32(representor->port_id);
 			break;
+		case RTE_FLOW_ITEM_TYPE_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_VLAN detected");
+			key_ls->vlan = NFP_FLOWER_MASK_VLAN_CFI;
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -623,12 +627,42 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_vlan(struct rte_flow *nfp_flow,
+		__rte_unused char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_vlan *spec;
+	const struct rte_flow_item_vlan *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge vlan: no item->spec!");
+		return 0;
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.mask_data;
+		meta_tci->tci |= mask->tci;
+	} else {
+		meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+		meta_tci->tci |= spec->tci;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -641,6 +675,18 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_eth),
 		.merge = nfp_flow_merge_eth,
 	},
+	[RTE_FLOW_ITEM_TYPE_VLAN] = {
+		.mask_support = &(const struct rte_flow_item_vlan){
+			.hdr = {
+				.vlan_tci  = RTE_BE16(0xefff),
+				.eth_proto = RTE_BE16(0xffff),
+			},
+			.has_more_vlan = 1,
+		},
+		.mask_default = &rte_flow_item_vlan_mask,
+		.mask_sz = sizeof(struct rte_flow_item_vlan),
+		.merge = nfp_flow_merge_vlan,
+	},
 };
 
 static int
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 2fdffa1..40cd062 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -26,6 +26,8 @@
 
 #define NFP_FL_META_FLAG_MANAGE_MASK    RTE_BIT32(7)
 
+#define NFP_FLOWER_MASK_VLAN_CFI        RTE_BIT32(12)
+
 #define NFP_MASK_TABLE_ENTRIES          1024
 
 /* The maximum action list size (in bytes) supported by the NFP. */
-- 
1.8.3.1


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

* [PATCH v6 10/27] net/nfp: support IPv4 flow item
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (8 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 09/27] net/nfp: support VLAN flow item Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 11/27] net/nfp: support IPv6 " Chaoyong He
                       ` (17 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 38 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 68 +++++++++++++++++++++++++++++++-
 3 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index b0af2a0..bf59123 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -28,6 +28,7 @@ Usage doc            = Y
 
 [rte_flow items]
 eth                  = Y
+ipv4                 = Y
 port_id              = Y
 vlan                 = Y
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index d776e37..5964ecf 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -253,6 +253,44 @@ struct nfp_flower_mac_mpls {
 	rte_be32_t mpls_lse;
 };
 
+/*
+ * L4 ports (for UDP, TCP, SCTP) (1W/4B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |            port_src           |           port_dst            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_tp_ports {
+	rte_be16_t port_src;
+	rte_be16_t port_dst;
+};
+
+struct nfp_flower_ip_ext {
+	uint8_t tos;
+	uint8_t proto;
+	uint8_t ttl;
+	uint8_t flags;
+};
+
+/*
+ * L3 IPv4 details (3W/12B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    DSCP   |ECN|   protocol    |      ttl      |     flags     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                        ipv4_addr_src                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                        ipv4_addr_dst                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ipv4 {
+	struct nfp_flower_ip_ext ip_ext;
+	rte_be32_t ipv4_src;
+	rte_be32_t ipv4_dst;
+};
+
 struct nfp_fl_act_head {
 	uint8_t jump_id;
 	uint8_t len_lw;
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 802fa6a..7a7a873 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -522,6 +522,11 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_VLAN detected");
 			key_ls->vlan = NFP_FLOWER_MASK_VLAN_CFI;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV4:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV4;
+			key_ls->key_size += sizeof(struct nfp_flower_ipv4);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -656,13 +661,58 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_ipv4(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_ipv4 *ipv4;
+	const struct rte_ipv4_hdr *hdr;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_ipv4 *spec;
+	const struct rte_flow_item_ipv4 *mask;
+
+	spec = item->spec;
+	mask = item->mask ? item->mask : proc->mask_default;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge ipv4: no item->spec!");
+		goto ipv4_end;
+	}
+
+	/*
+	 * reserve space for L4 info.
+	 * rte_flow has ipv4 before L4 but NFP flower fw requires L4 before ipv4
+	 */
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP)
+		*mbuf_off += sizeof(struct nfp_flower_tp_ports);
+
+	hdr = is_mask ? &mask->hdr : &spec->hdr;
+	ipv4 = (struct nfp_flower_ipv4 *)*mbuf_off;
+
+	ipv4->ip_ext.tos   = hdr->type_of_service;
+	ipv4->ip_ext.proto = hdr->next_proto_id;
+	ipv4->ip_ext.ttl   = hdr->time_to_live;
+	ipv4->ipv4_src     = hdr->src_addr;
+	ipv4->ipv4_dst     = hdr->dst_addr;
+
+ipv4_end:
+	*mbuf_off += sizeof(struct nfp_flower_ipv4);
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN,
+			RTE_FLOW_ITEM_TYPE_IPV4),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -676,6 +726,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_eth,
 	},
 	[RTE_FLOW_ITEM_TYPE_VLAN] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4),
 		.mask_support = &(const struct rte_flow_item_vlan){
 			.hdr = {
 				.vlan_tci  = RTE_BE16(0xefff),
@@ -687,6 +738,21 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_vlan),
 		.merge = nfp_flow_merge_vlan,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.mask_support = &(const struct rte_flow_item_ipv4){
+			.hdr = {
+				.type_of_service = 0xff,
+				.fragment_offset = RTE_BE16(0xffff),
+				.time_to_live    = 0xff,
+				.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_flow_merge_ipv4,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v6 11/27] net/nfp: support IPv6 flow item
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (9 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 10/27] net/nfp: support IPv4 " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 12/27] net/nfp: support TCP " Chaoyong He
                       ` (16 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 33 +++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 73 +++++++++++++++++++++++++++++++-
 3 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index bf59123..4869b45 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,6 +29,7 @@ Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 ipv4                 = Y
+ipv6                 = Y
 port_id              = Y
 vlan                 = Y
 
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 5964ecf..36d406f 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -291,6 +291,39 @@ struct nfp_flower_ipv4 {
 	rte_be32_t ipv4_dst;
 };
 
+/*
+ * L3 IPv6 details (10W/40B)
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    DSCP   |ECN|   protocol    |      ttl      |     flags     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   ipv6_exthdr   | res |            ipv6_flow_label            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,   31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,  63 - 32                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src,  95 - 64                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_src, 127 - 96                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,   31 - 0                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,  63 - 32                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst,  95 - 64                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                  ipv6_addr_dst, 127 - 96                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ipv6 {
+	struct nfp_flower_ip_ext ip_ext;
+	rte_be32_t ipv6_flow_label_exthdr;
+	uint8_t ipv6_src[16];
+	uint8_t ipv6_dst[16];
+};
+
 struct nfp_fl_act_head {
 	uint8_t jump_id;
 	uint8_t len_lw;
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 7a7a873..1da3c89 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -527,6 +527,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV4;
 			key_ls->key_size += sizeof(struct nfp_flower_ipv4);
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV6 detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV6;
+			key_ls->key_size += sizeof(struct nfp_flower_ipv6);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -705,6 +710,51 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_ipv6(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	struct nfp_flower_ipv6 *ipv6;
+	const struct rte_ipv6_hdr *hdr;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_ipv6 *spec;
+	const struct rte_flow_item_ipv6 *mask;
+
+	spec = item->spec;
+	mask = item->mask ? item->mask : proc->mask_default;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge ipv6: no item->spec!");
+		goto ipv6_end;
+	}
+
+	/*
+	 * reserve space for L4 info.
+	 * rte_flow has ipv4 before L4 but NFP flower fw requires L4 before ipv4
+	 */
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP)
+		*mbuf_off += sizeof(struct nfp_flower_tp_ports);
+
+	hdr = is_mask ? &mask->hdr : &spec->hdr;
+	ipv6 = (struct nfp_flower_ipv6 *)*mbuf_off;
+
+	ipv6->ip_ext.tos   = (hdr->vtc_flow & RTE_IPV6_HDR_TC_MASK) >>
+			RTE_IPV6_HDR_TC_SHIFT;
+	ipv6->ip_ext.proto = hdr->proto;
+	ipv6->ip_ext.ttl   = hdr->hop_limits;
+	memcpy(ipv6->ipv6_src, hdr->src_addr, sizeof(ipv6->ipv6_src));
+	memcpy(ipv6->ipv6_dst, hdr->dst_addr, sizeof(ipv6->ipv6_dst));
+
+ipv6_end:
+	*mbuf_off += sizeof(struct nfp_flower_ipv6);
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -712,7 +762,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_ETH] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN,
-			RTE_FLOW_ITEM_TYPE_IPV4),
+			RTE_FLOW_ITEM_TYPE_IPV4,
+			RTE_FLOW_ITEM_TYPE_IPV6),
 		.mask_support = &(const struct rte_flow_item_eth){
 			.hdr = {
 				.dst_addr.addr_bytes = "\xff\xff\xff\xff\xff\xff",
@@ -726,7 +777,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_eth,
 	},
 	[RTE_FLOW_ITEM_TYPE_VLAN] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_IPV4,
+			RTE_FLOW_ITEM_TYPE_IPV6),
 		.mask_support = &(const struct rte_flow_item_vlan){
 			.hdr = {
 				.vlan_tci  = RTE_BE16(0xefff),
@@ -753,6 +805,23 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_ipv4),
 		.merge = nfp_flow_merge_ipv4,
 	},
+	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.mask_support = &(const struct rte_flow_item_ipv6){
+			.hdr = {
+				.vtc_flow   = RTE_BE32(0x0ff00000),
+				.proto      = 0xff,
+				.hop_limits = 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",
+			},
+			.has_frag_ext = 1,
+		},
+		.mask_default = &rte_flow_item_ipv6_mask,
+		.mask_sz = sizeof(struct rte_flow_item_ipv6),
+		.merge = nfp_flow_merge_ipv6,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v6 12/27] net/nfp: support TCP flow item
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (10 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 11/27] net/nfp: support IPv6 " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 13/27] net/nfp: support UDP " Chaoyong He
                       ` (15 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

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

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 91 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.h       |  7 ++++
 3 files changed, 99 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 4869b45..670c12f 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -31,6 +31,7 @@ eth                  = Y
 ipv4                 = Y
 ipv6                 = Y
 port_id              = Y
+tcp                  = Y
 vlan                 = Y
 
 [rte_flow actions]
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 1da3c89..da6b31a 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -532,6 +532,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_IPV6;
 			key_ls->key_size += sizeof(struct nfp_flower_ipv6);
 			break;
+		case RTE_FLOW_ITEM_TYPE_TCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_TCP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -755,6 +760,78 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_tcp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	uint8_t tcp_flags;
+	struct nfp_flower_tp_ports *ports;
+	struct nfp_flower_ipv4 *ipv4 = NULL;
+	struct nfp_flower_ipv6 *ipv6 = NULL;
+	const struct rte_flow_item_tcp *spec;
+	const struct rte_flow_item_tcp *mask;
+	struct nfp_flower_meta_tci *meta_tci;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge tcp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ipv4  = (struct nfp_flower_ipv4 *)
+			(*mbuf_off - sizeof(struct nfp_flower_ipv4));
+		ports = (struct nfp_flower_tp_ports *)
+			((char *)ipv4 - sizeof(struct nfp_flower_tp_ports));
+	} else { /* IPv6 */
+		ipv6  = (struct nfp_flower_ipv6 *)
+			(*mbuf_off - sizeof(struct nfp_flower_ipv6));
+		ports = (struct nfp_flower_tp_ports *)
+			((char *)ipv6 - sizeof(struct nfp_flower_tp_ports));
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+		tcp_flags       = mask->hdr.tcp_flags;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+		tcp_flags       = spec->hdr.tcp_flags;
+	}
+
+	if (ipv4) {
+		if (tcp_flags & RTE_TCP_FIN_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_FIN;
+		if (tcp_flags & RTE_TCP_SYN_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_SYN;
+		if (tcp_flags & RTE_TCP_RST_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_RST;
+		if (tcp_flags & RTE_TCP_PSH_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_PSH;
+		if (tcp_flags & RTE_TCP_URG_FLAG)
+			ipv4->ip_ext.flags |= NFP_FL_TCP_FLAG_URG;
+	} else {  /* IPv6 */
+		if (tcp_flags & RTE_TCP_FIN_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_FIN;
+		if (tcp_flags & RTE_TCP_SYN_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_SYN;
+		if (tcp_flags & RTE_TCP_RST_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_RST;
+		if (tcp_flags & RTE_TCP_PSH_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_PSH;
+		if (tcp_flags & RTE_TCP_URG_FLAG)
+			ipv6->ip_ext.flags |= NFP_FL_TCP_FLAG_URG;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -791,6 +868,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_vlan,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -806,6 +884,7 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_ipv4,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -822,6 +901,18 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_ipv6),
 		.merge = nfp_flow_merge_ipv6,
 	},
+	[RTE_FLOW_ITEM_TYPE_TCP] = {
+		.mask_support = &(const struct rte_flow_item_tcp){
+			.hdr = {
+				.tcp_flags = 0xff,
+				.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_tcp,
+	},
 };
 
 static int
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index 40cd062..0ad89e5 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -24,6 +24,13 @@
 #define NFP_FLOWER_LAYER2_GENEVE_OP     RTE_BIT32(6)
 #define NFP_FLOWER_LAYER2_TUN_IPV6      RTE_BIT32(7)
 
+/* Compressed HW representation of TCP Flags */
+#define NFP_FL_TCP_FLAG_FIN             RTE_BIT32(0)
+#define NFP_FL_TCP_FLAG_SYN             RTE_BIT32(1)
+#define NFP_FL_TCP_FLAG_RST             RTE_BIT32(2)
+#define NFP_FL_TCP_FLAG_PSH             RTE_BIT32(3)
+#define NFP_FL_TCP_FLAG_URG             RTE_BIT32(4)
+
 #define NFP_FL_META_FLAG_MANAGE_MASK    RTE_BIT32(7)
 
 #define NFP_FLOWER_MASK_VLAN_CFI        RTE_BIT32(12)
-- 
1.8.3.1


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

* [PATCH v6 13/27] net/nfp: support UDP flow item
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (11 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 12/27] net/nfp: support TCP " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 14/27] net/nfp: support SCTP " Chaoyong He
                       ` (14 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload
of UDP item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 63 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 670c12f..0af740a 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -32,6 +32,7 @@ ipv4                 = Y
 ipv6                 = Y
 port_id              = Y
 tcp                  = Y
+udp                  = Y
 vlan                 = Y
 
 [rte_flow actions]
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index da6b31a..b13559b 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -537,6 +537,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
 			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
 			break;
+		case RTE_FLOW_ITEM_TYPE_UDP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_UDP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -832,6 +837,47 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_udp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	char *ports_off;
+	struct nfp_flower_tp_ports *ports;
+	const struct rte_flow_item_udp *spec;
+	const struct rte_flow_item_udp *mask;
+	struct nfp_flower_meta_tci *meta_tci;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge udp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv4) -
+			sizeof(struct nfp_flower_tp_ports);
+	} else {/* IPv6 */
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv6) -
+			sizeof(struct nfp_flower_tp_ports);
+	}
+	ports = (struct nfp_flower_tp_ports *)ports_off;
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -868,7 +914,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_vlan,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+			RTE_FLOW_ITEM_TYPE_UDP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -884,7 +931,8 @@ struct nfp_mask_id_entry {
 		.merge = nfp_flow_merge_ipv4,
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
-		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP),
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
+			RTE_FLOW_ITEM_TYPE_UDP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -913,6 +961,17 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_tcp),
 		.merge = nfp_flow_merge_tcp,
 	},
+	[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_udp,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v6 14/27] net/nfp: support SCTP flow item
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (12 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 13/27] net/nfp: support UDP " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 15/27] net/nfp: support SRC MAC flow action Chaoyong He
                       ` (13 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload
of SCTP item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 63 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 0af740a..27575d1 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -31,6 +31,7 @@ eth                  = Y
 ipv4                 = Y
 ipv6                 = Y
 port_id              = Y
+sctp                 = Y
 tcp                  = Y
 udp                  = Y
 vlan                 = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index b13559b..13b2b30 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -542,6 +542,11 @@ struct nfp_mask_id_entry {
 			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
 			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
 			break;
+		case RTE_FLOW_ITEM_TYPE_SCTP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_SCTP detected");
+			key_ls->key_layer |= NFP_FLOWER_LAYER_TP;
+			key_ls->key_size += sizeof(struct nfp_flower_tp_ports);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -878,6 +883,47 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static int
+nfp_flow_merge_sctp(struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		const struct nfp_flow_item_proc *proc,
+		bool is_mask)
+{
+	char *ports_off;
+	struct nfp_flower_tp_ports *ports;
+	struct nfp_flower_meta_tci *meta_tci;
+	const struct rte_flow_item_sctp *spec;
+	const struct rte_flow_item_sctp *mask;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge sctp: no item->spec!");
+		return 0;
+	}
+
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
+	if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv4) -
+			sizeof(struct nfp_flower_tp_ports);
+	} else { /* IPv6 */
+		ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv6) -
+			sizeof(struct nfp_flower_tp_ports);
+	}
+	ports = (struct nfp_flower_tp_ports *)ports_off;
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	if (is_mask) {
+		ports->port_src = mask->hdr.src_port;
+		ports->port_dst = mask->hdr.dst_port;
+	} else {
+		ports->port_src = spec->hdr.src_port;
+		ports->port_dst = spec->hdr.dst_port;
+	}
+
+	return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -915,7 +961,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
-			RTE_FLOW_ITEM_TYPE_UDP),
+			RTE_FLOW_ITEM_TYPE_UDP,
+			RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -932,7 +979,8 @@ struct nfp_mask_id_entry {
 	},
 	[RTE_FLOW_ITEM_TYPE_IPV6] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
-			RTE_FLOW_ITEM_TYPE_UDP),
+			RTE_FLOW_ITEM_TYPE_UDP,
+			RTE_FLOW_ITEM_TYPE_SCTP),
 		.mask_support = &(const struct rte_flow_item_ipv6){
 			.hdr = {
 				.vtc_flow   = RTE_BE32(0x0ff00000),
@@ -972,6 +1020,17 @@ struct nfp_mask_id_entry {
 		.mask_sz = sizeof(struct rte_flow_item_udp),
 		.merge = nfp_flow_merge_udp,
 	},
+	[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_sctp,
+	},
 };
 
 static int
-- 
1.8.3.1


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

* [PATCH v6 15/27] net/nfp: support SRC MAC flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (13 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 14/27] net/nfp: support SCTP " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 16/27] net/nfp: support DST " Chaoyong He
                       ` (12 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source MAC action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 27 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 47 ++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 27575d1..f7cd070 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -40,3 +40,4 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 port_id              = Y
+set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 36d406f..b61342e 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -335,6 +335,33 @@ struct nfp_fl_act_output {
 	rte_be32_t port;
 };
 
+/*
+ * ETH
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |   -   |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_dst_47_16_mask                        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      eth_dst_15_0_mask        |      eth_src_47_32_mask       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_src_31_0_mask                         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_dst_47_16                             |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      eth_dst_15_0             |      eth_src_47_32            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     eth_src_31_0                              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_eth {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	uint8_t eth_addr_mask[RTE_ETHER_ADDR_LEN * 2];
+	uint8_t eth_addr[RTE_ETHER_ADDR_LEN * 2];
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 13b2b30..8c065c4 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -561,6 +561,7 @@ struct nfp_mask_id_entry {
 		struct nfp_fl_key_ls *key_ls)
 {
 	int ret = 0;
+	bool mac_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -585,6 +586,13 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_PORT_ID detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_output);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_MAC_SRC detected");
+			if (!mac_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1203,6 +1211,36 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flow_action_set_mac(char *act_data,
+		const struct rte_flow_action *action,
+		bool mac_src_flag,
+		bool mac_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_eth *set_eth;
+	const struct rte_flow_action_set_mac *set_mac;
+
+	if (mac_set_flag)
+		set_eth = (struct nfp_fl_act_set_eth *)act_data - 1;
+	else
+		set_eth = (struct nfp_fl_act_set_eth *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_eth);
+	set_eth->head.jump_id = NFP_FL_ACTION_OPCODE_SET_ETHERNET;
+	set_eth->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_eth->reserved     = 0;
+
+	set_mac = (const struct rte_flow_action_set_mac *)action->conf;
+	if (mac_src_flag) {
+		rte_memcpy(&set_eth->eth_addr[RTE_ETHER_ADDR_LEN],
+				set_mac->mac_addr, RTE_ETHER_ADDR_LEN);
+	} else {
+		rte_memcpy(&set_eth->eth_addr[0],
+				set_mac->mac_addr, RTE_ETHER_ADDR_LEN);
+	}
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1212,6 +1250,7 @@ struct nfp_mask_id_entry {
 	char *position;
 	char *action_data;
 	bool drop_flag = false;
+	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
 	struct nfp_fl_rule_metadata *nfp_flow_meta;
@@ -1242,6 +1281,14 @@ struct nfp_mask_id_entry {
 
 			position += sizeof(struct nfp_fl_act_output);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_MAC_SRC");
+			nfp_flow_action_set_mac(position, action, true, mac_set_flag);
+			if (!mac_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 16/27] net/nfp: support DST MAC flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (14 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 15/27] net/nfp: support SRC MAC flow action Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 17/27] net/nfp: support pop VLAN " Chaoyong He
                       ` (11 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest MAC action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f7cd070..9e86164 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -40,4 +40,5 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 port_id              = Y
+set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 8c065c4..b440c95 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -593,6 +593,13 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_MAC_DST detected");
+			if (!mac_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1289,6 +1296,14 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_MAC_DST");
+			nfp_flow_action_set_mac(position, action, false, mac_set_flag);
+			if (!mac_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_eth);
+				mac_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 17/27] net/nfp: support pop VLAN flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (15 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 16/27] net/nfp: support DST " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 18/27] net/nfp: support push " Chaoyong He
                       ` (10 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of pop_vlan action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  5 +++++
 drivers/net/nfp/nfp_flow.c               | 25 +++++++++++++++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 9e86164..2c5d173 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -39,6 +39,7 @@ vlan                 = Y
 [rte_flow actions]
 count                = Y
 drop                 = Y
+of_pop_vlan          = Y
 port_id              = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index b61342e..4ce03da 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -362,6 +362,11 @@ struct nfp_fl_act_set_eth {
 	uint8_t eth_addr[RTE_ETHER_ADDR_LEN * 2];
 };
 
+struct nfp_fl_act_pop_vlan {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index b440c95..d496be7 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -600,6 +600,10 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_POP_VLAN detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_pop_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1248,6 +1252,22 @@ struct nfp_mask_id_entry {
 	}
 }
 
+static void
+nfp_flow_action_pop_vlan(char *act_data,
+		struct nfp_fl_rule_metadata *nfp_flow_meta)
+{
+	size_t act_size;
+	struct nfp_fl_act_pop_vlan *pop_vlan;
+
+	act_size = sizeof(struct nfp_fl_act_pop_vlan);
+	pop_vlan = (struct nfp_fl_act_pop_vlan *)act_data;
+	pop_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_POP_VLAN;
+	pop_vlan->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	pop_vlan->reserved     = 0;
+
+	nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_POPV);
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1304,6 +1324,11 @@ struct nfp_mask_id_entry {
 				mac_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_OF_POP_VLAN");
+			nfp_flow_action_pop_vlan(position, nfp_flow_meta);
+			position += sizeof(struct nfp_fl_act_pop_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 18/27] net/nfp: support push VLAN flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (16 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 17/27] net/nfp: support pop VLAN " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 19/27] net/nfp: support SRC IPv4 " Chaoyong He
                       ` (9 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of push_vlan action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  3 ++
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  7 ++++
 drivers/net/nfp/nfp_flow.c               | 60 ++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 2c5d173..005129d 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -40,6 +40,9 @@ vlan                 = Y
 count                = Y
 drop                 = Y
 of_pop_vlan          = Y
+of_push_vlan         = Y
+of_set_vlan_pcp      = Y
+of_set_vlan_vid      = Y
 port_id              = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 4ce03da..30a9ff5 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -367,6 +367,13 @@ struct nfp_fl_act_pop_vlan {
 	rte_be16_t reserved;
 };
 
+struct nfp_fl_act_push_vlan {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be16_t vlan_tpid;
+	rte_be16_t vlan_tci;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index d496be7..2339efb 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -604,6 +604,16 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_POP_VLAN detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_pop_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_push_vlan);
+			break;
+		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID detected");
+			break;
+		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP detected");
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1269,6 +1279,39 @@ struct nfp_mask_id_entry {
 }
 
 static int
+nfp_flow_action_push_vlan(char *act_data,
+		const struct rte_flow_action *action)
+{
+	size_t act_size;
+	struct nfp_fl_act_push_vlan *push_vlan;
+	const struct rte_flow_action_of_push_vlan *push_vlan_conf;
+	const struct rte_flow_action_of_set_vlan_pcp *vlan_pcp_conf;
+	const struct rte_flow_action_of_set_vlan_vid *vlan_vid_conf;
+
+	if (((action + 1)->type != RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP) ||
+			((action + 2)->type != RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID))
+		return -EINVAL;
+
+	act_size = sizeof(struct nfp_fl_act_push_vlan);
+	push_vlan = (struct nfp_fl_act_push_vlan *)act_data;
+	push_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_PUSH_VLAN;
+	push_vlan->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	push_vlan->reserved     = 0;
+
+	push_vlan_conf = (const struct rte_flow_action_of_push_vlan *)
+			action->conf;
+	vlan_pcp_conf  = (const struct rte_flow_action_of_set_vlan_pcp *)
+			(action + 1)->conf;
+	vlan_vid_conf  = (const struct rte_flow_action_of_set_vlan_vid *)
+			(action + 2)->conf;
+	push_vlan->vlan_tpid = push_vlan_conf->ethertype;
+	push_vlan->vlan_tci = ((vlan_pcp_conf->vlan_pcp & 0x07) << 13) |
+			(vlan_vid_conf->vlan_vid & 0x0fff);
+
+	return 0;
+}
+
+static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
 		struct rte_flow *nfp_flow)
@@ -1329,6 +1372,23 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_pop_vlan(position, nfp_flow_meta);
 			position += sizeof(struct nfp_fl_act_pop_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN");
+			ret = nfp_flow_action_push_vlan(position, action);
+			if (ret != 0) {
+				PMD_DRV_LOG(ERR, "Failed when process"
+						" RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN");
+				return ret;
+			}
+
+			/*
+			 * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP and
+			 * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID
+			 * have also been processed.
+			 */
+			action += 2;
+			position += sizeof(struct nfp_fl_act_push_vlan);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 19/27] net/nfp: support SRC IPv4 flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (17 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 18/27] net/nfp: support push " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 20/27] net/nfp: support DST " Chaoyong He
                       ` (8 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source IPv4 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 25 ++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 45 ++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 005129d..e62b3f7 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -44,5 +44,6 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 30a9ff5..77cb51d 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -374,6 +374,31 @@ struct nfp_fl_act_push_vlan {
 	rte_be16_t vlan_tci;
 };
 
+/*
+ * IPv4 addrs
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_saddr_mask                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_saddr                                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_daddr_mask                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv4_daddr                                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ip4_addrs {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be32_t ipv4_src_mask;
+	rte_be32_t ipv4_src;
+	rte_be32_t ipv4_dst_mask;
+	rte_be32_t ipv4_dst;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 2339efb..d8c0e63 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -562,6 +562,7 @@ struct nfp_mask_id_entry {
 {
 	int ret = 0;
 	bool mac_set_flag = false;
+	bool ip_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -614,6 +615,14 @@ struct nfp_mask_id_entry {
 		case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP detected");
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC detected");
+			if (!ip_set_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1278,6 +1287,33 @@ struct nfp_mask_id_entry {
 	nfp_flow_meta->shortcut = rte_cpu_to_be_32(NFP_FL_SC_ACT_POPV);
 }
 
+static void
+nfp_flow_action_set_ip(char *act_data,
+		const struct rte_flow_action *action,
+		bool ip_src_flag,
+		bool ip_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_addrs *set_ip;
+	const struct rte_flow_action_set_ipv4 *set_ipv4;
+
+	if (ip_set_flag)
+		set_ip = (struct nfp_fl_act_set_ip4_addrs *)act_data - 1;
+	else
+		set_ip = (struct nfp_fl_act_set_ip4_addrs *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_addrs);
+	set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS;
+	set_ip->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_ip->reserved     = 0;
+
+	set_ipv4 = (const struct rte_flow_action_set_ipv4 *)action->conf;
+	if (ip_src_flag)
+		set_ip->ipv4_src = set_ipv4->ipv4_addr;
+	else
+		set_ip->ipv4_dst = set_ipv4->ipv4_addr;
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1320,6 +1356,7 @@ struct nfp_mask_id_entry {
 	char *position;
 	char *action_data;
 	bool drop_flag = false;
+	bool ip_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
@@ -1389,6 +1426,14 @@ struct nfp_mask_id_entry {
 			action += 2;
 			position += sizeof(struct nfp_fl_act_push_vlan);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC");
+			nfp_flow_action_set_ip(position, action, true, ip_set_flag);
+			if (!ip_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 20/27] net/nfp: support DST IPv4 flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (18 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 19/27] net/nfp: support SRC IPv4 " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 21/27] net/nfp: support SRC IPv6 " Chaoyong He
                       ` (7 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest IPv4 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index e62b3f7..ddc457f 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -44,6 +44,7 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_dst         = Y
 set_ipv4_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index d8c0e63..2b39d39 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -623,6 +623,14 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_DST detected");
+			if (!ip_set_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1434,6 +1442,14 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_DST");
+			nfp_flow_action_set_ip(position, action, false, ip_set_flag);
+			if (!ip_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_addrs);
+				ip_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 21/27] net/nfp: support SRC IPv6 flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (19 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 20/27] net/nfp: support DST " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 22/27] net/nfp: support DST " Chaoyong He
                       ` (6 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set source IPv6 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 33 ++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 35 ++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index ddc457f..b17c701 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -46,5 +46,6 @@ of_set_vlan_vid      = Y
 port_id              = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 77cb51d..45e50dd 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -399,6 +399,39 @@ struct nfp_fl_act_set_ip4_addrs {
 	rte_be32_t ipv4_dst;
 };
 
+/*
+ * IPv6 addr
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_127_96_mask                     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_127_96                          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_95_64_mask                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_95_64                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_63_32_mask                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_63_32                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_31_0_mask                       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     ipv6_addr_31_0                            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ipv6_addr {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	struct {
+		rte_be32_t mask;
+		rte_be32_t exact;
+	} ipv6[4];
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 2b39d39..6821e29 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -631,6 +631,10 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1322,6 +1326,32 @@ struct nfp_mask_id_entry {
 		set_ip->ipv4_dst = set_ipv4->ipv4_addr;
 }
 
+static void
+nfp_flow_action_set_ipv6(char *act_data,
+		const struct rte_flow_action *action,
+		bool ip_src_flag)
+{
+	int i;
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_addr *set_ip;
+	const struct rte_flow_action_set_ipv6 *set_ipv6;
+
+	set_ip = (struct nfp_fl_act_set_ipv6_addr *)act_data;
+	set_ipv6 = (const struct rte_flow_action_set_ipv6 *)action->conf;
+
+	if (ip_src_flag)
+		set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_SRC;
+	else
+		set_ip->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_DST;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_addr);
+	set_ip->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+	set_ip->reserved = 0;
+
+	for (i = 0; i < 4; i++)
+		set_ip->ipv6[i].exact = set_ipv6->ipv6_addr[i];
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1450,6 +1480,11 @@ struct nfp_mask_id_entry {
 				ip_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC");
+			nfp_flow_action_set_ipv6(position, action, true);
+			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 22/27] net/nfp: support DST IPv6 flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (20 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 21/27] net/nfp: support SRC IPv6 " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:01     ` [PATCH v6 23/27] net/nfp: support TP SRC " Chaoyong He
                       ` (5 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set dest IPv6 address action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini | 1 +
 drivers/net/nfp/nfp_flow.c       | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index b17c701..5fcece7 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -46,6 +46,7 @@ of_set_vlan_vid      = Y
 port_id              = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 6821e29..e077ed3 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -635,6 +635,10 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DST detected");
+			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1485,6 +1489,11 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_set_ipv6(position, action, true);
 			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_DST");
+			nfp_flow_action_set_ipv6(position, action, false);
+			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 23/27] net/nfp: support TP SRC flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (21 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 22/27] net/nfp: support DST " Chaoyong He
@ 2022-10-21  8:01     ` Chaoyong He
  2022-10-21  8:02     ` [PATCH v6 24/27] net/nfp: support TP DST " Chaoyong He
                       ` (4 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:01 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set TP source port action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 21 +++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 44 ++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 5fcece7..f3ac51c 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -50,3 +50,4 @@ set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
+set_tp_src           = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 45e50dd..26de8b1 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -432,6 +432,27 @@ struct nfp_fl_act_set_ipv6_addr {
 	} ipv6[4];
 };
 
+/*
+ * TCP/UDP/SCTP
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|               -               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |          src_mask             |         dst_mask              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |          src                  |         dst                   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_tport {
+	struct nfp_fl_act_head head;
+	rte_be16_t reserved;
+	rte_be16_t src_port_mask;
+	rte_be16_t dst_port_mask;
+	rte_be16_t src_port;
+	rte_be16_t dst_port;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index e077ed3..9778020 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -563,6 +563,7 @@ struct nfp_mask_id_entry {
 	int ret = 0;
 	bool mac_set_flag = false;
 	bool ip_set_flag = false;
+	bool tp_set_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -639,6 +640,13 @@ struct nfp_mask_id_entry {
 			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DST detected");
 			key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TP_SRC detected");
+			if (!tp_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1356,6 +1364,33 @@ struct nfp_mask_id_entry {
 		set_ip->ipv6[i].exact = set_ipv6->ipv6_addr[i];
 }
 
+static void
+nfp_flow_action_set_tp(char *act_data,
+		const struct rte_flow_action *action,
+		bool tp_src_flag,
+		bool tp_set_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_tport *set_tp;
+	const struct rte_flow_action_set_tp *set_tp_conf;
+
+	if (tp_set_flag)
+		set_tp = (struct nfp_fl_act_set_tport *)act_data - 1;
+	else
+		set_tp = (struct nfp_fl_act_set_tport *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_tport);
+	set_tp->head.jump_id = NFP_FL_ACTION_OPCODE_SET_TCP;
+	set_tp->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+	set_tp->reserved     = 0;
+
+	set_tp_conf = (const struct rte_flow_action_set_tp *)action->conf;
+	if (tp_src_flag)
+		set_tp->src_port = set_tp_conf->port;
+	else
+		set_tp->dst_port = set_tp_conf->port;
+}
+
 static int
 nfp_flow_action_push_vlan(char *act_data,
 		const struct rte_flow_action *action)
@@ -1399,6 +1434,7 @@ struct nfp_mask_id_entry {
 	char *action_data;
 	bool drop_flag = false;
 	bool ip_set_flag = false;
+	bool tp_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
@@ -1494,6 +1530,14 @@ struct nfp_mask_id_entry {
 			nfp_flow_action_set_ipv6(position, action, false);
 			position += sizeof(struct nfp_fl_act_set_ipv6_addr);
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TP_SRC");
+			nfp_flow_action_set_tp(position, action, true, tp_set_flag);
+			if (!tp_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 24/27] net/nfp: support TP DST flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (22 preceding siblings ...)
  2022-10-21  8:01     ` [PATCH v6 23/27] net/nfp: support TP SRC " Chaoyong He
@ 2022-10-21  8:02     ` Chaoyong He
  2022-10-21  8:02     ` [PATCH v6 25/27] net/nfp: support TTL " Chaoyong He
                       ` (3 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:02 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of set
TP dest port action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index f3ac51c..e8ccd6a 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -50,4 +50,5 @@ set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
 set_mac_src          = Y
+set_tp_dst           = Y
 set_tp_src           = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 9778020..666dd8c 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -647,6 +647,13 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TP_DST detected");
+			if (!tp_set_flag) {
+				key_ls->act_size += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1538,6 +1545,14 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TP_DST");
+			nfp_flow_action_set_tp(position, action, false, tp_set_flag);
+			if (!tp_set_flag) {
+				position += sizeof(struct nfp_fl_act_set_tport);
+				tp_set_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 25/27] net/nfp: support TTL flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (23 preceding siblings ...)
  2022-10-21  8:02     ` [PATCH v6 24/27] net/nfp: support TP DST " Chaoyong He
@ 2022-10-21  8:02     ` Chaoyong He
  2022-10-21  8:02     ` [PATCH v6 26/27] net/nfp: support IPv4 DSCP " Chaoyong He
                       ` (2 subsequent siblings)
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:02 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding data structure and logics, to support
the offload of set TTL action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini         |  1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h | 44 +++++++++++++++++
 drivers/net/nfp/nfp_flow.c               | 84 ++++++++++++++++++++++++++++++++
 3 files changed, 129 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index e8ccd6a..1283583 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -52,3 +52,4 @@ set_mac_dst          = Y
 set_mac_src          = Y
 set_tp_dst           = Y
 set_tp_src           = Y
+set_ttl              = Y
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 26de8b1..6bf8ff7 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -400,6 +400,25 @@ struct nfp_fl_act_set_ip4_addrs {
 };
 
 /*
+ * IPv4 ttl tos
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|    ttl_mask   |   tos_mask    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |       ttl     |      tos      |               0               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ip4_ttl_tos {
+	struct nfp_fl_act_head head;
+	uint8_t ipv4_ttl_mask;
+	uint8_t ipv4_tos_mask;
+	uint8_t ipv4_ttl;
+	uint8_t ipv4_tos;
+	rte_be16_t reserved;
+};
+
+/*
  * IPv6 addr
  *    3                   2                   1
  *  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
@@ -433,6 +452,31 @@ struct nfp_fl_act_set_ipv6_addr {
 };
 
 /*
+ * ipv6 tc hl fl
+ *    3                   2                   1
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   -   |opcode |       |jump_id|  tclass_mask  |  hlimit_mask  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |               0               |  tclass       |  hlimit       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           0           |             flabel_mask               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           0           |             flabel                    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_set_ipv6_tc_hl_fl {
+	struct nfp_fl_act_head head;
+	uint8_t ipv6_tc_mask;
+	uint8_t ipv6_hop_limit_mask;
+	rte_be16_t reserved;
+	uint8_t ipv6_tc;
+	uint8_t ipv6_hop_limit;
+	rte_be32_t ipv6_label_mask;
+	rte_be32_t ipv6_label;
+};
+
+/*
  * TCP/UDP/SCTP
  *    3                   2                   1
  *  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
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 666dd8c..a4c14d3 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -561,9 +561,11 @@ struct nfp_mask_id_entry {
 		struct nfp_fl_key_ls *key_ls)
 {
 	int ret = 0;
+	bool tc_hl_flag = false;
 	bool mac_set_flag = false;
 	bool ip_set_flag = false;
 	bool tp_set_flag = false;
+	bool ttl_tos_flag = false;
 	const struct rte_flow_action *action;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -654,6 +656,22 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TTL:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TTL detected");
+			if (key_ls->key_layer & NFP_FLOWER_LAYER_IPV4) {
+				if (!ttl_tos_flag) {
+					key_ls->act_size +=
+						sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+					ttl_tos_flag = true;
+				}
+			} else {
+				if (!tc_hl_flag) {
+					key_ls->act_size +=
+						sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+					tc_hl_flag = true;
+				}
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1431,6 +1449,52 @@ struct nfp_mask_id_entry {
 	return 0;
 }
 
+static void
+nfp_flow_action_set_ttl(char *act_data,
+		const struct rte_flow_action *action,
+		bool ttl_tos_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_ttl_tos *ttl_tos;
+	const struct rte_flow_action_set_ttl *ttl_conf;
+
+	if (ttl_tos_flag)
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data - 1;
+	else
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+	ttl_tos->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS;
+	ttl_tos->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	ttl_conf = (const struct rte_flow_action_set_ttl *)action->conf;
+	ttl_tos->ipv4_ttl = ttl_conf->ttl_value;
+	ttl_tos->reserved = 0;
+}
+
+static void
+nfp_flow_action_set_hl(char *act_data,
+		const struct rte_flow_action *action,
+		bool tc_hl_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_tc_hl_fl *tc_hl;
+	const struct rte_flow_action_set_ttl *ttl_conf;
+
+	if (tc_hl_flag)
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data - 1;
+	else
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+	tc_hl->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL;
+	tc_hl->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	ttl_conf = (const struct rte_flow_action_set_ttl *)action->conf;
+	tc_hl->ipv6_hop_limit = ttl_conf->ttl_value;
+	tc_hl->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1439,17 +1503,21 @@ struct nfp_mask_id_entry {
 	int ret = 0;
 	char *position;
 	char *action_data;
+	bool ttl_tos_flag = false;
+	bool tc_hl_flag = false;
 	bool drop_flag = false;
 	bool ip_set_flag = false;
 	bool tp_set_flag = false;
 	bool mac_set_flag = false;
 	uint32_t total_actions = 0;
 	const struct rte_flow_action *action;
+	struct nfp_flower_meta_tci *meta_tci;
 	struct nfp_fl_rule_metadata *nfp_flow_meta;
 
 	nfp_flow_meta = nfp_flow->payload.meta;
 	action_data   = nfp_flow->payload.action_data;
 	position      = action_data;
+	meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
 		switch (action->type) {
@@ -1553,6 +1621,22 @@ struct nfp_mask_id_entry {
 				tp_set_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_TTL:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_TTL");
+			if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) {
+				nfp_flow_action_set_ttl(position, action, ttl_tos_flag);
+				if (!ttl_tos_flag) {
+					position += sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+					ttl_tos_flag = true;
+				}
+			} else {
+				nfp_flow_action_set_hl(position, action, ttl_tos_flag);
+				if (!tc_hl_flag) {
+					position += sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+					tc_hl_flag = true;
+				}
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 26/27] net/nfp: support IPv4 DSCP flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (24 preceding siblings ...)
  2022-10-21  8:02     ` [PATCH v6 25/27] net/nfp: support TTL " Chaoyong He
@ 2022-10-21  8:02     ` Chaoyong He
  2022-10-21  8:02     ` [PATCH v6 27/27] net/nfp: support IPv6 " Chaoyong He
  2022-10-21 13:04     ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Ferruh Yigit
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:02 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set IPv4 DSCP action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 1283583..596589f 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -44,6 +44,7 @@ of_push_vlan         = Y
 of_set_vlan_pcp      = Y
 of_set_vlan_vid      = Y
 port_id              = Y
+set_ipv4_dscp        = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
 set_ipv6_dst         = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index a4c14d3..c2f598c 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -672,6 +672,14 @@ struct nfp_mask_id_entry {
 				}
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP detected");
+			if (!ttl_tos_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+				ttl_tos_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1495,6 +1503,29 @@ struct nfp_mask_id_entry {
 	tc_hl->reserved = 0;
 }
 
+static void
+nfp_flow_action_set_tos(char *act_data,
+		const struct rte_flow_action *action,
+		bool ttl_tos_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ip4_ttl_tos *ttl_tos;
+	const struct rte_flow_action_set_dscp *tos_conf;
+
+	if (ttl_tos_flag)
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data - 1;
+	else
+		ttl_tos = (struct nfp_fl_act_set_ip4_ttl_tos *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+	ttl_tos->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS;
+	ttl_tos->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	tos_conf = (const struct rte_flow_action_set_dscp *)action->conf;
+	ttl_tos->ipv4_tos = tos_conf->dscp;
+	ttl_tos->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1637,6 +1668,14 @@ struct nfp_mask_id_entry {
 				}
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP");
+			nfp_flow_action_set_tos(position, action, ttl_tos_flag);
+			if (!ttl_tos_flag) {
+				position += sizeof(struct nfp_fl_act_set_ip4_ttl_tos);
+				ttl_tos_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* [PATCH v6 27/27] net/nfp: support IPv6 DSCP flow action
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (25 preceding siblings ...)
  2022-10-21  8:02     ` [PATCH v6 26/27] net/nfp: support IPv4 DSCP " Chaoyong He
@ 2022-10-21  8:02     ` Chaoyong He
  2022-10-21 13:04     ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Ferruh Yigit
  27 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-21  8:02 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

Add the corresponding logics to support the offload of
set IPv6 DSCP action.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  1 +
 drivers/net/nfp/nfp_flow.c       | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 596589f..0184980 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -47,6 +47,7 @@ port_id              = Y
 set_ipv4_dscp        = Y
 set_ipv4_dst         = Y
 set_ipv4_src         = Y
+set_ipv6_dscp        = Y
 set_ipv6_dst         = Y
 set_ipv6_src         = Y
 set_mac_dst          = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index c2f598c..69fc8be 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -680,6 +680,14 @@ struct nfp_mask_id_entry {
 				ttl_tos_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP detected");
+			if (!tc_hl_flag) {
+				key_ls->act_size +=
+					sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+				tc_hl_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
 			return -ENOTSUP;
@@ -1526,6 +1534,29 @@ struct nfp_mask_id_entry {
 	ttl_tos->reserved = 0;
 }
 
+static void
+nfp_flow_action_set_tc(char *act_data,
+		const struct rte_flow_action *action,
+		bool tc_hl_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_set_ipv6_tc_hl_fl *tc_hl;
+	const struct rte_flow_action_set_dscp *tos_conf;
+
+	if (tc_hl_flag)
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data - 1;
+	else
+		tc_hl = (struct nfp_fl_act_set_ipv6_tc_hl_fl *)act_data;
+
+	act_size = sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+	tc_hl->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL;
+	tc_hl->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+
+	tos_conf = (const struct rte_flow_action_set_dscp *)action->conf;
+	tc_hl->ipv6_tc = tos_conf->dscp;
+	tc_hl->reserved = 0;
+}
+
 static int
 nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
 		const struct rte_flow_action actions[],
@@ -1676,6 +1707,14 @@ struct nfp_mask_id_entry {
 				ttl_tos_flag = true;
 			}
 			break;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+			PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP");
+			nfp_flow_action_set_tc(position, action, ttl_tos_flag);
+			if (!tc_hl_flag) {
+				position += sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl);
+				tc_hl_flag = true;
+			}
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
 			return -ENOTSUP;
-- 
1.8.3.1


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

* Re: [PATCH v6 02/27] net/nfp: fix the promiscuous mode control functions
  2022-10-21  8:01     ` [PATCH v6 02/27] net/nfp: fix the promiscuous mode control functions Chaoyong He
@ 2022-10-21 13:03       ` Ferruh Yigit
  2022-10-22  6:49         ` Chaoyong He
  2022-10-22  8:11       ` [PATCH v7] net/nfp: fix the promiscuous mode functions Chaoyong He
  1 sibling, 1 reply; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-21 13:03 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers, niklas.soderlund

On 10/21/2022 9:01 AM, Chaoyong He wrote:
> The original functions of promiscuous mode can't process the
> representor port rightly, revise the logic to do that.
> 
> Fixes: e1124c4f8a45 ("net/nfp: add flower representor framework")
> 
> Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> ---
>   drivers/net/nfp/flower/nfp_flower_representor.c | 26 +++++++++++++++++++++++--
>   1 file changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
> index 0e60f50..cecdf46 100644
> --- a/drivers/net/nfp/flower/nfp_flower_representor.c
> +++ b/drivers/net/nfp/flower/nfp_flower_representor.c
> @@ -415,6 +415,9 @@
>   static int
>   nfp_flower_repr_promiscuous_enable(struct rte_eth_dev *dev)
>   {
> +	int ret;
> +	uint32_t update;
> +	uint32_t new_ctrl;
>   	struct nfp_net_hw *pf_hw;
>   	struct nfp_flower_representor *repr;
>   
> @@ -431,12 +434,23 @@
>   		return 0;
>   	}
>   
> -	return nfp_net_promisc_enable(pf_hw->eth_dev);
> +	new_ctrl = pf_hw->ctrl | NFP_NET_CFG_CTRL_PROMISC;
> +	update = NFP_NET_CFG_UPDATE_GEN;
> +	ret = nfp_net_reconfig(pf_hw, new_ctrl, update);
> +	if (ret < 0)
> +		return ret;
> +
> +	pf_hw->ctrl = new_ctrl;
> +

With this change 'nfp_net_promisc_enable()' seems not used at all in the 
driver.

And the difference between above code and 'nfp_net_promisc_enable()' is 
that capability check is removed, so it looks like hack for flower, 
instead why not fix the issue in the 'nfp_net_promisc_enable()'?

Same comment for 'nfp_net_promisc_disable()'.

> +	return 0;
>   }
>   
>   static int
>   nfp_flower_repr_promiscuous_disable(struct rte_eth_dev *dev)
>   {
> +	int ret;
> +	uint32_t update;
> +	uint32_t new_ctrl;
>   	struct nfp_net_hw *pf_hw;
>   	struct nfp_flower_representor *repr;
>   
> @@ -448,7 +462,15 @@
>   		return 0;
>   	}
>   
> -	return nfp_net_promisc_disable(pf_hw->eth_dev);
> +	new_ctrl = pf_hw->ctrl & ~NFP_NET_CFG_CTRL_PROMISC;
> +	update = NFP_NET_CFG_UPDATE_GEN;
> +	ret = nfp_net_reconfig(pf_hw, new_ctrl, update);
> +	if (ret < 0)
> +		return ret;
> +
> +	pf_hw->ctrl = new_ctrl;
> +
> +	return 0;
>   }
>   
>   static int


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

* Re: [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD
  2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
                       ` (26 preceding siblings ...)
  2022-10-21  8:02     ` [PATCH v6 27/27] net/nfp: support IPv6 " Chaoyong He
@ 2022-10-21 13:04     ` Ferruh Yigit
  27 siblings, 0 replies; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-21 13:04 UTC (permalink / raw)
  To: Chaoyong He, dev; +Cc: oss-drivers, niklas.soderlund

On 10/21/2022 9:01 AM, Chaoyong He wrote:
> This is the second patch series to add the support of rte_flow offload for
> nfp PMD, includes:
> Implement the rte_flow related API
> Implement the offload framework of nfp card
> Add the offload support of common rte_flow pattern items
> Add the offload support of common rte_flow actions
> 
> * Changes since v5
> - Fix two problems import by the first patch series.
> - Use RTE_BIT32 for bit.
> - Modify the release note.
> - Remove the incompletement logic about 'MARK' and 'RSS'.
> 
> * Changes since v4
> - Store the hash_key to avoid the uncessary repeat calculation.
> - Make sure '.validate' don't update 'flower_version'.
> - Guarante 'query' is zeroed out.
> - Use the 'rest' field of query action to decide if reset the stats.
> - Modify the 'nfp.ini' document.
> 
> * Changes since v3
> - Change the release note.
> - Change the headline of commit message.
> - Adjust the order of commits to prevent the memory problem.
> 
> * Changes since v2
> - Fix one problem import by the first patch series
> 
> * Changes since v1
> - Add the 'Depends-on' tag
> 
> Chaoyong He (27):
>    net/nfp: fix CPP bridge service requirement
>    net/nfp: fix the promiscuous mode control functions
>    net/nfp: fix the service stuck the app end
>    net/nfp: add the structures and functions for flow offload
>    net/nfp: add the stats process logic in ctrl VNIC service
>    net/nfp: add the flow APIs of nfp PMD
>    net/nfp: support basic flow items
>    net/nfp: support basic flow actions
>    net/nfp: support VLAN flow item
>    net/nfp: support IPv4 flow item
>    net/nfp: support IPv6 flow item
>    net/nfp: support TCP flow item
>    net/nfp: support UDP flow item
>    net/nfp: support SCTP flow item
>    net/nfp: support SRC MAC flow action
>    net/nfp: support DST MAC flow action
>    net/nfp: support pop VLAN flow action
>    net/nfp: support push VLAN flow action
>    net/nfp: support SRC IPv4 flow action
>    net/nfp: support DST IPv4 flow action
>    net/nfp: support SRC IPv6 flow action
>    net/nfp: support DST IPv6 flow action
>    net/nfp: support TP SRC flow action
>    net/nfp: support TP DST flow action
>    net/nfp: support TTL flow action
>    net/nfp: support IPv4 DSCP flow action
>    net/nfp: support IPv6 DSCP flow action


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

Patch 2/27 is independent fix and it can continue separately.


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

* RE: [PATCH v6 02/27] net/nfp: fix the promiscuous mode control functions
  2022-10-21 13:03       ` Ferruh Yigit
@ 2022-10-22  6:49         ` Chaoyong He
  0 siblings, 0 replies; 96+ messages in thread
From: Chaoyong He @ 2022-10-22  6:49 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: oss-drivers, Niklas Soderlund

> On 10/21/2022 9:01 AM, Chaoyong He wrote:
> > The original functions of promiscuous mode can't process the
> > representor port rightly, revise the logic to do that.
> >
> > Fixes: e1124c4f8a45 ("net/nfp: add flower representor framework")
> >
> > Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
> > ---
> >   drivers/net/nfp/flower/nfp_flower_representor.c | 26
> +++++++++++++++++++++++--
> >   1 file changed, 24 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c
> > b/drivers/net/nfp/flower/nfp_flower_representor.c
> > index 0e60f50..cecdf46 100644
> > --- a/drivers/net/nfp/flower/nfp_flower_representor.c
> > +++ b/drivers/net/nfp/flower/nfp_flower_representor.c
> > @@ -415,6 +415,9 @@
> >   static int
> >   nfp_flower_repr_promiscuous_enable(struct rte_eth_dev *dev)
> >   {
> > +	int ret;
> > +	uint32_t update;
> > +	uint32_t new_ctrl;
> >   	struct nfp_net_hw *pf_hw;
> >   	struct nfp_flower_representor *repr;
> >
> > @@ -431,12 +434,23 @@
> >   		return 0;
> >   	}
> >
> > -	return nfp_net_promisc_enable(pf_hw->eth_dev);
> > +	new_ctrl = pf_hw->ctrl | NFP_NET_CFG_CTRL_PROMISC;
> > +	update = NFP_NET_CFG_UPDATE_GEN;
> > +	ret = nfp_net_reconfig(pf_hw, new_ctrl, update);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	pf_hw->ctrl = new_ctrl;
> > +
> 
> With this change 'nfp_net_promisc_enable()' seems not used at all in the
> driver.
> 
Actually, 'nfp_net_promisc_enable()' is still be used by the VF and when the NIC
using CoreNIC firmware app.
In the `static const struct eth_dev_ops nfp_netvf_eth_dev_ops[]` of file 'nfp_ethdev_vf.c'
and `static const struct eth_dev_ops nfp_net_eth_dev_ops[]` of file 'nfp_ethdev.c'.

> And the difference between above code and 'nfp_net_promisc_enable()' is
> that capability check is removed, so it looks like hack for flower, instead why
> not fix the issue in the 'nfp_net_promisc_enable()'?
> 
> Same comment for 'nfp_net_promisc_disable()'.
> 
Yes, it's a good idea to fix this issue in the 'nfp_ent_promisc_enable()' and 'nfp_net_promisc_disable()'.
I will send a v7 patch for this one, thanks.

> > +	return 0;
> >   }
> >
> >   static int
> >   nfp_flower_repr_promiscuous_disable(struct rte_eth_dev *dev)
> >   {
> > +	int ret;
> > +	uint32_t update;
> > +	uint32_t new_ctrl;
> >   	struct nfp_net_hw *pf_hw;
> >   	struct nfp_flower_representor *repr;
> >
> > @@ -448,7 +462,15 @@
> >   		return 0;
> >   	}
> >
> > -	return nfp_net_promisc_disable(pf_hw->eth_dev);
> > +	new_ctrl = pf_hw->ctrl & ~NFP_NET_CFG_CTRL_PROMISC;
> > +	update = NFP_NET_CFG_UPDATE_GEN;
> > +	ret = nfp_net_reconfig(pf_hw, new_ctrl, update);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	pf_hw->ctrl = new_ctrl;
> > +
> > +	return 0;
> >   }
> >
> >   static int


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

* [PATCH v7] net/nfp: fix the promiscuous mode functions
  2022-10-21  8:01     ` [PATCH v6 02/27] net/nfp: fix the promiscuous mode control functions Chaoyong He
  2022-10-21 13:03       ` Ferruh Yigit
@ 2022-10-22  8:11       ` Chaoyong He
  2022-10-24 12:31         ` Ferruh Yigit
  1 sibling, 1 reply; 96+ messages in thread
From: Chaoyong He @ 2022-10-22  8:11 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He

The original functions of promiscuous mode can't process the
representor port rightly, revise the logic to do that.

Fixes: e1124c4f8a45 ("net/nfp: add flower representor framework")

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower.h             |  2 ++
 drivers/net/nfp/flower/nfp_flower_representor.c | 47 +++----------------------
 drivers/net/nfp/flower/nfp_flower_representor.h |  2 ++
 drivers/net/nfp/nfp_common.c                    | 10 +++++-
 4 files changed, 17 insertions(+), 44 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index 12a0fb5..f199741 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -6,6 +6,8 @@
 #ifndef _NFP_FLOWER_H_
 #define _NFP_FLOWER_H_
 
+#include "../nfp_common.h"
+
 /*
  * Flower fallback and ctrl path always adds and removes
  * 8 bytes of prepended data. Tx descriptors must point
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index f1cd298..5809c83 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -414,45 +414,6 @@
 }
 
 static int
-nfp_flower_repr_promiscuous_enable(struct rte_eth_dev *dev)
-{
-	struct nfp_net_hw *pf_hw;
-	struct nfp_flower_representor *repr;
-
-	repr = (struct nfp_flower_representor *)dev->data->dev_private;
-	pf_hw = repr->app_fw_flower->pf_hw;
-
-	if (!(pf_hw->cap & NFP_NET_CFG_CTRL_PROMISC)) {
-		PMD_DRV_LOG(INFO, "Promiscuous mode not supported");
-		return -ENOTSUP;
-	}
-
-	if (pf_hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) {
-		PMD_DRV_LOG(INFO, "Promiscuous mode already enabled");
-		return 0;
-	}
-
-	return nfp_net_promisc_enable(pf_hw->eth_dev);
-}
-
-static int
-nfp_flower_repr_promiscuous_disable(struct rte_eth_dev *dev)
-{
-	struct nfp_net_hw *pf_hw;
-	struct nfp_flower_representor *repr;
-
-	repr = (struct nfp_flower_representor *)dev->data->dev_private;
-	pf_hw = repr->app_fw_flower->pf_hw;
-
-	if ((pf_hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) == 0) {
-		PMD_DRV_LOG(INFO, "Promiscuous mode already disabled");
-		return 0;
-	}
-
-	return nfp_net_promisc_disable(pf_hw->eth_dev);
-}
-
-static int
 nfp_flower_repr_mac_addr_set(struct rte_eth_dev *ethdev,
 		struct rte_ether_addr *mac_addr)
 {
@@ -566,8 +527,8 @@
 	.stats_get            = nfp_flower_repr_stats_get,
 	.stats_reset          = nfp_flower_repr_stats_reset,
 
-	.promiscuous_enable   = nfp_flower_repr_promiscuous_enable,
-	.promiscuous_disable  = nfp_flower_repr_promiscuous_disable,
+	.promiscuous_enable   = nfp_net_promisc_enable,
+	.promiscuous_disable  = nfp_net_promisc_enable,
 
 	.mac_addr_set         = nfp_flower_repr_mac_addr_set,
 };
@@ -587,8 +548,8 @@
 	.stats_get            = nfp_flower_repr_stats_get,
 	.stats_reset          = nfp_flower_repr_stats_reset,
 
-	.promiscuous_enable   = nfp_flower_repr_promiscuous_enable,
-	.promiscuous_disable  = nfp_flower_repr_promiscuous_disable,
+	.promiscuous_enable   = nfp_net_promisc_enable,
+	.promiscuous_disable  = nfp_net_promisc_enable,
 
 	.mac_addr_set         = nfp_flower_repr_mac_addr_set,
 
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.h b/drivers/net/nfp/flower/nfp_flower_representor.h
index af44ef3..685cbe4 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.h
+++ b/drivers/net/nfp/flower/nfp_flower_representor.h
@@ -6,6 +6,8 @@
 #ifndef _NFP_FLOWER_REPRESENTOR_H_
 #define _NFP_FLOWER_REPRESENTOR_H_
 
+#include "nfp_flower.h"
+
 /*
  * enum nfp_repr_type - type of representor
  * @NFP_REPR_TYPE_PHYS_PORT:   external NIC port
diff --git a/drivers/net/nfp/nfp_common.c b/drivers/net/nfp/nfp_common.c
index 277ea23..463eb64 100644
--- a/drivers/net/nfp/nfp_common.c
+++ b/drivers/net/nfp/nfp_common.c
@@ -37,6 +37,8 @@
 #include "nfpcore/nfp_rtsym.h"
 #include "nfpcore/nfp_nsp.h"
 
+#include "flower/nfp_flower_representor.h"
+
 #include "nfp_common.h"
 #include "nfp_ctrl.h"
 #include "nfp_rxtx.h"
@@ -412,10 +414,16 @@
 	uint32_t new_ctrl, update = 0;
 	struct nfp_net_hw *hw;
 	int ret;
+	struct nfp_flower_representor *repr;
 
 	PMD_DRV_LOG(DEBUG, "Promiscuous mode enable");
 
-	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {
+		repr = dev->data->dev_private;
+		hw = repr->app_fw_flower->pf_hw;
+	} else {
+		hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	}
 
 	if (!(hw->cap & NFP_NET_CFG_CTRL_PROMISC)) {
 		PMD_INIT_LOG(INFO, "Promiscuous mode not supported");
-- 
1.8.3.1


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

* Re: [PATCH v7] net/nfp: fix the promiscuous mode functions
  2022-10-22  8:11       ` [PATCH v7] net/nfp: fix the promiscuous mode functions Chaoyong He
@ 2022-10-24 12:31         ` Ferruh Yigit
  0 siblings, 0 replies; 96+ messages in thread
From: Ferruh Yigit @ 2022-10-24 12:31 UTC (permalink / raw)
  To: Chaoyong He; +Cc: oss-drivers, niklas.soderlund, dev

On 10/22/2022 9:11 AM, Chaoyong He wrote:
> The original functions of promiscuous mode can't process the
> representor port rightly, revise the logic to do that.
> 
> Fixes: e1124c4f8a45 ("net/nfp: add flower representor framework")
> 
> Signed-off-by: Chaoyong He<chaoyong.he@corigine.com>

Applied to dpdk-next-net/main, thanks.

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

end of thread, other threads:[~2022-10-24 12:31 UTC | newest]

Thread overview: 96+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-18 11:26 [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Chaoyong He
2022-10-18 11:26 ` [PATCH v4 01/25] net/nfp: fix the requirement of cpp bridge service Chaoyong He
2022-10-18 12:39   ` Ferruh Yigit
2022-10-18 11:26 ` [PATCH v4 02/25] net/nfp: add the structures and functions for flow offload Chaoyong He
2022-10-18 11:26 ` [PATCH v4 03/25] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
2022-10-18 11:26 ` [PATCH v4 04/25] net/nfp: add the flow APIs of nfp PMD Chaoyong He
2022-10-18 11:26 ` [PATCH v4 05/25] net/nfp: support basic flow items Chaoyong He
2022-10-18 11:26 ` [PATCH v4 06/25] net/nfp: support basic flow actions Chaoyong He
2022-10-18 11:26 ` [PATCH v4 07/25] net/nfp: support VLAN flow item Chaoyong He
2022-10-18 11:26 ` [PATCH v4 08/25] net/nfp: support IPv4 " Chaoyong He
2022-10-18 11:26 ` [PATCH v4 09/25] net/nfp: support IPv6 " Chaoyong He
2022-10-18 11:26 ` [PATCH v4 10/25] net/nfp: support TCP " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 11/25] net/nfp: support UDP " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 12/25] net/nfp: support SCTP " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 13/25] net/nfp: support SRC MAC flow action Chaoyong He
2022-10-18 11:27 ` [PATCH v4 14/25] net/nfp: support DST " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 15/25] net/nfp: support pop VLAN " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 16/25] net/nfp: support push " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 17/25] net/nfp: support SRC IPv4 " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 18/25] net/nfp: support DST " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 19/25] net/nfp: support SRC IPv6 " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 20/25] net/nfp: support DST " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 21/25] net/nfp: support TP SRC " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 22/25] net/nfp: support TP DST " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 23/25] net/nfp: support TTL " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 24/25] net/nfp: support IPv4 DSCP " Chaoyong He
2022-10-18 11:27 ` [PATCH v4 25/25] net/nfp: support IPv6 " Chaoyong He
2022-10-18 12:27 ` [PATCH v4 00/25] add the basic rte_flow offload support of nfp PMD Ferruh Yigit
2022-10-20  2:19 ` [PATCH v5 " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 01/25] net/nfp: fix CPP bridge service requirement Chaoyong He
2022-10-20  2:19   ` [PATCH v5 02/25] net/nfp: add the structures and functions for flow offload Chaoyong He
2022-10-20  2:19   ` [PATCH v5 03/25] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
2022-10-20  2:19   ` [PATCH v5 04/25] net/nfp: add the flow APIs of nfp PMD Chaoyong He
2022-10-20 11:09     ` Ferruh Yigit
2022-10-20 11:42       ` Chaoyong He
2022-10-20  2:19   ` [PATCH v5 05/25] net/nfp: support basic flow items Chaoyong He
2022-10-20 11:11     ` Ferruh Yigit
2022-10-20 11:43       ` Chaoyong He
2022-10-20  2:19   ` [PATCH v5 06/25] net/nfp: support basic flow actions Chaoyong He
2022-10-20 11:12     ` Ferruh Yigit
2022-10-20 11:41       ` Chaoyong He
2022-10-20  2:19   ` [PATCH v5 07/25] net/nfp: support VLAN flow item Chaoyong He
2022-10-20  2:19   ` [PATCH v5 08/25] net/nfp: support IPv4 " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 09/25] net/nfp: support IPv6 " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 10/25] net/nfp: support TCP " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 11/25] net/nfp: support UDP " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 12/25] net/nfp: support SCTP " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 13/25] net/nfp: support SRC MAC flow action Chaoyong He
2022-10-20 11:12     ` Ferruh Yigit
2022-10-20 11:48       ` Chaoyong He
2022-10-20 11:55         ` Ferruh Yigit
2022-10-20  2:19   ` [PATCH v5 14/25] net/nfp: support DST " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 15/25] net/nfp: support pop VLAN " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 16/25] net/nfp: support push " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 17/25] net/nfp: support SRC IPv4 " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 18/25] net/nfp: support DST " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 19/25] net/nfp: support SRC IPv6 " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 20/25] net/nfp: support DST " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 21/25] net/nfp: support TP SRC " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 22/25] net/nfp: support TP DST " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 23/25] net/nfp: support TTL " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 24/25] net/nfp: support IPv4 DSCP " Chaoyong He
2022-10-20  2:19   ` [PATCH v5 25/25] net/nfp: support IPv6 " Chaoyong He
2022-10-21  8:01   ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD Chaoyong He
2022-10-21  8:01     ` [PATCH v6 01/27] net/nfp: fix CPP bridge service requirement Chaoyong He
2022-10-21  8:01     ` [PATCH v6 02/27] net/nfp: fix the promiscuous mode control functions Chaoyong He
2022-10-21 13:03       ` Ferruh Yigit
2022-10-22  6:49         ` Chaoyong He
2022-10-22  8:11       ` [PATCH v7] net/nfp: fix the promiscuous mode functions Chaoyong He
2022-10-24 12:31         ` Ferruh Yigit
2022-10-21  8:01     ` [PATCH v6 03/27] net/nfp: fix the service stuck the app end Chaoyong He
2022-10-21  8:01     ` [PATCH v6 04/27] net/nfp: add the structures and functions for flow offload Chaoyong He
2022-10-21  8:01     ` [PATCH v6 05/27] net/nfp: add the stats process logic in ctrl VNIC service Chaoyong He
2022-10-21  8:01     ` [PATCH v6 06/27] net/nfp: add the flow APIs of nfp PMD Chaoyong He
2022-10-21  8:01     ` [PATCH v6 07/27] net/nfp: support basic flow items Chaoyong He
2022-10-21  8:01     ` [PATCH v6 08/27] net/nfp: support basic flow actions Chaoyong He
2022-10-21  8:01     ` [PATCH v6 09/27] net/nfp: support VLAN flow item Chaoyong He
2022-10-21  8:01     ` [PATCH v6 10/27] net/nfp: support IPv4 " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 11/27] net/nfp: support IPv6 " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 12/27] net/nfp: support TCP " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 13/27] net/nfp: support UDP " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 14/27] net/nfp: support SCTP " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 15/27] net/nfp: support SRC MAC flow action Chaoyong He
2022-10-21  8:01     ` [PATCH v6 16/27] net/nfp: support DST " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 17/27] net/nfp: support pop VLAN " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 18/27] net/nfp: support push " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 19/27] net/nfp: support SRC IPv4 " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 20/27] net/nfp: support DST " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 21/27] net/nfp: support SRC IPv6 " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 22/27] net/nfp: support DST " Chaoyong He
2022-10-21  8:01     ` [PATCH v6 23/27] net/nfp: support TP SRC " Chaoyong He
2022-10-21  8:02     ` [PATCH v6 24/27] net/nfp: support TP DST " Chaoyong He
2022-10-21  8:02     ` [PATCH v6 25/27] net/nfp: support TTL " Chaoyong He
2022-10-21  8:02     ` [PATCH v6 26/27] net/nfp: support IPv4 DSCP " Chaoyong He
2022-10-21  8:02     ` [PATCH v6 27/27] net/nfp: support IPv6 " Chaoyong He
2022-10-21 13:04     ` [PATCH v6 00/27] add the basic rte_flow offload support of nfp PMD 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).