1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2020 Broadcom 3 * All rights reserved. 4 */ 5 6 /* Truflow Table APIs and supporting code */ 7 8 #include <rte_common.h> 9 10 #include "tf_tbl.h" 11 #include "tf_common.h" 12 #include "tf_rm.h" 13 #include "tf_util.h" 14 #include "tf_msg.h" 15 #include "tfp.h" 16 17 18 struct tf; 19 20 /** 21 * Table DBs. 22 */ 23 static void *tbl_db[TF_DIR_MAX]; 24 25 /** 26 * Table Shadow DBs 27 */ 28 /* static void *shadow_tbl_db[TF_DIR_MAX]; */ 29 30 /** 31 * Init flag, set on bind and cleared on unbind 32 */ 33 static uint8_t init; 34 35 /** 36 * Shadow init flag, set on bind and cleared on unbind 37 */ 38 /* static uint8_t shadow_init; */ 39 40 int 41 tf_tbl_bind(struct tf *tfp, 42 struct tf_tbl_cfg_parms *parms) 43 { 44 int rc; 45 int i; 46 struct tf_rm_create_db_parms db_cfg = { 0 }; 47 48 TF_CHECK_PARMS2(tfp, parms); 49 50 if (init) { 51 TFP_DRV_LOG(ERR, 52 "Table DB already initialized\n"); 53 return -EINVAL; 54 } 55 56 db_cfg.num_elements = parms->num_elements; 57 db_cfg.type = TF_DEVICE_MODULE_TYPE_TABLE; 58 db_cfg.num_elements = parms->num_elements; 59 db_cfg.cfg = parms->cfg; 60 61 for (i = 0; i < TF_DIR_MAX; i++) { 62 db_cfg.dir = i; 63 db_cfg.alloc_cnt = parms->resources->tbl_cnt[i].cnt; 64 db_cfg.rm_db = &tbl_db[i]; 65 rc = tf_rm_create_db(tfp, &db_cfg); 66 if (rc) { 67 TFP_DRV_LOG(ERR, 68 "%s: Table DB creation failed\n", 69 tf_dir_2_str(i)); 70 71 return rc; 72 } 73 } 74 75 init = 1; 76 77 TFP_DRV_LOG(INFO, 78 "Table Type - initialized\n"); 79 80 return 0; 81 } 82 83 int 84 tf_tbl_unbind(struct tf *tfp) 85 { 86 int rc; 87 int i; 88 struct tf_rm_free_db_parms fparms = { 0 }; 89 90 TF_CHECK_PARMS1(tfp); 91 92 /* Bail if nothing has been initialized */ 93 if (!init) { 94 TFP_DRV_LOG(INFO, 95 "No Table DBs created\n"); 96 return 0; 97 } 98 99 for (i = 0; i < TF_DIR_MAX; i++) { 100 fparms.dir = i; 101 fparms.rm_db = tbl_db[i]; 102 rc = tf_rm_free_db(tfp, &fparms); 103 if (rc) 104 return rc; 105 106 tbl_db[i] = NULL; 107 } 108 109 init = 0; 110 111 return 0; 112 } 113 114 int 115 tf_tbl_alloc(struct tf *tfp __rte_unused, 116 struct tf_tbl_alloc_parms *parms) 117 { 118 int rc; 119 uint32_t idx; 120 struct tf_rm_allocate_parms aparms = { 0 }; 121 122 TF_CHECK_PARMS2(tfp, parms); 123 124 if (!init) { 125 TFP_DRV_LOG(ERR, 126 "%s: No Table DBs created\n", 127 tf_dir_2_str(parms->dir)); 128 return -EINVAL; 129 } 130 131 /* Allocate requested element */ 132 aparms.rm_db = tbl_db[parms->dir]; 133 aparms.db_index = parms->type; 134 aparms.index = &idx; 135 rc = tf_rm_allocate(&aparms); 136 if (rc) { 137 TFP_DRV_LOG(ERR, 138 "%s: Failed allocate, type:%d\n", 139 tf_dir_2_str(parms->dir), 140 parms->type); 141 return rc; 142 } 143 144 *parms->idx = idx; 145 146 return 0; 147 } 148 149 int 150 tf_tbl_free(struct tf *tfp __rte_unused, 151 struct tf_tbl_free_parms *parms) 152 { 153 int rc; 154 struct tf_rm_is_allocated_parms aparms = { 0 }; 155 struct tf_rm_free_parms fparms = { 0 }; 156 int allocated = 0; 157 158 TF_CHECK_PARMS2(tfp, parms); 159 160 if (!init) { 161 TFP_DRV_LOG(ERR, 162 "%s: No Table DBs created\n", 163 tf_dir_2_str(parms->dir)); 164 return -EINVAL; 165 } 166 167 /* Check if element is in use */ 168 aparms.rm_db = tbl_db[parms->dir]; 169 aparms.db_index = parms->type; 170 aparms.index = parms->idx; 171 aparms.allocated = &allocated; 172 rc = tf_rm_is_allocated(&aparms); 173 if (rc) 174 return rc; 175 176 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { 177 TFP_DRV_LOG(ERR, 178 "%s: Entry already free, type:%d, index:%d\n", 179 tf_dir_2_str(parms->dir), 180 parms->type, 181 parms->idx); 182 return -EINVAL; 183 } 184 185 /* Free requested element */ 186 fparms.rm_db = tbl_db[parms->dir]; 187 fparms.db_index = parms->type; 188 fparms.index = parms->idx; 189 rc = tf_rm_free(&fparms); 190 if (rc) { 191 TFP_DRV_LOG(ERR, 192 "%s: Free failed, type:%d, index:%d\n", 193 tf_dir_2_str(parms->dir), 194 parms->type, 195 parms->idx); 196 return rc; 197 } 198 199 return 0; 200 } 201 202 int 203 tf_tbl_alloc_search(struct tf *tfp __rte_unused, 204 struct tf_tbl_alloc_search_parms *parms __rte_unused) 205 { 206 return 0; 207 } 208 209 int 210 tf_tbl_set(struct tf *tfp, 211 struct tf_tbl_set_parms *parms) 212 { 213 int rc; 214 int allocated = 0; 215 uint16_t hcapi_type; 216 struct tf_rm_is_allocated_parms aparms = { 0 }; 217 struct tf_rm_get_hcapi_parms hparms = { 0 }; 218 219 TF_CHECK_PARMS3(tfp, parms, parms->data); 220 221 if (!init) { 222 TFP_DRV_LOG(ERR, 223 "%s: No Table DBs created\n", 224 tf_dir_2_str(parms->dir)); 225 return -EINVAL; 226 } 227 228 /* Verify that the entry has been previously allocated */ 229 aparms.rm_db = tbl_db[parms->dir]; 230 aparms.db_index = parms->type; 231 aparms.index = parms->idx; 232 aparms.allocated = &allocated; 233 rc = tf_rm_is_allocated(&aparms); 234 if (rc) 235 return rc; 236 237 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { 238 TFP_DRV_LOG(ERR, 239 "%s, Invalid or not allocated index, type:%d, idx:%d\n", 240 tf_dir_2_str(parms->dir), 241 parms->type, 242 parms->idx); 243 return -EINVAL; 244 } 245 246 /* Set the entry */ 247 hparms.rm_db = tbl_db[parms->dir]; 248 hparms.db_index = parms->type; 249 hparms.hcapi_type = &hcapi_type; 250 rc = tf_rm_get_hcapi_type(&hparms); 251 if (rc) { 252 TFP_DRV_LOG(ERR, 253 "%s, Failed type lookup, type:%d, rc:%s\n", 254 tf_dir_2_str(parms->dir), 255 parms->type, 256 strerror(-rc)); 257 return rc; 258 } 259 260 rc = tf_msg_set_tbl_entry(tfp, 261 parms->dir, 262 hcapi_type, 263 parms->data_sz_in_bytes, 264 parms->data, 265 parms->idx); 266 if (rc) { 267 TFP_DRV_LOG(ERR, 268 "%s, Set failed, type:%d, rc:%s\n", 269 tf_dir_2_str(parms->dir), 270 parms->type, 271 strerror(-rc)); 272 return rc; 273 } 274 275 return 0; 276 } 277 278 int 279 tf_tbl_get(struct tf *tfp, 280 struct tf_tbl_get_parms *parms) 281 { 282 int rc; 283 uint16_t hcapi_type; 284 int allocated = 0; 285 struct tf_rm_is_allocated_parms aparms = { 0 }; 286 struct tf_rm_get_hcapi_parms hparms = { 0 }; 287 288 TF_CHECK_PARMS3(tfp, parms, parms->data); 289 290 if (!init) { 291 TFP_DRV_LOG(ERR, 292 "%s: No Table DBs created\n", 293 tf_dir_2_str(parms->dir)); 294 return -EINVAL; 295 } 296 297 /* Verify that the entry has been previously allocated */ 298 aparms.rm_db = tbl_db[parms->dir]; 299 aparms.db_index = parms->type; 300 aparms.index = parms->idx; 301 aparms.allocated = &allocated; 302 rc = tf_rm_is_allocated(&aparms); 303 if (rc) 304 return rc; 305 306 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { 307 TFP_DRV_LOG(ERR, 308 "%s, Invalid or not allocated index, type:%d, idx:%d\n", 309 tf_dir_2_str(parms->dir), 310 parms->type, 311 parms->idx); 312 return -EINVAL; 313 } 314 315 /* Set the entry */ 316 hparms.rm_db = tbl_db[parms->dir]; 317 hparms.db_index = parms->type; 318 hparms.hcapi_type = &hcapi_type; 319 rc = tf_rm_get_hcapi_type(&hparms); 320 if (rc) { 321 TFP_DRV_LOG(ERR, 322 "%s, Failed type lookup, type:%d, rc:%s\n", 323 tf_dir_2_str(parms->dir), 324 parms->type, 325 strerror(-rc)); 326 return rc; 327 } 328 329 /* Get the entry */ 330 rc = tf_msg_get_tbl_entry(tfp, 331 parms->dir, 332 hcapi_type, 333 parms->data_sz_in_bytes, 334 parms->data, 335 parms->idx); 336 if (rc) { 337 TFP_DRV_LOG(ERR, 338 "%s, Get failed, type:%d, rc:%s\n", 339 tf_dir_2_str(parms->dir), 340 parms->type, 341 strerror(-rc)); 342 return rc; 343 } 344 345 return 0; 346 } 347 348 int 349 tf_tbl_bulk_get(struct tf *tfp, 350 struct tf_tbl_get_bulk_parms *parms) 351 { 352 int rc; 353 int i; 354 uint16_t hcapi_type; 355 uint32_t idx; 356 int allocated = 0; 357 struct tf_rm_is_allocated_parms aparms = { 0 }; 358 struct tf_rm_get_hcapi_parms hparms = { 0 }; 359 360 TF_CHECK_PARMS2(tfp, parms); 361 362 if (!init) { 363 TFP_DRV_LOG(ERR, 364 "%s: No Table DBs created\n", 365 tf_dir_2_str(parms->dir)); 366 367 return -EINVAL; 368 } 369 /* Verify that the entries has been previously allocated */ 370 aparms.rm_db = tbl_db[parms->dir]; 371 aparms.db_index = parms->type; 372 aparms.allocated = &allocated; 373 idx = parms->starting_idx; 374 for (i = 0; i < parms->num_entries; i++) { 375 aparms.index = idx; 376 rc = tf_rm_is_allocated(&aparms); 377 if (rc) 378 return rc; 379 380 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { 381 TFP_DRV_LOG(ERR, 382 "%s, Invalid or not allocated index, type:%d, idx:%d\n", 383 tf_dir_2_str(parms->dir), 384 parms->type, 385 idx); 386 return -EINVAL; 387 } 388 idx++; 389 } 390 391 hparms.rm_db = tbl_db[parms->dir]; 392 hparms.db_index = parms->type; 393 hparms.hcapi_type = &hcapi_type; 394 rc = tf_rm_get_hcapi_type(&hparms); 395 if (rc) { 396 TFP_DRV_LOG(ERR, 397 "%s, Failed type lookup, type:%d, rc:%s\n", 398 tf_dir_2_str(parms->dir), 399 parms->type, 400 strerror(-rc)); 401 return rc; 402 } 403 404 /* Get the entries */ 405 rc = tf_msg_bulk_get_tbl_entry(tfp, 406 parms->dir, 407 hcapi_type, 408 parms->starting_idx, 409 parms->num_entries, 410 parms->entry_sz_in_bytes, 411 parms->physical_mem_addr); 412 if (rc) { 413 TFP_DRV_LOG(ERR, 414 "%s, Bulk get failed, type:%d, rc:%s\n", 415 tf_dir_2_str(parms->dir), 416 parms->type, 417 strerror(-rc)); 418 } 419 420 return rc; 421 } 422