DPDK patches and discussions
 help / color / mirror / Atom feed
From: Chaoyong He <chaoyong.he@corigine.com>
To: dev@dpdk.org
Cc: oss-drivers@corigine.com, Long Wu <long.wu@corigine.com>,
	Chaoyong He <chaoyong.he@corigine.com>,
	Peng Zhang <peng.zhang@corigine.com>
Subject: [PATCH] net/nfp: add partial flow control message
Date: Wed, 19 Jun 2024 18:03:31 +0800	[thread overview]
Message-ID: <20240619100331.3479906-1-chaoyong.he@corigine.com> (raw)

From: Long Wu <long.wu@corigine.com>

With new firmware, NFP PMD will use partial flow control
message to notify firmware the configuration of mark&queue
action. Moreover, if partial flow control message contains
both queue&mark configuration, the whole flow control
message can only contain partial flow control message.

With old firmware, NFP PMD does not support queue action
and still use mark flow control message to notify
firmware the configuration of mark action.

NFP PMD will use the 'NFP_FL_FEATS_FLOW_PARTIAL' and flower
extra features to distinguish the firmware is new or old.

Signed-off-by: Long Wu <long.wu@corigine.com>
Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/flower/nfp_conntrack.c   |  42 +++---
 drivers/net/nfp/flower/nfp_conntrack.h   |   2 +-
 drivers/net/nfp/flower/nfp_flower.h      |   1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  24 ++++
 drivers/net/nfp/flower/nfp_flower_flow.c | 167 ++++++++++++++++++++---
 drivers/net/nfp/flower/nfp_flower_flow.h |   2 +-
 6 files changed, 202 insertions(+), 36 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_conntrack.c b/drivers/net/nfp/flower/nfp_conntrack.c
index b0641b03d2..eff52c66ee 100644
--- a/drivers/net/nfp/flower/nfp_conntrack.c
+++ b/drivers/net/nfp/flower/nfp_conntrack.c
@@ -36,7 +36,7 @@ struct nfp_ct_flow_entry {
 	LIST_ENTRY(nfp_ct_flow_entry) post_ct_list;
 	LIST_HEAD(, nfp_ct_merge_entry) children;
 	enum ct_entry_type type;
-	struct nfp_flower_representor *repr;
+	struct rte_eth_dev *dev;
 	struct nfp_ct_zone_entry *ze;
 	struct nfp_initial_flow rule;
 	struct nfp_fl_stats stats;
@@ -660,7 +660,7 @@ nfp_ct_flow_actions_copy(const struct rte_flow_action *src,
 
 static struct nfp_ct_flow_entry *
 nfp_ct_flow_entry_get(struct nfp_ct_zone_entry *ze,
-		struct nfp_flower_representor *repr,
+		struct rte_eth_dev *dev,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
 		uint64_t cookie)
@@ -672,6 +672,7 @@ nfp_ct_flow_entry_get(struct nfp_ct_zone_entry *ze,
 	struct nfp_flow_priv *priv;
 	struct nfp_ct_map_entry *me;
 	struct nfp_ct_flow_entry *fe;
+	struct nfp_flower_representor *repr;
 
 	fe = rte_zmalloc("ct_flow_entry", sizeof(*fe), 0);
 	if (fe == NULL) {
@@ -680,7 +681,7 @@ nfp_ct_flow_entry_get(struct nfp_ct_zone_entry *ze,
 	}
 
 	fe->ze = ze;
-	fe->repr = repr;
+	fe->dev = dev;
 	fe->cookie = cookie;
 	LIST_INIT(&fe->children);
 
@@ -730,6 +731,7 @@ nfp_ct_flow_entry_get(struct nfp_ct_zone_entry *ze,
 	me->cookie = fe->cookie;
 	me->fe = fe;
 
+	repr = dev->data->dev_private;
 	priv = repr->app_fw_flower->flow_priv;
 	ret = nfp_ct_map_table_add(priv, me);
 	if (!ret) {
@@ -979,7 +981,7 @@ nfp_ct_zone_entry_free(struct nfp_ct_zone_entry *ze,
 }
 
 static int
-nfp_ct_offload_add(struct nfp_flower_representor *repr,
+nfp_ct_offload_add(struct rte_eth_dev *dev,
 		struct nfp_ct_merge_entry *merge_entry)
 {
 	int ret;
@@ -987,12 +989,13 @@ nfp_ct_offload_add(struct nfp_flower_representor *repr,
 	struct rte_flow *nfp_flow;
 	struct nfp_flow_priv *priv;
 	const struct rte_flow_item *items;
+	struct nfp_flower_representor *repr;
 	const struct rte_flow_action *actions;
 
 	cookie = rte_rand();
 	items = merge_entry->rule.items;
 	actions = merge_entry->rule.actions;
-	nfp_flow = nfp_flow_process(repr, items, actions, false, cookie, true, true);
+	nfp_flow = nfp_flow_process(dev, items, actions, false, cookie, true, true);
 	if (nfp_flow == NULL) {
 		PMD_DRV_LOG(ERR, "Process the merged flow rule failed.");
 		return -EINVAL;
@@ -1001,6 +1004,7 @@ nfp_ct_offload_add(struct nfp_flower_representor *repr,
 	merge_entry->ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id);
 
 	/* Add the flow to hardware */
+	repr = dev->data->dev_private;
 	priv = repr->app_fw_flower->flow_priv;
 	ret = nfp_flower_cmsg_flow_add(repr->app_fw_flower, nfp_flow);
 	if (ret != 0) {
@@ -1442,7 +1446,7 @@ nfp_ct_do_flow_merge(struct nfp_ct_zone_entry *ze,
 	uint8_t cnt_same_action = 0;
 	struct nfp_ct_merge_entry *merge_entry;
 
-	if (pre_ct_entry->repr != post_ct_entry->repr)
+	if (pre_ct_entry->dev != post_ct_entry->dev)
 		return true;
 
 	ret = nfp_ct_merge_items_check(pre_ct_entry->rule.items,
@@ -1504,7 +1508,7 @@ nfp_ct_do_flow_merge(struct nfp_ct_zone_entry *ze,
 	}
 
 	/* Send to firmware */
-	ret = nfp_ct_offload_add(pre_ct_entry->repr, merge_entry);
+	ret = nfp_ct_offload_add(pre_ct_entry->dev, merge_entry);
 	if (ret != 0) {
 		PMD_DRV_LOG(ERR, "Send the merged flow to firmware failed");
 		goto merge_table_del;
@@ -1557,7 +1561,7 @@ nfp_ct_merge_flow_entries(struct nfp_ct_flow_entry *fe,
 
 static bool
 nfp_flow_handle_pre_ct(const struct rte_flow_item *ct_item,
-		struct nfp_flower_representor *representor,
+		struct rte_eth_dev *dev,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
 		uint64_t cookie)
@@ -1567,7 +1571,9 @@ nfp_flow_handle_pre_ct(const struct rte_flow_item *ct_item,
 	struct nfp_ct_zone_entry *ze;
 	struct nfp_ct_flow_entry *fe;
 	const struct ct_data *ct = ct_item->spec;
+	struct nfp_flower_representor *representor;
 
+	representor = dev->data->dev_private;
 	priv = representor->app_fw_flower->flow_priv;
 	ze = nfp_ct_zone_entry_get(priv, ct->ct_zone, false);
 	if (ze == NULL) {
@@ -1576,7 +1582,7 @@ nfp_flow_handle_pre_ct(const struct rte_flow_item *ct_item,
 	}
 
 	/* Add entry to pre_ct_list */
-	fe = nfp_ct_flow_entry_get(ze, representor, items, actions, cookie);
+	fe = nfp_ct_flow_entry_get(ze, dev, items, actions, cookie);
 	if (fe == NULL) {
 		PMD_DRV_LOG(ERR, "Could not get ct flow entry");
 		goto ct_zone_entry_free;
@@ -1613,7 +1619,7 @@ nfp_flow_handle_pre_ct(const struct rte_flow_item *ct_item,
 
 static bool
 nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item,
-		struct nfp_flower_representor *representor,
+		struct rte_eth_dev *dev,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
 		uint64_t cookie)
@@ -1626,6 +1632,7 @@ nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item,
 	struct nfp_flow_priv *priv;
 	struct nfp_ct_zone_entry *ze;
 	struct nfp_ct_flow_entry *fe;
+	struct nfp_flower_representor *representor;
 	const struct ct_data *ct = ct_item->spec;
 	const struct ct_data *ct_mask = ct_item->mask;
 
@@ -1636,6 +1643,7 @@ nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item,
 		return false;
 	}
 
+	representor = dev->data->dev_private;
 	priv = representor->app_fw_flower->flow_priv;
 	ze = nfp_ct_zone_entry_get(priv, ct->ct_zone, wildcard);
 	if (ze == NULL) {
@@ -1644,7 +1652,7 @@ nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item,
 	}
 
 	/* Add entry to post_ct_list */
-	fe = nfp_ct_flow_entry_get(ze, representor, items, actions, cookie);
+	fe = nfp_ct_flow_entry_get(ze, dev, items, actions, cookie);
 	if (fe == NULL) {
 		PMD_DRV_LOG(ERR, "Could not get ct flow entry");
 		goto ct_zone_entry_free;
@@ -1681,7 +1689,7 @@ nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item,
 }
 
 struct rte_flow *
-nfp_ct_flow_setup(struct nfp_flower_representor *representor,
+nfp_ct_flow_setup(struct rte_eth_dev *dev,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
 		const struct rte_flow_item *ct_item,
@@ -1696,14 +1704,14 @@ nfp_ct_flow_setup(struct nfp_flower_representor *representor,
 	ct = ct_item->spec;
 
 	if (is_ct_commit_flow(ct)) {
-		return nfp_flow_process(representor, &items[1], actions,
+		return nfp_flow_process(dev, &items[1], actions,
 				validate_flag, cookie, false, false);
 	}
 
 	if (is_post_ct_flow(ct)) {
-		if (nfp_flow_handle_post_ct(ct_item, representor, &items[1],
+		if (nfp_flow_handle_post_ct(ct_item, dev, &items[1],
 				actions, cookie)) {
-			return nfp_flow_process(representor, &items[1], actions,
+			return nfp_flow_process(dev, &items[1], actions,
 					validate_flag, cookie, false, false);
 		}
 
@@ -1712,9 +1720,9 @@ nfp_ct_flow_setup(struct nfp_flower_representor *representor,
 	}
 
 	if (is_pre_ct_flow(ct, actions)) {
-		if (nfp_flow_handle_pre_ct(ct_item, representor, &items[1],
+		if (nfp_flow_handle_pre_ct(ct_item, dev, &items[1],
 				actions, cookie)) {
-			return nfp_flow_process(representor, &items[1], actions,
+			return nfp_flow_process(dev, &items[1], actions,
 					validate_flag, cookie, false, false);
 		}
 
diff --git a/drivers/net/nfp/flower/nfp_conntrack.h b/drivers/net/nfp/flower/nfp_conntrack.h
index 9bfca236ed..39d4e4b846 100644
--- a/drivers/net/nfp/flower/nfp_conntrack.h
+++ b/drivers/net/nfp/flower/nfp_conntrack.h
@@ -27,7 +27,7 @@ int nfp_ct_offload_del(struct rte_eth_dev *dev,
 		struct nfp_ct_map_entry *me,
 		struct rte_flow_error *error);
 
-struct rte_flow *nfp_ct_flow_setup(struct nfp_flower_representor *representor,
+struct rte_flow *nfp_ct_flow_setup(struct rte_eth_dev *dev,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
 		const struct rte_flow_item *ct_item,
diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index ae80782df4..b0d8fb0ed4 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -21,6 +21,7 @@
 #define NFP_FL_FEATS_QOS_PPS            RTE_BIT64(9)
 #define NFP_FL_FEATS_QOS_METER          RTE_BIT64(10)
 #define NFP_FL_FEATS_DECAP_V2           RTE_BIT64(11)
+#define NFP_FL_FEATS_FLOW_PARTIAL       RTE_BIT64(13)
 #define NFP_FL_FEATS_HOST_ACK           RTE_BIT64(31)
 
 /*
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 93183153aa..5d23227c24 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -976,6 +976,30 @@ struct nfp_fl_act_mark {
 	rte_be32_t mark;
 };
 
+/*
+ * Partial
+ *    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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | res |  opcode |  res  | len_lw|     flag       |     resv1    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                         Mark                                  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           queue_id            |              resv2            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * flag = 0x0: only mark action
+ * flag = 0x1: only queue action
+ * flag = 0x2: mark and queue action
+ */
+struct nfp_fl_act_partial {
+	struct nfp_fl_act_head head;
+	uint8_t flag;
+	uint8_t resv1;
+	rte_be32_t mark;
+	rte_be16_t queue_id;
+	rte_be16_t resv2;
+};
+
 int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower,
 		struct nfp_pf_dev *pf_dev);
 int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
diff --git a/drivers/net/nfp/flower/nfp_flower_flow.c b/drivers/net/nfp/flower/nfp_flower_flow.c
index 0fb63013d3..8aafbe4c86 100644
--- a/drivers/net/nfp/flower/nfp_flower_flow.c
+++ b/drivers/net/nfp/flower/nfp_flower_flow.c
@@ -83,7 +83,7 @@
 #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_SET_MARK           27
+#define NFP_FL_ACTION_OPCODE_SET_PARTIAL        27
 #define NFP_FL_ACTION_OPCODE_NUM                32
 
 #define NFP_FL_OUT_FLAGS_LAST            RTE_BIT32(15)
@@ -151,6 +151,12 @@ struct __rte_aligned(32) nfp_pre_tun_entry {
 	struct rte_ether_addr mac_addr;
 };
 
+static inline bool
+nfp_flow_support_partial(struct nfp_flower_representor *repr)
+{
+	return repr->app_fw_flower->ext_features & NFP_FL_FEATS_FLOW_PARTIAL;
+}
+
 static inline struct nfp_flow_priv *
 nfp_flow_dev_to_priv(struct rte_eth_dev *dev)
 {
@@ -1262,12 +1268,15 @@ struct nfp_action_flag {
 	bool tp_set_flag;
 	bool mac_set_flag;
 	bool ttl_tos_flag;
+	bool partial_flag;
+	bool partial_both_flag; /**< Both means Queue and Mark action */
 };
 
 struct nfp_action_calculate_param {
 	const struct rte_flow_action *action;
 	struct nfp_fl_key_ls *key_ls;
 	struct nfp_action_flag *flag;
+	struct rte_eth_dev *dev;
 };
 
 typedef int (*nfp_flow_key_check_action_fn)(struct nfp_action_calculate_param *param);
@@ -1473,21 +1482,46 @@ nfp_flow_action_check_modify(struct nfp_action_calculate_param *param)
 	return 0;
 }
 
+static int
+nfp_flow_action_check_queue(struct nfp_action_calculate_param *param)
+{
+	struct nfp_flower_representor *repr;
+	const struct rte_flow_action_queue *queue;
+
+	repr = param->dev->data->dev_private;
+	if (!nfp_flow_support_partial(repr)) {
+		PMD_DRV_LOG(ERR, "Queue action not supported");
+		return -ENOTSUP;
+	}
+
+	queue = param->action->conf;
+	if (queue->index >= param->dev->data->nb_rx_queues ||
+			param->dev->data->rx_queues[queue->index] == NULL) {
+		PMD_DRV_LOG(ERR, "Queue index is illegal");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static nfp_flow_key_check_action_fn check_action_fns[] = {
 	[RTE_FLOW_ACTION_TYPE_PORT_ID]          = nfp_flow_action_check_port,
 	[RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT] = nfp_flow_action_check_port,
 	[RTE_FLOW_ACTION_TYPE_METER]            = nfp_flow_action_check_meter,
 	[RTE_FLOW_ACTION_TYPE_MODIFY_FIELD]     = nfp_flow_action_check_modify,
+	[RTE_FLOW_ACTION_TYPE_QUEUE]            = nfp_flow_action_check_queue,
 };
 
 static int
-nfp_flow_key_layers_check_actions(const struct rte_flow_action actions[])
+nfp_flow_key_layers_check_actions(struct rte_eth_dev *dev,
+		const struct rte_flow_action actions[])
 {
 	int ret;
 	struct nfp_action_flag flag = {};
 	const struct rte_flow_action *action;
 	struct nfp_action_calculate_param param = {
 		.flag = &flag,
+		.dev = dev,
 	};
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -1616,7 +1650,33 @@ nfp_flow_action_calculate_meter(struct nfp_action_calculate_param *param)
 static void
 nfp_flow_action_calculate_mark(struct nfp_action_calculate_param *param)
 {
-	param->key_ls->act_size += sizeof(struct nfp_fl_act_mark);
+	struct nfp_flower_representor *repr;
+
+	repr = param->dev->data->dev_private;
+	if (!nfp_flow_support_partial(repr)) {
+		param->key_ls->act_size += sizeof(struct nfp_fl_act_mark);
+		return;
+	}
+
+	if (!param->flag->partial_flag) {
+		param->key_ls->act_size += sizeof(struct nfp_fl_act_partial);
+		param->flag->partial_flag = true;
+		return;
+	}
+
+	param->flag->partial_both_flag = true;
+}
+
+static void
+nfp_flow_action_calculate_queue(struct nfp_action_calculate_param *param)
+{
+	if (!param->flag->partial_flag) {
+		param->key_ls->act_size += sizeof(struct nfp_fl_act_partial);
+		param->flag->partial_flag = true;
+		return;
+	}
+
+	param->flag->partial_both_flag = true;
 }
 
 static void
@@ -1691,10 +1751,12 @@ static nfp_flow_key_calculate_action_fn action_fns[] = {
 	[RTE_FLOW_ACTION_TYPE_MARK]             = nfp_flow_action_calculate_mark,
 	[RTE_FLOW_ACTION_TYPE_RSS]              = nfp_flow_action_calculate_stub,
 	[RTE_FLOW_ACTION_TYPE_MODIFY_FIELD]     = nfp_flow_action_calculate_modify,
+	[RTE_FLOW_ACTION_TYPE_QUEUE]            = nfp_flow_action_calculate_queue,
 };
 
 static int
-nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
+nfp_flow_key_layers_calculate_actions(struct rte_eth_dev *dev,
+		const struct rte_flow_action actions[],
 		struct nfp_fl_key_ls *key_ls)
 {
 	struct nfp_action_flag flag = {};
@@ -1702,6 +1764,7 @@ nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
 	struct nfp_action_calculate_param param = {
 		.key_ls = key_ls,
 		.flag = &flag,
+		.dev = dev,
 	};
 
 	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
@@ -1720,11 +1783,18 @@ nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
 		action_fns[action->type](&param);
 	}
 
+	if (param.flag->partial_both_flag &&
+			key_ls->act_size != sizeof(struct nfp_fl_act_partial)) {
+		PMD_DRV_LOG(ERR, "Mark and Queue can not be offloaded with other actions");
+		return -ENOTSUP;
+	}
+
 	return 0;
 }
 
 static int
-nfp_flow_key_layers_calculate(const struct rte_flow_item items[],
+nfp_flow_key_layers_calculate(struct rte_eth_dev *dev,
+		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
 		struct nfp_fl_key_ls *key_ls)
 {
@@ -1751,13 +1821,13 @@ nfp_flow_key_layers_calculate(const struct rte_flow_item items[],
 		return ret;
 	}
 
-	ret = nfp_flow_key_layers_check_actions(actions);
+	ret = nfp_flow_key_layers_check_actions(dev, actions);
 	if (ret != 0) {
 		PMD_DRV_LOG(ERR, "flow actions check failed");
 		return ret;
 	}
 
-	ret = nfp_flow_key_layers_calculate_actions(actions, key_ls);
+	ret = nfp_flow_key_layers_calculate_actions(dev, actions, key_ls);
 	if (ret != 0) {
 		PMD_DRV_LOG(ERR, "flow actions check failed");
 		return ret;
@@ -4073,7 +4143,7 @@ nfp_flow_action_mark(char *act_data,
 	mark = action->conf;
 
 	fl_mark = (struct nfp_fl_act_mark *)act_data;
-	fl_mark->head.jump_id = NFP_FL_ACTION_OPCODE_SET_MARK;
+	fl_mark->head.jump_id = NFP_FL_ACTION_OPCODE_SET_PARTIAL;
 	fl_mark->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
 	fl_mark->reserved     = 0;
 	fl_mark->mark         = rte_cpu_to_be_32(mark->id);
@@ -4501,11 +4571,70 @@ nfp_flow_action_compile_meter(struct nfp_action_compile_param *param)
 	return 0;
 }
 
+static void
+nfp_flow_action_partial(const struct rte_flow_action *action,
+		char *act_data,
+		bool partial_flag)
+{
+	size_t act_size;
+	struct nfp_fl_act_partial *fl_partial;
+	const struct rte_flow_action_mark *mark;
+	const struct rte_flow_action_queue *queue;
+
+	if (partial_flag)
+		fl_partial = (struct nfp_fl_act_partial *)act_data - 1;
+	else
+		fl_partial = (struct nfp_fl_act_partial *)act_data;
+
+	if (action->type == RTE_FLOW_ACTION_TYPE_MARK) {
+		mark = action->conf;
+		fl_partial->mark = rte_cpu_to_be_32(mark->id);
+		fl_partial->flag = 0;
+	} else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
+		queue = action->conf;
+		fl_partial->queue_id = rte_cpu_to_be_16(queue->index);
+		fl_partial->flag = 1;
+	}
+
+	if (partial_flag) {
+		fl_partial->flag = 2;
+		return;
+	}
+
+	act_size = sizeof(struct nfp_fl_act_partial);
+	fl_partial->head.jump_id = NFP_FL_ACTION_OPCODE_SET_PARTIAL;
+	fl_partial->head.len_lw  = act_size >> NFP_FL_LW_SIZ;
+}
+
 static int
 nfp_flow_action_compile_mark(struct nfp_action_compile_param *param)
 {
-	nfp_flow_action_mark(param->position, param->action);
-	param->position += sizeof(struct nfp_fl_act_mark);
+	if (!nfp_flow_support_partial(param->repr)) {
+		nfp_flow_action_mark(param->position, param->action);
+		param->position += sizeof(struct nfp_fl_act_mark);
+
+		return 0;
+	}
+
+	nfp_flow_action_partial(param->action, param->position, param->flag->partial_flag);
+
+	if (!param->flag->partial_flag) {
+		param->flag->partial_flag = true;
+		param->position += sizeof(struct nfp_fl_act_partial);
+	}
+
+	return 0;
+}
+
+static int
+nfp_flow_action_compile_queue(struct nfp_action_compile_param *param)
+{
+	nfp_flow_action_partial(param->action, param->position, param->flag->partial_flag);
+
+	if (!param->flag->partial_flag) {
+		param->flag->partial_flag = true;
+		param->position += sizeof(struct nfp_fl_act_partial);
+	}
 
 	return 0;
 }
@@ -4631,6 +4760,7 @@ static nfp_flow_action_compile_fn action_compile_fns[] = {
 	[RTE_FLOW_ACTION_TYPE_MARK]             = nfp_flow_action_compile_mark,
 	[RTE_FLOW_ACTION_TYPE_RSS]              = nfp_flow_action_compile_rss,
 	[RTE_FLOW_ACTION_TYPE_MODIFY_FIELD]     = nfp_flow_action_compile_modify,
+	[RTE_FLOW_ACTION_TYPE_QUEUE]            = nfp_flow_action_compile_queue,
 };
 
 static int
@@ -4683,7 +4813,7 @@ nfp_flow_compile_action(struct nfp_flower_representor *representor,
 }
 
 struct rte_flow *
-nfp_flow_process(struct nfp_flower_representor *representor,
+nfp_flow_process(struct rte_eth_dev *dev,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
 		bool validate_flag,
@@ -4702,13 +4832,16 @@ nfp_flow_process(struct nfp_flower_representor *representor,
 	struct nfp_flow_priv *priv;
 	struct nfp_fl_key_ls key_layer;
 	struct nfp_fl_rule_metadata *nfp_flow_meta;
+	struct nfp_flower_representor *representor;
 
-	ret = nfp_flow_key_layers_calculate(items, actions, &key_layer);
+	ret = nfp_flow_key_layers_calculate(dev, items, actions, &key_layer);
 	if (ret != 0) {
 		PMD_DRV_LOG(ERR, "Key layers calculate failed.");
 		return NULL;
 	}
 
+	representor = dev->data->dev_private;
+
 	if (key_layer.port == (uint32_t)~0)
 		key_layer.port = representor->port_id;
 
@@ -4784,7 +4917,7 @@ nfp_flow_process(struct nfp_flower_representor *representor,
 }
 
 static struct rte_flow *
-nfp_flow_setup(struct nfp_flower_representor *representor,
+nfp_flow_setup(struct rte_eth_dev *dev,
 		const struct rte_flow_attr *attr,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
@@ -4813,10 +4946,10 @@ nfp_flow_setup(struct nfp_flower_representor *representor,
 	cookie = rte_rand();
 
 	if (ct_item != NULL)
-		return nfp_ct_flow_setup(representor, items, actions,
+		return nfp_ct_flow_setup(dev, items, actions,
 				ct_item, validate_flag, cookie);
 
-	return nfp_flow_process(representor, items, actions, validate_flag, cookie, true, false);
+	return nfp_flow_process(dev, items, actions, validate_flag, cookie, true, false);
 }
 
 int
@@ -4864,7 +4997,7 @@ nfp_flow_validate(struct rte_eth_dev *dev,
 
 	representor = dev->data->dev_private;
 
-	nfp_flow = nfp_flow_setup(representor, attr, items, actions, true);
+	nfp_flow = nfp_flow_setup(dev, attr, items, actions, true);
 	if (nfp_flow == NULL) {
 		return rte_flow_error_set(error, ENOTSUP,
 				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -4900,7 +5033,7 @@ nfp_flow_create(struct rte_eth_dev *dev,
 	app_fw_flower = representor->app_fw_flower;
 	priv = app_fw_flower->flow_priv;
 
-	nfp_flow = nfp_flow_setup(representor, attr, items, actions, false);
+	nfp_flow = nfp_flow_setup(dev, attr, items, actions, false);
 	if (nfp_flow == NULL) {
 		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				NULL, "This flow can not be offloaded.");
diff --git a/drivers/net/nfp/flower/nfp_flower_flow.h b/drivers/net/nfp/flower/nfp_flower_flow.h
index 5007438f67..f54ad6cf55 100644
--- a/drivers/net/nfp/flower/nfp_flower_flow.h
+++ b/drivers/net/nfp/flower/nfp_flower_flow.h
@@ -195,7 +195,7 @@ void nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev);
 int nfp_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops);
 bool nfp_flow_inner_item_get(const struct rte_flow_item items[],
 		const struct rte_flow_item **inner_item);
-struct rte_flow *nfp_flow_process(struct nfp_flower_representor *representor,
+struct rte_flow *nfp_flow_process(struct rte_eth_dev *dev,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
 		bool validate_flag,
-- 
2.39.1


             reply	other threads:[~2024-06-19 10:04 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-19 10:03 Chaoyong He [this message]
2024-07-07 22:42 ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240619100331.3479906-1-chaoyong.he@corigine.com \
    --to=chaoyong.he@corigine.com \
    --cc=dev@dpdk.org \
    --cc=long.wu@corigine.com \
    --cc=oss-drivers@corigine.com \
    --cc=peng.zhang@corigine.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).