X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_core%2Ftf_em_internal.c;h=0720bb905d96e0ef0f55b2d5012ca08f48074d64;hb=aebe3cb74c9046a122e948ef9631988423175cea;hp=3129fbe317b4991d4247e25fab3713c5752427af;hpb=e2a002d88c446d4a3334ddc11725502510b3896b;p=dpdk.git diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c index 3129fbe317..0720bb905d 100644 --- a/drivers/net/bnxt/tf_core/tf_em_internal.c +++ b/drivers/net/bnxt/tf_core/tf_em_internal.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019-2020 Broadcom + * Copyright(c) 2019-2021 Broadcom * All rights reserved. */ @@ -15,26 +15,16 @@ #include "tf_msg.h" #include "tfp.h" #include "tf_ext_flow_handle.h" - #include "bnxt.h" -/** - * EM DBs. - */ -static void *em_db[TF_DIR_MAX]; - #define TF_EM_DB_EM_REC 0 -/** - * Init flag, set on bind and cleared on unbind - */ -static uint8_t init; - - /** * EM Pool */ -static struct stack em_pool[TF_DIR_MAX]; +#if (TF_EM_ALLOC == 1) +#include "dpool.h" +#else /** * Create EM Tbl pool of memory indexes. @@ -52,14 +42,35 @@ static struct stack em_pool[TF_DIR_MAX]; * - Failure, entry not allocated, out of resources */ static int -tf_create_em_pool(enum tf_dir dir, +tf_create_em_pool(struct tf_session *tfs, + enum tf_dir dir, uint32_t num_entries, uint32_t start) { struct tfp_calloc_parms parms; uint32_t i, j; int rc = 0; - struct stack *pool = &em_pool[dir]; + struct stack *pool; + + /* + * Allocate stack pool + */ + parms.nitems = 1; + parms.size = sizeof(struct stack); + parms.alignment = 0; + + rc = tfp_calloc(&parms); + + if (rc) { + TFP_DRV_LOG(ERR, + "%s, EM stack allocation failure %s\n", + tf_dir_2_str(dir), + strerror(-rc)); + return rc; + } + + pool = (struct stack *)parms.mem_va; + tfs->em_pool[dir] = (void *)pool; /* Assumes that num_entries has been checked before we get here */ parms.nitems = num_entries / TF_SESSION_EM_ENTRY_SIZE; @@ -119,6 +130,8 @@ tf_create_em_pool(enum tf_dir dir, return 0; cleanup: tfp_free((void *)parms.mem_va); + tfp_free((void *)tfs->em_pool[dir]); + tfs->em_pool[dir] = NULL; return rc; } @@ -131,16 +144,23 @@ cleanup: * Return: */ static void -tf_free_em_pool(enum tf_dir dir) +tf_free_em_pool(struct tf_session *tfs, + enum tf_dir dir) { - struct stack *pool = &em_pool[dir]; + struct stack *pool = (struct stack *)tfs->em_pool[dir]; uint32_t *ptr; - ptr = stack_items(pool); + if (pool != NULL) { + ptr = stack_items(pool); + + if (ptr != NULL) + tfp_free(ptr); - if (ptr != NULL) - tfp_free(ptr); + tfp_free(pool); + tfs->em_pool[dir] = NULL; + } } +#endif /* TF_EM_ALLOC != 1 */ /** * Insert EM internal entry API @@ -157,17 +177,44 @@ tf_em_insert_int_entry(struct tf *tfp, uint16_t rptr_index = 0; uint8_t rptr_entry = 0; uint8_t num_of_entries = 0; - struct stack *pool = &em_pool[parms->dir]; + struct tf_session *tfs; +#if (TF_EM_ALLOC == 1) + struct dpool *pool; +#else + struct stack *pool; +#endif uint32_t index; - rc = stack_pop(pool, &index); + /* 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; + } +#if (TF_EM_ALLOC == 1) + pool = (struct dpool *)tfs->em_pool[parms->dir]; + index = dpool_alloc(pool, TF_SESSION_EM_ENTRY_SIZE, 0); + if (index == DP_INVALID_INDEX) { + PMD_DRV_LOG(ERR, + "%s, EM entry index allocation failed\n", + tf_dir_2_str(parms->dir)); + return -1; + } +#else + pool = (struct stack *)tfs->em_pool[parms->dir]; + rc = stack_pop(pool, &index); if (rc) { PMD_DRV_LOG(ERR, "%s, EM entry index allocation failed\n", tf_dir_2_str(parms->dir)); return rc; } +#endif + rptr_index = index; rc = tf_msg_insert_em_internal_entry(tfp, @@ -175,18 +222,15 @@ tf_em_insert_int_entry(struct tf *tfp, &rptr_index, &rptr_entry, &num_of_entries); - if (rc) + if (rc) { + /* Free the allocated index before returning */ +#if (TF_EM_ALLOC == 1) + dpool_free(pool, index); +#else + stack_push(pool, index); +#endif return -1; - - PMD_DRV_LOG - (ERR, - "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n", - tf_dir_2_str(parms->dir), - index, - rptr_index, - rptr_entry, - num_of_entries); - + } TF_SET_GFID(gfid, ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) | rptr_entry), @@ -200,7 +244,7 @@ tf_em_insert_int_entry(struct tf *tfp, TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle, (uint32_t)num_of_entries, 0, - 0, + TF_FLAGS_FLOW_HANDLE_INTERNAL, rptr_index, rptr_entry, 0); @@ -219,37 +263,124 @@ tf_em_delete_int_entry(struct tf *tfp, struct tf_delete_em_entry_parms *parms) { int rc = 0; - struct stack *pool = &em_pool[parms->dir]; + struct tf_session *tfs; +#if (TF_EM_ALLOC == 1) + struct dpool *pool; +#else + struct stack *pool; +#endif + /* 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_msg_delete_em_entry(tfp, parms); /* Return resource to pool */ - if (rc == 0) + if (rc == 0) { +#if (TF_EM_ALLOC == 1) + pool = (struct dpool *)tfs->em_pool[parms->dir]; + dpool_free(pool, parms->index); +#else + pool = (struct stack *)tfs->em_pool[parms->dir]; stack_push(pool, parms->index); +#endif + } + + return rc; +} + +#if (TF_EM_ALLOC == 1) +static int +tf_em_move_callback(void *user_data, + uint64_t entry_data, + uint32_t new_index) +{ + int rc; + struct tf *tfp = (struct tf *)user_data; + struct tf_move_em_entry_parms parms; + struct tf_dev_info *dev; + struct tf_session *tfs; + + memset(&parms, 0, sizeof(parms)); + + parms.tbl_scope_id = 0; + parms.flow_handle = entry_data; + parms.new_index = new_index; + TF_GET_DIR_FROM_FLOW_ID(entry_data, parms.dir); + parms.mem = TF_MEM_INTERNAL; + + /* 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; + } + + /* 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; + } + + if (dev->ops->tf_dev_move_int_em_entry != NULL) + rc = dev->ops->tf_dev_move_int_em_entry(tfp, &parms); + else + rc = -EOPNOTSUPP; return rc; } +#endif int tf_em_int_bind(struct tf *tfp, struct tf_em_cfg_parms *parms) { int rc; + int db_rc[TF_DIR_MAX] = { 0 }; int i; struct tf_rm_create_db_parms db_cfg = { 0 }; - uint8_t db_exists = 0; struct tf_rm_get_alloc_info_parms iparms; struct tf_rm_alloc_info info; + struct em_rm_db *em_db; + struct tfp_calloc_parms cparms; + struct tf_session *tfs; TF_CHECK_PARMS2(tfp, parms); - if (init) { - TFP_DRV_LOG(ERR, - "EM Int DB already initialized\n"); - return -EINVAL; + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + memset(&db_cfg, 0, sizeof(db_cfg)); + cparms.nitems = 1; + cparms.size = sizeof(struct em_rm_db); + cparms.alignment = 0; + if (tfp_calloc(&cparms) != 0) { + TFP_DRV_LOG(ERR, "em_rm_db alloc error %s\n", + strerror(ENOMEM)); + return -ENOMEM; } - db_cfg.type = TF_DEVICE_MODULE_TYPE_EM; + em_db = cparms.mem_va; + for (i = 0; i < TF_DIR_MAX; i++) + em_db->em_db[i] = NULL; + tf_session_set_db(tfp, TF_MODULE_TYPE_EM, em_db); + + db_cfg.module = TF_MODULE_TYPE_EM; db_cfg.num_elements = parms->num_elements; db_cfg.cfg = parms->cfg; @@ -275,43 +406,79 @@ tf_em_int_bind(struct tf *tfp, return rc; } - db_cfg.rm_db = &em_db[i]; - rc = tf_rm_create_db(tfp, &db_cfg); - if (rc) { - TFP_DRV_LOG(ERR, - "%s: EM Int DB creation failed\n", - tf_dir_2_str(i)); + db_cfg.rm_db = (void *)&em_db->em_db[i]; + if (tf_session_is_shared_session(tfs) && + (!tf_session_is_shared_session_creator(tfs))) + db_rc[i] = tf_rm_create_db_no_reservation(tfp, &db_cfg); + else + db_rc[i] = tf_rm_create_db(tfp, &db_cfg); + } - return rc; - } - db_exists = 1; + /* No db created */ + if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) { + TFP_DRV_LOG(ERR, "EM Int DB creation failed\n"); + return db_rc[TF_DIR_RX]; } - if (db_exists) - init = 1; - for (i = 0; i < TF_DIR_MAX; i++) { - iparms.rm_db = em_db[i]; - iparms.db_index = TF_EM_DB_EM_REC; - iparms.info = &info; + if (!tf_session_is_shared_session(tfs)) { + for (i = 0; i < TF_DIR_MAX; i++) { + iparms.rm_db = em_db->em_db[i]; + iparms.subtype = TF_EM_DB_EM_REC; + iparms.info = &info; + + rc = tf_rm_get_info(&iparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: EM DB get info failed\n", + tf_dir_2_str(i)); + return rc; + } +#if (TF_EM_ALLOC == 1) + /* + * Allocate stack pool + */ + cparms.nitems = 1; + cparms.size = sizeof(struct dpool); + cparms.alignment = 0; + + rc = tfp_calloc(&cparms); + + if (rc) { + TFP_DRV_LOG(ERR, + "%s, EM stack allocation failure %s\n", + tf_dir_2_str(i), + strerror(-rc)); + return rc; + } + + tfs->em_pool[i] = (struct dpool *)cparms.mem_va; + + rc = dpool_init(tfs->em_pool[i], + iparms.info->entry.start, + iparms.info->entry.stride, + 7, + (void *)tfp, + tf_em_move_callback); +#else + rc = tf_create_em_pool(tfs, + i, + iparms.info->entry.stride, + iparms.info->entry.start); +#endif + /* Logging handled in tf_create_em_pool */ + if (rc) + return rc; + } - rc = tf_rm_get_info(&iparms); if (rc) { TFP_DRV_LOG(ERR, - "%s: EM DB get info failed\n", + "%s: EM pool init failed\n", tf_dir_2_str(i)); return rc; } - - rc = tf_create_em_pool(i, - iparms.info->entry.stride, - iparms.info->entry.start); - /* Logging handled in tf_create_em_pool */ - if (rc) - return rc; } - return 0; } @@ -321,32 +488,82 @@ tf_em_int_unbind(struct tf *tfp) int rc; int i; struct tf_rm_free_db_parms fparms = { 0 }; + struct em_rm_db *em_db; + void *em_db_ptr = NULL; + struct tf_session *tfs; TF_CHECK_PARMS1(tfp); - /* Bail if nothing has been initialized */ - if (!init) { - TFP_DRV_LOG(INFO, - "No EM Int DBs created\n"); - return 0; + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + if (!tf_session_is_shared_session(tfs)) { + for (i = 0; i < TF_DIR_MAX; i++) +#if (TF_EM_ALLOC == 1) + dpool_free_all(tfs->em_pool[i]); +#else + tf_free_em_pool(tfs, i); +#endif } - for (i = 0; i < TF_DIR_MAX; i++) - tf_free_em_pool(i); + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr); + if (rc) { + return 0; + } + em_db = (struct em_rm_db *)em_db_ptr; for (i = 0; i < TF_DIR_MAX; i++) { + if (em_db->em_db[i] == NULL) + continue; fparms.dir = i; - fparms.rm_db = em_db[i]; - if (em_db[i] != NULL) { - rc = tf_rm_free_db(tfp, &fparms); - if (rc) - return rc; - } + fparms.rm_db = em_db->em_db[i]; + rc = tf_rm_free_db(tfp, &fparms); + if (rc) + return rc; - em_db[i] = NULL; + em_db->em_db[i] = NULL; } - init = 0; + return 0; +} + +int +tf_em_get_resc_info(struct tf *tfp, + struct tf_em_resource_info *em) +{ + int rc; + int d; + struct tf_resource_info *dinfo; + struct tf_rm_get_alloc_info_parms ainfo; + void *em_db_ptr = NULL; + struct em_rm_db *em_db; + + TF_CHECK_PARMS2(tfp, em); + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr); + if (rc == -ENOMEM) + return 0; /* db does not exist */ + else if (rc) + return rc; /* db error */ + + em_db = (struct em_rm_db *)em_db_ptr; + + /* check if reserved resource for EM is multiple of num_slices */ + for (d = 0; d < TF_DIR_MAX; d++) { + ainfo.rm_db = em_db->em_db[d]; + dinfo = em[d].info; + + if (!ainfo.rm_db) + continue; + + ainfo.info = (struct tf_rm_alloc_info *)dinfo; + ainfo.subtype = 0; + rc = tf_rm_get_all_info(&ainfo, TF_EM_TBL_TYPE_MAX); + if (rc && rc != -ENOTSUP) + return rc; + } return 0; }