From: Jay Ding Date: Wed, 15 Jul 2020 13:50:30 +0000 (+0530) Subject: net/bnxt: implement TF Identifier search X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=8ee821cfae8fe4fdc61f5265c020a490342ece0e;p=dpdk.git net/bnxt: implement TF Identifier search Implement shadow copy DB to hold reference count for each ID in each identifier type. Implement identifier search functionality. Signed-off-by: Jay Ding Signed-off-by: Somnath Kotur Reviewed-by: Randy Schacher Reviewed-by: Ajit Khaparde --- diff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build index 0b93c31716..8529b333c7 100644 --- a/drivers/net/bnxt/meson.build +++ b/drivers/net/bnxt/meson.build @@ -46,7 +46,7 @@ sources = files('bnxt_cpr.c', 'tf_core/ll.c', 'tf_core/tf_global_cfg.c', 'tf_core/tf_em_host.c', - 'tf_ulp/ulp_fc_mgr.c', + 'tf_core/tf_shadow_identifier.c', 'hcapi/hcapi_cfa_p4.c', @@ -63,6 +63,7 @@ sources = files('bnxt_cpr.c', 'tf_ulp/bnxt_ulp_flow.c', 'tf_ulp/ulp_port_db.c', 'tf_ulp/ulp_def_rules.c', + 'tf_ulp/ulp_fc_mgr.c', 'rte_pmd_bnxt.c') diff --git a/drivers/net/bnxt/tf_core/Makefile b/drivers/net/bnxt/tf_core/Makefile index b4fbdd00fc..cca0e2e85f 100644 --- a/drivers/net/bnxt/tf_core/Makefile +++ b/drivers/net/bnxt/tf_core/Makefile @@ -31,3 +31,4 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_tcam.c SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_util.c SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_if_tbl.c SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_global_cfg.c +SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_shadow_identifier.c diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c index a404cb8c78..97e7952a9c 100644 --- a/drivers/net/bnxt/tf_core/tf_core.c +++ b/drivers/net/bnxt/tf_core/tf_core.c @@ -534,6 +534,7 @@ tf_free_identifier(struct tf *tfp, fparms.dir = parms->dir; fparms.type = parms->ident_type; fparms.id = parms->id; + fparms.ref_cnt = &parms->ref_cnt; rc = dev->ops->tf_dev_free_ident(tfp, &fparms); if (rc) { TFP_DRV_LOG(ERR, @@ -546,6 +547,66 @@ tf_free_identifier(struct tf *tfp, return 0; } +int +tf_search_identifier(struct tf *tfp, + struct tf_search_identifier_parms *parms) +{ + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tf_ident_search_parms sparms; + + TF_CHECK_PARMS2(tfp, parms); + + /* Can't do static initialization due to UT enum check */ + memset(&sparms, 0, sizeof(struct tf_ident_search_parms)); + + /* Retrieve the session information */ + rc = tf_session_get_session(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup device, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + if (dev->ops->tf_dev_search_ident == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + sparms.dir = parms->dir; + sparms.type = parms->ident_type; + sparms.search_id = parms->search_id; + sparms.hit = &parms->hit; + sparms.ref_cnt = &parms->ref_cnt; + rc = dev->ops->tf_dev_search_ident(tfp, &sparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Identifier search failed, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + return 0; +} + int tf_alloc_tcam_entry(struct tf *tfp, struct tf_alloc_tcam_entry_parms *parms) diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h index 9e8042606c..9a5e816f4b 100644 --- a/drivers/net/bnxt/tf_core/tf_core.h +++ b/drivers/net/bnxt/tf_core/tf_core.h @@ -695,9 +695,9 @@ struct tf_alloc_identifier_parms { */ enum tf_identifier_type ident_type; /** - * [out] Identifier allocated + * [out] Allocated identifier */ - uint16_t id; + uint32_t id; }; /** @@ -715,7 +715,38 @@ struct tf_free_identifier_parms { /** * [in] ID to free */ - uint16_t id; + uint32_t id; + /** + * (experimental) + * [out] Current refcnt after free + */ + uint32_t ref_cnt; +}; + +/** + * tf_search_identifier parameter definition (experimental) + */ +struct tf_search_identifier_parms { + /** + * [in] receive or transmit direction + */ + enum tf_dir dir; + /** + * [in] Identifier type + */ + enum tf_identifier_type ident_type; + /** + * [in] Identifier data to search for + */ + uint32_t search_id; + /** + * [out] Set if matching identifier found + */ + bool hit; + /** + * [out] Current ref count after allocation + */ + uint32_t ref_cnt; }; /** @@ -724,6 +755,9 @@ struct tf_free_identifier_parms { * TruFlow core will allocate a free id from the per identifier resource type * pool reserved for the session during tf_open(). No firmware is involved. * + * If shadow copy is enabled, the internal ref_cnt is set to 1 in the + * shadow table for a newly allocated resource. + * * Returns success or failure code. */ int tf_alloc_identifier(struct tf *tfp, @@ -736,11 +770,41 @@ int tf_alloc_identifier(struct tf *tfp, * reserved for the session. No firmware is involved. During tf_close, the * complete pool is returned to the firmware. * + * additional operation (experimental) + * Decrement reference count. Only release resource once refcnt goes to 0 if + * shadow copy is enabled. + * * Returns success or failure code. */ int tf_free_identifier(struct tf *tfp, struct tf_free_identifier_parms *parms); +/** + * Search identifier resource (experimental) + * + * If the shadow copy is enabled search_id is used to search for a matching + * entry in the shadow table. The shadow table consists of an array of + * reference counts indexed by identifier. If a matching entry is found hit is + * set to TRUE, refcnt is increased by 1 and returned. Otherwise, hit is + * set to false and refcnt is set to 0. + * + * TODO: we may need a per table internal shadow copy enable flag to stage + * the shadow table implementation. We do not need the shadow table for other + * tables at this time so we may only want to enable the identifier shadow. + * + * TODO: remove this pseudocode below added to show that if search fails + * we shouldn't allocate a new entry but return. + * + * identifier alloc (search_en=1) + * if (ident is allocated and ref_cnt >=1) + * return ident - hit is set, incr refcnt + * else (not found) + * return + * + */ +int tf_search_identifier(struct tf *tfp, + struct tf_search_identifier_parms *parms); + /** * @page dram_table DRAM Table Scope Interface * diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h index 0bc7090568..fce7f25a85 100644 --- a/drivers/net/bnxt/tf_core/tf_device.h +++ b/drivers/net/bnxt/tf_core/tf_device.h @@ -198,6 +198,26 @@ struct tf_dev_ops { int (*tf_dev_free_ident)(struct tf *tfp, struct tf_ident_free_parms *parms); + /** + * Search of an identifier element. + * + * This API search the specified identifier element from a + * device specific identifier shadow DB. The allocated element + * is returned. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to identifier search parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_search_ident)(struct tf *tfp, + struct tf_ident_search_parms *parms); + /** * Allocation of a table type element. * diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c index dfe626c8a9..f38c38efb3 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p4.c +++ b/drivers/net/bnxt/tf_core/tf_device_p4.c @@ -86,6 +86,7 @@ const struct tf_dev_ops tf_dev_ops_p4_init = { .tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info, .tf_dev_alloc_ident = NULL, .tf_dev_free_ident = NULL, + .tf_dev_search_ident = NULL, .tf_dev_alloc_ext_tbl = NULL, .tf_dev_alloc_tbl = NULL, .tf_dev_free_ext_tbl = NULL, @@ -120,6 +121,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = { .tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info, .tf_dev_alloc_ident = tf_ident_alloc, .tf_dev_free_ident = tf_ident_free, + .tf_dev_search_ident = tf_ident_search, .tf_dev_alloc_tbl = tf_tbl_alloc, .tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc, .tf_dev_free_tbl = tf_tbl_free, diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c index 90aeaa4686..273d629544 100644 --- a/drivers/net/bnxt/tf_core/tf_identifier.c +++ b/drivers/net/bnxt/tf_core/tf_identifier.c @@ -6,6 +6,7 @@ #include #include "tf_identifier.h" +#include "tf_shadow_identifier.h" #include "tf_common.h" #include "tf_rm.h" #include "tf_util.h" @@ -23,6 +24,16 @@ static void *ident_db[TF_DIR_MAX]; */ static uint8_t init; +/** + * Identifier shadow DBs. + */ +static void *ident_shadow_db[TF_DIR_MAX]; + +/** + * Shadow DB Init flag, set on bind and cleared on unbind + */ +static uint8_t shadow_init; + int tf_ident_bind(struct tf *tfp, struct tf_ident_cfg_parms *parms) @@ -30,6 +41,8 @@ tf_ident_bind(struct tf *tfp, int rc; int i; struct tf_rm_create_db_parms db_cfg = { 0 }; + struct tf_shadow_ident_cfg_parms shadow_cfg = { 0 }; + struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 }; TF_CHECK_PARMS2(tfp, parms); @@ -55,6 +68,23 @@ tf_ident_bind(struct tf *tfp, return rc; } + + if (parms->shadow_copy) { + shadow_cfg.alloc_cnt = + parms->resources->ident_cnt[i].cnt; + shadow_cdb.num_elements = parms->num_elements; + shadow_cdb.tf_shadow_ident_db = &ident_shadow_db[i]; + shadow_cdb.cfg = &shadow_cfg; + rc = tf_shadow_ident_create_db(&shadow_cdb); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Ident shadow DB creation failed\n", + tf_dir_2_str(i)); + + return rc; + } + shadow_init = 1; + } } init = 1; @@ -71,6 +101,7 @@ tf_ident_unbind(struct tf *tfp) int rc = 0; int i; struct tf_rm_free_db_parms fparms = { 0 }; + struct tf_shadow_ident_free_db_parms sparms = { 0 }; TF_CHECK_PARMS1(tfp); @@ -89,10 +120,22 @@ tf_ident_unbind(struct tf *tfp) TFP_DRV_LOG(ERR, "rm free failed on unbind\n"); } + if (shadow_init) { + sparms.tf_shadow_ident_db = ident_shadow_db[i]; + rc = tf_shadow_ident_free_db(&sparms); + if (rc) { + /* TODO: If there are failures on unbind we + * really just have to try until all DBs are + * attempted to be cleared. + */ + } + ident_shadow_db[i] = NULL; + } ident_db[i] = NULL; } init = 0; + shadow_init = 0; return 0; } @@ -103,7 +146,9 @@ tf_ident_alloc(struct tf *tfp __rte_unused, { int rc; uint32_t id; + uint32_t base_id; struct tf_rm_allocate_parms aparms = { 0 }; + struct tf_shadow_ident_insert_parms iparms = { 0 }; TF_CHECK_PARMS2(tfp, parms); @@ -118,6 +163,7 @@ tf_ident_alloc(struct tf *tfp __rte_unused, aparms.rm_db = ident_db[parms->dir]; aparms.db_index = parms->type; aparms.index = &id; + aparms.base_index = &base_id; rc = tf_rm_allocate(&aparms); if (rc) { TFP_DRV_LOG(ERR, @@ -127,6 +173,21 @@ tf_ident_alloc(struct tf *tfp __rte_unused, return rc; } + if (shadow_init) { + iparms.tf_shadow_ident_db = ident_shadow_db[parms->dir]; + iparms.type = parms->type; + iparms.id = base_id; + + rc = tf_shadow_ident_insert(&iparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed insert shadow DB, type:%d\n", + tf_dir_2_str(parms->dir), + parms->type); + return rc; + } + } + *parms->id = id; return 0; @@ -139,7 +200,9 @@ tf_ident_free(struct tf *tfp __rte_unused, int rc; struct tf_rm_is_allocated_parms aparms = { 0 }; struct tf_rm_free_parms fparms = { 0 }; + struct tf_shadow_ident_remove_parms rparms = { 0 }; int allocated = 0; + uint32_t base_id; TF_CHECK_PARMS2(tfp, parms); @@ -154,6 +217,7 @@ tf_ident_free(struct tf *tfp __rte_unused, aparms.rm_db = ident_db[parms->dir]; aparms.db_index = parms->type; aparms.index = parms->id; + aparms.base_index = &base_id; aparms.allocated = &allocated; rc = tf_rm_is_allocated(&aparms); if (rc) @@ -168,6 +232,27 @@ tf_ident_free(struct tf *tfp __rte_unused, return -EINVAL; } + if (shadow_init) { + rparms.tf_shadow_ident_db = ident_shadow_db[parms->dir]; + rparms.type = parms->type; + rparms.id = base_id; + rparms.ref_cnt = parms->ref_cnt; + + rc = tf_shadow_ident_remove(&rparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: ref_cnt was 0 in shadow DB," + " type:%d, index:%d\n", + tf_dir_2_str(parms->dir), + parms->type, + parms->id); + return rc; + } + + if (*rparms.ref_cnt > 0) + return 0; + } + /* Free requested element */ fparms.rm_db = ident_db[parms->dir]; fparms.db_index = parms->type; @@ -184,3 +269,66 @@ tf_ident_free(struct tf *tfp __rte_unused, return 0; } + +int +tf_ident_search(struct tf *tfp __rte_unused, + struct tf_ident_search_parms *parms) +{ + int rc; + struct tf_rm_is_allocated_parms aparms = { 0 }; + struct tf_shadow_ident_search_parms sparms = { 0 }; + int allocated = 0; + uint32_t base_id; + + TF_CHECK_PARMS2(tfp, parms); + + if (!init) { + TFP_DRV_LOG(ERR, + "%s: No Identifier DBs created\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + if (!shadow_init) { + TFP_DRV_LOG(ERR, + "%s: Identifier Shadow copy is not enabled\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + /* Check if element is in use */ + aparms.rm_db = ident_db[parms->dir]; + aparms.db_index = parms->type; + aparms.index = parms->search_id; + aparms.base_index = &base_id; + aparms.allocated = &allocated; + rc = tf_rm_is_allocated(&aparms); + if (rc) + return rc; + + if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { + TFP_DRV_LOG(ERR, + "%s: Entry not allocated, type:%d, index:%d\n", + tf_dir_2_str(parms->dir), + parms->type, + parms->search_id); + return -EINVAL; + } + + sparms.tf_shadow_ident_db = ident_shadow_db[parms->dir]; + sparms.type = parms->type; + sparms.search_id = base_id; + sparms.hit = parms->hit; + sparms.ref_cnt = parms->ref_cnt; + + rc = tf_shadow_ident_search(&sparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed search shadow DB, type:%d\n", + tf_dir_2_str(parms->dir), + parms->type); + return rc; + } + + return 0; +} diff --git a/drivers/net/bnxt/tf_core/tf_identifier.h b/drivers/net/bnxt/tf_core/tf_identifier.h index 6e36c525fc..6d9fa08aef 100644 --- a/drivers/net/bnxt/tf_core/tf_identifier.h +++ b/drivers/net/bnxt/tf_core/tf_identifier.h @@ -66,6 +66,37 @@ struct tf_ident_free_parms { * [in] ID to free */ uint16_t id; + /** + * (experimental) + * [out] Current refcnt after free + */ + uint32_t *ref_cnt; +}; + +/** + * Identifier search parameter definition + */ +struct tf_ident_search_parms { + /** + * [in] receive or transmit direction + */ + enum tf_dir dir; + /** + * [in] Identifier type + */ + enum tf_identifier_type type; + /** + * [in] Identifier data to search for + */ + uint16_t search_id; + /** + * [out] Set if matching identifier found + */ + bool *hit; + /** + * [out] Current ref count after allocation + */ + uint32_t *ref_cnt; }; /** @@ -144,4 +175,20 @@ int tf_ident_alloc(struct tf *tfp, int tf_ident_free(struct tf *tfp, struct tf_ident_free_parms *parms); +/** + * Search a single identifier type. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_ident_search(struct tf *tfp, + struct tf_ident_search_parms *parms); + #endif /* _TF_IDENTIFIER_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c index fdb87ecb81..78bc231ab5 100644 --- a/drivers/net/bnxt/tf_core/tf_rm.c +++ b/drivers/net/bnxt/tf_core/tf_rm.c @@ -755,6 +755,7 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms) } *parms->index = index; + *parms->base_index = id; return rc; } @@ -841,6 +842,7 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms) if (rc) return rc; + *parms->base_index = adj_index; *parms->allocated = ba_inuse(rm_db->db[parms->db_index].pool, adj_index); diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h index 775f0aa1a1..971120a918 100644 --- a/drivers/net/bnxt/tf_core/tf_rm.h +++ b/drivers/net/bnxt/tf_core/tf_rm.h @@ -204,6 +204,10 @@ struct tf_rm_allocate_parms { * available index) */ uint32_t priority; + /** + * [in] Pointer to the allocated index before adjusted. + */ + uint32_t *base_index; }; /** @@ -246,6 +250,10 @@ struct tf_rm_is_allocated_parms { * [in] Pointer to flag that indicates the state of the query */ int *allocated; + /** + * [in] Pointer to the allocated index before adjusted. + */ + uint32_t *base_index; }; /** diff --git a/drivers/net/bnxt/tf_core/tf_shadow_identifier.c b/drivers/net/bnxt/tf_core/tf_shadow_identifier.c new file mode 100644 index 0000000000..390d22f81e --- /dev/null +++ b/drivers/net/bnxt/tf_core/tf_shadow_identifier.c @@ -0,0 +1,190 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2020 Broadcom + * All rights reserved. + */ + +#include + +#include "tf_shadow_identifier.h" +#include "tf_common.h" +#include "tf_util.h" +#include "tfp.h" + +/** + * Shadow identifier DB element + */ +struct tf_shadow_ident_element { + /** + * Identifier + */ + uint32_t *id; + + /** + * Reference count, array of number of identifier type entries + */ + uint32_t *ref_count; +}; + +/** + * Shadow identifier DB definition + */ +struct tf_shadow_ident_db { + /** + * Number of elements in the DB + */ + uint16_t num_entries; + + /** + * The DB consists of an array of elements + */ + struct tf_shadow_ident_element *db; +}; + +int +tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms) +{ + int rc; + int i; + struct tfp_calloc_parms cparms; + struct tf_shadow_ident_db *shadow_db; + struct tf_shadow_ident_element *db; + + TF_CHECK_PARMS1(parms); + + /* Build the shadow DB per the request */ + cparms.nitems = 1; + cparms.size = sizeof(struct tf_shadow_ident_db); + cparms.alignment = 0; + rc = tfp_calloc(&cparms); + if (rc) + return rc; + shadow_db = (void *)cparms.mem_va; + + /* Build the DB within shadow DB */ + cparms.nitems = parms->num_elements; + cparms.size = sizeof(struct tf_shadow_ident_element); + rc = tfp_calloc(&cparms); + if (rc) + return rc; + shadow_db->db = (struct tf_shadow_ident_element *)cparms.mem_va; + shadow_db->num_entries = parms->num_elements; + + db = shadow_db->db; + for (i = 0; i < parms->num_elements; i++) { + /* If the element didn't request an allocation no need + * to create a pool nor verify if we got a reservation. + */ + if (parms->cfg->alloc_cnt[i] == 0) + continue; + + /* Create array */ + cparms.nitems = parms->cfg->alloc_cnt[i]; + cparms.size = sizeof(uint32_t); + rc = tfp_calloc(&cparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Array alloc failed, type:%d\n", + tf_dir_2_str(parms->dir), + i); + goto fail; + } + db[i].ref_count = (uint32_t *)cparms.mem_va; + } + + *parms->tf_shadow_ident_db = (void *)shadow_db; + + return 0; +fail: + tfp_free((void *)db->ref_count); + tfp_free((void *)db); + tfp_free((void *)shadow_db); + parms->tf_shadow_ident_db = NULL; + + return -EINVAL; +} + +int +tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms) +{ + int i; + struct tf_shadow_ident_db *shadow_db; + + TF_CHECK_PARMS1(parms); + + shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db; + for (i = 0; i < shadow_db->num_entries; i++) + tfp_free((void *)shadow_db->db[i].ref_count); + + tfp_free((void *)shadow_db->db); + tfp_free((void *)parms->tf_shadow_ident_db); + + return 0; +} + +int +tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms) +{ + struct tf_shadow_ident_db *shadow_db; + uint32_t ref_cnt = 0; + + TF_CHECK_PARMS1(parms); + + shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db; + ref_cnt = shadow_db->db[parms->type].ref_count[parms->search_id]; + if (ref_cnt > 0) { + *parms->hit = 1; + *parms->ref_cnt = ++ref_cnt; + shadow_db->db[parms->type].ref_count[parms->search_id] = + ref_cnt; + } else { + *parms->hit = 0; + *parms->ref_cnt = 0; + } + + + return 0; +} + +#define ID_REF_CNT_MAX 0xffffffff +int +tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms) +{ + struct tf_shadow_ident_db *shadow_db; + + TF_CHECK_PARMS1(parms); + + shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db; + + /* In case of overflow, ref count keeps the max value */ + if (shadow_db->db[parms->type].ref_count[parms->id] < ID_REF_CNT_MAX) + shadow_db->db[parms->type].ref_count[parms->id]++; + else + TFP_DRV_LOG(ERR, + "Identifier %d in type %d reaches the max ref_cnt\n", + parms->type, + parms->id); + + parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id]; + + return 0; +} + +int +tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms) +{ + struct tf_shadow_ident_db *shadow_db; + uint32_t ref_cnt = 0; + + TF_CHECK_PARMS1(parms); + + shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db; + ref_cnt = shadow_db->db[parms->type].ref_count[parms->id]; + if (ref_cnt > 0) + shadow_db->db[parms->type].ref_count[parms->id]--; + else + return -EINVAL; + + *parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id]; + + return 0; +} diff --git a/drivers/net/bnxt/tf_core/tf_shadow_identifier.h b/drivers/net/bnxt/tf_core/tf_shadow_identifier.h new file mode 100644 index 0000000000..dd633afcea --- /dev/null +++ b/drivers/net/bnxt/tf_core/tf_shadow_identifier.h @@ -0,0 +1,229 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2020 Broadcom + * All rights reserved. + */ + +#ifndef _TF_SHADOW_IDENTIFIER_H_ +#define _TF_SHADOW_IDENTIFIER_H_ + +#include "tf_core.h" + +struct tf; + +/** + * The Shadow Identifier module provides shadow DB handling for identifier based + * TF types. A shadow DB provides the capability that allows for reuse + * of TF resources. + * + * A Shadow identifier DB is intended to be used by the Identifier Type module + * only. + */ + +/** + * Shadow DB configuration information for a single identifier type. + * + * It is used in an array of identifier types. The array must be ordered + * by the TF type is represents. + */ +struct tf_shadow_ident_cfg_parms { + /** + * TF Identifier type + */ + enum tf_identifier_type type; + + /** + * Number of entries the Shadow DB needs to hold + */ + int num_entries; + + /** + * Resource allocation count array. This array content + * originates from the tf_session_resources that is passed in + * on session open. + * Array size is num_elements. + */ + uint16_t *alloc_cnt; +}; + +/** + * Shadow identifier DB creation parameters + */ +struct tf_shadow_ident_create_db_parms { + /** + * [in] Receive or transmit direction. + */ + enum tf_dir dir; + /** + * [in] Configuration information for the shadow db + */ + struct tf_shadow_ident_cfg_parms *cfg; + /** + * [in] Number of elements in the parms structure + */ + uint16_t num_elements; + /** + * [out] Shadow identifier DB handle + */ + void **tf_shadow_ident_db; +}; + +/** + * Shadow identifier DB free parameters + */ +struct tf_shadow_ident_free_db_parms { + /** + * Shadow identifier DB handle + */ + void *tf_shadow_ident_db; +}; + +/** + * Shadow identifier search parameters + */ +struct tf_shadow_ident_search_parms { + /** + * [in] Shadow identifier DB handle + */ + void *tf_shadow_ident_db; + /** + * [in] Identifier type + */ + enum tf_identifier_type type; + /** + * [in] id to search + */ + uint16_t search_id; + /** + * [out] Index of the found element returned if hit + */ + bool *hit; + /** + * [out] Reference count incremented if hit + */ + uint32_t *ref_cnt; +}; + +/** + * Shadow identifier insert parameters + */ +struct tf_shadow_ident_insert_parms { + /** + * [in] Shadow identifier DB handle + */ + void *tf_shadow_ident_db; + /** + * [in] Tbl type + */ + enum tf_identifier_type type; + /** + * [in] Entry to update + */ + uint16_t id; + /** + * [out] Reference count after insert + */ + uint32_t ref_cnt; +}; + +/** + * Shadow identifier remove parameters + */ +struct tf_shadow_ident_remove_parms { + /** + * [in] Shadow identifier DB handle + */ + void *tf_shadow_ident_db; + /** + * [in] Tbl type + */ + enum tf_identifier_type type; + /** + * [in] Entry to update + */ + uint16_t id; + /** + * [out] Reference count after removal + */ + uint32_t *ref_cnt; +}; + +/** + * @page shadow_ident Shadow identifier DB + * + * @ref tf_shadow_ident_create_db + * + * @ref tf_shadow_ident_free_db + * + * @reg tf_shadow_ident_search + * + * @reg tf_shadow_ident_insert + * + * @reg tf_shadow_ident_remove + */ + +/** + * Creates and fills a Shadow identifier DB. The DB is indexed per the + * parms structure. + * + * [in] parms + * Pointer to create db parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms); + +/** + * Closes the Shadow identifier DB and frees all allocated + * resources per the associated database. + * + * [in] parms + * Pointer to the free DB parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms); + +/** + * Search Shadow identifier db for matching result + * + * [in] parms + * Pointer to the search parameters + * + * Returns + * - (0) if successful, element was found. + * - (-EINVAL) on failure. + */ +int tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms); + +/** + * Inserts an element into the Shadow identifier DB. Ref_count after insert + * will be incremented. + * + * [in] parms + * Pointer to insert parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms); + +/** + * Removes an element from the Shadow identifier DB. Will fail if the + * elements ref_count is 0. Ref_count after removal will be + * decremented. + * + * [in] parms + * Pointer to remove parameter + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms); + +#endif /* _TF_SHADOW_IDENTIFIER_H_ */