183f916bdSKishore Padmanabha /* SPDX-License-Identifier: BSD-3-Clause 283f916bdSKishore Padmanabha * Copyright(c) 2014-2023 Broadcom 383f916bdSKishore Padmanabha * All rights reserved. 483f916bdSKishore Padmanabha */ 583f916bdSKishore Padmanabha 683f916bdSKishore Padmanabha #include <rte_log.h> 783f916bdSKishore Padmanabha #include <rte_malloc.h> 883f916bdSKishore Padmanabha #include "tf_core.h" 983f916bdSKishore Padmanabha #include "ulp_mapper.h" 1083f916bdSKishore Padmanabha #include "ulp_alloc_tbl.h" 110c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h" 1283f916bdSKishore Padmanabha 1383f916bdSKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 1483f916bdSKishore Padmanabha #include "ulp_template_debug_proto.h" 1583f916bdSKishore Padmanabha #include "ulp_tf_debug.h" 1683f916bdSKishore Padmanabha #endif 1783f916bdSKishore Padmanabha 1883f916bdSKishore Padmanabha /* Retrieve the allocator table initialization parameters for the tbl_idx */ 1983f916bdSKishore Padmanabha static const struct bnxt_ulp_allocator_tbl_params* 2083f916bdSKishore Padmanabha ulp_allocator_tbl_params_get(struct bnxt_ulp_context *ulp_ctx, uint32_t tbl_idx) 2183f916bdSKishore Padmanabha { 2283f916bdSKishore Padmanabha struct bnxt_ulp_device_params *dparms; 2383f916bdSKishore Padmanabha const struct bnxt_ulp_allocator_tbl_params *alloc_tbl; 2483f916bdSKishore Padmanabha uint32_t dev_id; 2583f916bdSKishore Padmanabha 2683f916bdSKishore Padmanabha if (tbl_idx >= BNXT_ULP_ALLOCATOR_TBL_MAX_SZ) { 2783f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "Allocator table out of bounds %d\n", 2883f916bdSKishore Padmanabha tbl_idx); 2983f916bdSKishore Padmanabha return NULL; 3083f916bdSKishore Padmanabha } 3183f916bdSKishore Padmanabha 3283f916bdSKishore Padmanabha if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) 3383f916bdSKishore Padmanabha return NULL; 3483f916bdSKishore Padmanabha 3583f916bdSKishore Padmanabha dparms = bnxt_ulp_device_params_get(dev_id); 3683f916bdSKishore Padmanabha if (!dparms) { 3783f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to get device parms\n"); 3883f916bdSKishore Padmanabha return NULL; 3983f916bdSKishore Padmanabha } 4083f916bdSKishore Padmanabha 4183f916bdSKishore Padmanabha alloc_tbl = &dparms->allocator_tbl_params[tbl_idx]; 4283f916bdSKishore Padmanabha return alloc_tbl; 4383f916bdSKishore Padmanabha } 4483f916bdSKishore Padmanabha 4583f916bdSKishore Padmanabha /* 4683f916bdSKishore Padmanabha * Initialize the allocator table list 4783f916bdSKishore Padmanabha * 4883f916bdSKishore Padmanabha * mapper_data [in] Pointer to the mapper data and the allocator table is 4983f916bdSKishore Padmanabha * part of it 5083f916bdSKishore Padmanabha * 5183f916bdSKishore Padmanabha * returns 0 on success 5283f916bdSKishore Padmanabha */ 5383f916bdSKishore Padmanabha int32_t 5483f916bdSKishore Padmanabha ulp_allocator_tbl_list_init(struct bnxt_ulp_context *ulp_ctx, 5583f916bdSKishore Padmanabha struct bnxt_ulp_mapper_data *mapper_data) 5683f916bdSKishore Padmanabha { 5783f916bdSKishore Padmanabha const struct bnxt_ulp_allocator_tbl_params *tbl; 5883f916bdSKishore Padmanabha struct ulp_allocator_tbl_entry *entry; 5983f916bdSKishore Padmanabha uint32_t idx, pool_size; 6083f916bdSKishore Padmanabha 6183f916bdSKishore Padmanabha /* Allocate the generic tables. */ 6283f916bdSKishore Padmanabha for (idx = 0; idx < BNXT_ULP_ALLOCATOR_TBL_MAX_SZ; idx++) { 6383f916bdSKishore Padmanabha tbl = ulp_allocator_tbl_params_get(ulp_ctx, idx); 6483f916bdSKishore Padmanabha if (!tbl) { 6583f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to get alloc table parm %d\n", 6683f916bdSKishore Padmanabha idx); 6783f916bdSKishore Padmanabha return -EINVAL; 6883f916bdSKishore Padmanabha } 6983f916bdSKishore Padmanabha entry = &mapper_data->alloc_tbl[idx]; 7083f916bdSKishore Padmanabha 7183f916bdSKishore Padmanabha /* Allocate memory for result data and key data */ 7283f916bdSKishore Padmanabha if (tbl->num_entries != 0) { 7383f916bdSKishore Padmanabha /* assign the name */ 7483f916bdSKishore Padmanabha entry->alloc_tbl_name = tbl->name; 7583f916bdSKishore Padmanabha entry->num_entries = tbl->num_entries; 7683f916bdSKishore Padmanabha pool_size = BITALLOC_SIZEOF(tbl->num_entries); 7783f916bdSKishore Padmanabha /* allocate the big chunk of memory */ 7883f916bdSKishore Padmanabha entry->ulp_bitalloc = rte_zmalloc("ulp allocator", 7983f916bdSKishore Padmanabha pool_size, 0); 8083f916bdSKishore Padmanabha if (!entry->ulp_bitalloc) { 8183f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, 8283f916bdSKishore Padmanabha "%s:Fail to alloc bit alloc %d\n", 8383f916bdSKishore Padmanabha tbl->name, idx); 8483f916bdSKishore Padmanabha return -ENOMEM; 8583f916bdSKishore Padmanabha } 8683f916bdSKishore Padmanabha if (ba_init(entry->ulp_bitalloc, entry->num_entries, 8783f916bdSKishore Padmanabha true)) { 8883f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "%s:Unable to alloc ba %d\n", 8983f916bdSKishore Padmanabha tbl->name, idx); 9083f916bdSKishore Padmanabha return -ENOMEM; 9183f916bdSKishore Padmanabha } 9283f916bdSKishore Padmanabha } else { 9383f916bdSKishore Padmanabha BNXT_DRV_DBG(DEBUG, "%s:Unused alloc tbl entry is %d\n", 9483f916bdSKishore Padmanabha tbl->name, idx); 9583f916bdSKishore Padmanabha continue; 9683f916bdSKishore Padmanabha } 9783f916bdSKishore Padmanabha } 9883f916bdSKishore Padmanabha return 0; 9983f916bdSKishore Padmanabha } 10083f916bdSKishore Padmanabha 10183f916bdSKishore Padmanabha /* 10283f916bdSKishore Padmanabha * Free the allocator table list 10383f916bdSKishore Padmanabha * 10483f916bdSKishore Padmanabha * mapper_data [in] Pointer to the mapper data and the generic table is 10583f916bdSKishore Padmanabha * part of it 10683f916bdSKishore Padmanabha * 10783f916bdSKishore Padmanabha * returns 0 on success 10883f916bdSKishore Padmanabha */ 10983f916bdSKishore Padmanabha int32_t 11083f916bdSKishore Padmanabha ulp_allocator_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data) 11183f916bdSKishore Padmanabha { 11283f916bdSKishore Padmanabha struct ulp_allocator_tbl_entry *entry; 11383f916bdSKishore Padmanabha uint32_t idx; 11483f916bdSKishore Padmanabha 11583f916bdSKishore Padmanabha /* iterate the generic table. */ 11683f916bdSKishore Padmanabha for (idx = 0; idx < BNXT_ULP_ALLOCATOR_TBL_MAX_SZ; idx++) { 11783f916bdSKishore Padmanabha entry = &mapper_data->alloc_tbl[idx]; 11883f916bdSKishore Padmanabha if (entry->ulp_bitalloc) { 11983f916bdSKishore Padmanabha rte_free(entry->ulp_bitalloc); 12083f916bdSKishore Padmanabha entry->ulp_bitalloc = NULL; 12183f916bdSKishore Padmanabha } 12283f916bdSKishore Padmanabha } 12383f916bdSKishore Padmanabha /* success */ 12483f916bdSKishore Padmanabha return 0; 12583f916bdSKishore Padmanabha } 12683f916bdSKishore Padmanabha 12783f916bdSKishore Padmanabha /* 12883f916bdSKishore Padmanabha * utility function to calculate the table idx 12983f916bdSKishore Padmanabha * 13083f916bdSKishore Padmanabha * res_sub_type [in] - Resource sub type 13183f916bdSKishore Padmanabha * dir [in] - Direction 13283f916bdSKishore Padmanabha * 13383f916bdSKishore Padmanabha * returns None 13483f916bdSKishore Padmanabha */ 13583f916bdSKishore Padmanabha static int32_t 13683f916bdSKishore Padmanabha ulp_allocator_tbl_idx_calculate(uint32_t res_sub_type, uint32_t dir) 13783f916bdSKishore Padmanabha { 13883f916bdSKishore Padmanabha int32_t tbl_idx; 13983f916bdSKishore Padmanabha 14083f916bdSKishore Padmanabha /* Validate for direction */ 14183f916bdSKishore Padmanabha if (dir >= TF_DIR_MAX) { 14283f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "invalid argument %x\n", dir); 14383f916bdSKishore Padmanabha return -EINVAL; 14483f916bdSKishore Padmanabha } 14583f916bdSKishore Padmanabha tbl_idx = (res_sub_type << 1) | (dir & 0x1); 14683f916bdSKishore Padmanabha if (tbl_idx >= BNXT_ULP_ALLOCATOR_TBL_MAX_SZ) { 14783f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "invalid table index %x\n", tbl_idx); 14883f916bdSKishore Padmanabha return -EINVAL; 14983f916bdSKishore Padmanabha } 15083f916bdSKishore Padmanabha return tbl_idx; 15183f916bdSKishore Padmanabha } 15283f916bdSKishore Padmanabha 15383f916bdSKishore Padmanabha /* 15483f916bdSKishore Padmanabha * allocate a index from allocator 15583f916bdSKishore Padmanabha * 15683f916bdSKishore Padmanabha * mapper_data [in] Pointer to the mapper data and the allocator table is 15783f916bdSKishore Padmanabha * part of it 15883f916bdSKishore Padmanabha * 15983f916bdSKishore Padmanabha * returns index on success or negative number on failure 16083f916bdSKishore Padmanabha */ 16183f916bdSKishore Padmanabha int32_t 16283f916bdSKishore Padmanabha ulp_allocator_tbl_list_alloc(struct bnxt_ulp_mapper_data *mapper_data, 16383f916bdSKishore Padmanabha uint32_t res_sub_type, uint32_t dir, 16483f916bdSKishore Padmanabha int32_t *alloc_id) 16583f916bdSKishore Padmanabha { 16683f916bdSKishore Padmanabha struct ulp_allocator_tbl_entry *entry; 16783f916bdSKishore Padmanabha int32_t idx; 16883f916bdSKishore Padmanabha 16983f916bdSKishore Padmanabha idx = ulp_allocator_tbl_idx_calculate(res_sub_type, dir); 17083f916bdSKishore Padmanabha if (idx < 0) 17183f916bdSKishore Padmanabha return -EINVAL; 17283f916bdSKishore Padmanabha 17383f916bdSKishore Padmanabha entry = &mapper_data->alloc_tbl[idx]; 17483f916bdSKishore Padmanabha if (!entry->ulp_bitalloc || !entry->num_entries) { 17583f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "invalid table index %x\n", idx); 17683f916bdSKishore Padmanabha return -EINVAL; 17783f916bdSKishore Padmanabha } 17883f916bdSKishore Padmanabha *alloc_id = ba_alloc(entry->ulp_bitalloc); 17983f916bdSKishore Padmanabha 18083f916bdSKishore Padmanabha if (*alloc_id < 0) { 18183f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "unable to alloc index %x\n", idx); 18283f916bdSKishore Padmanabha return -ENOMEM; 18383f916bdSKishore Padmanabha } 184*d4b36fc5SKishore Padmanabha /* Not using zero index */ 185*d4b36fc5SKishore Padmanabha *alloc_id += 1; 18683f916bdSKishore Padmanabha return 0; 18783f916bdSKishore Padmanabha } 18883f916bdSKishore Padmanabha 18983f916bdSKishore Padmanabha /* 19083f916bdSKishore Padmanabha * free a index in allocator 19183f916bdSKishore Padmanabha * 19283f916bdSKishore Padmanabha * mapper_data [in] Pointer to the mapper data and the allocator table is 19383f916bdSKishore Padmanabha * part of it 19483f916bdSKishore Padmanabha * 19583f916bdSKishore Padmanabha * returns error 19683f916bdSKishore Padmanabha */ 19783f916bdSKishore Padmanabha int32_t 19883f916bdSKishore Padmanabha ulp_allocator_tbl_list_free(struct bnxt_ulp_mapper_data *mapper_data, 19983f916bdSKishore Padmanabha uint32_t res_sub_type, uint32_t dir, 20083f916bdSKishore Padmanabha int32_t index) 20183f916bdSKishore Padmanabha { 20283f916bdSKishore Padmanabha struct ulp_allocator_tbl_entry *entry; 20383f916bdSKishore Padmanabha int32_t rc; 20483f916bdSKishore Padmanabha int32_t idx; 20583f916bdSKishore Padmanabha 20683f916bdSKishore Padmanabha idx = ulp_allocator_tbl_idx_calculate(res_sub_type, dir); 20783f916bdSKishore Padmanabha if (idx < 0) 20883f916bdSKishore Padmanabha return -EINVAL; 20983f916bdSKishore Padmanabha 21083f916bdSKishore Padmanabha entry = &mapper_data->alloc_tbl[idx]; 21183f916bdSKishore Padmanabha if (!entry->ulp_bitalloc || !entry->num_entries) { 21283f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "invalid table index %x\n", idx); 21383f916bdSKishore Padmanabha return -EINVAL; 21483f916bdSKishore Padmanabha } 215*d4b36fc5SKishore Padmanabha /* not using zero index */ 216*d4b36fc5SKishore Padmanabha index -= 1; 21783f916bdSKishore Padmanabha if (index < 0 || index > entry->num_entries) { 21883f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "invalid alloc index %x\n", index); 21983f916bdSKishore Padmanabha return -EINVAL; 22083f916bdSKishore Padmanabha } 22183f916bdSKishore Padmanabha rc = ba_free(entry->ulp_bitalloc, index); 22283f916bdSKishore Padmanabha if (rc < 0) { 22383f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "%s:unable to free index %x\n", 22483f916bdSKishore Padmanabha entry->alloc_tbl_name, index); 22583f916bdSKishore Padmanabha return -EINVAL; 22683f916bdSKishore Padmanabha } 22783f916bdSKishore Padmanabha return 0; 22883f916bdSKishore Padmanabha } 229