X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_core%2Ftf_session.c;h=90b65c59e60810ae2c006277f49e0fea48c4ad57;hb=249feed2e40a0a69421acbd3a497fd38af1ebbb6;hp=0b2b6f4da2df2e4f39ed19f4b5f2cfddf124365b;hpb=a46bbb57605b40201c2bab6386a7890451224836;p=dpdk.git diff --git a/drivers/net/bnxt/tf_core/tf_session.c b/drivers/net/bnxt/tf_core/tf_session.c index 0b2b6f4da2..90b65c59e6 100644 --- a/drivers/net/bnxt/tf_core/tf_session.c +++ b/drivers/net/bnxt/tf_core/tf_session.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019-2020 Broadcom + * Copyright(c) 2019-2021 Broadcom * All rights reserved. */ @@ -11,23 +11,69 @@ #include "tf_common.h" #include "tf_msg.h" #include "tfp.h" +#include "bnxt.h" -int -tf_session_open_session(struct tf *tfp, - struct tf_session_open_session_parms *parms) +struct tf_session_client_create_parms { + /** + * [in] Pointer to the control channel name string + */ + char *ctrl_chan_name; + + /** + * [out] Firmware Session Client ID + */ + union tf_session_client_id *session_client_id; +}; + +struct tf_session_client_destroy_parms { + /** + * FW Session Client Identifier + */ + union tf_session_client_id session_client_id; +}; + +/** + * Creates a Session and the associated client. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to session client create parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + * - (-ENOMEM) if max session clients has been reached. + */ +static int +tf_session_create(struct tf *tfp, + struct tf_session_open_session_parms *parms) { int rc; struct tf_session *session = NULL; + struct tf_session_client *client; struct tfp_calloc_parms cparms; uint8_t fw_session_id; + uint8_t fw_session_client_id; union tf_session_id *session_id; + struct tf_dev_info dev; + bool shared_session_creator; + int name_len; + char *name; TF_CHECK_PARMS2(tfp, parms); + tf_dev_bind_ops(parms->open_cfg->device_type, + &dev); + /* Open FW session and get a new session_id */ - rc = tf_msg_session_open(tfp, + rc = tf_msg_session_open(parms->open_cfg->bp, parms->open_cfg->ctrl_chan_name, - &fw_session_id); + &fw_session_id, + &fw_session_client_id, + &dev, + &shared_session_creator); if (rc) { /* Log error */ if (rc == -EEXIST) @@ -70,59 +116,358 @@ tf_session_open_session(struct tf *tfp, goto cleanup; } tfp->session->core_data = cparms.mem_va; + session_id = &parms->open_cfg->session_id; + + /* Update Session Info, which is what is visible to the caller */ + tfp->session->ver.major = 0; + tfp->session->ver.minor = 0; + tfp->session->ver.update = 0; - /* Initialize Session and Device */ + tfp->session->session_id.internal.domain = session_id->internal.domain; + tfp->session->session_id.internal.bus = session_id->internal.bus; + tfp->session->session_id.internal.device = session_id->internal.device; + tfp->session->session_id.internal.fw_session_id = fw_session_id; + + /* Initialize Session and Device, which is private */ session = (struct tf_session *)tfp->session->core_data; session->ver.major = 0; session->ver.minor = 0; session->ver.update = 0; - session_id = &parms->open_cfg->session_id; session->session_id.internal.domain = session_id->internal.domain; session->session_id.internal.bus = session_id->internal.bus; session->session_id.internal.device = session_id->internal.device; session->session_id.internal.fw_session_id = fw_session_id; - /* Return the allocated fw session id */ - session_id->internal.fw_session_id = fw_session_id; + /* Return the allocated session id */ + session_id->id = session->session_id.id; session->shadow_copy = parms->open_cfg->shadow_copy; - tfp_memcpy(session->ctrl_chan_name, + /* Init session client list */ + ll_init(&session->client_ll); + + /* Create the local session client, initialize and attach to + * the session + */ + cparms.nitems = 1; + cparms.size = sizeof(struct tf_session_client); + cparms.alignment = 0; + rc = tfp_calloc(&cparms); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "Failed to allocate session client, rc:%s\n", + strerror(-rc)); + goto cleanup; + } + client = cparms.mem_va; + + /* Register FID with the client */ + rc = tfp_get_fid(tfp, &client->fw_fid); + if (rc) + return rc; + + client->session_client_id.internal.fw_session_id = fw_session_id; + client->session_client_id.internal.fw_session_client_id = + fw_session_client_id; + + tfp_memcpy(client->ctrl_chan_name, parms->open_cfg->ctrl_chan_name, TF_SESSION_NAME_MAX); - rc = dev_bind(tfp, - parms->open_cfg->device_type, - session->shadow_copy, - &parms->open_cfg->resources, - session->dev); + ll_insert(&session->client_ll, &client->ll_entry); + session->ref_count++; + + /* Init session em_ext_db */ + session->em_ext_db_handle = NULL; + + /* Populate the request */ + name_len = strnlen(parms->open_cfg->ctrl_chan_name, + TF_SESSION_NAME_MAX); + name = &parms->open_cfg->ctrl_chan_name[name_len - strlen("tf_shared")]; + if (!strncmp(name, "tf_shared", strlen("tf_shared"))) + session->shared_session = true; + + name = &parms->open_cfg->ctrl_chan_name[name_len - + strlen("tf_shared-wc_tcam")]; + if (!strncmp(name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam"))) + session->shared_session = true; + + if (session->shared_session && shared_session_creator) { + session->shared_session_creator = true; + parms->open_cfg->shared_session_creator = true; + } + + rc = tf_dev_bind(tfp, + parms->open_cfg->device_type, + session->shadow_copy, + &parms->open_cfg->resources, + &session->dev); + /* Logging handled by dev_bind */ if (rc) + goto cleanup; + + if (session->dev.ops->tf_dev_get_mailbox == NULL) { + /* Log error */ + TFP_DRV_LOG(ERR, + "No tf_dev_get_mailbox() defined for device\n"); + goto cleanup; + } + + session->dev_init = true; + + return 0; + + cleanup: + rc = tf_msg_session_close(tfp, + fw_session_id, + dev.ops->tf_dev_get_mailbox()); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "FW Session close failed, rc:%s\n", + strerror(-rc)); + } + + tfp_free(tfp->session->core_data); + tfp_free(tfp->session); + tfp->session = NULL; + return rc; +} + +/** + * Creates a Session Client on an existing Session. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to session client create parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + * - (-ENOMEM) if max session clients has been reached. + */ +static int +tf_session_client_create(struct tf *tfp, + struct tf_session_client_create_parms *parms) +{ + int rc; + struct tf_session *session = NULL; + struct tf_session_client *client; + struct tfp_calloc_parms cparms; + union tf_session_client_id session_client_id; + + TF_CHECK_PARMS2(tfp, parms); + + /* Using internal version as session client may not exist yet */ + rc = tf_session_get_session_internal(tfp, &session); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } + + client = tf_session_find_session_client_by_name(session, + parms->ctrl_chan_name); + if (client) { + TFP_DRV_LOG(ERR, + "Client %s, already registered with this session\n", + parms->ctrl_chan_name); + return -EOPNOTSUPP; + } + + rc = tf_msg_session_client_register + (tfp, + session, + parms->ctrl_chan_name, + &session_client_id.internal.fw_session_client_id); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to create client on session, rc:%s\n", + strerror(-rc)); return rc; + } - /* Query for Session Config + /* Create the local session client, initialize and attach to + * the session */ - rc = tf_msg_session_qcfg(tfp); + cparms.nitems = 1; + cparms.size = sizeof(struct tf_session_client); + cparms.alignment = 0; + rc = tfp_calloc(&cparms); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to allocate session client, rc:%s\n", + strerror(-rc)); + goto cleanup; + } + client = cparms.mem_va; + + /* Register FID with the client */ + rc = tfp_get_fid(tfp, &client->fw_fid); + if (rc) + return rc; + + /* Build the Session Client ID by adding the fw_session_id */ + rc = tf_session_get_fw_session_id + (tfp, + &session_client_id.internal.fw_session_id); if (rc) { TFP_DRV_LOG(ERR, - "Query config message send failed, rc:%s\n", + "Session Firmware id lookup failed, rc:%s\n", strerror(-rc)); - goto cleanup_close; + return rc; } + tfp_memcpy(client->ctrl_chan_name, + parms->ctrl_chan_name, + TF_SESSION_NAME_MAX); + + client->session_client_id.id = session_client_id.id; + + ll_insert(&session->client_ll, &client->ll_entry); + session->ref_count++; - return 0; + /* Build the return value */ + parms->session_client_id->id = session_client_id.id; cleanup: - tfp_free(tfp->session->core_data); - tfp_free(tfp->session); - tfp->session = NULL; + /* TBD - Add code to unregister newly create client from fw */ + + return rc; +} + + +/** + * Destroys a Session Client on an existing Session. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to the session client destroy parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + * - (-ENOTFOUND) error, client not owned by the session. + * - (-ENOTSUPP) error, unable to destroy client as its the last + * client. Please use the tf_session_close(). + */ +static int +tf_session_client_destroy(struct tf *tfp, + struct tf_session_client_destroy_parms *parms) +{ + int rc; + struct tf_session *tfs; + struct tf_session_client *client; + + TF_CHECK_PARMS2(tfp, parms); + + rc = tf_session_get_session(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } + + /* Check session owns this client and that we're not the last client */ + client = tf_session_get_session_client(tfs, + parms->session_client_id); + if (client == NULL) { + TFP_DRV_LOG(ERR, + "Client %d, not found within this session\n", + parms->session_client_id.id); + return -EINVAL; + } + + /* If last client the request is rejected and cleanup should + * be done by session close. + */ + if (tfs->ref_count == 1) + return -EOPNOTSUPP; + + rc = tf_msg_session_client_unregister + (tfp, + tfs, + parms->session_client_id.internal.fw_session_client_id); + + /* Log error, but continue. If FW fails we do not really have + * a way to fix this but the client would no longer be valid + * thus we remove from the session. + */ + if (rc) { + TFP_DRV_LOG(ERR, + "Client destroy on FW Failed, rc:%s\n", + strerror(-rc)); + } + + ll_delete(&tfs->client_ll, &client->ll_entry); + + /* Decrement the session ref_count */ + tfs->ref_count--; + + tfp_free(client); + return rc; +} + +int +tf_session_open_session(struct tf *tfp, + struct tf_session_open_session_parms *parms) +{ + int rc; + struct tf_session_client_create_parms scparms; + + TF_CHECK_PARMS3(tfp, parms, parms->open_cfg->bp); + + tfp->bp = parms->open_cfg->bp; + /* Decide if we're creating a new session or session client */ + if (tfp->session == NULL) { + rc = tf_session_create(tfp, parms); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to create session, ctrl_chan_name:%s, rc:%s\n", + parms->open_cfg->ctrl_chan_name, + strerror(-rc)); + return rc; + } + + TFP_DRV_LOG(INFO, + "Session created, session_client_id:%d," + "session_id:0x%08x, fw_session_id:%d\n", + parms->open_cfg->session_client_id.id, + parms->open_cfg->session_id.id, + parms->open_cfg->session_id.internal.fw_session_id); + } else { + scparms.ctrl_chan_name = parms->open_cfg->ctrl_chan_name; + scparms.session_client_id = &parms->open_cfg->session_client_id; + + /* Create the new client and get it associated with + * the session. + */ + rc = tf_session_client_create(tfp, &scparms); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to create client on session 0x%x, rc:%s\n", + parms->open_cfg->session_id.id, + strerror(-rc)); + return rc; + } + + TFP_DRV_LOG(INFO, + "Session Client:%d registered on session:0x%8x\n", + scparms.session_client_id->internal.fw_session_client_id, + tfp->session->session_id.id); + } - cleanup_close: - tf_close_session(tfp); - return -EINVAL; + return 0; } int @@ -145,7 +490,12 @@ tf_session_close_session(struct tf *tfp, { int rc; struct tf_session *tfs = NULL; + struct tf_session_client *client; struct tf_dev_info *tfd = NULL; + struct tf_session_client_destroy_parms scdparms; + uint16_t fid; + uint8_t fw_session_id = 1; + int mailbox = 0; TF_CHECK_PARMS2(tfp, parms); @@ -165,6 +515,58 @@ tf_session_close_session(struct tf *tfp, return rc; } + /* Get the client, we need it independently of the closure + * type (client or session closure). + * + * We find the client by way of the fid. Thus one cannot close + * a client on behalf of someone else. + */ + rc = tfp_get_fid(tfp, &fid); + if (rc) + return rc; + + client = tf_session_find_session_client_by_fid(tfs, + fid); + if (!client) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "Client not part of the session, unable to close, rc:%s\n", + strerror(-rc)); + return rc; + } + + /* In case multiple clients we chose to close those first */ + if (tfs->ref_count > 1) { + /* Linaro gcc can't static init this structure */ + memset(&scdparms, + 0, + sizeof(struct tf_session_client_destroy_parms)); + + scdparms.session_client_id = client->session_client_id; + /* Destroy requested client so its no longer + * registered with this session. + */ + rc = tf_session_client_destroy(tfp, &scdparms); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to unregister Client %d, rc:%s\n", + client->session_client_id.id, + strerror(-rc)); + return rc; + } + + TFP_DRV_LOG(INFO, + "Closed session client, session_client_id:%d\n", + client->session_client_id.id); + + TFP_DRV_LOG(INFO, + "session_id:0x%08x, ref_count:%d\n", + tfs->session_id.id, + tfs->ref_count); + + return 0; + } + /* Record the session we're closing so the caller knows the * details. */ @@ -178,8 +580,26 @@ tf_session_close_session(struct tf *tfp, return rc; } - /* In case we're attached only the session client gets closed */ - rc = tf_msg_session_close(tfp); + mailbox = tfd->ops->tf_dev_get_mailbox(); + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "Unable to lookup FW id, rc:%s\n", + strerror(-rc)); + return rc; + } + + /* Unbind the device */ + rc = tf_dev_unbind(tfp, tfd); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "Device unbind failed, rc:%s\n", + strerror(-rc)); + } + + rc = tf_msg_session_close(tfp, fw_session_id, mailbox); if (rc) { /* Log error */ TFP_DRV_LOG(ERR, @@ -187,33 +607,53 @@ tf_session_close_session(struct tf *tfp, strerror(-rc)); } + /* Final cleanup as we're last user of the session thus we + * also delete the last client. + */ + ll_delete(&tfs->client_ll, &client->ll_entry); + tfp_free(client); + tfs->ref_count--; - /* Final cleanup as we're last user of the session */ - if (tfs->ref_count == 0) { - /* Unbind the device */ - rc = dev_unbind(tfp, tfd); - if (rc) { - /* Log error */ - TFP_DRV_LOG(ERR, - "Device unbind failed, rc:%s\n", - strerror(-rc)); - } + TFP_DRV_LOG(INFO, + "Closed session, session_id:0x%08x, ref_count:%d\n", + tfs->session_id.id, + tfs->ref_count); - tfp_free(tfp->session->core_data); - tfp_free(tfp->session); - tfp->session = NULL; - } + tfs->dev_init = false; + + tfp_free(tfp->session->core_data); + tfp_free(tfp->session); + tfp->session = NULL; return 0; } +bool +tf_session_is_fid_supported(struct tf_session *tfs, + uint16_t fid) +{ + struct ll_entry *c_entry; + struct tf_session_client *client; + + for (c_entry = tfs->client_ll.head; + c_entry != NULL; + c_entry = c_entry->next) { + client = (struct tf_session_client *)c_entry; + if (client->fw_fid == fid) + return true; + } + + return false; +} + int -tf_session_get_session(struct tf *tfp, - struct tf_session **tfs) +tf_session_get_session_internal(struct tf *tfp, + struct tf_session **tfs) { - int rc; + int rc = 0; + /* Skip using the check macro as we want to control the error msg */ if (tfp->session == NULL || tfp->session->core_data == NULL) { rc = -EINVAL; TFP_DRV_LOG(ERR, @@ -224,24 +664,120 @@ tf_session_get_session(struct tf *tfp, *tfs = (struct tf_session *)(tfp->session->core_data); - return 0; + return rc; } int -tf_session_get_device(struct tf_session *tfs, - struct tf_dev_info **tfd) +tf_session_get_session(struct tf *tfp, + struct tf_session **tfs) { int rc; + uint16_t fw_fid; + bool supported = false; - if (tfs->dev == NULL) { - rc = -EINVAL; + rc = tf_session_get_session_internal(tfp, + tfs); + /* Logging done by tf_session_get_session_internal */ + if (rc) + return rc; + + /* As session sharing among functions aka 'individual clients' + * is supported we have to assure that the client is indeed + * registered before we get deep in the TruFlow api stack. + */ + rc = tfp_get_fid(tfp, &fw_fid); + if (rc) { TFP_DRV_LOG(ERR, - "Device not created, rc:%s\n", + "Internal FID lookup\n, rc:%s\n", strerror(-rc)); return rc; } - *tfd = tfs->dev; + supported = tf_session_is_fid_supported(*tfs, fw_fid); + if (!supported) { + TFP_DRV_LOG + (ERR, + "Ctrl channel not registered with session\n, rc:%s\n", + strerror(-rc)); + return -EINVAL; + } + + return rc; +} + +struct tf_session_client * +tf_session_get_session_client(struct tf_session *tfs, + union tf_session_client_id session_client_id) +{ + struct ll_entry *c_entry; + struct tf_session_client *client; + + /* Skip using the check macro as we just want to return */ + if (tfs == NULL) + return NULL; + + for (c_entry = tfs->client_ll.head; + c_entry != NULL; + c_entry = c_entry->next) { + client = (struct tf_session_client *)c_entry; + if (client->session_client_id.id == session_client_id.id) + return client; + } + + return NULL; +} + +struct tf_session_client * +tf_session_find_session_client_by_name(struct tf_session *tfs, + const char *ctrl_chan_name) +{ + struct ll_entry *c_entry; + struct tf_session_client *client; + + /* Skip using the check macro as we just want to return */ + if (tfs == NULL || ctrl_chan_name == NULL) + return NULL; + + for (c_entry = tfs->client_ll.head; + c_entry != NULL; + c_entry = c_entry->next) { + client = (struct tf_session_client *)c_entry; + if (strncmp(client->ctrl_chan_name, + ctrl_chan_name, + TF_SESSION_NAME_MAX) == 0) + return client; + } + + return NULL; +} + +struct tf_session_client * +tf_session_find_session_client_by_fid(struct tf_session *tfs, + uint16_t fid) +{ + struct ll_entry *c_entry; + struct tf_session_client *client; + + /* Skip using the check macro as we just want to return */ + if (tfs == NULL) + return NULL; + + for (c_entry = tfs->client_ll.head; + c_entry != NULL; + c_entry = c_entry->next) { + client = (struct tf_session_client *)c_entry; + if (client->fw_fid == fid) + return client; + } + + return NULL; +} + +int +tf_session_get_device(struct tf_session *tfs, + struct tf_dev_info **tfd) +{ + *tfd = &tfs->dev; return 0; } @@ -253,6 +789,7 @@ tf_session_get_fw_session_id(struct tf *tfp, int rc; struct tf_session *tfs = NULL; + /* Skip using the check macro as we want to control the error msg */ if (tfp->session == NULL) { rc = -EINVAL; TFP_DRV_LOG(ERR, @@ -261,7 +798,15 @@ tf_session_get_fw_session_id(struct tf *tfp, return rc; } - rc = tf_session_get_session(tfp, &tfs); + if (fw_session_id == NULL) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "Invalid Argument(s), rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = tf_session_get_session_internal(tfp, &tfs); if (rc) return rc; @@ -269,3 +814,202 @@ tf_session_get_fw_session_id(struct tf *tfp, return 0; } + +int +tf_session_get_session_id(struct tf *tfp, + union tf_session_id *session_id) +{ + int rc; + struct tf_session *tfs = NULL; + + if (tfp->session == NULL) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "Session not created, rc:%s\n", + strerror(-rc)); + return rc; + } + + if (session_id == NULL) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "Invalid Argument(s), rc:%s\n", + strerror(-rc)); + return rc; + } + + /* Using internal version as session client may not exist yet */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + *session_id = tfs->session_id; + + return 0; +} + +int +tf_session_get_em_ext_db(struct tf *tfp, + void **em_ext_db_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + *em_ext_db_handle = NULL; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + *em_ext_db_handle = tfs->em_ext_db_handle; + return rc; +} + +int +tf_session_set_em_ext_db(struct tf *tfp, + void *em_ext_db_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + tfs->em_ext_db_handle = em_ext_db_handle; + return rc; +} + +int +tf_session_get_db(struct tf *tfp, + enum tf_module_type type, + void **db_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + *db_handle = NULL; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + switch (type) { + case TF_MODULE_TYPE_IDENTIFIER: + if (tfs->id_db_handle) + *db_handle = tfs->id_db_handle; + else + rc = -ENOMEM; + break; + case TF_MODULE_TYPE_TABLE: + if (tfs->tbl_db_handle) + *db_handle = tfs->tbl_db_handle; + else + rc = -ENOMEM; + + break; + case TF_MODULE_TYPE_TCAM: + if (tfs->tcam_db_handle) + *db_handle = tfs->tcam_db_handle; + else + rc = -ENOMEM; + break; + case TF_MODULE_TYPE_EM: + if (tfs->em_db_handle) + *db_handle = tfs->em_db_handle; + else + rc = -ENOMEM; + break; + default: + rc = -EINVAL; + break; + } + + return rc; +} + +int +tf_session_set_db(struct tf *tfp, + enum tf_module_type type, + void *db_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + switch (type) { + case TF_MODULE_TYPE_IDENTIFIER: + tfs->id_db_handle = db_handle; + break; + case TF_MODULE_TYPE_TABLE: + tfs->tbl_db_handle = db_handle; + break; + case TF_MODULE_TYPE_TCAM: + tfs->tcam_db_handle = db_handle; + break; + case TF_MODULE_TYPE_EM: + tfs->em_db_handle = db_handle; + break; + default: + rc = -EINVAL; + break; + } + + return rc; +} + +#ifdef TF_TCAM_SHARED + +int +tf_session_get_tcam_shared_db(struct tf *tfp, + void **tcam_shared_db_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + *tcam_shared_db_handle = NULL; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + *tcam_shared_db_handle = tfs->tcam_shared_db_handle; + return rc; +} + +int +tf_session_set_tcam_shared_db(struct tf *tfp, + void *tcam_shared_db_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + tfs->tcam_shared_db_handle = tcam_shared_db_handle; + return rc; +} +#endif /* TF_TCAM_SHARED */