From: Jay Ding Date: Sun, 30 May 2021 08:58:40 +0000 (+0530) Subject: net/bnxt: support Thor WC TCAM X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=902fa8b50d609150f717394ba0c5b72890c66d9b;p=dpdk.git net/bnxt: support Thor WC TCAM 1. Add set/get/free/alloc for WC TCAM 2. Rework the key size in slice management. 3. Add 3 FKB WC keys for WC TCAM set cli cmd 4. Add transform key function for WC TCAM FKB key 5. Add checking for key buffer length for get_tcam Signed-off-by: Jay Ding Signed-off-by: Randy Schacher Signed-off-by: Venkat Duvvuru Reviewed-by: Farah Smith Reviewed-by: Ajit Khaparde --- diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c index a3b6afbc88..573fa0b1ed 100644 --- a/drivers/net/bnxt/tf_core/tf_core.c +++ b/drivers/net/bnxt/tf_core/tf_core.c @@ -842,8 +842,10 @@ tf_get_tcam_entry(struct tf *tfp __rte_unused, gparms.type = parms->tcam_tbl_type; gparms.idx = parms->idx; gparms.key = parms->key; + gparms.key_size = dev->ops->tf_dev_word_align(parms->key_sz_in_bits); gparms.mask = parms->mask; gparms.result = parms->result; + gparms.result_size = TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits); rc = dev->ops->tf_dev_get_tcam(tfp, &gparms); if (rc) { diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h index 0cc3719a1b..fcba492dc5 100644 --- a/drivers/net/bnxt/tf_core/tf_core.h +++ b/drivers/net/bnxt/tf_core/tf_core.h @@ -1286,7 +1286,7 @@ struct tf_get_tcam_entry_parms { */ uint8_t *mask; /** - * [out] key size in bits + * [in/out] key size in bits */ uint16_t key_sz_in_bits; /** @@ -1294,7 +1294,7 @@ struct tf_get_tcam_entry_parms { */ uint8_t *result; /** - * [out] struct containing result size in bits + * [in/out] struct containing result size in bits */ uint16_t result_sz_in_bits; }; @@ -1961,6 +1961,7 @@ enum tf_tunnel_encap_offsets { enum tf_global_config_type { TF_TUNNEL_ENCAP, /**< Tunnel Encap Config(TECT) */ TF_ACTION_BLOCK, /**< Action Block Config(ABCR) */ + TF_COUNTER_CFG, /**< Counter Configuration (CNTRS_CTRL) */ TF_GLOBAL_CFG_TYPE_MAX }; diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c index d0bede89e3..e5aaaac9a0 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p4.c +++ b/drivers/net/bnxt/tf_core/tf_device_p4.c @@ -144,8 +144,6 @@ tf_dev_p4_get_tcam_slice_info(struct tf *tfp __rte_unused, *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; - - *num_slices_per_row = 1; } else { /* for other type of tcam */ *num_slices_per_row = 1; } diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c index 50a8d82074..65e283ed11 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p58.c +++ b/drivers/net/bnxt/tf_core/tf_device_p58.c @@ -123,15 +123,14 @@ tf_dev_p58_get_tcam_slice_info(struct tf *tfp __rte_unused, uint16_t key_sz, uint16_t *num_slices_per_row) { -#define CFA_P58_WC_TCAM_SLICES_PER_ROW 2 -#define CFA_P58_WC_TCAM_SLICE_SIZE 12 +#define CFA_P58_WC_TCAM_SLICES_PER_ROW 1 +#define CFA_P58_WC_TCAM_SLICE_SIZE 24 if (type == TF_TCAM_TBL_TYPE_WC_TCAM) { + /* only support single slice key size now */ *num_slices_per_row = CFA_P58_WC_TCAM_SLICES_PER_ROW; if (key_sz > *num_slices_per_row * CFA_P58_WC_TCAM_SLICE_SIZE) return -ENOTSUP; - - *num_slices_per_row = 1; } else { /* for other type of tcam */ *num_slices_per_row = 1; } diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.h b/drivers/net/bnxt/tf_core/tf_device_p58.h index abd916985e..07f022769b 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p58.h +++ b/drivers/net/bnxt/tf_core/tf_device_p58.h @@ -189,5 +189,8 @@ struct tf_global_cfg_cfg tf_global_cfg_p58[TF_GLOBAL_CFG_TYPE_MAX] = { [TF_ACTION_BLOCK] = { TF_GLOBAL_CFG_CFG_HCAPI, TF_ACTION_BLOCK }, + [TF_COUNTER_CFG] = { + TF_GLOBAL_CFG_CFG_HCAPI, TF_COUNTER_CFG + }, }; #endif /* _TF_DEVICE_P58_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c index 1af5c6d11c..ec4c7890c3 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.c +++ b/drivers/net/bnxt/tf_core/tf_msg.c @@ -39,19 +39,8 @@ * array size (define above) should be checked and compared. */ #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56 -static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) == - TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET, - "HWRM message size changed: hwrm_tf_global_cfg_set_input"); - #define TF_MSG_SIZE_HWRM_TF_EM_INSERT 104 -static_assert(sizeof(struct hwrm_tf_em_insert_input) == - TF_MSG_SIZE_HWRM_TF_EM_INSERT, - "HWRM message size changed: hwrm_tf_em_insert_input"); - #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET 128 -static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) == - TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET, - "HWRM message size changed: hwrm_tf_tbl_type_set_input"); /** * This is the MAX data we can transport across regular HWRM @@ -630,6 +619,9 @@ tf_msg_insert_em_internal_entry(struct tf *tfp, struct tf_dev_info *dev; struct tf_session *tfs; + RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_em_insert_input) != + TF_MSG_SIZE_HWRM_TF_EM_INSERT); + /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) { @@ -1255,6 +1247,17 @@ tf_msg_tcam_entry_get(struct tf *tfp, if (mparms.tf_resp_code != 0) return tfp_le_to_cpu_32(mparms.tf_resp_code); + if (parms->key_size < resp.key_size || + parms->result_size < resp.result_size) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n", + tf_dir_2_str(parms->dir), + parms->key_size, + resp.key_size, + strerror(-rc)); + return rc; + } parms->key_size = resp.key_size; parms->result_size = resp.result_size; tfp_memcpy(parms->key, resp.dev_data, resp.key_size); @@ -1320,6 +1323,9 @@ tf_msg_set_tbl_entry(struct tf *tfp, struct tf_dev_info *dev; struct tf_session *tfs; + RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) != + TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET); + /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) { @@ -1554,6 +1560,9 @@ tf_msg_set_global_cfg(struct tf *tfp, struct tf_dev_info *dev; struct tf_session *tfs; + RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_global_cfg_set_input) != + TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET); + /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) { diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c index 42d503f500..1b5c29815d 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam.c +++ b/drivers/net/bnxt/tf_core/tf_tcam.c @@ -48,10 +48,13 @@ tf_tcam_bind(struct tf *tfp, struct tf_rm_free_db_parms fparms; struct tf_rm_create_db_parms db_cfg; struct tf_tcam_resources *tcam_cnt; - struct tf_shadow_tcam_free_db_parms fshadow; struct tf_rm_get_alloc_info_parms ainfo; + struct tf_shadow_tcam_free_db_parms fshadow; struct tf_shadow_tcam_cfg_parms shadow_cfg; struct tf_shadow_tcam_create_db_parms shadow_cdb; + uint16_t num_slices = 1; + struct tf_session *tfs; + struct tf_dev_info *dev; TF_CHECK_PARMS2(tfp, parms); @@ -61,11 +64,37 @@ tf_tcam_bind(struct tf *tfp, return -EINVAL; } + /* Retrieve the session information */ + rc = tf_session_get_session_internal(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, + "Operation not supported, rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, + TF_TCAM_TBL_TYPE_WC_TCAM, + 0, + &num_slices); + if (rc) + return rc; + tcam_cnt = parms->resources->tcam_cnt; - if ((tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % 2) || - (tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % 2)) { + if ((tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % num_slices) || + (tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % num_slices)) { TFP_DRV_LOG(ERR, - "Number of WC TCAM entries cannot be odd num\n"); + "Requested num of WC TCAM entries has to be multiple %d\n", + num_slices); return -EINVAL; } @@ -88,6 +117,26 @@ tf_tcam_bind(struct tf *tfp, } } + /* check if reserved resource for WC is multiple of num_slices */ + for (d = 0; d < TF_DIR_MAX; d++) { + memset(&info, 0, sizeof(info)); + ainfo.rm_db = tcam_db[d]; + ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM; + ainfo.info = &info; + rc = tf_rm_get_info(&ainfo); + if (rc) + goto error; + + if (info.entry.start % num_slices != 0 || + info.entry.stride % num_slices != 0) { + TFP_DRV_LOG(ERR, + "%s: TCAM reserved resource is not multiple of %d\n", + tf_dir_2_str(d), + num_slices); + return -EINVAL; + } + } + /* Initialize the TCAM manager. */ if (parms->shadow_copy) { for (d = 0; d < TF_DIR_MAX; d++) { @@ -163,7 +212,6 @@ tf_tcam_unbind(struct tf *tfp) int i; struct tf_rm_free_db_parms fparms; struct tf_shadow_tcam_free_db_parms fshadow; - TF_CHECK_PARMS1(tfp); /* Bail if nothing has been initialized */ @@ -202,11 +250,12 @@ int tf_tcam_alloc(struct tf *tfp, struct tf_tcam_alloc_parms *parms) { - int rc; + int rc, i; struct tf_session *tfs; struct tf_dev_info *dev; struct tf_rm_allocate_parms aparms; - uint16_t num_slice_per_row = 1; + uint16_t num_slices = 1; + uint32_t index; TF_CHECK_PARMS2(tfp, parms); @@ -236,32 +285,24 @@ tf_tcam_alloc(struct tf *tfp, return rc; } - /* Need to retrieve row size etc */ + /* Need to retrieve number of slices based on the key_size */ rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, parms->type, parms->key_size, - &num_slice_per_row); + &num_slices); if (rc) return rc; - /* Allocate requested element */ - memset(&aparms, 0, sizeof(aparms)); - - aparms.rm_db = tcam_db[parms->dir]; - aparms.subtype = parms->type; - aparms.priority = parms->priority; - 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; - } - - if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM && - (parms->idx % 2) != 0) { + /* + * For WC TCAM, number of slices could be 4, 2, 1 based on + * the key_size. For other TCAM, it is always 1 + */ + for (i = 0; i < num_slices; i++) { + memset(&aparms, 0, sizeof(aparms)); + aparms.rm_db = tcam_db[parms->dir]; + aparms.subtype = parms->type; + aparms.priority = parms->priority; + aparms.index = &index; rc = tf_rm_allocate(&aparms); if (rc) { TFP_DRV_LOG(ERR, @@ -270,9 +311,11 @@ tf_tcam_alloc(struct tf *tfp, parms->type); return rc; } - } - parms->idx *= num_slice_per_row; + /* return the start index of each row */ + if (i == 0) + parms->idx = index; + } return 0; } @@ -287,9 +330,10 @@ tf_tcam_free(struct tf *tfp, struct tf_rm_is_allocated_parms aparms; struct tf_rm_free_parms fparms; struct tf_rm_get_hcapi_parms hparms; - uint16_t num_slice_per_row = 1; + uint16_t num_slices = 1; int allocated = 0; struct tf_shadow_tcam_remove_parms shparms; + int i; TF_CHECK_PARMS2(tfp, parms); @@ -323,16 +367,24 @@ tf_tcam_free(struct tf *tfp, rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, parms->type, 0, - &num_slice_per_row); + &num_slices); if (rc) return rc; + if (parms->idx % num_slices) { + TFP_DRV_LOG(ERR, + "%s: TCAM reserved resource is not multiple of %d\n", + tf_dir_2_str(parms->dir), + num_slices); + return -EINVAL; + } + /* Check if element is in use */ memset(&aparms, 0, sizeof(aparms)); aparms.rm_db = tcam_db[parms->dir]; aparms.subtype = parms->type; - aparms.index = parms->idx / num_slice_per_row; + aparms.index = parms->idx; aparms.allocated = &allocated; rc = tf_rm_is_allocated(&aparms); if (rc) @@ -376,44 +428,20 @@ tf_tcam_free(struct tf *tfp, } } - /* Free requested element */ - memset(&fparms, 0, sizeof(fparms)); - fparms.rm_db = tcam_db[parms->dir]; - fparms.subtype = 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; - } - - if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM) { - int i; - - for (i = -1; i < 3; i += 3) { - aparms.index += i; - rc = tf_rm_is_allocated(&aparms); - if (rc) - return rc; - - if (allocated == TF_RM_ALLOCATED_ENTRY_IN_USE) { - /* Free requested element */ - fparms.index = aparms.index; - 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, - fparms.index); - return rc; - } - } + for (i = 0; i < num_slices; i++) { + /* Free requested element */ + memset(&fparms, 0, sizeof(fparms)); + fparms.rm_db = tcam_db[parms->dir]; + fparms.subtype = parms->type; + fparms.index = parms->idx + i; + 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; } } @@ -449,8 +477,8 @@ tf_tcam_alloc_search(struct tf *tfp, { struct tf_shadow_tcam_search_parms sparms; struct tf_shadow_tcam_bind_index_parms bparms; - struct tf_tcam_alloc_parms aparms; struct tf_tcam_free_parms fparms; + struct tf_tcam_alloc_parms aparms; uint16_t num_slice_per_row = 1; struct tf_session *tfs; struct tf_dev_info *dev; @@ -626,7 +654,7 @@ tf_tcam_set(struct tf *tfp __rte_unused, aparms.rm_db = tcam_db[parms->dir]; aparms.subtype = parms->type; - aparms.index = parms->idx / num_slice_per_row; + aparms.index = parms->idx; aparms.allocated = &allocated; rc = tf_rm_is_allocated(&aparms); if (rc) @@ -693,7 +721,6 @@ tf_tcam_get(struct tf *tfp __rte_unused, struct tf_dev_info *dev; struct tf_rm_is_allocated_parms aparms; struct tf_rm_get_hcapi_parms hparms; - uint16_t num_slice_per_row = 1; int allocated = 0; TF_CHECK_PARMS2(tfp, parms); @@ -715,29 +742,12 @@ tf_tcam_get(struct tf *tfp __rte_unused, 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 */ memset(&aparms, 0, sizeof(aparms)); aparms.rm_db = tcam_db[parms->dir]; aparms.subtype = parms->type; - aparms.index = parms->idx / num_slice_per_row; + aparms.index = parms->idx; aparms.allocated = &allocated; rc = tf_rm_is_allocated(&aparms); if (rc)