X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_core%2Ftf_em_common.c;h=3bdfc14e0519ad635e33cfb8ff12a740a6ed0452;hb=53a80512644c8a12cb8efc903f77dd7b42263565;hp=ad92cbdc75a2d29ebafb69aef8c5b3bb52fc969a;hpb=0ea250f896ca197bbf79e6920abff4531ced0c2c;p=dpdk.git diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c index ad92cbdc75..3bdfc14e05 100644 --- a/drivers/net/bnxt/tf_core/tf_em_common.c +++ b/drivers/net/bnxt/tf_core/tf_em_common.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019-2020 Broadcom + * Copyright(c) 2019-2021 Broadcom * All rights reserved. */ @@ -19,58 +19,23 @@ #include "tfp.h" #include "tf_device.h" #include "tf_ext_flow_handle.h" -#include "cfa_resource_types.h" +#include "hcapi_cfa.h" #include "bnxt.h" -/* Number of pointers per page_size */ -#define MAX_PAGE_PTRS(page_size) ((page_size) / sizeof(void *)) -/** - * EM DBs. - */ -void *eem_db[TF_DIR_MAX]; +/** Invalid table scope id */ +#define TF_TBL_SCOPE_INVALID 0xffffffff -/** - * Init flag, set on bind and cleared on unbind - */ -static uint8_t init; +/* Number of pointers per page_size */ +#define MAX_PAGE_PTRS(page_size) ((page_size) / sizeof(void *)) /** * Host or system */ static enum tf_mem_type mem_type; -/** Table scope array */ -struct tf_tbl_scope_cb tbl_scopes[TF_NUM_TBL_SCOPE]; - /* API defined in tf_em.h */ -struct tf_tbl_scope_cb * -tbl_scope_cb_find(uint32_t tbl_scope_id) -{ - int i; - struct tf_rm_is_allocated_parms parms = { 0 }; - int allocated; - - /* Check that id is valid */ - parms.rm_db = eem_db[TF_DIR_RX]; - parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE; - parms.index = tbl_scope_id; - parms.allocated = &allocated; - - i = tf_rm_is_allocated(&parms); - - if (i < 0 || allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) - return NULL; - - for (i = 0; i < TF_NUM_TBL_SCOPE; i++) { - if (tbl_scopes[i].tbl_scope_id == tbl_scope_id) - return &tbl_scopes[i]; - } - - return NULL; -} - int tf_create_tbl_pool_external(enum tf_dir dir, struct tf_tbl_scope_cb *tbl_scope_cb, @@ -158,6 +123,44 @@ tf_destroy_tbl_pool_external(enum tf_dir dir, tfp_free(ext_act_pool_mem); } +/** + * Looks up table scope control block using tbl_scope_id from tf_session. + * + * [in] tfp + * Pointer to Truflow Handle + * [in] tbl_scope_id + * table scope id + * + * Return: + * - Pointer to the tf_tbl_scope_cb, if found. + * - (NULL) on failure, not found. + */ +struct tf_tbl_scope_cb * +tf_em_ext_common_tbl_scope_find(struct tf *tfp, + uint32_t tbl_scope_id) +{ + int rc; + struct em_ext_db *ext_db; + void *ext_ptr = NULL; + struct tf_tbl_scope_cb *tbl_scope_cb = NULL; + struct ll_entry *entry; + + rc = tf_session_get_em_ext_db(tfp, &ext_ptr); + if (rc) + return NULL; + + ext_db = (struct em_ext_db *)ext_ptr; + + for (entry = ext_db->tbl_scope_ll.head; entry != NULL; + entry = entry->next) { + tbl_scope_cb = (struct tf_tbl_scope_cb *)entry; + if (tbl_scope_cb->tbl_scope_id == tbl_scope_id) + return tbl_scope_cb; + } + + return NULL; +} + /** * Allocate External Tbl entry from the scope pool. * @@ -182,16 +185,14 @@ tf_tbl_ext_alloc(struct tf *tfp, TF_CHECK_PARMS2(tfp, parms); - /* Get the pool info from the table scope - */ - tbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id); - + tbl_scope_cb = tf_em_ext_common_tbl_scope_find(tfp, parms->tbl_scope_id); if (tbl_scope_cb == NULL) { TFP_DRV_LOG(ERR, "%s, table scope not allocated\n", tf_dir_2_str(parms->dir)); return -EINVAL; } + pool = &tbl_scope_cb->ext_act_pool[parms->dir]; /* Allocate an element @@ -237,10 +238,7 @@ tf_tbl_ext_free(struct tf *tfp, TF_CHECK_PARMS2(tfp, parms); - /* Get the pool info from the table scope - */ - tbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id); - + tbl_scope_cb = tf_em_ext_common_tbl_scope_find(tfp, parms->tbl_scope_id); if (tbl_scope_cb == NULL) { TFP_DRV_LOG(ERR, "%s, table scope error\n", @@ -284,7 +282,7 @@ tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result, { key_entry->hdr.word1 = result->word1; key_entry->hdr.pointer = result->pointer; - memcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4); + memcpy(key_entry->key, in_key, TF_P4_HW_EM_KEY_MAX_SIZE + 4); } @@ -647,7 +645,18 @@ tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb, tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].entry_size = parms->rx_max_action_entry_sz_in_bits / 8; - tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EFC_TABLE].num_entries = 0; + tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EFC_TABLE].num_entries = + 0; + + tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_ACTION_TABLE].num_entries = + parms->rx_num_flows_in_k * TF_KILOBYTE; + tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_ACTION_TABLE].entry_size = + parms->rx_max_action_entry_sz_in_bits / 8; + + tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EM_LKUP_TABLE].num_entries = + parms->rx_num_flows_in_k * TF_KILOBYTE; + tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EM_LKUP_TABLE].entry_size = + parms->rx_max_key_sz_in_bits / 8; /* Tx */ tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].num_entries = @@ -665,7 +674,18 @@ tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb, tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].entry_size = parms->tx_max_action_entry_sz_in_bits / 8; - tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EFC_TABLE].num_entries = 0; + tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EFC_TABLE].num_entries = + 0; + + tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_ACTION_TABLE].num_entries = + parms->rx_num_flows_in_k * TF_KILOBYTE; + tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_ACTION_TABLE].entry_size = + parms->tx_max_action_entry_sz_in_bits / 8; + + tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EM_LKUP_TABLE].num_entries = + parms->rx_num_flows_in_k * TF_KILOBYTE; + tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EM_LKUP_TABLE].entry_size = + parms->tx_max_key_sz_in_bits / 8; return 0; } @@ -681,7 +701,8 @@ tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb, * TF_ERR_EM_DUP - key is already in table */ static int -tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb, +tf_insert_eem_entry(struct tf_dev_info *dev, + struct tf_tbl_scope_cb *tbl_scope_cb, struct tf_insert_em_entry_parms *parms) { uint32_t mask; @@ -706,22 +727,17 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb, if (!mask) return -EINVAL; -#ifdef TF_EEM_DEBUG - dump_raw((uint8_t *)parms->key, TF_HW_EM_KEY_MAX_SIZE + 4, "In Key"); -#endif + if (dev->ops->tf_dev_cfa_key_hash == NULL) + return -EINVAL; - big_hash = hcapi_cfa_key_hash((uint64_t *)parms->key, - (TF_HW_EM_KEY_MAX_SIZE + 4) * 8); + big_hash = dev->ops->tf_dev_cfa_key_hash((uint64_t *)parms->key, + (TF_P4_HW_EM_KEY_MAX_SIZE + 4) * 8); key0_hash = (uint32_t)(big_hash >> 32); key1_hash = (uint32_t)(big_hash & 0xFFFFFFFF); key0_index = key0_hash & mask; key1_index = key1_hash & mask; -#ifdef TF_EEM_DEBUG - TFP_DRV_LOG(DEBUG, "Key0 hash:0x%08x\n", key0_hash); - TFP_DRV_LOG(DEBUG, "Key1 hash:0x%08x\n", key1_hash); -#endif /* * Use the "result" arg to populate all of the key entry then * store the byte swapped "raw" entry in a local copy ready @@ -740,14 +756,14 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb, key_tbl.base0 = (uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE]; key_tbl.page_size = TF_EM_PAGE_SIZE; - key_obj.offset = index * TF_EM_KEY_RECORD_SIZE; + key_obj.offset = index * TF_P4_EM_KEY_RECORD_SIZE; key_obj.data = (uint8_t *)&key_entry; - key_obj.size = TF_EM_KEY_RECORD_SIZE; + key_obj.size = TF_P4_EM_KEY_RECORD_SIZE; - rc = hcapi_cfa_key_hw_op(&op, - &key_tbl, - &key_obj, - &key_loc); + rc = cfa_p4_devops.hcapi_cfa_key_hw_op(&op, + &key_tbl, + &key_obj, + &key_loc); if (rc == 0) { table_type = TF_KEY0_TABLE; @@ -756,12 +772,12 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb, key_tbl.base0 = (uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY1_TABLE]; - key_obj.offset = index * TF_EM_KEY_RECORD_SIZE; + key_obj.offset = index * TF_P4_EM_KEY_RECORD_SIZE; - rc = hcapi_cfa_key_hw_op(&op, - &key_tbl, - &key_obj, - &key_loc); + rc = cfa_p4_devops.hcapi_cfa_key_hw_op(&op, + &key_tbl, + &key_obj, + &key_loc); if (rc != 0) return rc; @@ -819,14 +835,14 @@ tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb, (uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables [(hash_type == 0 ? TF_KEY0_TABLE : TF_KEY1_TABLE)]; key_tbl.page_size = TF_EM_PAGE_SIZE; - key_obj.offset = index * TF_EM_KEY_RECORD_SIZE; + key_obj.offset = index * TF_P4_EM_KEY_RECORD_SIZE; key_obj.data = NULL; - key_obj.size = TF_EM_KEY_RECORD_SIZE; + key_obj.size = TF_P4_EM_KEY_RECORD_SIZE; - rc = hcapi_cfa_key_hw_op(&op, - &key_tbl, - &key_obj, - &key_loc); + rc = cfa_p4_devops.hcapi_cfa_key_hw_op(&op, + &key_tbl, + &key_obj, + &key_loc); if (!rc) return rc; @@ -841,20 +857,34 @@ tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb, * -EINVAL - Error */ int -tf_em_insert_ext_entry(struct tf *tfp __rte_unused, +tf_em_insert_ext_entry(struct tf *tfp, struct tf_insert_em_entry_parms *parms) { + int rc; struct tf_tbl_scope_cb *tbl_scope_cb; + struct tf_session *tfs; + struct tf_dev_info *dev; - tbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id); + tbl_scope_cb = tf_em_ext_common_tbl_scope_find(tfp, parms->tbl_scope_id); if (tbl_scope_cb == NULL) { TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n"); 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; + return tf_insert_eem_entry - (tbl_scope_cb, - parms); + (dev, + tbl_scope_cb, + parms); } /** Delete EM hash entry API @@ -864,12 +894,12 @@ tf_em_insert_ext_entry(struct tf *tfp __rte_unused, * -EINVAL - Error */ int -tf_em_delete_ext_entry(struct tf *tfp __rte_unused, +tf_em_delete_ext_entry(struct tf *tfp, struct tf_delete_em_entry_parms *parms) { struct tf_tbl_scope_cb *tbl_scope_cb; - tbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id); + tbl_scope_cb = tf_em_ext_common_tbl_scope_find(tfp, parms->tbl_scope_id); if (tbl_scope_cb == NULL) { TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n"); return -EINVAL; @@ -886,17 +916,27 @@ tf_em_ext_common_bind(struct tf *tfp, int rc; int i; struct tf_rm_create_db_parms db_cfg = { 0 }; - uint8_t db_exists = 0; + struct em_ext_db *ext_db; + struct tfp_calloc_parms cparms; TF_CHECK_PARMS2(tfp, parms); - if (init) { - TFP_DRV_LOG(ERR, - "EM Ext DB already initialized\n"); - return -EINVAL; + cparms.nitems = 1; + cparms.size = sizeof(struct em_ext_db); + cparms.alignment = 0; + if (tfp_calloc(&cparms) != 0) { + TFP_DRV_LOG(ERR, "em_ext_db alloc error %s\n", + strerror(ENOMEM)); + return -ENOMEM; } - db_cfg.type = TF_DEVICE_MODULE_TYPE_EM; + ext_db = cparms.mem_va; + ll_init(&ext_db->tbl_scope_ll); + for (i = 0; i < TF_DIR_MAX; i++) + ext_db->eem_db[i] = NULL; + tf_session_set_em_ext_db(tfp, ext_db); + + db_cfg.module = TF_MODULE_TYPE_EM; db_cfg.num_elements = parms->num_elements; db_cfg.cfg = parms->cfg; @@ -910,7 +950,7 @@ tf_em_ext_common_bind(struct tf *tfp, if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_TBL_SCOPE] == 0) continue; - db_cfg.rm_db = &eem_db[i]; + db_cfg.rm_db = (void *)&ext_db->eem_db[i]; rc = tf_rm_create_db(tfp, &db_cfg); if (rc) { TFP_DRV_LOG(ERR, @@ -919,12 +959,8 @@ tf_em_ext_common_bind(struct tf *tfp, return rc; } - db_exists = 1; } - if (db_exists) - init = 1; - mem_type = parms->mem_type; return 0; @@ -936,27 +972,77 @@ tf_em_ext_common_unbind(struct tf *tfp) int rc; int i; struct tf_rm_free_db_parms fparms = { 0 }; + struct em_ext_db *ext_db = NULL; + struct tf_session *tfs = NULL; + struct tf_dev_info *dev; + struct ll_entry *entry; + struct tf_tbl_scope_cb *tbl_scope_cb = NULL; + void *ext_ptr = NULL; + struct tf_free_tbl_scope_parms tparms = { 0 }; TF_CHECK_PARMS1(tfp); - /* Bail if nothing has been initialized */ - if (!init) { - TFP_DRV_LOG(INFO, - "No EM Ext DBs created\n"); - return 0; + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, "Failed to get tf_session, rc:%s\n", + strerror(-rc)); + return rc; } - for (i = 0; i < TF_DIR_MAX; i++) { - fparms.dir = i; - fparms.rm_db = eem_db[i]; - rc = tf_rm_free_db(tfp, &fparms); - if (rc) - return rc; + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup device, rc:%s\n", + strerror(-rc)); + return rc; + } - eem_db[i] = NULL; + rc = tf_session_get_em_ext_db(tfp, &ext_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get em_ext_db from session, rc:%s\n", + strerror(-rc)); + return rc; } + ext_db = (struct em_ext_db *)ext_ptr; + + if (ext_db != NULL) { + entry = ext_db->tbl_scope_ll.head; + while (entry != NULL) { + tbl_scope_cb = (struct tf_tbl_scope_cb *)entry; + entry = entry->next; + tparms.tbl_scope_id = + tbl_scope_cb->tbl_scope_id; + + if (dev->ops->tf_dev_free_tbl_scope) { + dev->ops->tf_dev_free_tbl_scope(tfp, + &tparms); + } else { + /* should not reach here */ + ll_delete(&ext_db->tbl_scope_ll, + &tbl_scope_cb->ll_entry); + tfp_free(tbl_scope_cb); + } + } - init = 0; + for (i = 0; i < TF_DIR_MAX; i++) { + if (ext_db->eem_db[i] == NULL) + continue; + + fparms.dir = i; + fparms.rm_db = ext_db->eem_db[i]; + rc = tf_rm_free_db(tfp, &fparms); + if (rc) + return rc; + + ext_db->eem_db[i] = NULL; + } + + tfp_free(ext_db); + } + + tf_session_set_em_ext_db(tfp, NULL); return 0; } @@ -1005,11 +1091,7 @@ int tf_tbl_ext_common_set(struct tf *tfp, return -EINVAL; } - /* Get the table scope control block associated with the - * external pool - */ - tbl_scope_cb = tbl_scope_cb_find(tbl_scope_id); - + tbl_scope_cb = tf_em_ext_common_tbl_scope_find(tfp, tbl_scope_id); if (tbl_scope_cb == NULL) { TFP_DRV_LOG(ERR, "%s, table scope error\n", @@ -1025,10 +1107,10 @@ int tf_tbl_ext_common_set(struct tf *tfp, key_obj.data = parms->data; key_obj.size = parms->data_sz_in_bytes; - rc = hcapi_cfa_key_hw_op(&op, - &key_tbl, - &key_obj, - &key_loc); + rc = cfa_p4_devops.hcapi_cfa_key_hw_op(&op, + &key_tbl, + &key_obj, + &key_loc); return rc; } @@ -1059,14 +1141,6 @@ int tf_em_ext_map_tbl_scope(struct tf *tfp, uint32_t sz_in_bytes = 8; struct tf_dev_info *dev; - tbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id); - - if (tbl_scope_cb == NULL) { - TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb tbl_scope_id(%d)\n", - parms->tbl_scope_id); - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -1077,6 +1151,13 @@ int tf_em_ext_map_tbl_scope(struct tf *tfp, if (rc) return rc; + tbl_scope_cb = tf_em_ext_common_tbl_scope_find(tfp, parms->tbl_scope_id); + if (tbl_scope_cb == NULL) { + TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb tbl_scope_id(%d)\n", + parms->tbl_scope_id); + return -EINVAL; + } + if (dev->ops->tf_dev_map_tbl_scope == NULL) { rc = -EOPNOTSUPP; TFP_DRV_LOG(ERR, @@ -1116,8 +1197,8 @@ int tf_em_ext_map_tbl_scope(struct tf *tfp, goto cleaner; } - gcfg_parms.type = - (enum tf_global_config_type)TF_GLOBAL_CFG_INTERNAL_PARIF_2_PF; + /* Note that TF_GLOBAL_CFG_INTERNAL_PARIF_2_PF is same as below enum */ + gcfg_parms.type = TF_GLOBAL_CFG_TYPE_MAX; gcfg_parms.offset = 0; gcfg_parms.config = (uint8_t *)data; gcfg_parms.config_mask = (uint8_t *)mask;