1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2023 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <rte_common.h> 7 8 #include "tf_identifier.h" 9 #include "tf_common.h" 10 #include "tf_rm.h" 11 #include "tf_util.h" 12 #include "tfp.h" 13 #include "tf_session.h" 14 15 struct tf; 16 17 int 18 tf_ident_bind(struct tf *tfp, 19 struct tf_ident_cfg_parms *parms) 20 { 21 int rc; 22 int db_rc[TF_DIR_MAX] = { 0 }; 23 int i; 24 struct tf_rm_create_db_parms db_cfg = { 0 }; 25 struct ident_rm_db *ident_db; 26 struct tfp_calloc_parms cparms; 27 struct tf_session *tfs; 28 29 TF_CHECK_PARMS2(tfp, parms); 30 31 /* Retrieve the session information */ 32 rc = tf_session_get_session_internal(tfp, &tfs); 33 if (rc) 34 return rc; 35 36 memset(&db_cfg, 0, sizeof(db_cfg)); 37 cparms.nitems = 1; 38 cparms.size = sizeof(struct ident_rm_db); 39 cparms.alignment = 0; 40 if (tfp_calloc(&cparms) != 0) { 41 TFP_DRV_LOG(ERR, "ident_rm_db alloc error %s\n", 42 strerror(ENOMEM)); 43 return -ENOMEM; 44 } 45 46 ident_db = cparms.mem_va; 47 for (i = 0; i < TF_DIR_MAX; i++) 48 ident_db->ident_db[i] = NULL; 49 tf_session_set_db(tfp, TF_MODULE_TYPE_IDENTIFIER, ident_db); 50 51 db_cfg.module = TF_MODULE_TYPE_IDENTIFIER; 52 db_cfg.num_elements = parms->num_elements; 53 db_cfg.cfg = parms->cfg; 54 55 for (i = 0; i < TF_DIR_MAX; i++) { 56 db_cfg.rm_db = (void *)&ident_db->ident_db[i]; 57 db_cfg.dir = i; 58 db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt; 59 if (tf_session_is_shared_session(tfs) && 60 (!tf_session_is_shared_session_creator(tfs))) 61 db_rc[i] = tf_rm_create_db_no_reservation(tfp, &db_cfg); 62 else 63 db_rc[i] = tf_rm_create_db(tfp, &db_cfg); 64 } 65 66 /* No db created */ 67 if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) { 68 TFP_DRV_LOG(ERR, "No Identifier DB created\n"); 69 return db_rc[TF_DIR_RX]; 70 } 71 72 TFP_DRV_LOG(INFO, 73 "Identifier - initialized\n"); 74 75 return 0; 76 } 77 78 int 79 tf_ident_unbind(struct tf *tfp) 80 { 81 int rc = 0; 82 int i; 83 struct tf_rm_free_db_parms fparms = { 0 }; 84 struct ident_rm_db *ident_db; 85 void *ident_db_ptr = NULL; 86 87 TF_CHECK_PARMS1(tfp); 88 89 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); 90 if (rc) 91 return 0; 92 93 ident_db = (struct ident_rm_db *)ident_db_ptr; 94 95 for (i = 0; i < TF_DIR_MAX; i++) { 96 if (ident_db->ident_db[i] == NULL) 97 continue; 98 fparms.rm_db = ident_db->ident_db[i]; 99 fparms.dir = i; 100 rc = tf_rm_free_db(tfp, &fparms); 101 if (rc) { 102 TFP_DRV_LOG(ERR, 103 "rm free failed on unbind\n"); 104 } 105 ident_db->ident_db[i] = NULL; 106 } 107 return 0; 108 } 109 110 int 111 tf_ident_alloc(struct tf *tfp __rte_unused, 112 struct tf_ident_alloc_parms *parms) 113 { 114 int rc; 115 uint32_t id; 116 uint32_t base_id; 117 struct tf_rm_allocate_parms aparms = { 0 }; 118 struct ident_rm_db *ident_db; 119 void *ident_db_ptr = NULL; 120 121 TF_CHECK_PARMS2(tfp, parms); 122 123 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); 124 if (rc) { 125 TFP_DRV_LOG(ERR, 126 "Failed to get ident_db from session, rc:%s\n", 127 strerror(-rc)); 128 return rc; 129 } 130 ident_db = (struct ident_rm_db *)ident_db_ptr; 131 132 aparms.rm_db = ident_db->ident_db[parms->dir]; 133 aparms.subtype = parms->type; 134 aparms.index = &id; 135 aparms.base_index = &base_id; 136 rc = tf_rm_allocate(&aparms); 137 if (rc) { 138 TFP_DRV_LOG(ERR, 139 "%s: Failed allocate, type:%d\n", 140 tf_dir_2_str(parms->dir), 141 parms->type); 142 return rc; 143 } 144 145 *parms->id = id; 146 return 0; 147 } 148 149 int 150 tf_ident_free(struct tf *tfp __rte_unused, 151 struct tf_ident_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 uint32_t base_id; 158 struct ident_rm_db *ident_db; 159 void *ident_db_ptr = NULL; 160 161 TF_CHECK_PARMS2(tfp, parms); 162 163 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); 164 if (rc) { 165 TFP_DRV_LOG(ERR, 166 "Failed to get ident_db from session, rc:%s\n", 167 strerror(-rc)); 168 return rc; 169 } 170 ident_db = (struct ident_rm_db *)ident_db_ptr; 171 172 /* Check if element is in use */ 173 aparms.rm_db = ident_db->ident_db[parms->dir]; 174 aparms.subtype = parms->type; 175 aparms.index = parms->id; 176 aparms.base_index = &base_id; 177 aparms.allocated = &allocated; 178 rc = tf_rm_is_allocated(&aparms); 179 if (rc) 180 return rc; 181 182 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { 183 TFP_DRV_LOG(ERR, 184 "%s: Entry already free, type:%d, index:%d\n", 185 tf_dir_2_str(parms->dir), 186 parms->type, 187 parms->id); 188 return -EINVAL; 189 } 190 191 /* Free requested element */ 192 fparms.rm_db = ident_db->ident_db[parms->dir]; 193 fparms.subtype = parms->type; 194 fparms.index = parms->id; 195 rc = tf_rm_free(&fparms); 196 if (rc) { 197 TFP_DRV_LOG(ERR, 198 "%s: Free failed, type:%d, index:%d\n", 199 tf_dir_2_str(parms->dir), 200 parms->type, 201 parms->id); 202 return rc; 203 } 204 205 return 0; 206 } 207 208 int 209 tf_ident_search(struct tf *tfp __rte_unused, 210 struct tf_ident_search_parms *parms) 211 { 212 int rc; 213 struct tf_rm_is_allocated_parms aparms = { 0 }; 214 int allocated = 0; 215 uint32_t base_id; 216 struct ident_rm_db *ident_db; 217 void *ident_db_ptr = NULL; 218 219 TF_CHECK_PARMS2(tfp, parms); 220 221 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); 222 if (rc) { 223 TFP_DRV_LOG(ERR, 224 "Failed to get ident_db from session, rc:%s\n", 225 strerror(-rc)); 226 return rc; 227 } 228 ident_db = (struct ident_rm_db *)ident_db_ptr; 229 230 /* Check if element is in use */ 231 aparms.rm_db = ident_db->ident_db[parms->dir]; 232 aparms.subtype = parms->type; 233 aparms.index = parms->search_id; 234 aparms.base_index = &base_id; 235 aparms.allocated = &allocated; 236 rc = tf_rm_is_allocated(&aparms); 237 if (rc) 238 return rc; 239 240 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { 241 TFP_DRV_LOG(ERR, 242 "%s: Entry not allocated, type:%d, index:%d\n", 243 tf_dir_2_str(parms->dir), 244 parms->type, 245 parms->search_id); 246 return -EINVAL; 247 } 248 return 0; 249 } 250 251 int 252 tf_ident_get_resc_info(struct tf *tfp, 253 struct tf_identifier_resource_info *ident) 254 { 255 int rc; 256 int d; 257 struct tf_resource_info *dinfo; 258 struct tf_rm_get_alloc_info_parms ainfo; 259 void *ident_db_ptr = NULL; 260 struct ident_rm_db *ident_db; 261 262 TF_CHECK_PARMS2(tfp, ident); 263 264 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); 265 if (rc == -ENOMEM) 266 return 0; /* db doesn't exist */ 267 else if (rc) 268 return rc; /* error getting db */ 269 270 ident_db = (struct ident_rm_db *)ident_db_ptr; 271 272 /* check if reserved resource for WC is multiple of num_slices */ 273 for (d = 0; d < TF_DIR_MAX; d++) { 274 ainfo.rm_db = ident_db->ident_db[d]; 275 276 if (!ainfo.rm_db) 277 continue; 278 279 dinfo = ident[d].info; 280 281 ainfo.info = (struct tf_rm_alloc_info *)dinfo; 282 ainfo.subtype = 0; 283 rc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX); 284 if (rc) 285 return rc; 286 } 287 288 return 0; 289 } 290