From: Mike Baucom Date: Wed, 15 Apr 2020 14:49:15 +0000 (+0530) Subject: net/bnxt: add cache table type for TCAM lookup X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=4bc32a80556eb85ca980dcc5e82455e3ae741007;p=dpdk.git net/bnxt: add cache table type for TCAM lookup In order to re-use allocated resources and reduce search complexity for simple keys, a generic software cache table was added for the TCAM. The implementation is specifically only for keys that can be compressed to less than 16 bits. The keys are generated using the same mechanisms as other search tables, but the table type is set to a cache that mirrors the actual TCAM table. The allocated result fields are stored in the cache entry and can be used for subsequent searches in future tables. Reviewed-by: Venkat Duvvuru Reviewed-by: Ajit Khaparde Signed-off-by: Mike Baucom Signed-off-by: Venkat Duvvuru --- diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c index 56e67002d5..dc7b7ca5ed 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c +++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c @@ -66,6 +66,16 @@ ulp_mapper_def_regfile_write(struct bnxt_ulp_mapper_data *mapper_data, return 0; } +/* Retrieve the cache initialization parameters for the tbl_idx */ +static struct bnxt_ulp_cache_tbl_params * +ulp_mapper_cache_tbl_params_get(uint32_t tbl_idx) +{ + if (tbl_idx >= BNXT_ULP_CACHE_TBL_MAX_SZ) + return NULL; + + return &ulp_cache_tbl_params[tbl_idx]; +} + /* * Get the size of the action property for a given index. * @@ -256,6 +266,126 @@ ulp_mapper_ident_fields_get(struct bnxt_ulp_mapper_class_tbl_info *tbl, return &ulp_ident_list[idx]; } +static struct bnxt_ulp_mapper_cache_entry * +ulp_mapper_cache_entry_get(struct bnxt_ulp_context *ulp, + enum bnxt_ulp_cache_tbl_id id, + uint16_t key) +{ + struct bnxt_ulp_mapper_data *mapper_data; + + mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp); + if (!mapper_data || !mapper_data->cache_tbl[id]) { + BNXT_TF_DBG(ERR, "Unable to acquire the cache tbl (%d)\n", id); + return NULL; + } + + return &mapper_data->cache_tbl[id][key]; +} + +/* + * Concatenates the tbl_type and tbl_id into a 32bit value for storing in the + * resource_type. This is done to conserve memory since both the tbl_type and + * tbl_id are 16bit. + */ +static inline void +ulp_mapper_cache_res_type_set(struct ulp_flow_db_res_params *res, + uint16_t tbl_type, + uint16_t tbl_id) +{ + res->resource_type = + ((uint32_t)tbl_id << ULP_MAPPER_CACHE_RES_TBL_ID_SHFT) | + ((uint32_t)tbl_type << ULP_MAPPER_CACHE_RES_TBL_TYPE_SHFT); +} + +/* Extracts the tbl_type and tbl_id from the 32bit resource type. */ +static inline void +ulp_mapper_cache_res_type_get(struct ulp_flow_db_res_params *res, + uint16_t *tbl_type, + uint16_t *tbl_id) +{ + *tbl_type = (uint16_t)((res->resource_type >> + ULP_MAPPER_CACHE_RES_TBL_TYPE_SHFT) & + ULP_MAPPER_CACHE_RES_TBL_MASK); + *tbl_id = (uint16_t)((res->resource_type >> + ULP_MAPPER_CACHE_RES_TBL_ID_SHFT) & + ULP_MAPPER_CACHE_RES_TBL_MASK); +} + +static int32_t +ulp_mapper_cache_entry_free(struct bnxt_ulp_context *ulp, + struct tf *tfp, + struct ulp_flow_db_res_params *res) +{ + struct bnxt_ulp_mapper_cache_entry *cache_entry; + struct tf_free_identifier_parms ident_parms; + struct tf_free_tcam_entry_parms tcam_parms; + uint16_t table_id, table_type; + int32_t rc, trc, i; + + /* + * The table id, used for cache, and table_type, used for tcam, are + * both encoded within the resource. We must first extract them to + * formulate the args for tf calls. + */ + ulp_mapper_cache_res_type_get(res, &table_type, &table_id); + + cache_entry = ulp_mapper_cache_entry_get(ulp, table_id, + (uint16_t)res->resource_hndl); + if (!cache_entry || !cache_entry->ref_count) { + BNXT_TF_DBG(ERR, "Cache entry (%d:%d) not valid on free.\n", + table_id, (uint16_t)res->resource_hndl); + return -EINVAL; + } + + /* + * See if we need to delete the entry. The tcam and identifiers are all + * tracked by the cached entries reference count. All are deleted when + * the reference count hit zero. + */ + cache_entry->ref_count--; + if (cache_entry->ref_count) + return 0; + + /* + * Need to delete the tcam entry and the allocated identifiers. + * In the event of a failure, need to try to delete the remaining + * resources before returning error. + */ + tcam_parms.dir = res->direction; + tcam_parms.tcam_tbl_type = table_type; + tcam_parms.idx = cache_entry->tcam_idx; + rc = tf_free_tcam_entry(tfp, &tcam_parms); + if (rc) + BNXT_TF_DBG(ERR, "Failed to free tcam [%d][%s][0x%04x] rc=%d\n", + table_type, + (res->direction == TF_DIR_RX) ? "RX" : "TX", + tcam_parms.idx, rc); + + /* + * Free the identifiers associated with the tcam entry. Entries with + * negative one are considered uninitialized. + */ + for (i = 0; i < BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM; i++) { + if (cache_entry->idents[i] == ULP_IDENTS_INVALID) + continue; + + ident_parms.dir = res->direction; + ident_parms.ident_type = cache_entry->ident_types[i]; + ident_parms.id = cache_entry->idents[i]; + trc = tf_free_identifier(tfp, &ident_parms); + if (trc) { + BNXT_TF_DBG(ERR, "Failed to free identifier " + "[%d][%s][0x%04x] rc=%d\n", + ident_parms.ident_type, + (res->direction == TF_DIR_RX) ? "RX" : "TX", + ident_parms.id, trc); + rc = trc; + } + } + + return rc; +} + static inline int32_t ulp_mapper_tcam_entry_free(struct bnxt_ulp_context *ulp __rte_unused, struct tf *tfp, @@ -337,10 +467,16 @@ ulp_mapper_mark_free(struct bnxt_ulp_context *ulp, 0); } +/* + * Process the identifier instruction and either store it in the flow database + * or return it in the val (if not NULL) on success. If val is NULL, the + * identifier is to be stored in the flow database. + */ static int32_t ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms, struct bnxt_ulp_mapper_class_tbl_info *tbl, - struct bnxt_ulp_mapper_ident_info *ident) + struct bnxt_ulp_mapper_ident_info *ident, + uint16_t *val) { struct ulp_flow_db_res_params fid_parms; uint64_t id = 0; @@ -378,22 +514,26 @@ ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms, } /* Link the resource to the flow in the flow db */ - memset(&fid_parms, 0, sizeof(fid_parms)); - fid_parms.direction = tbl->direction; - fid_parms.resource_func = ident->resource_func; - fid_parms.resource_type = ident->ident_type; - fid_parms.resource_hndl = iparms.id; - fid_parms.critical_resource = 0; + if (!val) { + memset(&fid_parms, 0, sizeof(fid_parms)); + fid_parms.direction = tbl->direction; + fid_parms.resource_func = ident->resource_func; + fid_parms.resource_type = ident->ident_type; + fid_parms.resource_hndl = iparms.id; + fid_parms.critical_resource = 0; - rc = ulp_flow_db_resource_add(parms->ulp_ctx, - parms->tbl_idx, - parms->fid, - &fid_parms); - if (rc) { - BNXT_TF_DBG(ERR, "Failed to link resource to flow rc = %d\n", - rc); - /* Need to free the identifier, so goto error */ - goto error; + rc = ulp_flow_db_resource_add(parms->ulp_ctx, + parms->tbl_idx, + parms->fid, + &fid_parms); + if (rc) { + BNXT_TF_DBG(ERR, "Failed to link res to flow rc = %d\n", + rc); + /* Need to free the identifier, so goto error */ + goto error; + } + } else { + *val = iparms.id; } return 0; @@ -848,6 +988,12 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms, uint32_t hit = 0; uint16_t tmplen = 0; + /* Skip this if was handled by the cache. */ + if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP) { + parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL; + return 0; + } + tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx); if (!tfp) { BNXT_TF_DBG(ERR, "Failed to get truflow pointer\n"); @@ -930,15 +1076,22 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms, struct bnxt_ulp_mapper_ident_info *idents; uint32_t num_dflds, num_idents; - /* Alloc identifiers */ - idents = ulp_mapper_ident_fields_get(tbl, &num_idents); - - for (i = 0; i < num_idents; i++) { - rc = ulp_mapper_ident_process(parms, tbl, &idents[i]); - - /* Already logged the error, just return */ - if (rc) - goto error; + /* + * Since the cache entry is responsible for allocating + * identifiers when in use, allocate the identifiers only + * during normal processing. + */ + if (parms->tcam_tbl_opc == + BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL) { + idents = ulp_mapper_ident_fields_get(tbl, &num_idents); + + for (i = 0; i < num_idents; i++) { + rc = ulp_mapper_ident_process(parms, tbl, + &idents[i], NULL); + /* Already logged the error, just return */ + if (rc) + goto error; + } } /* Create the result data blob */ @@ -986,32 +1139,57 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms, sparms.idx); goto error; } + + /* Update cache with TCAM index if the was cache allocated. */ + if (parms->tcam_tbl_opc == + BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_ALLOC) { + if (!parms->cache_ptr) { + BNXT_TF_DBG(ERR, "Unable to update cache"); + rc = -EINVAL; + goto error; + } + parms->cache_ptr->tcam_idx = aparms.idx; + } + } else { BNXT_TF_DBG(ERR, "Not supporting search before alloc now\n"); rc = -EINVAL; goto error; } - /* Link the resource to the flow in the flow db */ - fid_parms.direction = tbl->direction; - fid_parms.resource_func = tbl->resource_func; - fid_parms.resource_type = tbl->table_type; - fid_parms.critical_resource = tbl->critical_resource; - fid_parms.resource_hndl = aparms.idx; - - rc = ulp_flow_db_resource_add(parms->ulp_ctx, - parms->tbl_idx, - parms->fid, - &fid_parms); - if (rc) { - BNXT_TF_DBG(ERR, "Failed to link resource to flow rc = %d\n", - rc); - /* Need to free the identifier, so goto error */ - goto error; + /* + * Only link the entry to the flow db in the event that cache was not + * used. + */ + if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL) { + fid_parms.direction = tbl->direction; + fid_parms.resource_func = tbl->resource_func; + fid_parms.resource_type = tbl->table_type; + fid_parms.critical_resource = tbl->critical_resource; + fid_parms.resource_hndl = aparms.idx; + rc = ulp_flow_db_resource_add(parms->ulp_ctx, + parms->tbl_idx, + parms->fid, + &fid_parms); + if (rc) { + BNXT_TF_DBG(ERR, + "Failed to link resource to flow rc = %d\n", + rc); + /* Need to free the identifier, so goto error */ + goto error; + } + } else { + /* + * Reset the tcam table opcode to normal in case the next tcam + * entry does not use cache. + */ + parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL; + parms->cache_ptr = NULL; } return 0; error: + parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL; free_parms.dir = tbl->direction; free_parms.tcam_tbl_type = tbl->table_type; free_parms.idx = aparms.idx; @@ -1324,6 +1502,153 @@ error: return rc; } +static int32_t +ulp_mapper_cache_tbl_process(struct bnxt_ulp_mapper_parms *parms, + struct bnxt_ulp_mapper_class_tbl_info *tbl) +{ + struct bnxt_ulp_mapper_class_key_field_info *kflds; + struct bnxt_ulp_mapper_cache_entry *cache_entry; + struct bnxt_ulp_mapper_ident_info *idents; + uint32_t i, num_kflds = 0, num_idents = 0; + struct ulp_flow_db_res_params fid_parms; + struct tf_free_identifier_parms fparms; + uint16_t tmplen, tmp_ident; + struct ulp_blob key; + uint8_t *cache_key; + uint64_t regval; + uint16_t *ckey; + int32_t rc; + + /* Get the key fields list and build the key. */ + kflds = ulp_mapper_key_fields_get(tbl, &num_kflds); + if (!kflds || !num_kflds) { + BNXT_TF_DBG(ERR, "Failed to get key fields\n"); + return -EINVAL; + } + if (!ulp_blob_init(&key, tbl->key_bit_size, parms->order)) { + BNXT_TF_DBG(ERR, "Failed to alloc blob\n"); + return -EINVAL; + } + for (i = 0; i < num_kflds; i++) { + /* Setup the key */ + rc = ulp_mapper_keymask_field_process(parms, tbl->direction, + &kflds[i], + &key, 1, "Cache Key"); + if (rc) { + BNXT_TF_DBG(ERR, + "Failed to create key for Cache rc=%d\n", + rc); + return -EINVAL; + } + } + + /* + * Perform the lookup in the cache table with constructed key. The + * cache_key is a byte array of tmplen, it needs to be converted to a + * index for the cache table. + */ + cache_key = ulp_blob_data_get(&key, &tmplen); + ckey = (uint16_t *)cache_key; + cache_entry = ulp_mapper_cache_entry_get(parms->ulp_ctx, + tbl->cache_tbl_id, + *ckey); + + /* + * Get the identifier list for processing by both the hit and miss + * processing. + */ + idents = ulp_mapper_ident_fields_get(tbl, &num_idents); + + if (!cache_entry->ref_count) { + /* Initialize the cache entry */ + cache_entry->tcam_idx = 0; + cache_entry->ref_count = 0; + for (i = 0; i < BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM; i++) + cache_entry->idents[i] = ULP_IDENTS_INVALID; + + /* Need to allocate identifiers for storing in the cache. */ + for (i = 0; i < num_idents; i++) { + /* + * Since we are using the cache, the identifier does not + * get added to the flow db. Pass in the pointer to the + * tmp_ident. + */ + rc = ulp_mapper_ident_process(parms, tbl, + &idents[i], &tmp_ident); + if (rc) + goto error; + + cache_entry->ident_types[i] = idents[i].ident_type; + cache_entry->idents[i] = tmp_ident; + } + + /* Tell the TCAM processor to alloc an entry */ + parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_ALLOC; + /* Store the cache key for use by the tcam process code */ + parms->cache_ptr = cache_entry; + } else { + /* Cache hit, get values from result. */ + for (i = 0; i < num_idents; i++) { + regval = (uint64_t)cache_entry->idents[i]; + if (!ulp_regfile_write(parms->regfile, + idents[i].regfile_wr_idx, + tfp_cpu_to_be_64(regval))) { + BNXT_TF_DBG(ERR, + "Failed to write to regfile\n"); + return -EINVAL; + } + } + /* + * The cached entry is being used, so let the tcam processing + * know not to process this table. + */ + parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP; + } + + /* Made through the cache processing, increment the reference count. */ + cache_entry->ref_count++; + + /* Link the cache to the flow db. */ + memset(&fid_parms, 0, sizeof(fid_parms)); + fid_parms.direction = tbl->direction; + fid_parms.resource_func = tbl->resource_func; + + /* + * Cache resource type is composed of both table_type and cache_tbl_id + * need to set it appropriately via setter. + */ + ulp_mapper_cache_res_type_set(&fid_parms, + tbl->table_type, + tbl->cache_tbl_id); + fid_parms.resource_hndl = (uint64_t)*ckey; + fid_parms.critical_resource = tbl->critical_resource; + rc = ulp_flow_db_resource_add(parms->ulp_ctx, + parms->tbl_idx, + parms->fid, + &fid_parms); + if (rc) + BNXT_TF_DBG(ERR, "Failed to add cache to flow db.\n"); + + return rc; +error: + /* + * This error handling only gets called when the idents are being + * allocated for the cache on misses. Using the num_idents that was + * previously set. + */ + for (i = 0; i < num_idents; i++) { + if (cache_entry->idents[i] == ULP_IDENTS_INVALID) + continue; + + fparms.dir = tbl->direction; + fparms.ident_type = idents[i].ident_type; + fparms.id = cache_entry->idents[i]; + tf_free_identifier(parms->tfp, &fparms); + } + + return rc; +} + /* * Function to process the action template. Iterate through the list * action info templates and process it. @@ -1378,6 +1703,9 @@ ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms) case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE: rc = ulp_mapper_index_tbl_process(parms, tbl); break; + case BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE: + rc = ulp_mapper_cache_tbl_process(parms, tbl); + break; default: BNXT_TF_DBG(ERR, "Unexpected class resource %d\n", tbl->resource_func); @@ -1413,6 +1741,9 @@ ulp_mapper_resource_free(struct bnxt_ulp_context *ulp, } switch (res->resource_func) { + case BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE: + rc = ulp_mapper_cache_entry_free(ulp, tfp, res); + break; case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE: rc = ulp_mapper_tcam_entry_free(ulp, tfp, res); break; @@ -1530,6 +1861,7 @@ ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx, parms.hdr_field = cparms->hdr_field; parms.tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx); parms.ulp_ctx = ulp_ctx; + parms.tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL; /* Get the device id from the ulp context */ if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) { @@ -1586,6 +1918,14 @@ ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx, return -EINVAL; } + rc = ulp_regfile_write(parms.regfile, + BNXT_ULP_REGFILE_INDEX_CLASS_TID, + tfp_cpu_to_be_64((uint64_t)parms.class_tid)); + if (!rc) { + BNXT_TF_DBG(ERR, "Unable to write template ID to regfile\n"); + return -EINVAL; + } + /* Allocate a Flow ID for attaching all resources for the flow to. * Once allocated, all errors have to walk the list of resources and * free each of them. @@ -1631,13 +1971,14 @@ flow_error: int32_t ulp_mapper_init(struct bnxt_ulp_context *ulp_ctx) { + struct bnxt_ulp_cache_tbl_params *tbl; struct tf_alloc_identifier_parms iparms; struct bnxt_ulp_mapper_data *data; struct bnxt_ulp_def_ident_info *dflt_ids; uint32_t i, num_dflt_ids, reg_idx; uint64_t regval; struct tf *tfp; - int32_t rc; + int32_t rc, csize; if (!ulp_ctx) return -EINVAL; @@ -1677,16 +2018,37 @@ ulp_mapper_init(struct bnxt_ulp_context *ulp_ctx) reg_idx = dflt_ids[i].def_regfile_index; /* All regfile entries are stored as 64bit big-endian values. */ regval = tfp_cpu_to_be_64((uint64_t)iparms.id); - if (ulp_mapper_def_regfile_write(data, - iparms.dir, - reg_idx, - regval)) { + rc = ulp_mapper_def_regfile_write(data, iparms.dir, + reg_idx, regval); + if (rc) { BNXT_TF_DBG(ERR, "Failed to write to default " "regfile.\n"); goto error; } } + /* Allocate the ulp cache tables. */ + for (i = 0; i < BNXT_ULP_CACHE_TBL_MAX_SZ; i++) { + tbl = ulp_mapper_cache_tbl_params_get(i); + if (!tbl) { + BNXT_TF_DBG(ERR, "Failed to get cache table parms (%d)", + i); + goto error; + } + if (tbl->num_entries != 0) { + csize = sizeof(struct bnxt_ulp_mapper_cache_entry) * + tbl->num_entries; + data->cache_tbl[i] = rte_zmalloc("ulp mapper cache tbl", + csize, 0); + if (!data->cache_tbl[i]) { + BNXT_TF_DBG(ERR, "Failed to allocate Cache " + "table %d.\n", i); + rc = -ENOMEM; + goto error; + } + } + } + return 0; error: /* Ignore the return code in favor of returning the original error. */ @@ -1750,6 +2112,12 @@ ulp_mapper_deinit(struct bnxt_ulp_context *ulp_ctx) } free_mapper_data: + /* Free the ulp cache tables */ + for (i = 0; i < BNXT_ULP_CACHE_TBL_MAX_SZ; i++) { + rte_free(data->cache_tbl[i]); + data->cache_tbl[i] = NULL; + } + rte_free(data); /* Reset the data pointer within the ulp_ctx. */ bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, NULL); diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.h b/drivers/net/bnxt/tf_ulp/ulp_mapper.h index fb47f1c279..162d869c82 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_mapper.h +++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.h @@ -16,6 +16,31 @@ #include "ulp_utils.h" #define ULP_SZ_BITS2BYTES(x) (((x) + 7) / 8) +#define ULP_IDENTS_INVALID ((uint16_t)0xffff) +#define ULP_MAPPER_CACHE_RES_TBL_ID_SHFT 16 +#define ULP_MAPPER_CACHE_RES_TBL_TYPE_SHFT 0 +#define ULP_MAPPER_CACHE_RES_TBL_MASK ((uint32_t)0x0000ffff) + +/* + * The cache table opcode is used to convey informat from the cache handler + * to the tcam handler. The opcodes do the following: + * NORMAL - tcam should process all instructions as normal + * SKIP - tcam is using the cached entry and doesn't need to process the + * instruction. + * ALLOC - tcam needs to allocate the tcam index and store in the cache entry + */ +enum bnxt_ulp_cache_table_opc { + BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL, + BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP, + BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_ALLOC +}; + +struct bnxt_ulp_mapper_cache_entry { + uint32_t ref_count; + uint16_t tcam_idx; + uint16_t idents[BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM]; + uint8_t ident_types[BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM]; +}; struct bnxt_ulp_mapper_def_id_entry { enum tf_identifier_type ident_type; @@ -25,6 +50,8 @@ struct bnxt_ulp_mapper_def_id_entry { struct bnxt_ulp_mapper_data { struct bnxt_ulp_mapper_def_id_entry dflt_ids[TF_DIR_MAX][BNXT_ULP_DEF_IDENT_INFO_TBL_MAX_SZ]; + struct bnxt_ulp_mapper_cache_entry + *cache_tbl[BNXT_ULP_CACHE_TBL_MAX_SZ]; }; /* Internal Structure for passing the arguments around */ @@ -47,6 +74,8 @@ struct bnxt_ulp_mapper_parms { uint32_t fid; enum bnxt_ulp_flow_db_tables tbl_idx; struct bnxt_ulp_mapper_data *mapper_data; + enum bnxt_ulp_cache_table_opc tcam_tbl_opc; + struct bnxt_ulp_mapper_cache_entry *cache_ptr; }; struct bnxt_ulp_mapper_create_parms { diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db.c b/drivers/net/bnxt/tf_ulp/ulp_template_db.c index cd3f65f7a0..86384169fb 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_template_db.c +++ b/drivers/net/bnxt/tf_ulp/ulp_template_db.c @@ -297,6 +297,21 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = { } }; +struct bnxt_ulp_cache_tbl_params ulp_cache_tbl_params[] = { + [BNXT_ULP_CACHE_TBL_ID_L2_CNTXT_TCAM_INGRESS] = { + .num_entries = 16384 + }, + [BNXT_ULP_CACHE_TBL_ID_L2_CNTXT_TCAM_EGRESS] = { + .num_entries = 16384 + }, + [BNXT_ULP_CACHE_TBL_ID_PROFILE_TCAM_INGRESS] = { + .num_entries = 16384 + }, + [BNXT_ULP_CACHE_TBL_ID_PROFILE_TCAM_EGRESS] = { + .num_entries = 16384 + } +}; + struct bnxt_ulp_def_ident_info ulp_def_ident_tbl[] = { [0] = { .ident_type = TF_IDENT_TYPE_PROF_FUNC, @@ -566,29 +581,70 @@ struct bnxt_ulp_mapper_tbl_list_info ulp_class_tmpl_list[] = { [((0 << BNXT_ULP_LOG2_MAX_NUM_DEV) | BNXT_ULP_DEVICE_ID_WH_PLUS)] = { .device_name = BNXT_ULP_DEVICE_ID_WH_PLUS, - .num_tbls = 3, + .num_tbls = 5, .start_tbl_idx = 0 } }; struct bnxt_ulp_mapper_class_tbl_info ulp_class_tbl_list[] = { + { + .resource_func = BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE, + .table_type = TF_TCAM_TBL_TYPE_L2_CTXT_TCAM, + .direction = TF_DIR_RX, + .priority = BNXT_ULP_PRIORITY_NOT_USED, + .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO, + .key_start_idx = 0, + .blob_key_bit_size = 12, + .key_bit_size = 12, + .key_num_fields = 2, + .result_start_idx = 0, + .result_bit_size = 10, + .result_num_fields = 1, + .ident_start_idx = 0, + .ident_nums = 1, + .mark_enable = BNXT_ULP_MARK_ENABLE_NO, + .critical_resource = 0, + .cache_tbl_id = BNXT_ULP_CACHE_TBL_ID_L2_CNTXT_TCAM_INGRESS, + .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_NOT_USED + }, { .resource_func = BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE, .table_type = TF_TCAM_TBL_TYPE_L2_CTXT_TCAM, .direction = TF_DIR_RX, .priority = BNXT_ULP_PRIORITY_LEVEL_0, .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO, - .key_start_idx = 0, + .key_start_idx = 2, .blob_key_bit_size = 167, .key_bit_size = 167, .key_num_fields = 13, - .result_start_idx = 0, + .result_start_idx = 1, .result_bit_size = 64, .result_num_fields = 13, - .ident_start_idx = 0, + .ident_start_idx = 1, + .ident_nums = 0, + .mark_enable = BNXT_ULP_MARK_ENABLE_NO, + .critical_resource = 0, + .cache_tbl_id = 0, + .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_NOT_USED + }, + { + .resource_func = BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE, + .table_type = TF_TCAM_TBL_TYPE_PROF_TCAM, + .direction = TF_DIR_RX, + .priority = BNXT_ULP_PRIORITY_NOT_USED, + .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO, + .key_start_idx = 15, + .blob_key_bit_size = 16, + .key_bit_size = 16, + .key_num_fields = 3, + .result_start_idx = 14, + .result_bit_size = 10, + .result_num_fields = 1, + .ident_start_idx = 1, .ident_nums = 1, .mark_enable = BNXT_ULP_MARK_ENABLE_NO, .critical_resource = 0, + .cache_tbl_id = BNXT_ULP_CACHE_TBL_ID_PROFILE_TCAM_INGRESS, .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_NOT_USED }, { @@ -597,17 +653,18 @@ struct bnxt_ulp_mapper_class_tbl_info ulp_class_tbl_list[] = { .direction = TF_DIR_RX, .priority = BNXT_ULP_PRIORITY_LEVEL_0, .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO, - .key_start_idx = 13, + .key_start_idx = 18, .blob_key_bit_size = 81, .key_bit_size = 81, .key_num_fields = 42, - .result_start_idx = 13, + .result_start_idx = 15, .result_bit_size = 38, .result_num_fields = 8, - .ident_start_idx = 1, - .ident_nums = 1, + .ident_start_idx = 2, + .ident_nums = 0, .mark_enable = BNXT_ULP_MARK_ENABLE_NO, .critical_resource = 0, + .cache_tbl_id = 0, .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_NOT_USED }, { @@ -616,22 +673,44 @@ struct bnxt_ulp_mapper_class_tbl_info ulp_class_tbl_list[] = { .direction = TF_DIR_RX, .priority = BNXT_ULP_PRIORITY_NOT_USED, .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO, - .key_start_idx = 55, + .key_start_idx = 60, .blob_key_bit_size = 448, .key_bit_size = 448, .key_num_fields = 11, - .result_start_idx = 21, + .result_start_idx = 23, .result_bit_size = 64, .result_num_fields = 9, .ident_start_idx = 2, .ident_nums = 0, .mark_enable = BNXT_ULP_MARK_ENABLE_YES, .critical_resource = 1, + .cache_tbl_id = 0, .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_NOT_USED } }; struct bnxt_ulp_mapper_class_key_field_info ulp_class_key_field_list[] = { + { + .field_bit_size = 8, + .mask_opcode = BNXT_ULP_MASK_OPC_SET_TO_CONSTANT, + .mask_operand = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .spec_opcode = BNXT_ULP_SPEC_OPC_SET_TO_HDR_FIELD, + .spec_operand = {(BNXT_ULP_HF0_IDX_SVIF_INDEX >> 8) & 0xff, + BNXT_ULP_HF0_IDX_SVIF_INDEX & 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, + { + .field_bit_size = 4, + .mask_opcode = BNXT_ULP_MASK_OPC_SET_TO_CONSTANT, + .mask_operand = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .spec_opcode = BNXT_ULP_SPEC_OPC_SET_TO_CONSTANT, + .spec_operand = {BNXT_ULP_SYM_TUN_HDR_TYPE_NONE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, { .field_bit_size = 12, .mask_opcode = BNXT_ULP_MASK_OPC_SET_TO_CONSTANT, @@ -754,6 +833,39 @@ struct bnxt_ulp_mapper_class_key_field_info ulp_class_key_field_list[] = { .spec_operand = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, + /* class template id: 0, wh_plus, table: profile_tcam_cache_0 */ + { + .field_bit_size = 1, + .mask_opcode = BNXT_ULP_MASK_OPC_SET_TO_CONSTANT, + .mask_operand = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .spec_opcode = BNXT_ULP_SPEC_OPC_SET_TO_CONSTANT, + .spec_operand = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, + { + .field_bit_size = 7, + .mask_opcode = BNXT_ULP_MASK_OPC_SET_TO_CONSTANT, + .mask_operand = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .spec_opcode = BNXT_ULP_SPEC_OPC_SET_TO_DEF_REGFILE, + .spec_operand = { + (BNXT_ULP_DEF_REGFILE_INDEX_DEF_PROF_FUNC_ID >> 8) & 0xff, + BNXT_ULP_DEF_REGFILE_INDEX_DEF_PROF_FUNC_ID & 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, + { + .field_bit_size = 8, + .mask_opcode = BNXT_ULP_MASK_OPC_SET_TO_CONSTANT, + .mask_operand = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .spec_opcode = BNXT_ULP_SPEC_OPC_SET_TO_REGFILE, + .spec_operand = {(BNXT_ULP_REGFILE_INDEX_CLASS_TID >> 8) & 0xff, + BNXT_ULP_REGFILE_INDEX_CLASS_TID & 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, { .field_bit_size = 1, .mask_opcode = BNXT_ULP_MASK_OPC_SET_TO_CONSTANT, @@ -1257,6 +1369,14 @@ struct bnxt_ulp_mapper_class_key_field_info ulp_class_key_field_list[] = { }; struct bnxt_ulp_mapper_result_field_info ulp_class_result_field_list[] = { + { + .field_bit_size = 10, + .result_opcode = BNXT_ULP_RESULT_OPC_SET_TO_REGFILE, + .result_operand = {(BNXT_ULP_REGFILE_INDEX_L2_CNTXT_ID_0 >> 8) & 0xff, + BNXT_ULP_REGFILE_INDEX_L2_CNTXT_ID_0 & 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, { .field_bit_size = 10, .result_opcode = BNXT_ULP_RESULT_OPC_SET_TO_REGFILE, @@ -1340,6 +1460,15 @@ struct bnxt_ulp_mapper_result_field_info ulp_class_result_field_list[] = { .result_operand = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, + + { + .field_bit_size = 10, + .result_opcode = BNXT_ULP_RESULT_OPC_SET_TO_REGFILE, + .result_operand = {(BNXT_ULP_REGFILE_INDEX_EM_PROFILE_ID_0 >> 8) & 0xff, + BNXT_ULP_REGFILE_INDEX_EM_PROFILE_ID_0 & 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, { .field_bit_size = 4, .result_opcode = BNXT_ULP_RESULT_OPC_SET_TO_CONSTANT, @@ -1458,14 +1587,14 @@ struct bnxt_ulp_mapper_ident_info ulp_ident_list[] = { .ident_type = TF_IDENT_TYPE_L2_CTXT, .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_L2_CNTXT_ID_0, .ident_bit_size = 10, - .ident_bit_pos = 54 + .ident_bit_pos = 0 }, { .resource_func = BNXT_ULP_RESOURCE_FUNC_IDENTIFIER, .ident_type = TF_IDENT_TYPE_EM_PROF, .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_EM_PROFILE_ID_0, - .ident_bit_size = 8, - .ident_bit_pos = 2 + .ident_bit_size = 10, + .ident_bit_pos = 0 } }; diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db.h b/drivers/net/bnxt/tf_ulp/ulp_template_db.h index cf4ff9f39b..a5606bdc4e 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_template_db.h +++ b/drivers/net/bnxt/tf_ulp/ulp_template_db.h @@ -11,9 +11,10 @@ #ifndef ULP_TEMPLATE_DB_H_ #define ULP_TEMPLATE_DB_H_ -#define BNXT_ULP_REGFILE_MAX_SZ 15 +#define BNXT_ULP_REGFILE_MAX_SZ 16 #define BNXT_ULP_MAX_NUM_DEVICES 4 #define BNXT_ULP_LOG2_MAX_NUM_DEV 2 +#define BNXT_ULP_CACHE_TBL_MAX_SZ 4 #define BNXT_ULP_CLASS_SIG_TBL_MAX_SZ 256 #define BNXT_ULP_CLASS_MATCH_LIST_MAX_SZ 2 #define BNXT_ULP_CLASS_HID_LOW_PRIME 7919 @@ -28,6 +29,7 @@ #define BNXT_ULP_ACT_HID_SHFTR 0 #define BNXT_ULP_ACT_HID_SHFTL 23 #define BNXT_ULP_ACT_HID_MASK 255 +#define BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM 2 #define BNXT_ULP_DEF_IDENT_INFO_TBL_MAX_SZ 1 enum bnxt_ulp_action_bit { @@ -95,6 +97,14 @@ enum bnxt_ulp_byte_order { BNXT_ULP_BYTE_ORDER_LAST = 2 }; +enum bnxt_ulp_cache_tbl_id { + BNXT_ULP_CACHE_TBL_ID_L2_CNTXT_TCAM_INGRESS = 0, + BNXT_ULP_CACHE_TBL_ID_L2_CNTXT_TCAM_EGRESS = 1, + BNXT_ULP_CACHE_TBL_ID_PROFILE_TCAM_INGRESS = 2, + BNXT_ULP_CACHE_TBL_ID_PROFILE_TCAM_EGRESS = 3, + BNXT_ULP_CACHE_TBL_ID_LAST = 4 +}; + enum bnxt_ulp_chf_idx { BNXT_ULP_CHF_IDX_MPLS_TAG_NUM = 0, BNXT_ULP_CHF_IDX_O_VTAG_NUM = 1, @@ -188,17 +198,19 @@ enum bnxt_ulp_regfile_index { BNXT_ULP_REGFILE_INDEX_ENCAP_PTR_0 = 11, BNXT_ULP_REGFILE_INDEX_ENCAP_PTR_1 = 12, BNXT_ULP_REGFILE_INDEX_CRITICAL_RESOURCE = 13, - BNXT_ULP_REGFILE_INDEX_NOT_USED = 14, - BNXT_ULP_REGFILE_INDEX_LAST = 15 + BNXT_ULP_REGFILE_INDEX_CACHE_ENTRY_PTR = 14, + BNXT_ULP_REGFILE_INDEX_NOT_USED = 15, + BNXT_ULP_REGFILE_INDEX_LAST = 16 }; enum bnxt_ulp_resource_func { BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE = 0, BNXT_ULP_RESOURCE_FUNC_EM_TABLE = 1, BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE = 2, - BNXT_ULP_RESOURCE_FUNC_IDENTIFIER = 3, - BNXT_ULP_RESOURCE_FUNC_HW_FID = 4, - BNXT_ULP_RESOURCE_FUNC_LAST = 5 + BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE = 3, + BNXT_ULP_RESOURCE_FUNC_IDENTIFIER = 4, + BNXT_ULP_RESOURCE_FUNC_HW_FID = 5, + BNXT_ULP_RESOURCE_FUNC_LAST = 6 }; enum bnxt_ulp_result_opc { diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h index 476d5b9bb3..1bef5ab0e4 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h +++ b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h @@ -181,6 +181,8 @@ struct bnxt_ulp_mapper_class_tbl_info { uint8_t mark_enable; enum bnxt_ulp_regfile_index regfile_wr_idx; + + enum bnxt_ulp_cache_tbl_id cache_tbl_id; }; struct bnxt_ulp_mapper_act_tbl_info { @@ -228,6 +230,10 @@ struct bnxt_ulp_def_ident_info { enum bnxt_ulp_def_regfile_index def_regfile_index; }; +struct bnxt_ulp_cache_tbl_params { + uint16_t num_entries; +}; + /* * Flow Mapper Static Data Externs: * Access to the below static data should be done through access functions and @@ -296,4 +302,11 @@ extern uint32_t ulp_act_prop_map_table[]; * be initialized and where to store them. */ extern struct bnxt_ulp_def_ident_info ulp_def_ident_tbl[]; + +/* + * The ulp_cache_tbl_parms table provides the sizes of the cache tables the + * mapper must dynamically allocate during initialization. + */ +extern struct bnxt_ulp_cache_tbl_params ulp_cache_tbl_params[]; + #endif /* _ULP_TEMPLATE_STRUCT_H_ */