xref: /dpdk/drivers/net/bnxt/tf_core/tf_identifier.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
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 #include "tf_session.h"
15 
16 struct tf;
17 
18 /**
19  * Identifier shadow DBs.
20  */
21 static void *ident_shadow_db[TF_DIR_MAX];
22 
23 /**
24  * Shadow DB Init flag, set on bind and cleared on unbind
25  */
26 static uint8_t shadow_init;
27 
28 int
29 tf_ident_bind(struct tf *tfp,
30 	      struct tf_ident_cfg_parms *parms)
31 {
32 	int rc;
33 	int db_rc[TF_DIR_MAX] = { 0 };
34 	int i;
35 	struct tf_rm_create_db_parms db_cfg = { 0 };
36 	struct tf_shadow_ident_cfg_parms shadow_cfg = { 0 };
37 	struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 };
38 	struct ident_rm_db *ident_db;
39 	struct tfp_calloc_parms cparms;
40 	struct tf_session *tfs;
41 
42 	TF_CHECK_PARMS2(tfp, parms);
43 
44 	/* Retrieve the session information */
45 	rc = tf_session_get_session_internal(tfp, &tfs);
46 	if (rc)
47 		return rc;
48 
49 	memset(&db_cfg, 0, sizeof(db_cfg));
50 	cparms.nitems = 1;
51 	cparms.size = sizeof(struct ident_rm_db);
52 	cparms.alignment = 0;
53 	if (tfp_calloc(&cparms) != 0) {
54 		TFP_DRV_LOG(ERR, "ident_rm_db alloc error %s\n",
55 			    strerror(ENOMEM));
56 		return -ENOMEM;
57 	}
58 
59 	ident_db = cparms.mem_va;
60 	for (i = 0; i < TF_DIR_MAX; i++)
61 		ident_db->ident_db[i] = NULL;
62 	tf_session_set_db(tfp, TF_MODULE_TYPE_IDENTIFIER, ident_db);
63 
64 	db_cfg.module = TF_MODULE_TYPE_IDENTIFIER;
65 	db_cfg.num_elements = parms->num_elements;
66 	db_cfg.cfg = parms->cfg;
67 
68 	for (i = 0; i < TF_DIR_MAX; i++) {
69 		db_cfg.rm_db = (void *)&ident_db->ident_db[i];
70 		db_cfg.dir = i;
71 		db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt;
72 		if (tf_session_is_shared_session(tfs) &&
73 			(!tf_session_is_shared_session_creator(tfs)))
74 			db_rc[i] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
75 		else
76 			db_rc[i] = tf_rm_create_db(tfp, &db_cfg);
77 
78 		if (parms->shadow_copy) {
79 			shadow_cfg.alloc_cnt =
80 				parms->resources->ident_cnt[i].cnt;
81 			shadow_cdb.num_elements = parms->num_elements;
82 			shadow_cdb.tf_shadow_ident_db = &ident_shadow_db[i];
83 			shadow_cdb.cfg = &shadow_cfg;
84 			rc = tf_shadow_ident_create_db(&shadow_cdb);
85 			if (rc) {
86 				TFP_DRV_LOG(ERR,
87 				    "%s: Ident shadow DB creation failed\n",
88 				    tf_dir_2_str(i));
89 
90 				return rc;
91 			}
92 			shadow_init = 1;
93 		}
94 	}
95 
96 	/* No db created */
97 	if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
98 		TFP_DRV_LOG(ERR, "No Identifier DB created\n");
99 		return db_rc[TF_DIR_RX];
100 	}
101 
102 	TFP_DRV_LOG(INFO,
103 		    "Identifier - initialized\n");
104 
105 	return 0;
106 }
107 
108 int
109 tf_ident_unbind(struct tf *tfp)
110 {
111 	int rc = 0;
112 	int i;
113 	struct tf_rm_free_db_parms fparms = { 0 };
114 	struct tf_shadow_ident_free_db_parms sparms = { 0 };
115 	struct ident_rm_db *ident_db;
116 	void *ident_db_ptr = NULL;
117 
118 	TF_CHECK_PARMS1(tfp);
119 
120 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
121 	if (rc)
122 		return 0;
123 	ident_db = (struct ident_rm_db *)ident_db_ptr;
124 
125 	for (i = 0; i < TF_DIR_MAX; i++) {
126 		if (ident_db->ident_db[i] == NULL)
127 			continue;
128 		fparms.rm_db = ident_db->ident_db[i];
129 		fparms.dir = i;
130 		rc = tf_rm_free_db(tfp, &fparms);
131 		if (rc) {
132 			TFP_DRV_LOG(ERR,
133 				    "rm free failed on unbind\n");
134 		}
135 		if (shadow_init) {
136 			sparms.tf_shadow_ident_db = ident_shadow_db[i];
137 			rc = tf_shadow_ident_free_db(&sparms);
138 			if (rc) {
139 				/* TODO: If there are failures on unbind we
140 				 * really just have to try until all DBs are
141 				 * attempted to be cleared.
142 				 */
143 			}
144 			ident_shadow_db[i] = NULL;
145 		}
146 		ident_db->ident_db[i] = NULL;
147 	}
148 
149 	shadow_init = 0;
150 
151 	return 0;
152 }
153 
154 int
155 tf_ident_alloc(struct tf *tfp __rte_unused,
156 	       struct tf_ident_alloc_parms *parms)
157 {
158 	int rc;
159 	uint32_t id;
160 	uint32_t base_id;
161 	struct tf_rm_allocate_parms aparms = { 0 };
162 	struct tf_shadow_ident_insert_parms iparms = { 0 };
163 	struct ident_rm_db *ident_db;
164 	void *ident_db_ptr = NULL;
165 
166 	TF_CHECK_PARMS2(tfp, parms);
167 
168 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
169 	if (rc) {
170 		TFP_DRV_LOG(ERR,
171 			    "Failed to get ident_db from session, rc:%s\n",
172 			    strerror(-rc));
173 		return rc;
174 	}
175 	ident_db = (struct ident_rm_db *)ident_db_ptr;
176 
177 	aparms.rm_db = ident_db->ident_db[parms->dir];
178 	aparms.subtype = parms->type;
179 	aparms.index = &id;
180 	aparms.base_index = &base_id;
181 	rc = tf_rm_allocate(&aparms);
182 	if (rc) {
183 		TFP_DRV_LOG(ERR,
184 			    "%s: Failed allocate, type:%d\n",
185 			    tf_dir_2_str(parms->dir),
186 			    parms->type);
187 		return rc;
188 	}
189 
190 	if (shadow_init) {
191 		iparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
192 		iparms.type = parms->type;
193 		iparms.id = base_id;
194 
195 		rc = tf_shadow_ident_insert(&iparms);
196 		if (rc) {
197 			TFP_DRV_LOG(ERR,
198 				    "%s: Failed insert shadow DB, type:%d\n",
199 				    tf_dir_2_str(parms->dir),
200 				    parms->type);
201 			return rc;
202 		}
203 	}
204 
205 	*parms->id = id;
206 
207 	return 0;
208 }
209 
210 int
211 tf_ident_free(struct tf *tfp __rte_unused,
212 	      struct tf_ident_free_parms *parms)
213 {
214 	int rc;
215 	struct tf_rm_is_allocated_parms aparms = { 0 };
216 	struct tf_rm_free_parms fparms = { 0 };
217 	struct tf_shadow_ident_remove_parms rparms = { 0 };
218 	int allocated = 0;
219 	uint32_t base_id;
220 	struct ident_rm_db *ident_db;
221 	void *ident_db_ptr = NULL;
222 
223 	TF_CHECK_PARMS2(tfp, parms);
224 
225 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
226 	if (rc) {
227 		TFP_DRV_LOG(ERR,
228 			    "Failed to get ident_db from session, rc:%s\n",
229 			    strerror(-rc));
230 		return rc;
231 	}
232 	ident_db = (struct ident_rm_db *)ident_db_ptr;
233 
234 	/* Check if element is in use */
235 	aparms.rm_db = ident_db->ident_db[parms->dir];
236 	aparms.subtype = parms->type;
237 	aparms.index = parms->id;
238 	aparms.base_index = &base_id;
239 	aparms.allocated = &allocated;
240 	rc = tf_rm_is_allocated(&aparms);
241 	if (rc)
242 		return rc;
243 
244 	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
245 		TFP_DRV_LOG(ERR,
246 			    "%s: Entry already free, type:%d, index:%d\n",
247 			    tf_dir_2_str(parms->dir),
248 			    parms->type,
249 			    parms->id);
250 		return -EINVAL;
251 	}
252 
253 	if (shadow_init) {
254 		rparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
255 		rparms.type = parms->type;
256 		rparms.id = base_id;
257 		rparms.ref_cnt = parms->ref_cnt;
258 
259 		rc = tf_shadow_ident_remove(&rparms);
260 		if (rc) {
261 			TFP_DRV_LOG(ERR,
262 				    "%s: ref_cnt was 0 in shadow DB,"
263 				    " type:%d, index:%d\n",
264 				    tf_dir_2_str(parms->dir),
265 				    parms->type,
266 				    parms->id);
267 			return rc;
268 		}
269 
270 		if (*rparms.ref_cnt > 0)
271 			return 0;
272 	}
273 
274 	/* Free requested element */
275 	fparms.rm_db = ident_db->ident_db[parms->dir];
276 	fparms.subtype = parms->type;
277 	fparms.index = parms->id;
278 	rc = tf_rm_free(&fparms);
279 	if (rc) {
280 		TFP_DRV_LOG(ERR,
281 			    "%s: Free failed, type:%d, index:%d\n",
282 			    tf_dir_2_str(parms->dir),
283 			    parms->type,
284 			    parms->id);
285 		return rc;
286 	}
287 
288 	return 0;
289 }
290 
291 int
292 tf_ident_search(struct tf *tfp __rte_unused,
293 		struct tf_ident_search_parms *parms)
294 {
295 	int rc;
296 	struct tf_rm_is_allocated_parms aparms = { 0 };
297 	struct tf_shadow_ident_search_parms sparms = { 0 };
298 	int allocated = 0;
299 	uint32_t base_id;
300 	struct ident_rm_db *ident_db;
301 	void *ident_db_ptr = NULL;
302 
303 	TF_CHECK_PARMS2(tfp, parms);
304 
305 	if (!shadow_init) {
306 		TFP_DRV_LOG(ERR,
307 			    "%s: Identifier Shadow copy is not enabled\n",
308 			    tf_dir_2_str(parms->dir));
309 		return -EINVAL;
310 	}
311 
312 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
313 	if (rc) {
314 		TFP_DRV_LOG(ERR,
315 			    "Failed to get ident_db from session, rc:%s\n",
316 			    strerror(-rc));
317 		return rc;
318 	}
319 	ident_db = (struct ident_rm_db *)ident_db_ptr;
320 
321 	/* Check if element is in use */
322 	aparms.rm_db = ident_db->ident_db[parms->dir];
323 	aparms.subtype = parms->type;
324 	aparms.index = parms->search_id;
325 	aparms.base_index = &base_id;
326 	aparms.allocated = &allocated;
327 	rc = tf_rm_is_allocated(&aparms);
328 	if (rc)
329 		return rc;
330 
331 	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
332 		TFP_DRV_LOG(ERR,
333 			    "%s: Entry not allocated, type:%d, index:%d\n",
334 			    tf_dir_2_str(parms->dir),
335 			    parms->type,
336 			    parms->search_id);
337 		return -EINVAL;
338 	}
339 
340 	sparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
341 	sparms.type = parms->type;
342 	sparms.search_id = base_id;
343 	sparms.hit = parms->hit;
344 	sparms.ref_cnt = parms->ref_cnt;
345 
346 	rc = tf_shadow_ident_search(&sparms);
347 	if (rc) {
348 		TFP_DRV_LOG(ERR,
349 			    "%s: Failed search shadow DB, type:%d\n",
350 			    tf_dir_2_str(parms->dir),
351 			    parms->type);
352 		return rc;
353 	}
354 
355 	return 0;
356 }
357 
358 int
359 tf_ident_get_resc_info(struct tf *tfp,
360 		       struct tf_identifier_resource_info *ident)
361 {
362 	int rc;
363 	int d;
364 	struct tf_resource_info *dinfo;
365 	struct tf_rm_get_alloc_info_parms ainfo;
366 	void *ident_db_ptr = NULL;
367 	struct ident_rm_db *ident_db;
368 
369 	TF_CHECK_PARMS2(tfp, ident);
370 
371 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
372 	if (rc == -ENOMEM)
373 		return 0; /* db doesn't exist */
374 	else if (rc)
375 		return rc; /* error getting db */
376 
377 	ident_db = (struct ident_rm_db *)ident_db_ptr;
378 
379 	/* check if reserved resource for WC is multiple of num_slices */
380 	for (d = 0; d < TF_DIR_MAX; d++) {
381 		ainfo.rm_db = ident_db->ident_db[d];
382 
383 		if (!ainfo.rm_db)
384 			continue;
385 
386 		dinfo = ident[d].info;
387 
388 		ainfo.info = (struct tf_rm_alloc_info *)dinfo;
389 		ainfo.subtype = 0;
390 		rc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX);
391 		if (rc)
392 			return rc;
393 	}
394 
395 	return 0;
396 }
397