[v4,67/86] net/ntnic: add flow info and flow configure APIs

Message ID 20241029164243.1648775-68-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 warning coding style issues

Commit Message

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

Inline profile was extended with flow info and create APIS.

Module which operate with age queue was extended with
create and free operations.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/flow_api.h          |  3 +
 drivers/net/ntnic/include/flow_api_engine.h   |  1 +
 drivers/net/ntnic/nthw/flow_api/flow_api.c    | 19 +----
 .../flow_api/profile_inline/flm_age_queue.c   | 77 +++++++++++++++++++
 .../flow_api/profile_inline/flm_age_queue.h   |  5 ++
 .../profile_inline/flow_api_profile_inline.c  | 62 ++++++++++++++-
 .../profile_inline/flow_api_profile_inline.h  |  9 +++
 drivers/net/ntnic/ntnic_mod_reg.h             |  9 +++
 8 files changed, 169 insertions(+), 16 deletions(-)
  

Patch

diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h
index ed96f77bc0..89f071d982 100644
--- a/drivers/net/ntnic/include/flow_api.h
+++ b/drivers/net/ntnic/include/flow_api.h
@@ -77,6 +77,9 @@  struct flow_eth_dev {
 	/* QSL_HSH index if RSS needed QSL v6+ */
 	int rss_target_id;
 
+	/* The size of buffer for aged out flow list */
+	uint32_t nb_aging_objects;
+
 	struct flow_eth_dev *next;
 };
 
diff --git a/drivers/net/ntnic/include/flow_api_engine.h b/drivers/net/ntnic/include/flow_api_engine.h
index 155a9e1fd6..604a896717 100644
--- a/drivers/net/ntnic/include/flow_api_engine.h
+++ b/drivers/net/ntnic/include/flow_api_engine.h
@@ -320,6 +320,7 @@  struct flow_handle {
 			uint32_t flm_teid;
 			uint8_t flm_rqi;
 			uint8_t flm_qfi;
+			uint8_t flm_scrub_prof;
 		};
 	};
 };
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index b101a9462e..5349dc84ab 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -1075,12 +1075,6 @@  static 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)
 {
-	(void)dev;
-	(void)caller_id;
-	(void)port_info;
-	(void)queue_info;
-	(void)error;
-
 	const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops();
 
 	if (profile_inline_ops == NULL) {
@@ -1088,20 +1082,14 @@  static int flow_info_get(struct flow_eth_dev *dev, uint8_t caller_id,
 		return -1;
 	}
 
-	return 0;
+	return profile_inline_ops->flow_info_get_profile_inline(dev, caller_id, port_info,
+			queue_info, error);
 }
 
 static int flow_configure(struct flow_eth_dev *dev, uint8_t caller_id,
 	const struct rte_flow_port_attr *port_attr, uint16_t nb_queue,
 	const struct rte_flow_queue_attr *queue_attr[], struct rte_flow_error *error)
 {
-	(void)dev;
-	(void)caller_id;
-	(void)port_attr;
-	(void)queue_attr;
-	(void)nb_queue;
-	(void)error;
-
 	const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops();
 
 	if (profile_inline_ops == NULL) {
@@ -1109,7 +1097,8 @@  static int flow_configure(struct flow_eth_dev *dev, uint8_t caller_id,
 		return -1;
 	}
 
-	return 0;
+	return profile_inline_ops->flow_configure_profile_inline(dev, caller_id, port_attr,
+			nb_queue, queue_attr, error);
 }
 
 int flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size)
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_age_queue.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_age_queue.c
index f6f04009fe..fbc947ee1d 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_age_queue.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_age_queue.c
@@ -4,12 +4,89 @@ 
  */
 
 #include <rte_ring.h>
+#include <rte_errno.h>
 
 #include "ntlog.h"
 #include "flm_age_queue.h"
 
 /* Queues for flm aged events */
 static struct rte_ring *age_queue[MAX_EVT_AGE_QUEUES];
+static RTE_ATOMIC(uint16_t) age_event[MAX_EVT_AGE_PORTS];
+
+void flm_age_queue_free(uint8_t port, uint16_t caller_id)
+{
+	struct rte_ring *q = NULL;
+
+	if (port < MAX_EVT_AGE_PORTS)
+		rte_atomic_store_explicit(&age_event[port], 0, rte_memory_order_seq_cst);
+
+	if (caller_id < MAX_EVT_AGE_QUEUES && age_queue[caller_id] != NULL) {
+		q = age_queue[caller_id];
+		age_queue[caller_id] = NULL;
+	}
+
+	if (q != NULL)
+		rte_ring_free(q);
+}
+
+struct rte_ring *flm_age_queue_create(uint8_t port, uint16_t caller_id, unsigned int count)
+{
+	char name[20];
+	struct rte_ring *q = NULL;
+
+	if (rte_is_power_of_2(count) == false || count > RTE_RING_SZ_MASK) {
+		NT_LOG(WRN,
+			FILTER,
+			"FLM aged event queue number of elements (%u) is invalid, must be power of 2, and not exceed %u",
+			count,
+			RTE_RING_SZ_MASK);
+		return NULL;
+	}
+
+	if (port >= MAX_EVT_AGE_PORTS) {
+		NT_LOG(WRN,
+			FILTER,
+			"FLM aged event queue cannot be created for port %u. Max supported port is %u",
+			port,
+			MAX_EVT_AGE_PORTS - 1);
+		return NULL;
+	}
+
+	rte_atomic_store_explicit(&age_event[port], 0, rte_memory_order_seq_cst);
+
+	if (caller_id >= MAX_EVT_AGE_QUEUES) {
+		NT_LOG(WRN,
+			FILTER,
+			"FLM aged event queue cannot be created for caller_id %u. Max supported caller_id is %u",
+			caller_id,
+			MAX_EVT_AGE_QUEUES - 1);
+		return NULL;
+	}
+
+	if (age_queue[caller_id] != NULL) {
+		NT_LOG(DBG, FILTER, "FLM aged event queue %u already created", caller_id);
+		return age_queue[caller_id];
+	}
+
+	snprintf(name, 20, "AGE_EVENT%u", caller_id);
+	q = rte_ring_create_elem(name,
+			FLM_AGE_ELEM_SIZE,
+			count,
+			SOCKET_ID_ANY,
+			RING_F_SP_ENQ | RING_F_SC_DEQ);
+
+	if (q == NULL) {
+		NT_LOG(WRN,
+			FILTER,
+			"FLM aged event queue cannot be created due to error %02X",
+			rte_errno);
+		return NULL;
+	}
+
+	age_queue[caller_id] = q;
+
+	return q;
+}
 
 int flm_age_queue_get(uint16_t caller_id, struct flm_age_event_s *obj)
 {
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_age_queue.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_age_queue.h
index d61609cc01..9ff6ef6de0 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_age_queue.h
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_age_queue.h
@@ -15,8 +15,13 @@  struct flm_age_event_s {
 /* Max number of event queues */
 #define MAX_EVT_AGE_QUEUES 256
 
+/* Max number of event ports */
+#define MAX_EVT_AGE_PORTS 128
+
 #define FLM_AGE_ELEM_SIZE sizeof(struct flm_age_event_s)
 
+void flm_age_queue_free(uint8_t port, uint16_t caller_id);
+struct rte_ring *flm_age_queue_create(uint8_t port, uint16_t caller_id, unsigned int count);
 int flm_age_queue_get(uint16_t caller_id, struct flm_age_event_s *obj);
 unsigned int flm_age_queue_count(uint16_t caller_id);
 unsigned int flm_age_queue_get_size(uint16_t caller_id);
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index cdec414144..1824c931fe 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -490,7 +490,7 @@  static int flm_flow_programming(struct flow_handle *fh, uint32_t flm_op)
 	learn_record->ft = fh->flm_ft;
 	learn_record->kid = fh->flm_kid;
 	learn_record->eor = 1;
-	learn_record->scrub_prof = 0;
+	learn_record->scrub_prof = fh->flm_scrub_prof;
 
 	flm_lrn_queue_release_write_buffer(flm_lrn_queue_arr);
 	return 0;
@@ -2438,6 +2438,7 @@  static void copy_fd_to_fh_flm(struct flow_handle *fh, const struct nic_flow_def
 	fh->flm_rpl_ext_ptr = rpl_ext_ptr;
 	fh->flm_prio = (uint8_t)priority;
 	fh->flm_ft = (uint8_t)flm_ft;
+	fh->flm_scrub_prof = (uint8_t)flm_scrub;
 
 	for (unsigned int i = 0; i < fd->modify_field_count; ++i) {
 		switch (fd->modify_field[i].select) {
@@ -4558,6 +4559,63 @@  int flow_get_flm_stats_profile_inline(struct flow_nic_dev *ndev, uint64_t *data,
 	return 0;
 }
 
+int flow_info_get_profile_inline(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)
+{
+	(void)queue_info;
+	(void)caller_id;
+	int res = 0;
+
+	flow_nic_set_error(ERR_SUCCESS, error);
+	memset(port_info, 0, sizeof(struct rte_flow_port_info));
+
+	port_info->max_nb_aging_objects = dev->nb_aging_objects;
+
+	return res;
+}
+
+int flow_configure_profile_inline(struct flow_eth_dev *dev, uint8_t caller_id,
+	const struct rte_flow_port_attr *port_attr, uint16_t nb_queue,
+	const struct rte_flow_queue_attr *queue_attr[],
+	struct rte_flow_error *error)
+{
+	(void)nb_queue;
+	(void)queue_attr;
+	int res = 0;
+
+	flow_nic_set_error(ERR_SUCCESS, error);
+
+	if (port_attr->nb_aging_objects > 0) {
+		if (dev->nb_aging_objects > 0) {
+			flm_age_queue_free(dev->port_id, caller_id);
+			dev->nb_aging_objects = 0;
+		}
+
+		struct rte_ring *age_queue =
+			flm_age_queue_create(dev->port_id, caller_id, port_attr->nb_aging_objects);
+
+		if (age_queue == NULL) {
+			error->message = "Failed to allocate aging objects";
+			goto error_out;
+		}
+
+		dev->nb_aging_objects = port_attr->nb_aging_objects;
+	}
+
+	return res;
+
+error_out:
+	error->type = RTE_FLOW_ERROR_TYPE_UNSPECIFIED;
+
+	if (port_attr->nb_aging_objects > 0) {
+		flm_age_queue_free(dev->port_id, caller_id);
+		dev->nb_aging_objects = 0;
+	}
+
+	return -1;
+}
+
 static const struct profile_inline_ops ops = {
 	/*
 	 * Management
@@ -4579,6 +4637,8 @@  static const struct profile_inline_ops ops = {
 	 * Stats
 	 */
 	.flow_get_flm_stats_profile_inline = flow_get_flm_stats_profile_inline,
+	.flow_info_get_profile_inline = flow_info_get_profile_inline,
+	.flow_configure_profile_inline = flow_configure_profile_inline,
 	/*
 	 * NT Flow FLM Meter API
 	 */
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
index e1934bc6a6..ea1d9c31b2 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
@@ -64,4 +64,13 @@  int flow_nic_set_hasher_fields_inline(struct flow_nic_dev *ndev,
 
 int flow_get_flm_stats_profile_inline(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size);
 
+int flow_info_get_profile_inline(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);
+
+int flow_configure_profile_inline(struct flow_eth_dev *dev, uint8_t caller_id,
+	const struct rte_flow_port_attr *port_attr, uint16_t nb_queue,
+	const struct rte_flow_queue_attr *queue_attr[],
+	struct rte_flow_error *error);
+
 #endif	/* _FLOW_API_PROFILE_INLINE_H_ */
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index 52f197e873..15da911ca7 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -309,6 +309,15 @@  struct profile_inline_ops {
 	void (*flm_setup_queues)(void);
 	void (*flm_free_queues)(void);
 	uint32_t (*flm_update)(struct flow_eth_dev *dev);
+
+	int (*flow_info_get_profile_inline)(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);
+
+	int (*flow_configure_profile_inline)(struct flow_eth_dev *dev, uint8_t caller_id,
+	const struct rte_flow_port_attr *port_attr, uint16_t nb_queue,
+	const struct rte_flow_queue_attr *queue_attr[],
+	struct rte_flow_error *error);
 };
 
 void register_profile_inline_ops(const struct profile_inline_ops *ops);