From 8de01320196a3158946f1905e2237d0bdfaacf4e Mon Sep 17 00:00:00 2001 From: Jay Ding Date: Thu, 2 Jul 2020 16:28:04 -0700 Subject: [PATCH] net/bnxt: support TCAM access Implement TCAM alloc, free, bind, and unbind functions Update tf_core, tf_msg, etc. Signed-off-by: Jay Ding Signed-off-by: Venkat Duvvuru Reviewed-by: Randy Schacher Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/tf_core/tf_core.c | 258 ++++++++++----------- drivers/net/bnxt/tf_core/tf_device.h | 14 +- drivers/net/bnxt/tf_core/tf_device_p4.c | 25 ++- drivers/net/bnxt/tf_core/tf_msg.c | 31 +-- drivers/net/bnxt/tf_core/tf_msg.h | 4 +- drivers/net/bnxt/tf_core/tf_tcam.c | 285 +++++++++++++++++++++++- drivers/net/bnxt/tf_core/tf_tcam.h | 66 ++++-- 7 files changed, 480 insertions(+), 203 deletions(-) diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c index 648d0d1bd6..29522c66ec 100644 --- a/drivers/net/bnxt/tf_core/tf_core.c +++ b/drivers/net/bnxt/tf_core/tf_core.c @@ -19,43 +19,6 @@ #include "tf_common.h" #include "hwrm_tf.h" -static int tf_check_tcam_entry(enum tf_tcam_tbl_type tcam_tbl_type, - enum tf_device_type device, - uint16_t key_sz_in_bits, - uint16_t *num_slice_per_row) -{ - uint16_t key_bytes; - uint16_t slice_sz = 0; - -#define CFA_P4_WC_TCAM_SLICES_PER_ROW 2 -#define CFA_P4_WC_TCAM_SLICE_SIZE 12 - - if (tcam_tbl_type == TF_TCAM_TBL_TYPE_WC_TCAM) { - key_bytes = TF_BITS2BYTES_WORD_ALIGN(key_sz_in_bits); - if (device == TF_DEVICE_TYPE_WH) { - slice_sz = CFA_P4_WC_TCAM_SLICE_SIZE; - *num_slice_per_row = CFA_P4_WC_TCAM_SLICES_PER_ROW; - } else { - TFP_DRV_LOG(ERR, - "Unsupported device type %d\n", - device); - return -ENOTSUP; - } - - if (key_bytes > *num_slice_per_row * slice_sz) { - TFP_DRV_LOG(ERR, - "%s: Key size %d is not supported\n", - tf_tcam_tbl_2_str(tcam_tbl_type), - key_bytes); - return -ENOTSUP; - } - } else { /* for other type of tcam */ - *num_slice_per_row = 1; - } - - return 0; -} - /** * Create EM Tbl pool of memory indexes. * @@ -918,49 +881,56 @@ tf_alloc_tcam_entry(struct tf *tfp, struct tf_alloc_tcam_entry_parms *parms) { int rc; - int index; struct tf_session *tfs; - struct bitalloc *session_pool; - uint16_t num_slice_per_row; - - /* TEMP, due to device design. When tcam is modularized device - * should be retrieved from the session - */ - enum tf_device_type device_type; - /* TEMP */ - device_type = TF_DEVICE_TYPE_WH; + struct tf_dev_info *dev; + struct tf_tcam_alloc_parms aparms = { 0 }; - TF_CHECK_PARMS_SESSION(tfp, parms); + TF_CHECK_PARMS2(tfp, parms); - tfs = (struct tf_session *)(tfp->session->core_data); + /* Retrieve the session information */ + rc = tf_session_get_session(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } - rc = tf_check_tcam_entry(parms->tcam_tbl_type, - device_type, - parms->key_sz_in_bits, - &num_slice_per_row); - /* Error logging handled by tf_check_tcam_entry */ - if (rc) + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup device, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); return rc; + } - rc = tf_rm_lookup_tcam_type_pool(tfs, - parms->dir, - parms->tcam_tbl_type, - &session_pool); - /* Error logging handled by tf_rm_lookup_tcam_type_pool */ - if (rc) + if (dev->ops->tf_dev_alloc_tcam == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); return rc; + } - index = ba_alloc(session_pool); - if (index == BA_FAIL) { - TFP_DRV_LOG(ERR, "%s: %s: No resource available\n", + aparms.dir = parms->dir; + aparms.type = parms->tcam_tbl_type; + aparms.key_size = TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits); + aparms.priority = parms->priority; + rc = dev->ops->tf_dev_alloc_tcam(tfp, &aparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: TCAM allocation failed, rc:%s\n", tf_dir_2_str(parms->dir), - tf_tcam_tbl_2_str(parms->tcam_tbl_type)); - return -ENOMEM; + strerror(-rc)); + return rc; } - index *= num_slice_per_row; + parms->idx = aparms.idx; - parms->idx = index; return 0; } @@ -969,55 +939,60 @@ tf_set_tcam_entry(struct tf *tfp, struct tf_set_tcam_entry_parms *parms) { int rc; - int id; - int index; struct tf_session *tfs; - struct bitalloc *session_pool; - uint16_t num_slice_per_row; - - /* TEMP, due to device design. When tcam is modularized device - * should be retrieved from the session - */ - enum tf_device_type device_type; - /* TEMP */ - device_type = TF_DEVICE_TYPE_WH; + struct tf_dev_info *dev; + struct tf_tcam_set_parms sparms = { 0 }; - TF_CHECK_PARMS_SESSION(tfp, parms); + TF_CHECK_PARMS2(tfp, parms); - tfs = (struct tf_session *)(tfp->session->core_data); + /* Retrieve the session information */ + rc = tf_session_get_session(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } - rc = tf_check_tcam_entry(parms->tcam_tbl_type, - device_type, - parms->key_sz_in_bits, - &num_slice_per_row); - /* Error logging handled by tf_check_tcam_entry */ - if (rc) + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup device, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); return rc; + } - rc = tf_rm_lookup_tcam_type_pool(tfs, - parms->dir, - parms->tcam_tbl_type, - &session_pool); - /* Error logging handled by tf_rm_lookup_tcam_type_pool */ - if (rc) + if (dev->ops->tf_dev_set_tcam == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); return rc; + } - /* Verify that the entry has been previously allocated */ - index = parms->idx / num_slice_per_row; + sparms.dir = parms->dir; + sparms.type = parms->tcam_tbl_type; + sparms.idx = parms->idx; + sparms.key = parms->key; + sparms.mask = parms->mask; + sparms.key_size = TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits); + sparms.result = parms->result; + sparms.result_size = TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits); - id = ba_inuse(session_pool, index); - if (id != 1) { + rc = dev->ops->tf_dev_set_tcam(tfp, &sparms); + if (rc) { TFP_DRV_LOG(ERR, - "%s: %s: Invalid or not allocated index, idx:%d\n", - tf_dir_2_str(parms->dir), - tf_tcam_tbl_2_str(parms->tcam_tbl_type), - parms->idx); - return -EINVAL; + "%s: TCAM set failed, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; } - rc = tf_msg_tcam_entry_set(tfp, parms); - - return rc; + return 0; } int @@ -1033,59 +1008,52 @@ tf_free_tcam_entry(struct tf *tfp, struct tf_free_tcam_entry_parms *parms) { int rc; - int index; struct tf_session *tfs; - struct bitalloc *session_pool; - uint16_t num_slice_per_row = 1; - - /* TEMP, due to device design. When tcam is modularized device - * should be retrieved from the session - */ - enum tf_device_type device_type; - /* TEMP */ - device_type = TF_DEVICE_TYPE_WH; + struct tf_dev_info *dev; + struct tf_tcam_free_parms fparms = { 0 }; - TF_CHECK_PARMS_SESSION(tfp, parms); - tfs = (struct tf_session *)(tfp->session->core_data); + TF_CHECK_PARMS2(tfp, parms); - rc = tf_check_tcam_entry(parms->tcam_tbl_type, - device_type, - 0, - &num_slice_per_row); - /* Error logging handled by tf_check_tcam_entry */ - if (rc) + /* Retrieve the session information */ + rc = tf_session_get_session(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); return rc; + } - rc = tf_rm_lookup_tcam_type_pool(tfs, - parms->dir, - parms->tcam_tbl_type, - &session_pool); - /* Error logging handled by tf_rm_lookup_tcam_type_pool */ - if (rc) + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup device, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); return rc; + } - index = parms->idx / num_slice_per_row; - - rc = ba_inuse(session_pool, index); - if (rc == BA_FAIL || rc == BA_ENTRY_FREE) { - TFP_DRV_LOG(ERR, "%s: %s: Entry %d already free", + if (dev->ops->tf_dev_free_tcam == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", tf_dir_2_str(parms->dir), - tf_tcam_tbl_2_str(parms->tcam_tbl_type), - index); - return -EINVAL; + strerror(-rc)); + return rc; } - ba_free(session_pool, index); - - rc = tf_msg_tcam_entry_free(tfp, parms); + fparms.dir = parms->dir; + fparms.type = parms->tcam_tbl_type; + fparms.idx = parms->idx; + rc = dev->ops->tf_dev_free_tcam(tfp, &fparms); if (rc) { - /* Log error */ - TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s", + TFP_DRV_LOG(ERR, + "%s: TCAM allocation failed, rc:%s\n", tf_dir_2_str(parms->dir), - tf_tcam_tbl_2_str(parms->tcam_tbl_type), - parms->idx, strerror(-rc)); + return rc; } - return rc; + return 0; } diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h index 01726c3126..bbdfb151c9 100644 --- a/drivers/net/bnxt/tf_core/tf_device.h +++ b/drivers/net/bnxt/tf_core/tf_device.h @@ -116,8 +116,11 @@ struct tf_dev_ops { * [in] tfp * Pointer to TF handle * - * [out] slice_size - * Pointer to slice size the device supports + * [in] type + * TCAM table type + * + * [in] key_sz + * Key size * * [out] num_slices_per_row * Pointer to number of slices per row the device supports @@ -126,9 +129,10 @@ struct tf_dev_ops { * - (0) if successful. * - (-EINVAL) on failure. */ - int (*tf_dev_get_wc_tcam_slices)(struct tf *tfp, - uint16_t *slice_size, - uint16_t *num_slices_per_row); + int (*tf_dev_get_tcam_slice_info)(struct tf *tfp, + enum tf_tcam_tbl_type type, + uint16_t key_sz, + uint16_t *num_slices_per_row); /** * Allocation of an identifier element. diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c index f4bd95f1c4..77fb693ddb 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p4.c +++ b/drivers/net/bnxt/tf_core/tf_device_p4.c @@ -56,18 +56,21 @@ tf_dev_p4_get_max_types(struct tf *tfp __rte_unused, * - (-EINVAL) on failure. */ static int -tf_dev_p4_get_wc_tcam_slices(struct tf *tfp __rte_unused, - uint16_t *slice_size, - uint16_t *num_slices_per_row) +tf_dev_p4_get_tcam_slice_info(struct tf *tfp __rte_unused, + enum tf_tcam_tbl_type type, + uint16_t key_sz, + uint16_t *num_slices_per_row) { -#define CFA_P4_WC_TCAM_SLICE_SIZE 12 -#define CFA_P4_WC_TCAM_SLICES_PER_ROW 2 +#define CFA_P4_WC_TCAM_SLICES_PER_ROW 2 +#define CFA_P4_WC_TCAM_SLICE_SIZE 12 - if (slice_size == NULL || num_slices_per_row == NULL) - return -EINVAL; - - *slice_size = CFA_P4_WC_TCAM_SLICE_SIZE; - *num_slices_per_row = CFA_P4_WC_TCAM_SLICES_PER_ROW; + if (type == TF_TCAM_TBL_TYPE_WC_TCAM) { + *num_slices_per_row = CFA_P4_WC_TCAM_SLICES_PER_ROW; + if (key_sz > *num_slices_per_row * CFA_P4_WC_TCAM_SLICE_SIZE) + return -ENOTSUP; + } else { /* for other type of tcam */ + *num_slices_per_row = 1; + } return 0; } @@ -77,7 +80,7 @@ tf_dev_p4_get_wc_tcam_slices(struct tf *tfp __rte_unused, */ const struct tf_dev_ops tf_dev_ops_p4 = { .tf_dev_get_max_types = tf_dev_p4_get_max_types, - .tf_dev_get_wc_tcam_slices = tf_dev_p4_get_wc_tcam_slices, + .tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info, .tf_dev_alloc_ident = tf_ident_alloc, .tf_dev_free_ident = tf_ident_free, .tf_dev_alloc_tbl = tf_tbl_alloc, diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c index 60274eb354..b50e1d48c4 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.c +++ b/drivers/net/bnxt/tf_core/tf_msg.c @@ -9,6 +9,7 @@ #include #include "tf_msg_common.h" +#include "tf_device.h" #include "tf_msg.h" #include "tf_util.h" #include "tf_session.h" @@ -1480,27 +1481,19 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp, return tfp_le_to_cpu_32(parms.tf_resp_code); } -#define TF_BYTES_PER_SLICE(tfp) 12 -#define NUM_SLICES(tfp, bytes) \ - (((bytes) + TF_BYTES_PER_SLICE(tfp) - 1) / TF_BYTES_PER_SLICE(tfp)) - int tf_msg_tcam_entry_set(struct tf *tfp, - struct tf_set_tcam_entry_parms *parms) + struct tf_tcam_set_parms *parms) { int rc; struct tfp_send_msg_parms mparms = { 0 }; struct hwrm_tf_tcam_set_input req = { 0 }; struct hwrm_tf_tcam_set_output resp = { 0 }; - uint16_t key_bytes = - TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits); - uint16_t result_bytes = - TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits); struct tf_msg_dma_buf buf = { 0 }; uint8_t *data = NULL; int data_size = 0; - rc = tf_tcam_tbl_2_hwrm(parms->tcam_tbl_type, &req.type); + rc = tf_tcam_tbl_2_hwrm(parms->type, &req.type); if (rc != 0) return rc; @@ -1508,11 +1501,11 @@ tf_msg_tcam_entry_set(struct tf *tfp, if (parms->dir == TF_DIR_TX) req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX; - req.key_size = key_bytes; - req.mask_offset = key_bytes; + req.key_size = parms->key_size; + req.mask_offset = parms->key_size; /* Result follows after key and mask, thus multiply by 2 */ - req.result_offset = 2 * key_bytes; - req.result_size = result_bytes; + req.result_offset = 2 * parms->key_size; + req.result_size = parms->result_size; data_size = 2 * req.key_size + req.result_size; if (data_size <= TF_PCI_BUF_SIZE_MAX) { @@ -1530,9 +1523,9 @@ tf_msg_tcam_entry_set(struct tf *tfp, sizeof(buf.pa_addr)); } - tfp_memcpy(&data[0], parms->key, key_bytes); - tfp_memcpy(&data[key_bytes], parms->mask, key_bytes); - tfp_memcpy(&data[req.result_offset], parms->result, result_bytes); + tfp_memcpy(&data[0], parms->key, parms->key_size); + tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size); + tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size); mparms.tf_type = HWRM_TF_TCAM_SET; mparms.req_data = (uint32_t *)&req; @@ -1554,7 +1547,7 @@ cleanup: int tf_msg_tcam_entry_free(struct tf *tfp, - struct tf_free_tcam_entry_parms *in_parms) + struct tf_tcam_free_parms *in_parms) { int rc; struct hwrm_tf_tcam_free_input req = { 0 }; @@ -1562,7 +1555,7 @@ tf_msg_tcam_entry_free(struct tf *tfp, struct tfp_send_msg_parms parms = { 0 }; /* Populate the request */ - rc = tf_tcam_tbl_2_hwrm(in_parms->tcam_tbl_type, &req.type); + rc = tf_tcam_tbl_2_hwrm(in_parms->type, &req.type); if (rc != 0) return rc; diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h index 1dad2b9fba..a3e0f7bba1 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.h +++ b/drivers/net/bnxt/tf_core/tf_msg.h @@ -247,7 +247,7 @@ int tf_msg_em_op(struct tf *tfp, * 0 on Success else internal Truflow error */ int tf_msg_tcam_entry_set(struct tf *tfp, - struct tf_set_tcam_entry_parms *parms); + struct tf_tcam_set_parms *parms); /** * Sends tcam entry 'free' to the Firmware. @@ -262,7 +262,7 @@ int tf_msg_tcam_entry_set(struct tf *tfp, * 0 on Success else internal Truflow error */ int tf_msg_tcam_entry_free(struct tf *tfp, - struct tf_free_tcam_entry_parms *parms); + struct tf_tcam_free_parms *parms); /** * Sends Set message of a Table Type element to the firmware. diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c index 3ad99dd0dc..b9dba5323f 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam.c +++ b/drivers/net/bnxt/tf_core/tf_tcam.c @@ -3,16 +3,24 @@ * All rights reserved. */ +#include #include #include "tf_tcam.h" +#include "tf_common.h" +#include "tf_util.h" +#include "tf_rm_new.h" +#include "tf_device.h" +#include "tfp.h" +#include "tf_session.h" +#include "tf_msg.h" struct tf; /** * TCAM DBs. */ -/* static void *tcam_db[TF_DIR_MAX]; */ +static void *tcam_db[TF_DIR_MAX]; /** * TCAM Shadow DBs @@ -22,7 +30,7 @@ struct tf; /** * Init flag, set on bind and cleared on unbind */ -/* static uint8_t init; */ +static uint8_t init; /** * Shadow init flag, set on bind and cleared on unbind @@ -33,19 +41,131 @@ int tf_tcam_bind(struct tf *tfp __rte_unused, struct tf_tcam_cfg_parms *parms __rte_unused) { + int rc; + int i; + struct tf_rm_create_db_parms db_cfg = { 0 }; + + TF_CHECK_PARMS2(tfp, parms); + + if (init) { + TFP_DRV_LOG(ERR, + "TCAM already initialized\n"); + return -EINVAL; + } + + db_cfg.num_elements = parms->num_elements; + + for (i = 0; i < TF_DIR_MAX; i++) { + db_cfg.dir = i; + db_cfg.num_elements = parms->num_elements; + db_cfg.cfg = parms->cfg; + db_cfg.alloc_num = parms->resources->tcam_tbl_cnt[i]; + db_cfg.rm_db = tcam_db[i]; + rc = tf_rm_create_db(tfp, &db_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: TCAM DB creation failed\n", + tf_dir_2_str(i)); + return rc; + } + } + + init = 1; + return 0; } int tf_tcam_unbind(struct tf *tfp __rte_unused) { + int rc; + int i; + struct tf_rm_free_db_parms fparms = { 0 }; + + TF_CHECK_PARMS1(tfp); + + /* Bail if nothing has been initialized done silent as to + * allow for creation cleanup. + */ + if (!init) + return -EINVAL; + + for (i = 0; i < TF_DIR_MAX; i++) { + fparms.dir = i; + fparms.rm_db = tcam_db[i]; + rc = tf_rm_free_db(tfp, &fparms); + if (rc) + return rc; + + tcam_db[i] = NULL; + } + + init = 0; + return 0; } int -tf_tcam_alloc(struct tf *tfp __rte_unused, - struct tf_tcam_alloc_parms *parms __rte_unused) +tf_tcam_alloc(struct tf *tfp, + struct tf_tcam_alloc_parms *parms) { + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tf_rm_allocate_parms aparms = { 0 }; + uint16_t num_slice_per_row = 1; + + TF_CHECK_PARMS2(tfp, parms); + + if (!init) { + TFP_DRV_LOG(ERR, + "%s: No TCAM DBs created\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + /* Retrieve the session information */ + rc = tf_session_get_session(tfp, &tfs); + if (rc) + return rc; + + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) + return rc; + + if (dev->ops->tf_dev_get_tcam_slice_info == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + /* Need to retrieve row size etc */ + rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, + parms->type, + parms->key_size, + &num_slice_per_row); + if (rc) + return rc; + + /* Allocate requested element */ + aparms.rm_db = tcam_db[parms->dir]; + aparms.db_index = parms->type; + aparms.index = (uint32_t *)&parms->idx; + rc = tf_rm_allocate(&aparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed tcam, type:%d\n", + tf_dir_2_str(parms->dir), + parms->type); + return rc; + } + + parms->idx *= num_slice_per_row; + return 0; } @@ -53,6 +173,92 @@ int tf_tcam_free(struct tf *tfp __rte_unused, struct tf_tcam_free_parms *parms __rte_unused) { + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tf_rm_is_allocated_parms aparms = { 0 }; + struct tf_rm_free_parms fparms = { 0 }; + uint16_t num_slice_per_row = 1; + int allocated = 0; + + TF_CHECK_PARMS2(tfp, parms); + + if (!init) { + TFP_DRV_LOG(ERR, + "%s: No TCAM DBs created\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + /* Retrieve the session information */ + rc = tf_session_get_session(tfp, &tfs); + if (rc) + return rc; + + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) + return rc; + + if (dev->ops->tf_dev_get_tcam_slice_info == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + /* Need to retrieve row size etc */ + rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, + parms->type, + 0, + &num_slice_per_row); + if (rc) + return rc; + + /* Check if element is in use */ + aparms.rm_db = tcam_db[parms->dir]; + aparms.db_index = parms->type; + aparms.index = parms->idx / num_slice_per_row; + aparms.allocated = &allocated; + rc = tf_rm_is_allocated(&aparms); + if (rc) + return rc; + + if (!allocated) { + TFP_DRV_LOG(ERR, + "%s: Entry already free, type:%d, index:%d\n", + tf_dir_2_str(parms->dir), + parms->type, + parms->idx); + return rc; + } + + /* Free requested element */ + fparms.rm_db = tcam_db[parms->dir]; + fparms.db_index = parms->type; + fparms.index = parms->idx / num_slice_per_row; + rc = tf_rm_free(&fparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Free failed, type:%d, index:%d\n", + tf_dir_2_str(parms->dir), + parms->type, + parms->idx); + return rc; + } + + rc = tf_msg_tcam_entry_free(tfp, parms); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s", + tf_dir_2_str(parms->dir), + tf_tcam_tbl_2_str(parms->type), + parms->idx, + strerror(-rc)); + } + return 0; } @@ -67,6 +273,77 @@ int tf_tcam_set(struct tf *tfp __rte_unused, struct tf_tcam_set_parms *parms __rte_unused) { + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tf_rm_is_allocated_parms aparms = { 0 }; + uint16_t num_slice_per_row = 1; + int allocated = 0; + + TF_CHECK_PARMS2(tfp, parms); + + if (!init) { + TFP_DRV_LOG(ERR, + "%s: No TCAM DBs created\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + /* Retrieve the session information */ + rc = tf_session_get_session(tfp, &tfs); + if (rc) + return rc; + + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) + return rc; + + if (dev->ops->tf_dev_get_tcam_slice_info == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + /* Need to retrieve row size etc */ + rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, + parms->type, + parms->key_size, + &num_slice_per_row); + if (rc) + return rc; + + /* Check if element is in use */ + aparms.rm_db = tcam_db[parms->dir]; + aparms.db_index = parms->type; + aparms.index = parms->idx / num_slice_per_row; + aparms.allocated = &allocated; + rc = tf_rm_is_allocated(&aparms); + if (rc) + return rc; + + if (!allocated) { + TFP_DRV_LOG(ERR, + "%s: Entry is not allocated, type:%d, index:%d\n", + tf_dir_2_str(parms->dir), + parms->type, + parms->idx); + return rc; + } + + rc = tf_msg_tcam_entry_set(tfp, parms); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s", + tf_dir_2_str(parms->dir), + tf_tcam_tbl_2_str(parms->type), + parms->idx, + strerror(-rc)); + } + return 0; } diff --git a/drivers/net/bnxt/tf_core/tf_tcam.h b/drivers/net/bnxt/tf_core/tf_tcam.h index 68c25eb1bd..67c3bcb499 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam.h +++ b/drivers/net/bnxt/tf_core/tf_tcam.h @@ -50,10 +50,18 @@ struct tf_tcam_alloc_parms { * [in] Type of the allocation */ enum tf_tcam_tbl_type type; + /** + * [in] key size + */ + uint16_t key_size; + /** + * [in] Priority of entry requested (definition TBD) + */ + uint32_t priority; /** * [out] Idx of allocated entry or found entry (if search_enable) */ - uint32_t idx; + uint16_t idx; }; /** @@ -71,7 +79,7 @@ struct tf_tcam_free_parms { /** * [in] Index to free */ - uint32_t idx; + uint16_t idx; /** * [out] Reference count after free, only valid if session has been * created with shadow_copy. @@ -90,7 +98,7 @@ struct tf_tcam_alloc_search_parms { /** * [in] TCAM table type */ - enum tf_tcam_tbl_type tcam_tbl_type; + enum tf_tcam_tbl_type type; /** * [in] Enable search for matching entry */ @@ -100,9 +108,9 @@ struct tf_tcam_alloc_search_parms { */ uint8_t *key; /** - * [in] key size in bits (if search) + * [in] key size (if search) */ - uint16_t key_sz_in_bits; + uint16_t key_size; /** * [in] Mask data to match on (if search) */ @@ -139,17 +147,29 @@ struct tf_tcam_set_parms { */ enum tf_tcam_tbl_type type; /** - * [in] Entry data + * [in] Entry index to write to */ - uint8_t *data; + uint32_t idx; /** - * [in] Entry size + * [in] array containing key */ - uint16_t data_sz_in_bytes; + uint8_t *key; /** - * [in] Entry index to write to + * [in] array containing mask fields */ - uint32_t idx; + uint8_t *mask; + /** + * [in] key size + */ + uint16_t key_size; + /** + * [in] array containing result + */ + uint8_t *result; + /** + * [in] result size + */ + uint16_t result_size; }; /** @@ -165,17 +185,29 @@ struct tf_tcam_get_parms { */ enum tf_tcam_tbl_type type; /** - * [out] Entry data + * [in] Entry index to read */ - uint8_t *data; + uint32_t idx; /** - * [out] Entry size + * [out] array containing key */ - uint16_t data_sz_in_bytes; + uint8_t *key; /** - * [in] Entry index to read + * [out] array containing mask fields */ - uint32_t idx; + uint8_t *mask; + /** + * [out] key size + */ + uint16_t key_size; + /** + * [out] array containing result + */ + uint8_t *result; + /** + * [out] result size + */ + uint16_t result_size; }; /** -- 2.20.1