xref: /dpdk/drivers/net/bnxt/tf_core/v3/tfo.c (revision 80317ff6adfde7f618a100098e068ad5512e8e22)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2022 Broadcom
3  * All rights reserved.
4  */
5 #include <stdio.h>
6 #include <errno.h>
7 #include <string.h>
8 #include "tfo.h"
9 #include "cfa_types.h"
10 #include "cfa_tim.h"
11 #include "bnxt.h"
12 
13 /** Table scope stored configuration
14  */
15 struct tfc_tsid_db {
16 	bool ts_valid; /**< Table scope is valid */
17 	bool ts_is_shared; /**< Table scope is shared */
18 	bool ts_is_bs_owner; /**< Backing store allocated by this instance (PF) */
19 	uint16_t ts_max_pools; /**< maximum pools per CPM instance */
20 	enum cfa_app_type ts_app; /**< application type TF/AFM */
21 	/** backing store memory config */
22 	struct tfc_ts_mem_cfg ts_mem[CFA_REGION_TYPE_MAX][CFA_DIR_MAX];
23 	/** pool info config */
24 	struct tfc_ts_pool_info ts_pool[CFA_DIR_MAX];
25 };
26 
27 /** TFC Object Signature
28  * This signature identifies the tfc object database and
29  * is used for pointer validation
30  */
31 #define TFC_OBJ_SIGNATURE 0xABACABAF
32 
33 /** TFC Object
34  * This data structure contains all data stored per bnxt port
35  * Access is restricted through set/get APIs.
36  *
37  * If a module (e.g. tbl_scope needs to store data, it should
38  * be added here and accessor functions created.
39  */
40 struct tfc_object {
41 	uint32_t signature; /**< TF object signature */
42 	uint16_t sid; /**< Session ID */
43 	bool is_pf; /**< port is a PF */
44 	struct cfa_bld_mpcinfo mpc_info; /**< MPC ops handle */
45 	struct tfc_tsid_db tsid_db[TFC_TBL_SCOPE_MAX]; /**< tsid database */
46 	/** TIM instance pointer (PF) - this is where the 4 instances
47 	 *  of the TPM (rx/tx_lkup, rx/tx_act) will be stored per shared
48 	 *  table scope.  Only valid on a PF.
49 	 */
50 	void *ts_tim;
51 };
52 
53 void tfo_open(void **tfo, bool is_pf)
54 {
55 	int rc;
56 	struct tfc_object *tfco = NULL;
57 	uint32_t tim_db_size;
58 
59 	if (tfo == NULL) {
60 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
61 		return;
62 	}
63 
64 	tfco = (struct tfc_object *)rte_zmalloc("tf", sizeof(*tfco), 0);
65 	if  (tfco == NULL)
66 		return;
67 
68 	tfco->signature = TFC_OBJ_SIGNATURE;
69 	tfco->is_pf = is_pf;
70 	tfco->sid = INVALID_SID;
71 	tfco->ts_tim = NULL;
72 
73 	/* Bind to the MPC builder */
74 	rc = cfa_bld_mpc_bind(CFA_P70, &tfco->mpc_info);
75 	if (rc) {
76 		PMD_DRV_LOG_LINE(ERR, "MPC bind failed");
77 		rte_free(tfco);
78 		*tfo = NULL;
79 		return;
80 	}
81 	if (is_pf) {
82 		/* Allocate TIM */
83 		rc = cfa_tim_query(TFC_TBL_SCOPE_MAX, CFA_REGION_TYPE_MAX,
84 				   &tim_db_size);
85 		if (rc)
86 			goto cleanup;
87 
88 		tfco->ts_tim = rte_zmalloc("TIM", tim_db_size, 0);
89 		if (tfco->ts_tim == NULL)
90 			goto cleanup;
91 
92 		rc = cfa_tim_open(tfco->ts_tim,
93 				  tim_db_size,
94 				  TFC_TBL_SCOPE_MAX,
95 				  CFA_REGION_TYPE_MAX);
96 		if (rc) {
97 			rte_free(tfco->ts_tim);
98 			tfco->ts_tim = NULL;
99 			goto cleanup;
100 		}
101 	}
102 
103 	*tfo = tfco;
104 	return;
105 
106  cleanup:
107 	if (tfco != NULL)
108 		rte_free(tfo);
109 }
110 
111 void tfo_close(void **tfo)
112 {
113 	struct tfc_object *tfco = (struct tfc_object *)(*tfo);
114 	enum cfa_region_type region;
115 	int dir;
116 	int tsid;
117 	void *tim;
118 	void *tpm;
119 
120 	if (*tfo && tfco->signature == TFC_OBJ_SIGNATURE) {
121 		/*  If TIM is setup free it and any TPMs */
122 		if (tfo_tim_get(*tfo, &tim))
123 			goto done;
124 
125 		if (!tim)
126 			goto done;
127 
128 		for (tsid = 0; tsid < TFC_TBL_SCOPE_MAX; tsid++) {
129 			for (region = 0; region < CFA_REGION_TYPE_MAX; region++) {
130 				for (dir = 0; dir < CFA_DIR_MAX; dir++) {
131 					tpm = NULL;
132 					cfa_tim_tpm_inst_get(tim,
133 							     tsid,
134 							     region,
135 							     dir,
136 							     &tpm);
137 					if (tpm) {
138 						cfa_tim_tpm_inst_set(tim,
139 								     tsid,
140 								     region,
141 								     dir,
142 								     NULL);
143 						rte_free(tpm);
144 					}
145 				}
146 			}
147 		}
148 		rte_free(tim);
149 		tfco->ts_tim = NULL;
150 done:
151 		rte_free(*tfo);
152 		*tfo = NULL;
153 	}
154 }
155 
156 int tfo_mpcinfo_get(void *tfo, struct cfa_bld_mpcinfo **mpc_info)
157 {
158 	struct tfc_object *tfco = (struct tfc_object *)tfo;
159 
160 	if (tfo == NULL) {
161 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
162 		return -EINVAL;
163 	}
164 
165 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
166 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
167 		return -EINVAL;
168 	}
169 
170 	*mpc_info = &tfco->mpc_info;
171 
172 	return 0;
173 }
174 
175 int tfo_ts_validate(void *tfo, uint8_t ts_tsid, bool *ts_valid)
176 {
177 	struct tfc_object *tfco = (struct tfc_object *)tfo;
178 	struct tfc_tsid_db *tsid_db;
179 
180 	if (tfo == NULL) {
181 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
182 		return -EINVAL;
183 	}
184 
185 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
186 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
187 		return -EINVAL;
188 	}
189 
190 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
191 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
192 		return -EINVAL;
193 	}
194 	tsid_db = &tfco->tsid_db[ts_tsid];
195 
196 	if (ts_valid)
197 		*ts_valid = tsid_db->ts_valid;
198 
199 	return 0;
200 }
201 
202 int tfo_ts_set(void *tfo, uint8_t ts_tsid, bool ts_is_shared,
203 	       enum cfa_app_type ts_app, bool ts_valid, uint16_t ts_max_pools)
204 {
205 	struct tfc_object *tfco = (struct tfc_object *)tfo;
206 	struct tfc_tsid_db *tsid_db;
207 
208 	if (tfo == NULL) {
209 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
210 		return -EINVAL;
211 	}
212 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
213 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
214 		return -EINVAL;
215 	}
216 
217 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
218 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
219 		return -EINVAL;
220 	}
221 
222 	tsid_db = &tfco->tsid_db[ts_tsid];
223 
224 	tsid_db->ts_valid = ts_valid;
225 	tsid_db->ts_is_shared = ts_is_shared;
226 	tsid_db->ts_app = ts_app;
227 	tsid_db->ts_max_pools = ts_max_pools;
228 
229 	return 0;
230 }
231 
232 int tfo_ts_get(void *tfo, uint8_t ts_tsid, bool *ts_is_shared,
233 	       enum cfa_app_type *ts_app, bool *ts_valid,
234 	       uint16_t *ts_max_pools)
235 {
236 	struct tfc_object *tfco = (struct tfc_object *)tfo;
237 	struct tfc_tsid_db *tsid_db;
238 
239 	if (tfo == NULL) {
240 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
241 		return -EINVAL;
242 	}
243 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
244 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
245 		return -EINVAL;
246 	}
247 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
248 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
249 		return -EINVAL;
250 	}
251 
252 	tsid_db = &tfco->tsid_db[ts_tsid];
253 
254 	if (ts_valid)
255 		*ts_valid = tsid_db->ts_valid;
256 
257 	if (ts_is_shared)
258 		*ts_is_shared = tsid_db->ts_is_shared;
259 
260 	if (ts_app)
261 		*ts_app = tsid_db->ts_app;
262 
263 	if (ts_max_pools)
264 		*ts_max_pools = tsid_db->ts_max_pools;
265 
266 	return 0;
267 }
268 
269 /** Set the table scope memory configuration for this direction
270  */
271 int tfo_ts_set_mem_cfg(void *tfo, uint8_t ts_tsid, enum cfa_dir dir,
272 		       enum cfa_region_type region, bool is_bs_owner,
273 		       struct tfc_ts_mem_cfg *mem_cfg)
274 {
275 	struct tfc_object *tfco = (struct tfc_object *)tfo;
276 	int rc = 0;
277 	struct tfc_tsid_db *tsid_db;
278 
279 	if (tfo == NULL) {
280 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
281 		return -EINVAL;
282 	}
283 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
284 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
285 		return -EINVAL;
286 	}
287 	if (mem_cfg == NULL) {
288 		PMD_DRV_LOG_LINE(ERR, "Invalid mem_cfg pointer");
289 		return -EINVAL;
290 	}
291 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
292 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
293 		return -EINVAL;
294 	}
295 
296 	tsid_db = &tfco->tsid_db[ts_tsid];
297 
298 	tsid_db->ts_mem[region][dir] = *mem_cfg;
299 	tsid_db->ts_is_bs_owner = is_bs_owner;
300 
301 	return rc;
302 }
303 
304 /** Get the table scope memory configuration for this direction
305  */
306 int tfo_ts_get_mem_cfg(void *tfo, uint8_t ts_tsid, enum cfa_dir dir,
307 		       enum cfa_region_type region, bool *is_bs_owner,
308 		       struct tfc_ts_mem_cfg *mem_cfg)
309 {
310 	struct tfc_object *tfco = (struct tfc_object *)tfo;
311 	int rc = 0;
312 	struct tfc_tsid_db *tsid_db;
313 
314 	if (tfo == NULL) {
315 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
316 		return -EINVAL;
317 	}
318 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
319 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
320 		return -EINVAL;
321 	}
322 	if (mem_cfg == NULL) {
323 		PMD_DRV_LOG_LINE(ERR, "Invalid mem_cfg pointer");
324 		return -EINVAL;
325 	}
326 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
327 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
328 		return -EINVAL;
329 	}
330 
331 	tsid_db = &tfco->tsid_db[ts_tsid];
332 
333 	*mem_cfg = tsid_db->ts_mem[region][dir];
334 	if (is_bs_owner)
335 		*is_bs_owner = tsid_db->ts_is_bs_owner;
336 
337 	return rc;
338 }
339 
340 /** Get the Pool Manager instance
341  */
342 int tfo_ts_get_cpm_inst(void *tfo, uint8_t ts_tsid, enum cfa_dir dir,
343 			struct tfc_cpm **cpm_lkup, struct tfc_cpm **cpm_act)
344 {
345 	int rc = 0;
346 	struct tfc_object *tfco = (struct tfc_object *)tfo;
347 	struct tfc_tsid_db *tsid_db;
348 
349 	if (tfo == NULL) {
350 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
351 		return -EINVAL;
352 	}
353 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
354 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
355 		return -EINVAL;
356 	}
357 	if (cpm_lkup == NULL) {
358 		PMD_DRV_LOG_LINE(ERR, "Invalid cpm_lkup pointer");
359 		return -EINVAL;
360 	}
361 	if (cpm_act == NULL) {
362 		PMD_DRV_LOG_LINE(ERR, "Invalid cpm_act pointer");
363 		return -EINVAL;
364 	}
365 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
366 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
367 		return -EINVAL;
368 	}
369 
370 	tsid_db = &tfco->tsid_db[ts_tsid];
371 
372 	*cpm_lkup = tsid_db->ts_pool[dir].lkup_cpm;
373 	*cpm_act = tsid_db->ts_pool[dir].act_cpm;
374 
375 	return rc;
376 }
377 /** Set the Pool Manager instance
378  */
379 int tfo_ts_set_cpm_inst(void *tfo, uint8_t ts_tsid, enum cfa_dir dir,
380 			struct tfc_cpm *cpm_lkup, struct tfc_cpm *cpm_act)
381 {
382 	int rc = 0;
383 	struct tfc_object *tfco = (struct tfc_object *)tfo;
384 	struct tfc_tsid_db *tsid_db;
385 
386 	if (tfo == NULL) {
387 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
388 		return -EINVAL;
389 	}
390 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
391 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
392 		return -EINVAL;
393 	}
394 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
395 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
396 		return -EINVAL;
397 	}
398 	tsid_db = &tfco->tsid_db[ts_tsid];
399 
400 	tsid_db->ts_pool[dir].lkup_cpm = cpm_lkup;
401 	tsid_db->ts_pool[dir].act_cpm = cpm_act;
402 
403 	return rc;
404 }
405 /** Set the table scope pool memory configuration for this direction
406  */
407 int tfo_ts_set_pool_info(void *tfo, uint8_t ts_tsid, enum cfa_dir dir,
408 			 struct tfc_ts_pool_info *ts_pool)
409 {
410 	struct tfc_object *tfco = (struct tfc_object *)tfo;
411 	int rc = 0;
412 	struct tfc_tsid_db *tsid_db;
413 
414 	if (tfo == NULL) {
415 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
416 		return -EINVAL;
417 	}
418 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
419 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
420 		return -EINVAL;
421 	}
422 	if (ts_pool == NULL) {
423 		PMD_DRV_LOG_LINE(ERR, "Invalid ts_pool pointer");
424 		return -EINVAL;
425 	}
426 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
427 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
428 		return -EINVAL;
429 	}
430 	tsid_db = &tfco->tsid_db[ts_tsid];
431 
432 	tsid_db->ts_pool[dir] = *ts_pool;
433 
434 	return rc;
435 }
436 
437 /** Get the table scope pool memory configuration for this direction
438  */
439 int tfo_ts_get_pool_info(void *tfo, uint8_t ts_tsid, enum cfa_dir dir,
440 			 struct tfc_ts_pool_info *ts_pool)
441 {
442 	struct tfc_object *tfco = (struct tfc_object *)tfo;
443 	int rc = 0;
444 	struct tfc_tsid_db *tsid_db;
445 
446 	if (tfo == NULL) {
447 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
448 		return -EINVAL;
449 	}
450 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
451 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
452 		return -EINVAL;
453 	}
454 	if (ts_pool == NULL) {
455 		PMD_DRV_LOG_LINE(ERR, "Invalid ts_pool pointer");
456 		return -EINVAL;
457 	}
458 	if (ts_tsid >= TFC_TBL_SCOPE_MAX) {
459 		PMD_DRV_LOG_LINE(ERR, "Invalid tsid %d", ts_tsid);
460 		return -EINVAL;
461 	}
462 	tsid_db = &tfco->tsid_db[ts_tsid];
463 
464 	*ts_pool = tsid_db->ts_pool[dir];
465 
466 	return rc;
467 }
468 
469 int tfo_sid_set(void *tfo, uint16_t sid)
470 {
471 	struct tfc_object *tfco = (struct tfc_object *)tfo;
472 
473 	if (tfo == NULL)  {
474 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
475 		return -EINVAL;
476 	}
477 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
478 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
479 		return -EINVAL;
480 	}
481 	if (tfco->sid != INVALID_SID && sid != INVALID_SID &&
482 	    tfco->sid != sid) {
483 		PMD_DRV_LOG_LINE(ERR,
484 				 "Cannot set SID %u, current session is %u",
485 				 sid, tfco->sid);
486 		return -EINVAL;
487 	}
488 
489 	tfco->sid = sid;
490 
491 	return 0;
492 }
493 
494 int tfo_sid_get(void *tfo, uint16_t *sid)
495 {
496 	struct tfc_object *tfco = (struct tfc_object *)tfo;
497 
498 	if (tfo == NULL) {
499 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
500 		return -EINVAL;
501 	}
502 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
503 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
504 		return -EINVAL;
505 	}
506 	if (sid == NULL) {
507 		PMD_DRV_LOG_LINE(ERR, "Invalid sid pointer");
508 		return -EINVAL;
509 	}
510 
511 	if (tfco->sid == INVALID_SID) {
512 		/* Session has not been created */
513 		return -ENODEV;
514 	}
515 
516 	*sid = tfco->sid;
517 
518 	return 0;
519 }
520 
521 int tfo_tim_set(void *tfo, void *tim)
522 {
523 	struct tfc_object *tfco = (struct tfc_object *)tfo;
524 
525 	if (tfo == NULL) {
526 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
527 		return -EINVAL;
528 	}
529 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
530 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
531 		return -EINVAL;
532 	}
533 	if (tim == NULL) {
534 		PMD_DRV_LOG_LINE(ERR, "Invalid tim pointer");
535 		return -EINVAL;
536 	}
537 
538 	if (tfco->ts_tim != NULL &&
539 	    tfco->ts_tim != tim) {
540 		PMD_DRV_LOG_LINE(ERR,
541 				 "Cannot set TS TIM, TIM is already set");
542 		return -EINVAL;
543 	}
544 
545 	tfco->ts_tim = tim;
546 
547 	return 0;
548 }
549 
550 int tfo_tim_get(void *tfo, void **tim)
551 {
552 	struct tfc_object *tfco = (struct tfc_object *)tfo;
553 
554 	if (tfo == NULL) {
555 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo pointer");
556 		return -EINVAL;
557 	}
558 	if (tfco->signature != TFC_OBJ_SIGNATURE) {
559 		PMD_DRV_LOG_LINE(ERR, "Invalid tfo object");
560 		return -EINVAL;
561 	}
562 	if (tim == NULL) {
563 		PMD_DRV_LOG_LINE(ERR, "Invalid tim pointer to pointer");
564 		return -EINVAL;
565 	}
566 	if (tfco->ts_tim == NULL) {
567 		/* ts tim could be null, no need to log error message */
568 		return -ENODEV;
569 	}
570 
571 	*tim = tfco->ts_tim;
572 
573 	return 0;
574 }
575