1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2023 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <rte_log.h> 7 #include <rte_malloc.h> 8 #include "tf_core.h" 9 #include "ulp_mapper.h" 10 #include "ulp_alloc_tbl.h" 11 #include "bnxt_ulp_utils.h" 12 13 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 14 #include "ulp_template_debug_proto.h" 15 #include "ulp_tf_debug.h" 16 #endif 17 18 /* Retrieve the allocator table initialization parameters for the tbl_idx */ 19 static const struct bnxt_ulp_allocator_tbl_params* 20 ulp_allocator_tbl_params_get(struct bnxt_ulp_context *ulp_ctx, uint32_t tbl_idx) 21 { 22 struct bnxt_ulp_device_params *dparms; 23 const struct bnxt_ulp_allocator_tbl_params *alloc_tbl; 24 uint32_t dev_id; 25 26 if (tbl_idx >= BNXT_ULP_ALLOCATOR_TBL_MAX_SZ) { 27 BNXT_DRV_DBG(ERR, "Allocator table out of bounds %d\n", 28 tbl_idx); 29 return NULL; 30 } 31 32 if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) 33 return NULL; 34 35 dparms = bnxt_ulp_device_params_get(dev_id); 36 if (!dparms) { 37 BNXT_DRV_DBG(ERR, "Failed to get device parms\n"); 38 return NULL; 39 } 40 41 alloc_tbl = &dparms->allocator_tbl_params[tbl_idx]; 42 return alloc_tbl; 43 } 44 45 /* 46 * Initialize the allocator table list 47 * 48 * mapper_data [in] Pointer to the mapper data and the allocator table is 49 * part of it 50 * 51 * returns 0 on success 52 */ 53 int32_t 54 ulp_allocator_tbl_list_init(struct bnxt_ulp_context *ulp_ctx, 55 struct bnxt_ulp_mapper_data *mapper_data) 56 { 57 const struct bnxt_ulp_allocator_tbl_params *tbl; 58 struct ulp_allocator_tbl_entry *entry; 59 uint32_t idx, pool_size; 60 61 /* Allocate the generic tables. */ 62 for (idx = 0; idx < BNXT_ULP_ALLOCATOR_TBL_MAX_SZ; idx++) { 63 tbl = ulp_allocator_tbl_params_get(ulp_ctx, idx); 64 if (!tbl) { 65 BNXT_DRV_DBG(ERR, "Failed to get alloc table parm %d\n", 66 idx); 67 return -EINVAL; 68 } 69 entry = &mapper_data->alloc_tbl[idx]; 70 71 /* Allocate memory for result data and key data */ 72 if (tbl->num_entries != 0) { 73 /* assign the name */ 74 entry->alloc_tbl_name = tbl->name; 75 entry->num_entries = tbl->num_entries; 76 pool_size = BITALLOC_SIZEOF(tbl->num_entries); 77 /* allocate the big chunk of memory */ 78 entry->ulp_bitalloc = rte_zmalloc("ulp allocator", 79 pool_size, 0); 80 if (!entry->ulp_bitalloc) { 81 BNXT_DRV_DBG(ERR, 82 "%s:Fail to alloc bit alloc %d\n", 83 tbl->name, idx); 84 return -ENOMEM; 85 } 86 if (ba_init(entry->ulp_bitalloc, entry->num_entries, 87 true)) { 88 BNXT_DRV_DBG(ERR, "%s:Unable to alloc ba %d\n", 89 tbl->name, idx); 90 return -ENOMEM; 91 } 92 } else { 93 BNXT_DRV_DBG(DEBUG, "%s:Unused alloc tbl entry is %d\n", 94 tbl->name, idx); 95 continue; 96 } 97 } 98 return 0; 99 } 100 101 /* 102 * Free the allocator table list 103 * 104 * mapper_data [in] Pointer to the mapper data and the generic table is 105 * part of it 106 * 107 * returns 0 on success 108 */ 109 int32_t 110 ulp_allocator_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data) 111 { 112 struct ulp_allocator_tbl_entry *entry; 113 uint32_t idx; 114 115 /* iterate the generic table. */ 116 for (idx = 0; idx < BNXT_ULP_ALLOCATOR_TBL_MAX_SZ; idx++) { 117 entry = &mapper_data->alloc_tbl[idx]; 118 if (entry->ulp_bitalloc) { 119 rte_free(entry->ulp_bitalloc); 120 entry->ulp_bitalloc = NULL; 121 } 122 } 123 /* success */ 124 return 0; 125 } 126 127 /* 128 * utility function to calculate the table idx 129 * 130 * res_sub_type [in] - Resource sub type 131 * dir [in] - Direction 132 * 133 * returns None 134 */ 135 static int32_t 136 ulp_allocator_tbl_idx_calculate(uint32_t res_sub_type, uint32_t dir) 137 { 138 int32_t tbl_idx; 139 140 /* Validate for direction */ 141 if (dir >= TF_DIR_MAX) { 142 BNXT_DRV_DBG(ERR, "invalid argument %x\n", dir); 143 return -EINVAL; 144 } 145 tbl_idx = (res_sub_type << 1) | (dir & 0x1); 146 if (tbl_idx >= BNXT_ULP_ALLOCATOR_TBL_MAX_SZ) { 147 BNXT_DRV_DBG(ERR, "invalid table index %x\n", tbl_idx); 148 return -EINVAL; 149 } 150 return tbl_idx; 151 } 152 153 /* 154 * allocate a index from allocator 155 * 156 * mapper_data [in] Pointer to the mapper data and the allocator table is 157 * part of it 158 * 159 * returns index on success or negative number on failure 160 */ 161 int32_t 162 ulp_allocator_tbl_list_alloc(struct bnxt_ulp_mapper_data *mapper_data, 163 uint32_t res_sub_type, uint32_t dir, 164 int32_t *alloc_id) 165 { 166 struct ulp_allocator_tbl_entry *entry; 167 int32_t idx; 168 169 idx = ulp_allocator_tbl_idx_calculate(res_sub_type, dir); 170 if (idx < 0) 171 return -EINVAL; 172 173 entry = &mapper_data->alloc_tbl[idx]; 174 if (!entry->ulp_bitalloc || !entry->num_entries) { 175 BNXT_DRV_DBG(ERR, "invalid table index %x\n", idx); 176 return -EINVAL; 177 } 178 *alloc_id = ba_alloc(entry->ulp_bitalloc); 179 180 if (*alloc_id < 0) { 181 BNXT_DRV_DBG(ERR, "unable to alloc index %x\n", idx); 182 return -ENOMEM; 183 } 184 /* Not using zero index */ 185 *alloc_id += 1; 186 return 0; 187 } 188 189 /* 190 * free a index in allocator 191 * 192 * mapper_data [in] Pointer to the mapper data and the allocator table is 193 * part of it 194 * 195 * returns error 196 */ 197 int32_t 198 ulp_allocator_tbl_list_free(struct bnxt_ulp_mapper_data *mapper_data, 199 uint32_t res_sub_type, uint32_t dir, 200 int32_t index) 201 { 202 struct ulp_allocator_tbl_entry *entry; 203 int32_t rc; 204 int32_t idx; 205 206 idx = ulp_allocator_tbl_idx_calculate(res_sub_type, dir); 207 if (idx < 0) 208 return -EINVAL; 209 210 entry = &mapper_data->alloc_tbl[idx]; 211 if (!entry->ulp_bitalloc || !entry->num_entries) { 212 BNXT_DRV_DBG(ERR, "invalid table index %x\n", idx); 213 return -EINVAL; 214 } 215 /* not using zero index */ 216 index -= 1; 217 if (index < 0 || index > entry->num_entries) { 218 BNXT_DRV_DBG(ERR, "invalid alloc index %x\n", index); 219 return -EINVAL; 220 } 221 rc = ba_free(entry->ulp_bitalloc, index); 222 if (rc < 0) { 223 BNXT_DRV_DBG(ERR, "%s:unable to free index %x\n", 224 entry->alloc_tbl_name, index); 225 return -EINVAL; 226 } 227 return 0; 228 } 229