1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2021 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <rte_common.h> 7 8 #include "tf_identifier.h" 9 #include "tf_shadow_identifier.h" 10 #include "tf_common.h" 11 #include "tf_rm.h" 12 #include "tf_util.h" 13 #include "tfp.h" 14 15 struct tf; 16 17 /** 18 * Identifier DBs. 19 */ 20 static void *ident_db[TF_DIR_MAX]; 21 22 /** 23 * Init flag, set on bind and cleared on unbind 24 */ 25 static uint8_t init; 26 27 /** 28 * Identifier shadow DBs. 29 */ 30 static void *ident_shadow_db[TF_DIR_MAX]; 31 32 /** 33 * Shadow DB Init flag, set on bind and cleared on unbind 34 */ 35 static uint8_t shadow_init; 36 37 int 38 tf_ident_bind(struct tf *tfp, 39 struct tf_ident_cfg_parms *parms) 40 { 41 int rc; 42 int i; 43 struct tf_rm_create_db_parms db_cfg = { 0 }; 44 struct tf_shadow_ident_cfg_parms shadow_cfg = { 0 }; 45 struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 }; 46 47 TF_CHECK_PARMS2(tfp, parms); 48 49 if (init) { 50 TFP_DRV_LOG(ERR, 51 "Identifier DB already initialized\n"); 52 return -EINVAL; 53 } 54 55 db_cfg.type = TF_DEVICE_MODULE_TYPE_IDENTIFIER; 56 db_cfg.num_elements = parms->num_elements; 57 db_cfg.cfg = parms->cfg; 58 59 for (i = 0; i < TF_DIR_MAX; i++) { 60 db_cfg.dir = i; 61 db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt; 62 db_cfg.rm_db = &ident_db[i]; 63 rc = tf_rm_create_db(tfp, &db_cfg); 64 if (rc) { 65 TFP_DRV_LOG(ERR, 66 "%s: Identifier DB creation failed\n", 67 tf_dir_2_str(i)); 68 69 return rc; 70 } 71 72 if (parms->shadow_copy) { 73 shadow_cfg.alloc_cnt = 74 parms->resources->ident_cnt[i].cnt; 75 shadow_cdb.num_elements = parms->num_elements; 76 shadow_cdb.tf_shadow_ident_db = &ident_shadow_db[i]; 77 shadow_cdb.cfg = &shadow_cfg; 78 rc = tf_shadow_ident_create_db(&shadow_cdb); 79 if (rc) { 80 TFP_DRV_LOG(ERR, 81 "%s: Ident shadow DB creation failed\n", 82 tf_dir_2_str(i)); 83 84 return rc; 85 } 86 shadow_init = 1; 87 } 88 } 89 90 init = 1; 91 92 TFP_DRV_LOG(INFO, 93 "Identifier - initialized\n"); 94 95 return 0; 96 } 97 98 int 99 tf_ident_unbind(struct tf *tfp) 100 { 101 int rc = 0; 102 int i; 103 struct tf_rm_free_db_parms fparms = { 0 }; 104 struct tf_shadow_ident_free_db_parms sparms = { 0 }; 105 106 TF_CHECK_PARMS1(tfp); 107 108 /* Bail if nothing has been initialized */ 109 if (!init) { 110 TFP_DRV_LOG(INFO, 111 "No Identifier DBs created\n"); 112 return 0; 113 } 114 115 for (i = 0; i < TF_DIR_MAX; i++) { 116 fparms.dir = i; 117 fparms.rm_db = ident_db[i]; 118 rc = tf_rm_free_db(tfp, &fparms); 119 if (rc) { 120 TFP_DRV_LOG(ERR, 121 "rm free failed on unbind\n"); 122 } 123 if (shadow_init) { 124 sparms.tf_shadow_ident_db = ident_shadow_db[i]; 125 rc = tf_shadow_ident_free_db(&sparms); 126 if (rc) { 127 /* TODO: If there are failures on unbind we 128 * really just have to try until all DBs are 129 * attempted to be cleared. 130 */ 131 } 132 ident_shadow_db[i] = NULL; 133 } 134 ident_db[i] = NULL; 135 } 136 137 init = 0; 138 shadow_init = 0; 139 140 return 0; 141 } 142 143 int 144 tf_ident_alloc(struct tf *tfp __rte_unused, 145 struct tf_ident_alloc_parms *parms) 146 { 147 int rc; 148 uint32_t id; 149 uint32_t base_id; 150 struct tf_rm_allocate_parms aparms = { 0 }; 151 struct tf_shadow_ident_insert_parms iparms = { 0 }; 152 153 TF_CHECK_PARMS2(tfp, parms); 154 155 if (!init) { 156 TFP_DRV_LOG(ERR, 157 "%s: No Identifier DBs created\n", 158 tf_dir_2_str(parms->dir)); 159 return -EINVAL; 160 } 161 162 /* Allocate requested element */ 163 aparms.rm_db = ident_db[parms->dir]; 164 aparms.db_index = parms->type; 165 aparms.index = &id; 166 aparms.base_index = &base_id; 167 rc = tf_rm_allocate(&aparms); 168 if (rc) { 169 TFP_DRV_LOG(ERR, 170 "%s: Failed allocate, type:%d\n", 171 tf_dir_2_str(parms->dir), 172 parms->type); 173 return rc; 174 } 175 176 if (shadow_init) { 177 iparms.tf_shadow_ident_db = ident_shadow_db[parms->dir]; 178 iparms.type = parms->type; 179 iparms.id = base_id; 180 181 rc = tf_shadow_ident_insert(&iparms); 182 if (rc) { 183 TFP_DRV_LOG(ERR, 184 "%s: Failed insert shadow DB, type:%d\n", 185 tf_dir_2_str(parms->dir), 186 parms->type); 187 return rc; 188 } 189 } 190 191 *parms->id = id; 192 193 return 0; 194 } 195 196 int 197 tf_ident_free(struct tf *tfp __rte_unused, 198 struct tf_ident_free_parms *parms) 199 { 200 int rc; 201 struct tf_rm_is_allocated_parms aparms = { 0 }; 202 struct tf_rm_free_parms fparms = { 0 }; 203 struct tf_shadow_ident_remove_parms rparms = { 0 }; 204 int allocated = 0; 205 uint32_t base_id; 206 207 TF_CHECK_PARMS2(tfp, parms); 208 209 if (!init) { 210 TFP_DRV_LOG(ERR, 211 "%s: No Identifier DBs created\n", 212 tf_dir_2_str(parms->dir)); 213 return -EINVAL; 214 } 215 216 /* Check if element is in use */ 217 aparms.rm_db = ident_db[parms->dir]; 218 aparms.db_index = parms->type; 219 aparms.index = parms->id; 220 aparms.base_index = &base_id; 221 aparms.allocated = &allocated; 222 rc = tf_rm_is_allocated(&aparms); 223 if (rc) 224 return rc; 225 226 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { 227 TFP_DRV_LOG(ERR, 228 "%s: Entry already free, type:%d, index:%d\n", 229 tf_dir_2_str(parms->dir), 230 parms->type, 231 parms->id); 232 return -EINVAL; 233 } 234 235 if (shadow_init) { 236 rparms.tf_shadow_ident_db = ident_shadow_db[parms->dir]; 237 rparms.type = parms->type; 238 rparms.id = base_id; 239 rparms.ref_cnt = parms->ref_cnt; 240 241 rc = tf_shadow_ident_remove(&rparms); 242 if (rc) { 243 TFP_DRV_LOG(ERR, 244 "%s: ref_cnt was 0 in shadow DB," 245 " type:%d, index:%d\n", 246 tf_dir_2_str(parms->dir), 247 parms->type, 248 parms->id); 249 return rc; 250 } 251 252 if (*rparms.ref_cnt > 0) 253 return 0; 254 } 255 256 /* Free requested element */ 257 fparms.rm_db = ident_db[parms->dir]; 258 fparms.db_index = parms->type; 259 fparms.index = parms->id; 260 rc = tf_rm_free(&fparms); 261 if (rc) { 262 TFP_DRV_LOG(ERR, 263 "%s: Free failed, type:%d, index:%d\n", 264 tf_dir_2_str(parms->dir), 265 parms->type, 266 parms->id); 267 return rc; 268 } 269 270 return 0; 271 } 272 273 int 274 tf_ident_search(struct tf *tfp __rte_unused, 275 struct tf_ident_search_parms *parms) 276 { 277 int rc; 278 struct tf_rm_is_allocated_parms aparms = { 0 }; 279 struct tf_shadow_ident_search_parms sparms = { 0 }; 280 int allocated = 0; 281 uint32_t base_id; 282 283 TF_CHECK_PARMS2(tfp, parms); 284 285 if (!init) { 286 TFP_DRV_LOG(ERR, 287 "%s: No Identifier DBs created\n", 288 tf_dir_2_str(parms->dir)); 289 return -EINVAL; 290 } 291 292 if (!shadow_init) { 293 TFP_DRV_LOG(ERR, 294 "%s: Identifier Shadow copy is not enabled\n", 295 tf_dir_2_str(parms->dir)); 296 return -EINVAL; 297 } 298 299 /* Check if element is in use */ 300 aparms.rm_db = ident_db[parms->dir]; 301 aparms.db_index = parms->type; 302 aparms.index = parms->search_id; 303 aparms.base_index = &base_id; 304 aparms.allocated = &allocated; 305 rc = tf_rm_is_allocated(&aparms); 306 if (rc) 307 return rc; 308 309 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { 310 TFP_DRV_LOG(ERR, 311 "%s: Entry not allocated, type:%d, index:%d\n", 312 tf_dir_2_str(parms->dir), 313 parms->type, 314 parms->search_id); 315 return -EINVAL; 316 } 317 318 sparms.tf_shadow_ident_db = ident_shadow_db[parms->dir]; 319 sparms.type = parms->type; 320 sparms.search_id = base_id; 321 sparms.hit = parms->hit; 322 sparms.ref_cnt = parms->ref_cnt; 323 324 rc = tf_shadow_ident_search(&sparms); 325 if (rc) { 326 TFP_DRV_LOG(ERR, 327 "%s: Failed search shadow DB, type:%d\n", 328 tf_dir_2_str(parms->dir), 329 parms->type); 330 return rc; 331 } 332 333 return 0; 334 } 335