xref: /dpdk/drivers/net/bnxt/tf_core/tf_identifier.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
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