Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2019-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <string.h>
7 : : #include <rte_common.h>
8 : :
9 : : #include "tf_tcam.h"
10 : : #include "tf_common.h"
11 : : #include "tf_util.h"
12 : : #include "tf_rm.h"
13 : : #include "tf_device.h"
14 : : #include "tfp.h"
15 : : #include "tf_session.h"
16 : : #include "tf_msg.h"
17 : : #include "tf_tcam_mgr_msg.h"
18 : :
19 : : struct tf;
20 : :
21 : : int
22 : 0 : tf_tcam_bind(struct tf *tfp,
23 : : struct tf_tcam_cfg_parms *parms)
24 : : {
25 : : int rc;
26 : 0 : int db_rc[TF_DIR_MAX] = { 0 };
27 : : int d, t;
28 : : struct tf_rm_alloc_info info;
29 : : struct tf_rm_free_db_parms fparms;
30 : : struct tf_rm_create_db_parms db_cfg;
31 : : struct tf_tcam_resources local_tcam_cnt[TF_DIR_MAX];
32 : : struct tf_tcam_resources *tcam_cnt;
33 : : struct tf_rm_get_alloc_info_parms ainfo;
34 : 0 : uint16_t num_slices = 1;
35 : : struct tf_session *tfs;
36 : : struct tf_dev_info *dev;
37 : : struct tcam_rm_db *tcam_db;
38 : : struct tfp_calloc_parms cparms;
39 : : struct tf_resource_info resv_res[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX];
40 : : uint32_t rx_supported;
41 : : uint32_t tx_supported;
42 : : bool no_req = true;
43 : :
44 [ # # ]: 0 : TF_CHECK_PARMS2(tfp, parms);
45 : :
46 : : /* Retrieve the session information */
47 : 0 : rc = tf_session_get_session_internal(tfp, &tfs);
48 [ # # ]: 0 : if (rc)
49 : : return rc;
50 : :
51 : : /* Retrieve the device information */
52 : 0 : rc = tf_session_get_device(tfs, &dev);
53 [ # # ]: 0 : if (rc)
54 : : return rc;
55 : :
56 [ # # ]: 0 : if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
57 : : rc = -EOPNOTSUPP;
58 : 0 : TFP_DRV_LOG(ERR,
59 : : "Operation not supported, rc:%s\n",
60 : : strerror(-rc));
61 : 0 : return rc;
62 : : }
63 : :
64 : 0 : tcam_cnt = parms->resources->tcam_cnt;
65 : :
66 [ # # ]: 0 : for (d = 0; d < TF_DIR_MAX; d++) {
67 [ # # ]: 0 : for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
68 : 0 : rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, t, 0,
69 : : &num_slices);
70 [ # # ]: 0 : if (rc)
71 : 0 : return rc;
72 : :
73 [ # # ]: 0 : if (num_slices == 1)
74 : 0 : continue;
75 : :
76 [ # # ]: 0 : if (tcam_cnt[d].cnt[t] % num_slices) {
77 : 0 : TFP_DRV_LOG(ERR,
78 : : "%s: Requested num of %s entries "
79 : : "has to be multiple of %d\n",
80 : : tf_dir_2_str(d),
81 : : tf_tcam_tbl_2_str(t),
82 : : num_slices);
83 : 0 : return -EINVAL;
84 : : }
85 : : }
86 : : }
87 : :
88 : : memset(&db_cfg, 0, sizeof(db_cfg));
89 : 0 : cparms.nitems = 1;
90 : 0 : cparms.size = sizeof(struct tcam_rm_db);
91 : 0 : cparms.alignment = 0;
92 [ # # ]: 0 : if (tfp_calloc(&cparms) != 0) {
93 : 0 : TFP_DRV_LOG(ERR, "tcam_rm_db alloc error %s\n",
94 : : strerror(ENOMEM));
95 : 0 : return -ENOMEM;
96 : : }
97 : :
98 : 0 : tcam_db = cparms.mem_va;
99 [ # # ]: 0 : for (d = 0; d < TF_DIR_MAX; d++)
100 : 0 : tcam_db->tcam_db[d] = NULL;
101 : 0 : tf_session_set_db(tfp, TF_MODULE_TYPE_TCAM, tcam_db);
102 : :
103 : 0 : db_cfg.module = TF_MODULE_TYPE_TCAM;
104 : 0 : db_cfg.num_elements = parms->num_elements;
105 : 0 : db_cfg.cfg = parms->cfg;
106 : :
107 [ # # ]: 0 : for (d = 0; d < TF_DIR_MAX; d++) {
108 : 0 : db_cfg.dir = d;
109 : 0 : db_cfg.alloc_cnt = tcam_cnt[d].cnt;
110 : 0 : db_cfg.rm_db = (void *)&tcam_db->tcam_db[d];
111 [ # # # # ]: 0 : if (tf_session_is_shared_session(tfs) &&
112 : : (!tf_session_is_shared_session_creator(tfs)))
113 : 0 : db_rc[d] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
114 : : else
115 : 0 : db_rc[d] = tf_rm_create_db(tfp, &db_cfg);
116 : : }
117 : : /* No db created */
118 [ # # # # ]: 0 : if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
119 : 0 : TFP_DRV_LOG(ERR, "No TCAM DB created\n");
120 : 0 : return db_rc[TF_DIR_RX];
121 : : }
122 : :
123 : : /* Collect info on which entries were reserved. */
124 [ # # ]: 0 : for (d = 0; d < TF_DIR_MAX; d++) {
125 [ # # ]: 0 : for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
126 : : memset(&info, 0, sizeof(info));
127 [ # # ]: 0 : if (tcam_cnt[d].cnt[t] == 0) {
128 : 0 : resv_res[d][t].start = 0;
129 : 0 : resv_res[d][t].stride = 0;
130 : 0 : continue;
131 : : }
132 : 0 : ainfo.rm_db = tcam_db->tcam_db[d];
133 : 0 : ainfo.subtype = t;
134 : 0 : ainfo.info = &info;
135 : 0 : rc = tf_rm_get_info(&ainfo);
136 [ # # ]: 0 : if (rc)
137 : 0 : goto error;
138 : :
139 : 0 : rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, t, 0,
140 : : &num_slices);
141 [ # # ]: 0 : if (rc)
142 : 0 : return rc;
143 : :
144 [ # # ]: 0 : if (num_slices > 1) {
145 : : /* check if reserved resource for is multiple of
146 : : * num_slices
147 : : */
148 [ # # ]: 0 : if (info.entry.start % num_slices != 0 ||
149 [ # # ]: 0 : info.entry.stride % num_slices != 0) {
150 : 0 : TFP_DRV_LOG(ERR,
151 : : "%s: %s reserved resource"
152 : : " is not multiple of %d\n",
153 : : tf_dir_2_str(d),
154 : : tf_tcam_tbl_2_str(t),
155 : : num_slices);
156 : : rc = -EINVAL;
157 : 0 : goto error;
158 : : }
159 : : }
160 : :
161 : 0 : resv_res[d][t].start = info.entry.start;
162 : 0 : resv_res[d][t].stride = info.entry.stride;
163 : : }
164 : : }
165 : :
166 : 0 : rc = tf_tcam_mgr_bind_msg(tfp, dev, parms, resv_res);
167 [ # # ]: 0 : if (rc)
168 : : return rc;
169 : :
170 : 0 : rc = tf_tcam_mgr_qcaps_msg(tfp, dev,
171 : : &rx_supported, &tx_supported);
172 [ # # ]: 0 : if (rc)
173 : : return rc;
174 : :
175 [ # # ]: 0 : for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
176 [ # # ]: 0 : if (rx_supported & 1 << t)
177 : 0 : tfs->tcam_mgr_control[TF_DIR_RX][t] = 1;
178 [ # # ]: 0 : if (tx_supported & 1 << t)
179 : 0 : tfs->tcam_mgr_control[TF_DIR_TX][t] = 1;
180 : : }
181 : :
182 : : /*
183 : : * Make a local copy of tcam_cnt with only resources not managed by TCAM
184 : : * Manager requested.
185 : : */
186 : : memcpy(&local_tcam_cnt, tcam_cnt, sizeof(local_tcam_cnt));
187 : : tcam_cnt = local_tcam_cnt;
188 [ # # ]: 0 : for (d = 0; d < TF_DIR_MAX; d++) {
189 [ # # ]: 0 : for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
190 : : /* If controlled by TCAM Manager */
191 [ # # ]: 0 : if (tfs->tcam_mgr_control[d][t])
192 : 0 : tcam_cnt[d].cnt[t] = 0;
193 : : else if (tcam_cnt[d].cnt[t] > 0)
194 : : no_req = false;
195 : : }
196 : : }
197 : :
198 : : /* If no resources left to request */
199 : : if (no_req)
200 : : goto finished;
201 : :
202 : 0 : finished:
203 : 0 : TFP_DRV_LOG(INFO,
204 : : "TCAM - initialized\n");
205 : :
206 : 0 : return 0;
207 : 0 : error:
208 [ # # ]: 0 : for (d = 0; d < TF_DIR_MAX; d++) {
209 [ # # ]: 0 : if (tcam_db->tcam_db[d] != NULL) {
210 : : memset(&fparms, 0, sizeof(fparms));
211 : 0 : fparms.dir = d;
212 : 0 : fparms.rm_db = tcam_db->tcam_db[d];
213 : : /*
214 : : * Ignoring return here since we are in the error case
215 : : */
216 : 0 : (void)tf_rm_free_db(tfp, &fparms);
217 : :
218 : : tcam_db->tcam_db[d] = NULL;
219 : : }
220 : 0 : tcam_db->tcam_db[d] = NULL;
221 : 0 : tf_session_set_db(tfp, TF_MODULE_TYPE_TCAM, NULL);
222 : : }
223 : : return rc;
224 : : }
225 : :
226 : : int
227 : 0 : tf_tcam_unbind(struct tf *tfp)
228 : : {
229 : : int rc;
230 : : int i;
231 : : struct tf_rm_free_db_parms fparms;
232 : : struct tcam_rm_db *tcam_db;
233 : 0 : void *tcam_db_ptr = NULL;
234 : : struct tf_session *tfs;
235 : : struct tf_dev_info *dev;
236 [ # # ]: 0 : TF_CHECK_PARMS1(tfp);
237 : :
238 : : /* Retrieve the session information */
239 : 0 : rc = tf_session_get_session_internal(tfp, &tfs);
240 [ # # ]: 0 : if (rc)
241 : : return rc;
242 : :
243 : : /* Retrieve the device information */
244 : 0 : rc = tf_session_get_device(tfs, &dev);
245 [ # # ]: 0 : if (rc)
246 : : return rc;
247 : 0 : rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
248 [ # # ]: 0 : if (rc)
249 : : return 0;
250 : :
251 : 0 : tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
252 : :
253 [ # # ]: 0 : for (i = 0; i < TF_DIR_MAX; i++) {
254 [ # # ]: 0 : if (tcam_db->tcam_db[i] != NULL) {
255 : : memset(&fparms, 0, sizeof(fparms));
256 : 0 : fparms.dir = i;
257 : 0 : fparms.rm_db = tcam_db->tcam_db[i];
258 : 0 : rc = tf_rm_free_db(tfp, &fparms);
259 [ # # ]: 0 : if (rc)
260 : 0 : return rc;
261 : :
262 : 0 : tcam_db->tcam_db[i] = NULL;
263 : : }
264 : :
265 : : }
266 : :
267 : 0 : rc = tf_tcam_mgr_unbind_msg(tfp, dev);
268 [ # # ]: 0 : if (rc)
269 : 0 : return rc;
270 : :
271 : : return 0;
272 : : }
273 : :
274 : : int
275 : 0 : tf_tcam_alloc(struct tf *tfp,
276 : : struct tf_tcam_alloc_parms *parms)
277 : : {
278 : : int rc, i;
279 : : struct tf_session *tfs;
280 : : struct tf_dev_info *dev;
281 : : struct tf_rm_allocate_parms aparms;
282 : 0 : uint16_t num_slices = 1;
283 : : uint32_t index;
284 : : struct tcam_rm_db *tcam_db;
285 : 0 : void *tcam_db_ptr = NULL;
286 : :
287 [ # # ]: 0 : TF_CHECK_PARMS2(tfp, parms);
288 : :
289 : : /* Retrieve the session information */
290 : 0 : rc = tf_session_get_session_internal(tfp, &tfs);
291 [ # # ]: 0 : if (rc)
292 : : return rc;
293 : :
294 : : /* Retrieve the device information */
295 : 0 : rc = tf_session_get_device(tfs, &dev);
296 [ # # ]: 0 : if (rc)
297 : : return rc;
298 : :
299 [ # # ]: 0 : if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
300 : : rc = -EOPNOTSUPP;
301 : 0 : TFP_DRV_LOG(ERR,
302 : : "%s: Operation not supported, rc:%s\n",
303 : : tf_dir_2_str(parms->dir),
304 : : strerror(-rc));
305 : 0 : return rc;
306 : : }
307 : :
308 : : /* Need to retrieve number of slices based on the key_size */
309 : 0 : rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
310 : : parms->type,
311 : 0 : parms->key_size,
312 : : &num_slices);
313 [ # # ]: 0 : if (rc)
314 : : return rc;
315 : :
316 : : /* If TCAM controlled by TCAM Manager */
317 [ # # ]: 0 : if (tfs->tcam_mgr_control[parms->dir][parms->type])
318 : 0 : return tf_tcam_mgr_alloc_msg(tfp, dev, parms);
319 : 0 : rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
320 [ # # ]: 0 : if (rc) {
321 : 0 : TFP_DRV_LOG(ERR,
322 : : "Failed to get tcam_db from session, rc:%s\n",
323 : : strerror(-rc));
324 : 0 : return rc;
325 : : }
326 : 0 : tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
327 : :
328 : : /*
329 : : * For WC TCAM, number of slices could be 4, 2, 1 based on
330 : : * the key_size. For other TCAM, it is always 1
331 : : */
332 [ # # ]: 0 : for (i = 0; i < num_slices; i++) {
333 : : memset(&aparms, 0, sizeof(aparms));
334 : 0 : aparms.rm_db = tcam_db->tcam_db[parms->dir];
335 : 0 : aparms.subtype = parms->type;
336 : 0 : aparms.priority = parms->priority;
337 : 0 : aparms.index = &index;
338 : 0 : rc = tf_rm_allocate(&aparms);
339 [ # # ]: 0 : if (rc) {
340 : 0 : TFP_DRV_LOG(ERR,
341 : : "%s: Failed tcam, type:%d\n",
342 : : tf_dir_2_str(parms->dir),
343 : : parms->type);
344 : 0 : return rc;
345 : : }
346 : :
347 : : /* return the start index of each row */
348 [ # # ]: 0 : if (i == 0)
349 : 0 : parms->idx = index;
350 : : }
351 : :
352 : : return 0;
353 : : }
354 : :
355 : : int
356 : 0 : tf_tcam_free(struct tf *tfp,
357 : : struct tf_tcam_free_parms *parms)
358 : : {
359 : : int rc;
360 : : struct tf_session *tfs;
361 : : struct tf_dev_info *dev;
362 : : struct tf_rm_is_allocated_parms aparms;
363 : : struct tf_rm_free_parms fparms;
364 : : struct tf_rm_get_hcapi_parms hparms;
365 : 0 : uint16_t num_slices = 1;
366 : 0 : int allocated = 0;
367 : : int i;
368 : : struct tcam_rm_db *tcam_db;
369 : 0 : void *tcam_db_ptr = NULL;
370 : :
371 [ # # ]: 0 : TF_CHECK_PARMS2(tfp, parms);
372 : :
373 : : /* Retrieve the session information */
374 : 0 : rc = tf_session_get_session_internal(tfp, &tfs);
375 [ # # ]: 0 : if (rc)
376 : : return rc;
377 : :
378 : : /* Retrieve the device information */
379 : 0 : rc = tf_session_get_device(tfs, &dev);
380 [ # # ]: 0 : if (rc)
381 : : return rc;
382 : :
383 [ # # ]: 0 : if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
384 : : rc = -EOPNOTSUPP;
385 : 0 : TFP_DRV_LOG(ERR,
386 : : "%s: Operation not supported, rc:%s\n",
387 : : tf_dir_2_str(parms->dir),
388 : : strerror(-rc));
389 : 0 : return rc;
390 : : }
391 : :
392 : : /* Need to retrieve row size etc */
393 : 0 : rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
394 : : parms->type,
395 : : 0,
396 : : &num_slices);
397 [ # # ]: 0 : if (rc)
398 : : return rc;
399 : :
400 : : /* If TCAM controlled by TCAM Manager */
401 [ # # ]: 0 : if (tfs->tcam_mgr_control[parms->dir][parms->type])
402 : : /*
403 : : * If a session can have multiple references to an entry, check
404 : : * the reference count here before actually freeing the entry.
405 : : */
406 : 0 : return tf_tcam_mgr_free_msg(tfp, dev, parms);
407 : :
408 [ # # ]: 0 : if (parms->idx % num_slices) {
409 : 0 : TFP_DRV_LOG(ERR,
410 : : "%s: TCAM reserved resource is not multiple of %d\n",
411 : : tf_dir_2_str(parms->dir),
412 : : num_slices);
413 : 0 : return -EINVAL;
414 : : }
415 : :
416 : 0 : rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
417 [ # # ]: 0 : if (rc) {
418 : 0 : TFP_DRV_LOG(ERR,
419 : : "Failed to get em_ext_db from session, rc:%s\n",
420 : : strerror(-rc));
421 : 0 : return rc;
422 : : }
423 : 0 : tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
424 : :
425 : : /* Check if element is in use */
426 : : memset(&aparms, 0, sizeof(aparms));
427 : 0 : aparms.rm_db = tcam_db->tcam_db[parms->dir];
428 : 0 : aparms.subtype = parms->type;
429 : 0 : aparms.index = parms->idx;
430 : 0 : aparms.allocated = &allocated;
431 : 0 : rc = tf_rm_is_allocated(&aparms);
432 [ # # ]: 0 : if (rc)
433 : : return rc;
434 : :
435 [ # # ]: 0 : if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
436 : 0 : TFP_DRV_LOG(ERR,
437 : : "%s: Entry already free, type:%d, index:%d\n",
438 : : tf_dir_2_str(parms->dir),
439 : : parms->type,
440 : : parms->idx);
441 : 0 : return -EINVAL;
442 : : }
443 : :
444 [ # # ]: 0 : for (i = 0; i < num_slices; i++) {
445 : : /* Free requested element */
446 : : memset(&fparms, 0, sizeof(fparms));
447 : 0 : fparms.rm_db = tcam_db->tcam_db[parms->dir];
448 : 0 : fparms.subtype = parms->type;
449 : 0 : fparms.index = parms->idx + i;
450 : 0 : rc = tf_rm_free(&fparms);
451 [ # # ]: 0 : if (rc) {
452 : 0 : TFP_DRV_LOG(ERR,
453 : : "%s: Free failed, type:%d, index:%d\n",
454 : : tf_dir_2_str(parms->dir),
455 : : parms->type,
456 : : parms->idx);
457 : 0 : return rc;
458 : : }
459 : : }
460 : :
461 : : /* Convert TF type to HCAPI RM type */
462 : : memset(&hparms, 0, sizeof(hparms));
463 : :
464 : 0 : hparms.rm_db = tcam_db->tcam_db[parms->dir];
465 : 0 : hparms.subtype = parms->type;
466 : 0 : hparms.hcapi_type = &parms->hcapi_type;
467 : :
468 : 0 : rc = tf_rm_get_hcapi_type(&hparms);
469 [ # # ]: 0 : if (rc)
470 : : return rc;
471 : :
472 : 0 : rc = tf_msg_tcam_entry_free(tfp, dev, parms);
473 [ # # ]: 0 : if (rc) {
474 : : /* Log error */
475 : 0 : TFP_DRV_LOG(ERR,
476 : : "%s: %s: Entry %d free failed, rc:%s\n",
477 : : tf_dir_2_str(parms->dir),
478 : : tf_tcam_tbl_2_str(parms->type),
479 : : parms->idx,
480 : : strerror(-rc));
481 : 0 : return rc;
482 : : }
483 : :
484 : : return 0;
485 : : }
486 : :
487 : : int
488 : 0 : tf_tcam_set(struct tf *tfp __rte_unused,
489 : : struct tf_tcam_set_parms *parms __rte_unused)
490 : : {
491 : : int rc;
492 : : struct tf_session *tfs;
493 : : struct tf_dev_info *dev;
494 : : struct tf_rm_is_allocated_parms aparms;
495 : : struct tf_rm_get_hcapi_parms hparms;
496 : 0 : uint16_t num_slice_per_row = 1;
497 : 0 : int allocated = 0;
498 : : struct tcam_rm_db *tcam_db;
499 : 0 : void *tcam_db_ptr = NULL;
500 : :
501 [ # # ]: 0 : TF_CHECK_PARMS2(tfp, parms);
502 : :
503 : : /* Retrieve the session information */
504 : 0 : rc = tf_session_get_session_internal(tfp, &tfs);
505 [ # # ]: 0 : if (rc)
506 : : return rc;
507 : :
508 : : /* Retrieve the device information */
509 : 0 : rc = tf_session_get_device(tfs, &dev);
510 [ # # ]: 0 : if (rc)
511 : : return rc;
512 : :
513 [ # # ]: 0 : if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
514 : : rc = -EOPNOTSUPP;
515 : 0 : TFP_DRV_LOG(ERR,
516 : : "%s: Operation not supported, rc:%s\n",
517 : : tf_dir_2_str(parms->dir),
518 : : strerror(-rc));
519 : 0 : return rc;
520 : : }
521 : :
522 : : /* Need to retrieve row size etc */
523 : 0 : rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
524 : : parms->type,
525 : 0 : parms->key_size,
526 : : &num_slice_per_row);
527 [ # # ]: 0 : if (rc)
528 : : return rc;
529 : :
530 : : /* If TCAM controlled by TCAM Manager */
531 [ # # ]: 0 : if (tfs->tcam_mgr_control[parms->dir][parms->type])
532 : 0 : return tf_tcam_mgr_set_msg(tfp, dev, parms);
533 : :
534 : 0 : rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
535 [ # # ]: 0 : if (rc) {
536 : 0 : TFP_DRV_LOG(ERR,
537 : : "Failed to get em_ext_db from session, rc:%s\n",
538 : : strerror(-rc));
539 : 0 : return rc;
540 : : }
541 : 0 : tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
542 : :
543 : : /* Check if element is in use */
544 : : memset(&aparms, 0, sizeof(aparms));
545 : :
546 : 0 : aparms.rm_db = tcam_db->tcam_db[parms->dir];
547 : 0 : aparms.subtype = parms->type;
548 : 0 : aparms.index = parms->idx;
549 : 0 : aparms.allocated = &allocated;
550 : 0 : rc = tf_rm_is_allocated(&aparms);
551 [ # # ]: 0 : if (rc)
552 : : return rc;
553 : :
554 [ # # ]: 0 : if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
555 : 0 : TFP_DRV_LOG(ERR,
556 : : "%s: Entry is not allocated, type:%d, index:%d\n",
557 : : tf_dir_2_str(parms->dir),
558 : : parms->type,
559 : : parms->idx);
560 : 0 : return -EINVAL;
561 : : }
562 : :
563 : : /* Convert TF type to HCAPI RM type */
564 : : memset(&hparms, 0, sizeof(hparms));
565 : :
566 : 0 : hparms.rm_db = tcam_db->tcam_db[parms->dir];
567 : 0 : hparms.subtype = parms->type;
568 : 0 : hparms.hcapi_type = &parms->hcapi_type;
569 : :
570 : 0 : rc = tf_rm_get_hcapi_type(&hparms);
571 [ # # ]: 0 : if (rc)
572 : : return rc;
573 : :
574 : 0 : rc = tf_msg_tcam_entry_set(tfp, dev, parms);
575 [ # # ]: 0 : if (rc) {
576 : : /* Log error */
577 : 0 : TFP_DRV_LOG(ERR,
578 : : "%s: %s: Entry %d set failed, rc:%s",
579 : : tf_dir_2_str(parms->dir),
580 : : tf_tcam_tbl_2_str(parms->type),
581 : : parms->idx,
582 : : strerror(-rc));
583 : 0 : return rc;
584 : : }
585 : : return 0;
586 : : }
587 : :
588 : : int
589 : 0 : tf_tcam_get(struct tf *tfp __rte_unused,
590 : : struct tf_tcam_get_parms *parms)
591 : : {
592 : : int rc;
593 : : struct tf_session *tfs;
594 : : struct tf_dev_info *dev;
595 : : struct tf_rm_is_allocated_parms aparms;
596 : : struct tf_rm_get_hcapi_parms hparms;
597 : 0 : int allocated = 0;
598 : : struct tcam_rm_db *tcam_db;
599 : 0 : void *tcam_db_ptr = NULL;
600 : :
601 [ # # ]: 0 : TF_CHECK_PARMS2(tfp, parms);
602 : :
603 : : /* Retrieve the session information */
604 : 0 : rc = tf_session_get_session_internal(tfp, &tfs);
605 [ # # ]: 0 : if (rc)
606 : : return rc;
607 : :
608 : : /* Retrieve the device information */
609 : 0 : rc = tf_session_get_device(tfs, &dev);
610 [ # # ]: 0 : if (rc)
611 : : return rc;
612 : :
613 : : /* If TCAM controlled by TCAM Manager */
614 [ # # ]: 0 : if (tfs->tcam_mgr_control[parms->dir][parms->type])
615 : 0 : return tf_tcam_mgr_get_msg(tfp, dev, parms);
616 : :
617 : 0 : rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
618 [ # # ]: 0 : if (rc) {
619 : 0 : TFP_DRV_LOG(ERR,
620 : : "Failed to get em_ext_db from session, rc:%s\n",
621 : : strerror(-rc));
622 : 0 : return rc;
623 : : }
624 : 0 : tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
625 : :
626 : : /* Check if element is in use */
627 : : memset(&aparms, 0, sizeof(aparms));
628 : :
629 : 0 : aparms.rm_db = tcam_db->tcam_db[parms->dir];
630 : 0 : aparms.subtype = parms->type;
631 : 0 : aparms.index = parms->idx;
632 : 0 : aparms.allocated = &allocated;
633 : 0 : rc = tf_rm_is_allocated(&aparms);
634 [ # # ]: 0 : if (rc)
635 : : return rc;
636 : :
637 [ # # ]: 0 : if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
638 : 0 : TFP_DRV_LOG(ERR,
639 : : "%s: Entry is not allocated, type:%d, index:%d\n",
640 : : tf_dir_2_str(parms->dir),
641 : : parms->type,
642 : : parms->idx);
643 : 0 : return -EINVAL;
644 : : }
645 : :
646 : : /* Convert TF type to HCAPI RM type */
647 : : memset(&hparms, 0, sizeof(hparms));
648 : :
649 : 0 : hparms.rm_db = tcam_db->tcam_db[parms->dir];
650 : 0 : hparms.subtype = parms->type;
651 : 0 : hparms.hcapi_type = &parms->hcapi_type;
652 : :
653 : 0 : rc = tf_rm_get_hcapi_type(&hparms);
654 [ # # ]: 0 : if (rc)
655 : : return rc;
656 : :
657 : 0 : rc = tf_msg_tcam_entry_get(tfp, dev, parms);
658 [ # # ]: 0 : if (rc) {
659 : : /* Log error */
660 : 0 : TFP_DRV_LOG(ERR,
661 : : "%s: %s: Entry %d set failed, rc:%s",
662 : : tf_dir_2_str(parms->dir),
663 : : tf_tcam_tbl_2_str(parms->type),
664 : : parms->idx,
665 : : strerror(-rc));
666 : 0 : return rc;
667 : : }
668 : :
669 : : return 0;
670 : : }
671 : :
672 : : int
673 : 0 : tf_tcam_get_resc_info(struct tf *tfp,
674 : : struct tf_tcam_resource_info *tcam)
675 : : {
676 : : int rc;
677 : : int d;
678 : : struct tf_resource_info *dinfo;
679 : : struct tf_rm_get_alloc_info_parms ainfo;
680 : 0 : void *tcam_db_ptr = NULL;
681 : : struct tcam_rm_db *tcam_db;
682 : :
683 [ # # ]: 0 : TF_CHECK_PARMS2(tfp, tcam);
684 : :
685 : 0 : rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
686 [ # # ]: 0 : if (rc == -ENOMEM)
687 : : return 0; /* db doesn't exist */
688 [ # # ]: 0 : else if (rc)
689 : : return rc; /* error getting db */
690 : :
691 : 0 : tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
692 : :
693 : : /* check if reserved resource for WC is multiple of num_slices */
694 [ # # ]: 0 : for (d = 0; d < TF_DIR_MAX; d++) {
695 : 0 : ainfo.rm_db = tcam_db->tcam_db[d];
696 : :
697 [ # # ]: 0 : if (!ainfo.rm_db)
698 : 0 : continue;
699 : :
700 : 0 : dinfo = tcam[d].info;
701 : :
702 : 0 : ainfo.info = (struct tf_rm_alloc_info *)dinfo;
703 : 0 : ainfo.subtype = 0;
704 : 0 : rc = tf_rm_get_all_info(&ainfo, TF_TCAM_TBL_TYPE_MAX);
705 [ # # ]: 0 : if (rc && rc != -ENOTSUP)
706 : 0 : return rc;
707 : : }
708 : :
709 : : return 0;
710 : : }
|