1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2021 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <rte_log.h> 7 #include <rte_malloc.h> 8 #include "tf_core.h" 9 #include "tfp.h" 10 #include "ulp_mapper.h" 11 #include "ulp_flow_db.h" 12 13 /* Retrieve the generic table initialization parameters for the tbl_idx */ 14 static struct bnxt_ulp_generic_tbl_params* 15 ulp_mapper_gen_tbl_params_get(uint32_t tbl_idx) 16 { 17 if (tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ) 18 return NULL; 19 20 return &ulp_generic_tbl_params[tbl_idx]; 21 } 22 23 /* 24 * Initialize the generic table list 25 * 26 * mapper_data [in] Pointer to the mapper data and the generic table is 27 * part of it 28 * 29 * returns 0 on success 30 */ 31 int32_t 32 ulp_mapper_generic_tbl_list_init(struct bnxt_ulp_mapper_data *mapper_data) 33 { 34 struct bnxt_ulp_generic_tbl_params *tbl; 35 struct ulp_mapper_gen_tbl_list *entry; 36 uint32_t idx, size; 37 38 /* Allocate the generic tables. */ 39 for (idx = 0; idx < BNXT_ULP_GEN_TBL_MAX_SZ; idx++) { 40 tbl = ulp_mapper_gen_tbl_params_get(idx); 41 if (!tbl) { 42 BNXT_TF_DBG(ERR, "Failed to get gen table parms %d\n", 43 idx); 44 return -EINVAL; 45 } 46 entry = &mapper_data->gen_tbl_list[idx]; 47 if (tbl->result_num_entries != 0) { 48 /* add 4 bytes for reference count */ 49 entry->mem_data_size = (tbl->result_num_entries + 1) * 50 (tbl->result_num_bytes + sizeof(uint32_t)); 51 52 /* allocate the big chunk of memory */ 53 entry->mem_data = rte_zmalloc("ulp mapper gen tbl", 54 entry->mem_data_size, 0); 55 if (!entry->mem_data) { 56 BNXT_TF_DBG(ERR, 57 "Failed to allocate gen table %d\n", 58 idx); 59 return -ENOMEM; 60 } 61 /* Populate the generic table container */ 62 entry->container.num_elem = tbl->result_num_entries; 63 entry->container.byte_data_size = tbl->result_num_bytes; 64 entry->container.ref_count = 65 (uint32_t *)entry->mem_data; 66 size = sizeof(uint32_t) * (tbl->result_num_entries + 1); 67 entry->container.byte_data = &entry->mem_data[size]; 68 entry->container.byte_order = tbl->result_byte_order; 69 } 70 } 71 /* success */ 72 return 0; 73 } 74 75 /* 76 * Free the generic table list 77 * 78 * mapper_data [in] Pointer to the mapper data and the generic table is 79 * part of it 80 * 81 * returns 0 on success 82 */ 83 int32_t 84 ulp_mapper_generic_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data) 85 { 86 struct ulp_mapper_gen_tbl_list *tbl_list; 87 uint32_t idx; 88 89 /* iterate the generic table. */ 90 for (idx = 0; idx < BNXT_ULP_GEN_TBL_MAX_SZ; idx++) { 91 tbl_list = &mapper_data->gen_tbl_list[idx]; 92 if (tbl_list->mem_data) { 93 rte_free(tbl_list->mem_data); 94 tbl_list->mem_data = NULL; 95 } 96 } 97 /* success */ 98 return 0; 99 } 100 101 /* 102 * Get the generic table list entry 103 * 104 * ulp_ctxt [in] - Ptr to ulp_context 105 * tbl_idx [in] - Table index to the generic table list 106 * key [in] - Key index to the table 107 * entry [out] - output will include the entry if found 108 * 109 * returns 0 on success. 110 */ 111 int32_t 112 ulp_mapper_gen_tbl_entry_get(struct bnxt_ulp_context *ulp, 113 uint32_t tbl_idx, 114 uint32_t key, 115 struct ulp_mapper_gen_tbl_entry *entry) 116 { 117 struct bnxt_ulp_mapper_data *mapper_data; 118 struct ulp_mapper_gen_tbl_list *tbl_list; 119 120 mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp); 121 if (!mapper_data || tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ || 122 !entry) { 123 BNXT_TF_DBG(ERR, "invalid arguments %x:%x\n", tbl_idx, key); 124 return -EINVAL; 125 } 126 /* populate the output and return the values */ 127 tbl_list = &mapper_data->gen_tbl_list[tbl_idx]; 128 if (key > tbl_list->container.num_elem) { 129 BNXT_TF_DBG(ERR, "invalid key %x:%x\n", key, 130 tbl_list->container.num_elem); 131 return -EINVAL; 132 } 133 entry->ref_count = &tbl_list->container.ref_count[key]; 134 entry->byte_data_size = tbl_list->container.byte_data_size; 135 entry->byte_data = &tbl_list->container.byte_data[key * 136 entry->byte_data_size]; 137 entry->byte_order = tbl_list->container.byte_order; 138 return 0; 139 } 140 141 /* 142 * utility function to calculate the table idx 143 * 144 * res_sub_type [in] - Resource sub type 145 * dir [in] - Direction 146 * 147 * returns None 148 */ 149 int32_t 150 ulp_mapper_gen_tbl_idx_calculate(uint32_t res_sub_type, uint32_t dir) 151 { 152 int32_t tbl_idx; 153 154 /* Validate for direction */ 155 if (dir >= TF_DIR_MAX) { 156 BNXT_TF_DBG(ERR, "invalid argument %x\n", dir); 157 return -EINVAL; 158 } 159 tbl_idx = (res_sub_type << 1) | (dir & 0x1); 160 if (tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ) { 161 BNXT_TF_DBG(ERR, "invalid table index %x\n", tbl_idx); 162 return -EINVAL; 163 } 164 return tbl_idx; 165 } 166 167 /* 168 * Set the data in the generic table entry, Data is in Big endian format 169 * 170 * entry [in] - generic table entry 171 * len [in] - The length of the data in bits to be set 172 * data [in] - pointer to the data to be used for setting the value. 173 * data_size [in] - length of the data pointer in bytes. 174 * 175 * returns 0 on success 176 */ 177 int32_t 178 ulp_mapper_gen_tbl_entry_data_set(struct ulp_mapper_gen_tbl_entry *entry, 179 uint32_t len, uint8_t *data, 180 uint32_t data_size) 181 { 182 /* validate the null arguments */ 183 if (!entry || !data) { 184 BNXT_TF_DBG(ERR, "invalid argument\n"); 185 return -EINVAL; 186 } 187 188 /* check the size of the buffer for validation */ 189 if (len > ULP_BYTE_2_BITS(entry->byte_data_size) || 190 data_size < ULP_BITS_2_BYTE(len)) { 191 BNXT_TF_DBG(ERR, "invalid offset or length %x:%x\n", 192 len, entry->byte_data_size); 193 return -EINVAL; 194 } 195 memcpy(entry->byte_data, data, ULP_BITS_2_BYTE(len)); 196 return 0; 197 } 198 199 /* 200 * Get the data in the generic table entry, Data is in Big endian format 201 * 202 * entry [in] - generic table entry 203 * offset [in] - The offset in bits where the data has to get 204 * len [in] - The length of the data in bits to be get 205 * data [out] - pointer to the data to be used for setting the value. 206 * data_size [in] - The size of data in bytes 207 * 208 * returns 0 on success 209 */ 210 int32_t 211 ulp_mapper_gen_tbl_entry_data_get(struct ulp_mapper_gen_tbl_entry *entry, 212 uint32_t offset, uint32_t len, uint8_t *data, 213 uint32_t data_size) 214 { 215 /* validate the null arguments */ 216 if (!entry || !data) { 217 BNXT_TF_DBG(ERR, "invalid argument\n"); 218 return -EINVAL; 219 } 220 221 /* check the size of the buffer for validation */ 222 if ((offset + len) > ULP_BYTE_2_BITS(entry->byte_data_size) || 223 len > ULP_BYTE_2_BITS(data_size)) { 224 BNXT_TF_DBG(ERR, "invalid offset or length %x:%x:%x\n", 225 offset, len, entry->byte_data_size); 226 return -EINVAL; 227 } 228 if (entry->byte_order == BNXT_ULP_BYTE_ORDER_LE) 229 ulp_bs_pull_lsb(entry->byte_data, data, data_size, offset, len); 230 else 231 ulp_bs_pull_msb(entry->byte_data, data, offset, len); 232 233 return 0; 234 } 235 236 /* 237 * Free the generic table list entry 238 * 239 * ulp_ctx [in] - Pointer to the ulp context 240 * res [in] - Pointer to flow db resource entry 241 * 242 * returns 0 on success 243 */ 244 int32_t 245 ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx, 246 struct ulp_flow_db_res_params *res) 247 { 248 struct ulp_mapper_gen_tbl_entry entry; 249 int32_t tbl_idx; 250 uint32_t fid = 0; 251 252 /* Extract the resource sub type and direction */ 253 tbl_idx = ulp_mapper_gen_tbl_idx_calculate(res->resource_sub_type, 254 res->direction); 255 if (tbl_idx < 0) { 256 BNXT_TF_DBG(ERR, "invalid argument %x:%x\n", 257 res->resource_sub_type, res->direction); 258 return -EINVAL; 259 } 260 261 /* Get the generic table entry*/ 262 if (ulp_mapper_gen_tbl_entry_get(ulp_ctx, tbl_idx, res->resource_hndl, 263 &entry)) { 264 BNXT_TF_DBG(ERR, "Gen tbl entry get failed %x:%" PRIX64 "\n", 265 tbl_idx, res->resource_hndl); 266 return -EINVAL; 267 } 268 269 /* Decrement the reference count */ 270 if (!ULP_GEN_TBL_REF_CNT(&entry)) { 271 BNXT_TF_DBG(ERR, "generic table corrupt %x:%" PRIX64 "\n", 272 tbl_idx, res->resource_hndl); 273 return -EINVAL; 274 } 275 ULP_GEN_TBL_REF_CNT_DEC(&entry); 276 277 /* retain the details since there are other users */ 278 if (ULP_GEN_TBL_REF_CNT(&entry)) 279 return 0; 280 281 /* Delete the generic table entry. First extract the fid */ 282 if (ulp_mapper_gen_tbl_entry_data_get(&entry, ULP_GEN_TBL_FID_OFFSET, 283 ULP_GEN_TBL_FID_SIZE_BITS, 284 (uint8_t *)&fid, 285 sizeof(fid))) { 286 BNXT_TF_DBG(ERR, "Unable to get fid %x:%" PRIX64 "\n", 287 tbl_idx, res->resource_hndl); 288 return -EINVAL; 289 } 290 fid = tfp_be_to_cpu_32(fid); 291 292 /* Destroy the flow associated with the shared flow id */ 293 if (ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_RID, 294 fid)) 295 BNXT_TF_DBG(ERR, "Error in deleting shared flow id %x\n", fid); 296 297 /* clear the byte data of the generic table entry */ 298 memset(entry.byte_data, 0, entry.byte_data_size); 299 300 return 0; 301 } 302