[v4,80/86] net/ntnic: add async create/destroy API declaration

Message ID 20241029164243.1648775-81-sil-plv@napatech.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series Provide flow filter API and statistics |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Serhii Iliushyk Oct. 29, 2024, 4:42 p.m. UTC
From: Danylo Vodopianov <dvo-plv@napatech.com>

Fast path async create and destroy flow API implementation were added.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/flow_api_engine.h   |   8 ++
 drivers/net/ntnic/ntnic_ethdev.c              |   1 +
 drivers/net/ntnic/ntnic_filter/ntnic_filter.c | 105 ++++++++++++++++++
 drivers/net/ntnic/ntnic_mod_reg.c             |  15 +++
 drivers/net/ntnic/ntnic_mod_reg.h             |  18 +++
 5 files changed, 147 insertions(+)
  

Patch

diff --git a/drivers/net/ntnic/include/flow_api_engine.h b/drivers/net/ntnic/include/flow_api_engine.h
index b40a27fbf1..505fb8e501 100644
--- a/drivers/net/ntnic/include/flow_api_engine.h
+++ b/drivers/net/ntnic/include/flow_api_engine.h
@@ -343,6 +343,14 @@  struct flow_handle {
 	};
 };
 
+struct flow_pattern_template {
+};
+
+struct flow_actions_template {
+};
+struct flow_template_table {
+};
+
 void km_attach_ndev_resource_management(struct km_flow_def_s *km, void **handle);
 void km_free_ndev_resource_management(void **handle);
 
diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 068c3d932a..77436eb02d 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -1252,6 +1252,7 @@  eth_dev_start(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
+	eth_dev->flow_fp_ops = get_dev_fp_flow_ops();
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
 	const int n_intf_no = internals->n_intf_no;
diff --git a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
index 0e20606a41..d1f3ed4831 100644
--- a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
+++ b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
@@ -4,6 +4,11 @@ 
  */
 
 #include <rte_flow_driver.h>
+#include <rte_pci.h>
+#include <rte_version.h>
+#include <rte_flow.h>
+
+#include "ntlog.h"
 #include "nt_util.h"
 #include "create_elements.h"
 #include "ntnic_mod_reg.h"
@@ -881,6 +886,96 @@  static int eth_flow_configure(struct rte_eth_dev *dev, const struct rte_flow_por
 	return res;
 }
 
+static struct rte_flow *eth_flow_async_create(struct rte_eth_dev *dev, uint32_t queue_id,
+	const struct rte_flow_op_attr *op_attr,
+	struct rte_flow_template_table *template_table, const struct rte_flow_item pattern[],
+	uint8_t pattern_template_index, const struct rte_flow_action actions[],
+	uint8_t actions_template_index, void *user_data, struct rte_flow_error *error)
+{
+	const struct flow_filter_ops *flow_filter_ops = get_flow_filter_ops();
+
+	if (flow_filter_ops == NULL) {
+		NT_LOG_DBGX(ERR, FILTER, "flow_filter module uninitialized");
+		return NULL;
+	}
+
+	struct pmd_internals *internals = dev->data->dev_private;
+
+	struct fpga_info_s *fpga_info = &internals->p_drv->ntdrv.adapter_info.fpga_info;
+	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
+		.message = "none" };
+
+	struct cnv_action_s action = { 0 };
+	struct cnv_match_s match = { 0 };
+
+	if (create_match_elements(&match, pattern, MAX_ELEMENTS) != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+			"Error in pattern");
+		return NULL;
+	}
+
+	if (fpga_info->profile == FPGA_INFO_PROFILE_INLINE) {
+		uint32_t queue_offset = 0;
+
+		if (internals->type == PORT_TYPE_OVERRIDE && internals->vpq_nb_vq > 0)
+			queue_offset = internals->vpq[0].id;
+
+		if (create_action_elements_inline(&action, actions, MAX_ACTIONS, queue_offset) !=
+			0) {
+			rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+				"Error in actions");
+			return NULL;
+		}
+
+	} else {
+		rte_flow_error_set(error, EPERM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			"Unsupported adapter profile");
+		return NULL;
+	}
+
+	struct flow_handle *res =
+		flow_filter_ops->flow_async_create(internals->flw_dev,
+			queue_id,
+			(const struct rte_flow_op_attr *)op_attr,
+			(struct flow_template_table *)template_table,
+			match.rte_flow_item,
+			pattern_template_index,
+			action.flow_actions,
+			actions_template_index,
+			user_data,
+			&rte_flow_error);
+
+	convert_error(error, &rte_flow_error);
+	return (struct rte_flow *)res;
+}
+
+static int eth_flow_async_destroy(struct rte_eth_dev *dev, uint32_t queue_id,
+	const struct rte_flow_op_attr *op_attr, struct rte_flow *flow,
+	void *user_data, struct rte_flow_error *error)
+{
+	const struct flow_filter_ops *flow_filter_ops = get_flow_filter_ops();
+
+	if (flow_filter_ops == NULL) {
+		NT_LOG_DBGX(ERR, FILTER, "flow_filter module uninitialized");
+		return -1;
+	}
+
+	struct pmd_internals *internals = dev->data->dev_private;
+
+	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
+		.message = "none" };
+
+	int res = flow_filter_ops->flow_async_destroy(internals->flw_dev,
+			queue_id,
+			(const struct rte_flow_op_attr *)op_attr,
+			(struct flow_handle *)flow,
+			user_data,
+			&rte_flow_error);
+
+	convert_error(error, &rte_flow_error);
+	return res;
+}
+
 static int poll_statistics(struct pmd_internals *internals)
 {
 	int flow;
@@ -1017,3 +1112,13 @@  void dev_flow_init(void)
 {
 	register_dev_flow_ops(&dev_flow_ops);
 }
+
+static struct rte_flow_fp_ops async_dev_flow_ops = {
+	.async_create = eth_flow_async_create,
+	.async_destroy = eth_flow_async_destroy,
+};
+
+void dev_fp_flow_init(void)
+{
+	register_dev_fp_flow_ops(&async_dev_flow_ops);
+}
diff --git a/drivers/net/ntnic/ntnic_mod_reg.c b/drivers/net/ntnic/ntnic_mod_reg.c
index 10aa778a57..658fac72c0 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.c
+++ b/drivers/net/ntnic/ntnic_mod_reg.c
@@ -199,6 +199,21 @@  const struct flow_filter_ops *get_flow_filter_ops(void)
 	return flow_filter_ops;
 }
 
+static const struct rte_flow_fp_ops *dev_fp_flow_ops;
+
+void register_dev_fp_flow_ops(const struct rte_flow_fp_ops *ops)
+{
+	dev_fp_flow_ops = ops;
+}
+
+const struct rte_flow_fp_ops *get_dev_fp_flow_ops(void)
+{
+	if (dev_fp_flow_ops == NULL)
+		dev_fp_flow_init();
+
+	return dev_fp_flow_ops;
+}
+
 static const struct rte_flow_ops *dev_flow_ops;
 
 void register_dev_flow_ops(const struct rte_flow_ops *ops)
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index 563e62ebce..572da11d02 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -7,6 +7,7 @@ 
 #define __NTNIC_MOD_REG_H__
 
 #include <stdint.h>
+#include <rte_flow.h>
 
 #include "rte_ethdev.h"
 #include "rte_flow_driver.h"
@@ -426,6 +427,19 @@  struct flow_filter_ops {
 		uint32_t nb_contexts,
 		struct rte_flow_error *error);
 
+	/*
+	 * RTE flow asynchronous operations functions
+	 */
+	struct flow_handle *(*flow_async_create)(struct flow_eth_dev *dev, uint32_t queue_id,
+		const struct rte_flow_op_attr *op_attr,
+		struct flow_template_table *template_table, const struct rte_flow_item pattern[],
+		uint8_t pattern_template_index, const struct rte_flow_action actions[],
+		uint8_t actions_template_index, void *user_data, struct rte_flow_error *error);
+
+	int (*flow_async_destroy)(struct flow_eth_dev *dev, uint32_t queue_id,
+		const struct rte_flow_op_attr *op_attr, struct flow_handle *flow,
+		void *user_data, struct rte_flow_error *error);
+
 	int (*flow_info_get)(struct flow_eth_dev *dev, uint8_t caller_id,
 		struct rte_flow_port_info *port_info, struct rte_flow_queue_info *queue_info,
 		struct rte_flow_error *error);
@@ -436,6 +450,10 @@  struct flow_filter_ops {
 		struct rte_flow_error *error);
 };
 
+void register_dev_fp_flow_ops(const struct rte_flow_fp_ops *ops);
+const struct rte_flow_fp_ops *get_dev_fp_flow_ops(void);
+void dev_fp_flow_init(void);
+
 void register_dev_flow_ops(const struct rte_flow_ops *ops);
 const struct rte_flow_ops *get_dev_flow_ops(void);
 void dev_flow_init(void);