@@ -61,6 +61,10 @@ struct flow_nic_dev {
void *km_res_handle;
void *kcc_res_handle;
+ void *group_handle;
+ void *hw_db_handle;
+ void *id_table_handle;
+
uint32_t flow_unique_id_counter;
/* linked list of all flows created on this NIC */
struct flow_handle *flow_base;
@@ -6,6 +6,8 @@
#ifndef _FLOW_API_ENGINE_H_
#define _FLOW_API_ENGINE_H_
+#include <stdint.h>
+
/*
* Resource management
*/
@@ -46,6 +48,9 @@ enum res_type_e {
*/
#define MAX_OUTPUT_DEST (128)
+#define MAX_CPY_WRITERS_SUPPORTED 8
+
+
struct flow_handle {
struct flow_eth_dev *dev;
struct flow_handle *next;
@@ -55,4 +60,9 @@ void km_free_ndev_resource_management(void **handle);
void kcc_free_ndev_resource_management(void **handle);
+/*
+ * Group management
+ */
+int flow_group_handle_create(void **handle, uint32_t group_count);
+int flow_group_handle_destroy(void **handle);
#endif /* _FLOW_API_ENGINE_H_ */
@@ -18,6 +18,7 @@ includes = [
include_directories('nthw/supported'),
include_directories('nthw/model'),
include_directories('nthw/flow_filter'),
+ include_directories('nthw/flow_api'),
include_directories('nim/'),
]
@@ -47,7 +48,10 @@ sources = files(
'nthw/core/nthw_sdc.c',
'nthw/core/nthw_si5340.c',
'nthw/flow_api/flow_api.c',
+ 'nthw/flow_api/flow_group.c',
+ 'nthw/flow_api/flow_id_table.c',
'nthw/flow_api/profile_inline/flow_api_profile_inline.c',
+ 'nthw/flow_api/profile_inline/flow_api_hw_db_inline.c',
'nthw/flow_api/flow_backend/flow_backend.c',
'nthw/flow_api/flow_filter.c',
'nthw/flow_api/flow_kcc.c',
new file mode 100644
@@ -0,0 +1,55 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "flow_api_engine.h"
+
+#define OWNER_ID_COUNT 256
+#define PORT_COUNT 8
+
+struct group_lookup_entry_s {
+ uint64_t ref_counter;
+ uint32_t *reverse_lookup;
+};
+
+struct group_handle_s {
+ uint32_t group_count;
+
+ uint32_t *translation_table;
+
+ struct group_lookup_entry_s *lookup_entries;
+};
+
+int flow_group_handle_create(void **handle, uint32_t group_count)
+{
+ struct group_handle_s *group_handle;
+
+ *handle = calloc(1, sizeof(struct group_handle_s));
+ group_handle = *handle;
+
+ group_handle->group_count = group_count;
+ group_handle->translation_table =
+ calloc((uint32_t)(group_count * PORT_COUNT * OWNER_ID_COUNT), sizeof(uint32_t));
+ group_handle->lookup_entries = calloc(group_count, sizeof(struct group_lookup_entry_s));
+
+ return *handle != NULL ? 0 : -1;
+}
+
+int flow_group_handle_destroy(void **handle)
+{
+ if (*handle) {
+ struct group_handle_s *group_handle = (struct group_handle_s *)*handle;
+
+ free(group_handle->translation_table);
+ free(group_handle->lookup_entries);
+
+ free(*handle);
+ *handle = NULL;
+ }
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,52 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "flow_id_table.h"
+
+#define NTNIC_ARRAY_BITS 14
+#define NTNIC_ARRAY_SIZE (1 << NTNIC_ARRAY_BITS)
+
+struct ntnic_id_table_element {
+ union flm_handles handle;
+ uint8_t caller_id;
+ uint8_t type;
+};
+
+struct ntnic_id_table_data {
+ struct ntnic_id_table_element *arrays[NTNIC_ARRAY_SIZE];
+ pthread_mutex_t mtx;
+
+ uint32_t next_id;
+
+ uint32_t free_head;
+ uint32_t free_tail;
+ uint32_t free_count;
+};
+
+void *ntnic_id_table_create(void)
+{
+ struct ntnic_id_table_data *handle = calloc(1, sizeof(struct ntnic_id_table_data));
+
+ pthread_mutex_init(&handle->mtx, NULL);
+ handle->next_id = 1;
+
+ return handle;
+}
+
+void ntnic_id_table_destroy(void *id_table)
+{
+ struct ntnic_id_table_data *handle = id_table;
+
+ for (uint32_t i = 0; i < NTNIC_ARRAY_SIZE; ++i)
+ free(handle->arrays[i]);
+
+ pthread_mutex_destroy(&handle->mtx);
+
+ free(id_table);
+}
new file mode 100644
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#ifndef _FLOW_ID_TABLE_H_
+#define _FLOW_ID_TABLE_H_
+
+#include <stdint.h>
+
+union flm_handles {
+ uint64_t idx;
+ void *p;
+};
+
+void *ntnic_id_table_create(void);
+void ntnic_id_table_destroy(void *id_table);
+
+#endif /* FLOW_ID_TABLE_H_ */
new file mode 100644
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+
+#include "flow_api_hw_db_inline.h"
+
+/******************************************************************************/
+/* Handle */
+/******************************************************************************/
+
+struct hw_db_inline_resource_db {
+ /* Actions */
+ struct hw_db_inline_resource_db_cot {
+ struct hw_db_inline_cot_data data;
+ int ref;
+ } *cot;
+
+ uint32_t nb_cot;
+
+ /* Hardware */
+
+ struct hw_db_inline_resource_db_cfn {
+ uint64_t priority;
+ int cfn_hw;
+ int ref;
+ } *cfn;
+};
+
+int hw_db_inline_create(struct flow_nic_dev *ndev, void **db_handle)
+{
+ /* Note: calloc is required for functionality in the hw_db_inline_destroy() */
+ struct hw_db_inline_resource_db *db = calloc(1, sizeof(struct hw_db_inline_resource_db));
+
+ if (db == NULL)
+ return -1;
+
+ db->nb_cot = ndev->be.cat.nb_cat_funcs;
+ db->cot = calloc(db->nb_cot, sizeof(struct hw_db_inline_resource_db_cot));
+
+ if (db->cot == NULL) {
+ hw_db_inline_destroy(db);
+ return -1;
+ }
+
+ *db_handle = db;
+ return 0;
+}
+
+void hw_db_inline_destroy(void *db_handle)
+{
+ struct hw_db_inline_resource_db *db = (struct hw_db_inline_resource_db *)db_handle;
+
+ free(db->cot);
+
+ free(db->cfn);
+
+ free(db);
+}
new file mode 100644
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef _FLOW_API_HW_DB_INLINE_H_
+#define _FLOW_API_HW_DB_INLINE_H_
+
+#include <stdint.h>
+
+#include "flow_api.h"
+
+struct hw_db_inline_cot_data {
+ uint32_t matcher_color_contrib : 4;
+ uint32_t frag_rcp : 4;
+ uint32_t padding : 24;
+};
+
+/**/
+
+int hw_db_inline_create(struct flow_nic_dev *ndev, void **db_handle);
+void hw_db_inline_destroy(void *db_handle);
+
+#endif /* _FLOW_API_HW_DB_INLINE_H_ */
@@ -4,6 +4,9 @@
*/
#include "ntlog.h"
+#include "flow_api_engine.h"
+#include "flow_api_hw_db_inline.h"
+#include "flow_id_table.h"
#include "flow_api_profile_inline.h"
#include "ntnic_mod_reg.h"
@@ -12,13 +15,62 @@
* Public functions
*/
-int initialize_flow_management_of_ndev_profile_inline(struct flow_nic_dev *ndev __rte_unused)
+int initialize_flow_management_of_ndev_profile_inline(struct flow_nic_dev *ndev)
{
+ if (!ndev->flow_mgnt_prepared) {
+ /* Check static arrays are big enough */
+ assert(ndev->be.tpe.nb_cpy_writers <= MAX_CPY_WRITERS_SUPPORTED);
+
+ ndev->id_table_handle = ntnic_id_table_create();
+
+ if (ndev->id_table_handle == NULL)
+ goto err_exit0;
+
+ if (flow_group_handle_create(&ndev->group_handle, ndev->be.flm.nb_categories))
+ goto err_exit0;
+
+ if (hw_db_inline_create(ndev, &ndev->hw_db_handle))
+ goto err_exit0;
+
+ ndev->flow_mgnt_prepared = 1;
+ }
+
+ return 0;
+
+err_exit0:
+ done_flow_management_of_ndev_profile_inline(ndev);
return -1;
}
-int done_flow_management_of_ndev_profile_inline(struct flow_nic_dev *ndev __rte_unused)
+int done_flow_management_of_ndev_profile_inline(struct flow_nic_dev *ndev)
{
+#ifdef FLOW_DEBUG
+ ndev->be.iface->set_debug_mode(ndev->be.be_dev, FLOW_BACKEND_DEBUG_MODE_WRITE);
+#endif
+
+ if (ndev->flow_mgnt_prepared) {
+ flow_nic_free_resource(ndev, RES_KM_FLOW_TYPE, 0);
+ flow_nic_free_resource(ndev, RES_KM_CATEGORY, 0);
+
+ flow_group_handle_destroy(&ndev->group_handle);
+ ntnic_id_table_destroy(ndev->id_table_handle);
+
+ flow_nic_free_resource(ndev, RES_CAT_CFN, 0);
+
+ hw_mod_tpe_reset(&ndev->be);
+ flow_nic_free_resource(ndev, RES_TPE_RCP, 0);
+ flow_nic_free_resource(ndev, RES_TPE_EXT, 0);
+ flow_nic_free_resource(ndev, RES_TPE_RPL, 0);
+
+ hw_db_inline_destroy(ndev->hw_db_handle);
+
+#ifdef FLOW_DEBUG
+ ndev->be.iface->set_debug_mode(ndev->be.be_dev, FLOW_BACKEND_DEBUG_MODE_NONE);
+#endif
+
+ ndev->flow_mgnt_prepared = 0;
+ }
+
return 0;
}