1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
7 #include <rte_common.h>
10 #include "tf_common.h"
13 #include "tf_device.h"
15 #include "tf_session.h"
23 static void *tcam_db[TF_DIR_MAX];
28 /* static void *shadow_tcam_db[TF_DIR_MAX]; */
31 * Init flag, set on bind and cleared on unbind
36 * Shadow init flag, set on bind and cleared on unbind
38 /* static uint8_t shadow_init; */
41 tf_tcam_bind(struct tf *tfp,
42 struct tf_tcam_cfg_parms *parms)
46 struct tf_tcam_resources *tcam_cnt;
47 struct tf_rm_create_db_parms db_cfg = { 0 };
49 TF_CHECK_PARMS2(tfp, parms);
53 "TCAM DB already initialized\n");
57 tcam_cnt = parms->resources->tcam_cnt;
58 if ((tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % 2) ||
59 (tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % 2)) {
61 "Number of WC TCAM entries cannot be odd num\n");
65 db_cfg.type = TF_DEVICE_MODULE_TYPE_TCAM;
66 db_cfg.num_elements = parms->num_elements;
67 db_cfg.cfg = parms->cfg;
69 for (i = 0; i < TF_DIR_MAX; i++) {
71 db_cfg.alloc_cnt = parms->resources->tcam_cnt[i].cnt;
72 db_cfg.rm_db = &tcam_db[i];
73 rc = tf_rm_create_db(tfp, &db_cfg);
76 "%s: TCAM DB creation failed\n",
85 "TCAM - initialized\n");
91 tf_tcam_unbind(struct tf *tfp)
95 struct tf_rm_free_db_parms fparms = { 0 };
99 /* Bail if nothing has been initialized */
102 "No TCAM DBs created\n");
106 for (i = 0; i < TF_DIR_MAX; i++) {
108 fparms.rm_db = tcam_db[i];
109 rc = tf_rm_free_db(tfp, &fparms);
122 tf_tcam_alloc(struct tf *tfp,
123 struct tf_tcam_alloc_parms *parms)
126 struct tf_session *tfs;
127 struct tf_dev_info *dev;
128 struct tf_rm_allocate_parms aparms = { 0 };
129 uint16_t num_slice_per_row = 1;
131 TF_CHECK_PARMS2(tfp, parms);
135 "%s: No TCAM DBs created\n",
136 tf_dir_2_str(parms->dir));
140 /* Retrieve the session information */
141 rc = tf_session_get_session(tfp, &tfs);
145 /* Retrieve the device information */
146 rc = tf_session_get_device(tfs, &dev);
150 if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
153 "%s: Operation not supported, rc:%s\n",
154 tf_dir_2_str(parms->dir),
159 /* Need to retrieve row size etc */
160 rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
167 /* Allocate requested element */
168 aparms.rm_db = tcam_db[parms->dir];
169 aparms.db_index = parms->type;
170 aparms.priority = parms->priority;
171 aparms.index = (uint32_t *)&parms->idx;
172 rc = tf_rm_allocate(&aparms);
175 "%s: Failed tcam, type:%d\n",
176 tf_dir_2_str(parms->dir),
181 if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM &&
182 (parms->idx % 2) != 0) {
183 rc = tf_rm_allocate(&aparms);
186 "%s: Failed tcam, type:%d\n",
187 tf_dir_2_str(parms->dir),
193 parms->idx *= num_slice_per_row;
199 tf_tcam_free(struct tf *tfp,
200 struct tf_tcam_free_parms *parms)
203 struct tf_session *tfs;
204 struct tf_dev_info *dev;
205 struct tf_rm_is_allocated_parms aparms = { 0 };
206 struct tf_rm_free_parms fparms = { 0 };
207 struct tf_rm_get_hcapi_parms hparms = { 0 };
208 uint16_t num_slice_per_row = 1;
211 TF_CHECK_PARMS2(tfp, parms);
215 "%s: No TCAM DBs created\n",
216 tf_dir_2_str(parms->dir));
220 /* Retrieve the session information */
221 rc = tf_session_get_session(tfp, &tfs);
225 /* Retrieve the device information */
226 rc = tf_session_get_device(tfs, &dev);
230 if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
233 "%s: Operation not supported, rc:%s\n",
234 tf_dir_2_str(parms->dir),
239 /* Need to retrieve row size etc */
240 rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
247 /* Check if element is in use */
248 aparms.rm_db = tcam_db[parms->dir];
249 aparms.db_index = parms->type;
250 aparms.index = parms->idx / num_slice_per_row;
251 aparms.allocated = &allocated;
252 rc = tf_rm_is_allocated(&aparms);
256 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
258 "%s: Entry already free, type:%d, index:%d\n",
259 tf_dir_2_str(parms->dir),
265 /* Free requested element */
266 fparms.rm_db = tcam_db[parms->dir];
267 fparms.db_index = parms->type;
268 fparms.index = parms->idx / num_slice_per_row;
269 rc = tf_rm_free(&fparms);
272 "%s: Free failed, type:%d, index:%d\n",
273 tf_dir_2_str(parms->dir),
279 if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM) {
282 for (i = -1; i < 3; i += 3) {
284 rc = tf_rm_is_allocated(&aparms);
288 if (allocated == TF_RM_ALLOCATED_ENTRY_IN_USE) {
289 /* Free requested element */
290 fparms.index = aparms.index;
291 rc = tf_rm_free(&fparms);
294 "%s: Free failed, type:%d, index:%d\n",
295 tf_dir_2_str(parms->dir),
304 /* Convert TF type to HCAPI RM type */
305 hparms.rm_db = tcam_db[parms->dir];
306 hparms.db_index = parms->type;
307 hparms.hcapi_type = &parms->hcapi_type;
309 rc = tf_rm_get_hcapi_type(&hparms);
313 rc = tf_msg_tcam_entry_free(tfp, parms);
317 "%s: %s: Entry %d free failed, rc:%s\n",
318 tf_dir_2_str(parms->dir),
319 tf_tcam_tbl_2_str(parms->type),
328 tf_tcam_alloc_search(struct tf *tfp __rte_unused,
329 struct tf_tcam_alloc_search_parms *parms __rte_unused)
335 tf_tcam_set(struct tf *tfp __rte_unused,
336 struct tf_tcam_set_parms *parms __rte_unused)
339 struct tf_session *tfs;
340 struct tf_dev_info *dev;
341 struct tf_rm_is_allocated_parms aparms = { 0 };
342 struct tf_rm_get_hcapi_parms hparms = { 0 };
343 uint16_t num_slice_per_row = 1;
346 TF_CHECK_PARMS2(tfp, parms);
350 "%s: No TCAM DBs created\n",
351 tf_dir_2_str(parms->dir));
355 /* Retrieve the session information */
356 rc = tf_session_get_session(tfp, &tfs);
360 /* Retrieve the device information */
361 rc = tf_session_get_device(tfs, &dev);
365 if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
368 "%s: Operation not supported, rc:%s\n",
369 tf_dir_2_str(parms->dir),
374 /* Need to retrieve row size etc */
375 rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
382 /* Check if element is in use */
383 aparms.rm_db = tcam_db[parms->dir];
384 aparms.db_index = parms->type;
385 aparms.index = parms->idx / num_slice_per_row;
386 aparms.allocated = &allocated;
387 rc = tf_rm_is_allocated(&aparms);
391 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
393 "%s: Entry is not allocated, type:%d, index:%d\n",
394 tf_dir_2_str(parms->dir),
400 /* Convert TF type to HCAPI RM type */
401 hparms.rm_db = tcam_db[parms->dir];
402 hparms.db_index = parms->type;
403 hparms.hcapi_type = &parms->hcapi_type;
405 rc = tf_rm_get_hcapi_type(&hparms);
409 rc = tf_msg_tcam_entry_set(tfp, parms);
413 "%s: %s: Entry %d set failed, rc:%s",
414 tf_dir_2_str(parms->dir),
415 tf_tcam_tbl_2_str(parms->type),
424 tf_tcam_get(struct tf *tfp __rte_unused,
425 struct tf_tcam_get_parms *parms __rte_unused)