X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_core%2Ftf_msg.c;h=0fbb2fe837631c5a73bb499a4157fe95d0d7e796;hb=53a80512644c8a12cb8efc903f77dd7b42263565;hp=02d8a49713196dc8644bd29db89294ea527ab55b;hpb=ced3cded44928094f9d9ec7ee06fede936d53f84;p=dpdk.git diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c index 02d8a49713..0fbb2fe837 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.c +++ b/drivers/net/bnxt/tf_core/tf_msg.c @@ -1,13 +1,15 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019-2020 Broadcom + * Copyright(c) 2019-2021 Broadcom * All rights reserved. */ +#include #include #include #include #include +#include "tf_em_common.h" #include "tf_msg_common.h" #include "tf_device.h" #include "tf_msg.h" @@ -15,14 +17,57 @@ #include "tf_common.h" #include "tf_session.h" #include "tfp.h" -#include "hwrm_tf.h" #include "tf_em.h" +/* Specific msg size defines as we cannot use defines in tf.yaml. This + * means we have to manually sync hwrm with these defines if the + * tf.yaml changes. + */ +#define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE 16 +#define TF_MSG_EM_INSERT_KEY_SIZE 64 +#define TF_MSG_EM_INSERT_RECORD_SIZE 80 +#define TF_MSG_TBL_TYPE_SET_DATA_SIZE 88 + +/* Compile check - Catch any msg changes that we depend on, like the + * defines listed above for array size checking. + * + * Checking array size is dangerous in that the type could change and + * we wouldn't be able to catch it. Thus we check if the complete msg + * changed instead. Best we can do. + * + * If failure is observed then both msg size (defines below) and the + * 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 */ #define TF_PCI_BUF_SIZE_MAX 88 +/** + * This is the length of shared session name "tf_share" + */ +#define TF_SHARED_SESSION_NAME_LEN 8 + +/** + * This is the length of tcam shared session name "tf_shared-wc_tcam" + */ +#define TF_TCAM_SHARED_SESSION_NAME_LEN 17 + /** * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method */ @@ -79,31 +124,49 @@ tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf) /* HWRM Direct messages */ int -tf_msg_session_open(struct tf *tfp, +tf_msg_session_open(struct bnxt *bp, char *ctrl_chan_name, - uint8_t *fw_session_id) + uint8_t *fw_session_id, + uint8_t *fw_session_client_id, + struct tf_dev_info *dev, + bool *shared_session_creator) { int rc; struct hwrm_tf_session_open_input req = { 0 }; struct hwrm_tf_session_open_output resp = { 0 }; struct tfp_send_msg_parms parms = { 0 }; + int name_len; + char *session_name; + char *tcam_session_name; /* Populate the request */ - tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX); + name_len = strnlen(ctrl_chan_name, TF_SESSION_NAME_MAX); + session_name = &ctrl_chan_name[name_len - strlen("tf_shared")]; + tcam_session_name = &ctrl_chan_name[name_len - strlen("tf_shared-wc_tcam")]; + if (!strncmp(tcam_session_name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam"))) + tfp_memcpy(&req.session_name, tcam_session_name, TF_TCAM_SHARED_SESSION_NAME_LEN); + else if (!strncmp(session_name, "tf_shared", strlen("tf_shared"))) + tfp_memcpy(&req.session_name, session_name, TF_SHARED_SESSION_NAME_LEN); + else + tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX); parms.tf_type = HWRM_TF_SESSION_OPEN; parms.req_data = (uint32_t *)&req; parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(bp, &parms); if (rc) return rc; - *fw_session_id = resp.fw_session_id; + *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id); + *fw_session_client_id = + (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id); + *shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags + & HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR); return rc; } @@ -117,26 +180,144 @@ tf_msg_session_attach(struct tf *tfp __rte_unused, } int -tf_msg_session_close(struct tf *tfp) +tf_msg_session_client_register(struct tf *tfp, + struct tf_session *tfs, + char *ctrl_channel_name, + uint8_t *fw_session_client_id) +{ + int rc; + struct hwrm_tf_session_register_input req = { 0 }; + struct hwrm_tf_session_register_output resp = { 0 }; + struct tfp_send_msg_parms parms = { 0 }; + uint8_t fw_session_id; + struct tf_dev_info *dev; + int name_len; + char *session_name; + char *tcam_session_name; + + /* 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; + } + + 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; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + name_len = strnlen(ctrl_channel_name, TF_SESSION_NAME_MAX); + session_name = &ctrl_channel_name[name_len - strlen("tf_shared")]; + tcam_session_name = &ctrl_channel_name[name_len - + strlen("tf_shared-wc_tcam")]; + if (!strncmp(tcam_session_name, + "tf_shared-wc_tcam", + strlen("tf_shared-wc_tcam"))) + tfp_memcpy(&req.session_client_name, + tcam_session_name, + TF_TCAM_SHARED_SESSION_NAME_LEN); + else if (!strncmp(session_name, "tf_shared", strlen("tf_shared"))) + tfp_memcpy(&req.session_client_name, + session_name, + TF_SHARED_SESSION_NAME_LEN); + else + tfp_memcpy(&req.session_client_name, + ctrl_channel_name, + TF_SESSION_NAME_MAX); + + parms.tf_type = HWRM_TF_SESSION_REGISTER; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), + &parms); + if (rc) + return rc; + + *fw_session_client_id = + (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id); + + return rc; +} + +int +tf_msg_session_client_unregister(struct tf *tfp, + struct tf_session *tfs, + uint8_t fw_session_client_id) +{ + int rc; + struct hwrm_tf_session_unregister_input req = { 0 }; + struct hwrm_tf_session_unregister_output resp = { 0 }; + struct tfp_send_msg_parms parms = { 0 }; + uint8_t fw_session_id; + struct tf_dev_info *dev; + + /* 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; + } + + 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; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id); + + parms.tf_type = HWRM_TF_SESSION_UNREGISTER; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), + &parms); + + return rc; +} + +int +tf_msg_session_close(struct tf *tfp, + uint8_t fw_session_id, + int mailbox) { int rc; struct hwrm_tf_session_close_input req = { 0 }; struct hwrm_tf_session_close_output resp = { 0 }; - struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data); struct tfp_send_msg_parms parms = { 0 }; /* Populate the request */ - req.fw_session_id = - tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); parms.tf_type = HWRM_TF_SESSION_CLOSE; parms.req_data = (uint32_t *)&req; parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = mailbox; - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); return rc; } @@ -147,27 +328,55 @@ tf_msg_session_qcfg(struct tf *tfp) int rc; struct hwrm_tf_session_qcfg_input req = { 0 }; struct hwrm_tf_session_qcfg_output resp = { 0 }; - struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data); struct tfp_send_msg_parms parms = { 0 }; + uint8_t fw_session_id; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-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; + } + + 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; + } /* Populate the request */ - req.fw_session_id = - tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); parms.tf_type = HWRM_TF_SESSION_QCFG, parms.req_data = (uint32_t *)&req; parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); return rc; } int tf_msg_session_resc_qcaps(struct tf *tfp, + struct tf_dev_info *dev, enum tf_dir dir, uint16_t size, struct tf_rm_resc_req_entry *query, @@ -182,6 +391,16 @@ tf_msg_session_resc_qcaps(struct tf *tfp, struct tf_msg_dma_buf qcaps_buf = { 0 }; struct tf_rm_resc_req_entry *data; int dma_size; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } TF_CHECK_PARMS3(tfp, query, resv_strategy); @@ -211,45 +430,37 @@ tf_msg_session_resc_qcaps(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); if (rc) - return rc; + goto cleanup; /* Process the response * Should always get expected number of entries */ if (tfp_le_to_cpu_32(resp.size) != size) { - TFP_DRV_LOG(ERR, - "%s: QCAPS message size error, rc:%s\n", + TFP_DRV_LOG(WARNING, + "%s: QCAPS message size error, rc:%s, request %d vs response %d\n", tf_dir_2_str(dir), - strerror(-EINVAL)); - return -EINVAL; + strerror(EINVAL), + size, + resp.size); } - printf("size: %d\n", tfp_le_to_cpu_32(resp.size)); - /* Post process the response */ data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr; - printf("\nQCAPS\n"); - for (i = 0; i < size; i++) { + for (i = 0; i < resp.size; i++) { query[i].type = tfp_le_to_cpu_32(data[i].type); query[i].min = tfp_le_to_cpu_16(data[i].min); query[i].max = tfp_le_to_cpu_16(data[i].max); - - printf("type: %d(0x%x) %d %d\n", - query[i].type, - query[i].type, - query[i].min, - query[i].max); - } *resv_strategy = resp.flags & HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK; +cleanup: tf_msg_free_dma_buf(&qcaps_buf); return rc; @@ -257,6 +468,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp, int tf_msg_session_resc_alloc(struct tf *tfp, + struct tf_dev_info *dev, enum tf_dir dir, uint16_t size, struct tf_rm_resc_req_entry *request, @@ -273,6 +485,16 @@ tf_msg_session_resc_alloc(struct tf *tfp, struct tf_rm_resc_req_entry *req_data; struct tf_rm_resc_entry *resv_data; int dma_size; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } TF_CHECK_PARMS3(tfp, request, resv); @@ -293,8 +515,10 @@ tf_msg_session_resc_alloc(struct tf *tfp, dma_size = size * sizeof(struct tf_rm_resc_entry); rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); - if (rc) + if (rc) { + tf_msg_free_dma_buf(&req_buf); return rc; + } /* Populate the request */ req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); @@ -316,11 +540,11 @@ tf_msg_session_resc_alloc(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); if (rc) - return rc; + goto cleanup; /* Process the response * Should always get expected number of entries @@ -329,28 +553,127 @@ tf_msg_session_resc_alloc(struct tf *tfp, TFP_DRV_LOG(ERR, "%s: Alloc message size error, rc:%s\n", tf_dir_2_str(dir), - strerror(-EINVAL)); - return -EINVAL; + strerror(EINVAL)); + rc = -EINVAL; + goto cleanup; } - printf("\nRESV\n"); - printf("size: %d\n", tfp_le_to_cpu_32(resp.size)); - /* Post process the response */ resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; for (i = 0; i < size; i++) { resv[i].type = tfp_le_to_cpu_32(resv_data[i].type); resv[i].start = tfp_le_to_cpu_16(resv_data[i].start); resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride); + } + +cleanup: + tf_msg_free_dma_buf(&req_buf); + tf_msg_free_dma_buf(&resv_buf); + + return rc; +} + +int +tf_msg_session_resc_info(struct tf *tfp, + struct tf_dev_info *dev, + enum tf_dir dir, + uint16_t size, + struct tf_rm_resc_req_entry *request, + struct tf_rm_resc_entry *resv) +{ + int rc; + int i; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_session_resc_info_input req = { 0 }; + struct hwrm_tf_session_resc_info_output resp = { 0 }; + uint8_t fw_session_id; + struct tf_msg_dma_buf req_buf = { 0 }; + struct tf_msg_dma_buf resv_buf = { 0 }; + struct tf_rm_resc_req_entry *req_data; + struct tf_rm_resc_entry *resv_data; + int dma_size; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } + + TF_CHECK_PARMS3(tfp, request, resv); + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(dir), + strerror(-rc)); + return rc; + } + + /* Prepare DMA buffers */ + dma_size = size * sizeof(struct tf_rm_resc_req_entry); + rc = tf_msg_alloc_dma_buf(&req_buf, dma_size); + if (rc) + return rc; + + dma_size = size * sizeof(struct tf_rm_resc_entry); + rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); + if (rc) { + tf_msg_free_dma_buf(&req_buf); + return rc; + } - printf("%d type: %d(0x%x) %d %d\n", - i, - resv[i].type, - resv[i].type, - resv[i].start, - resv[i].stride); + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + req.flags = tfp_cpu_to_le_16(dir); + req.req_size = size; + + req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr; + for (i = 0; i < size; i++) { + req_data[i].type = tfp_cpu_to_le_32(request[i].type); + req_data[i].min = tfp_cpu_to_le_16(request[i].min); + req_data[i].max = tfp_cpu_to_le_16(request[i].max); + } + + req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr); + req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); + + parms.tf_type = HWRM_TF_SESSION_RESC_INFO; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); + if (rc) + goto cleanup; + + /* Process the response + * Should always get expected number of entries + */ + if (tfp_le_to_cpu_32(resp.size) != size) { + TFP_DRV_LOG(ERR, + "%s: Alloc message size error, rc:%s\n", + tf_dir_2_str(dir), + strerror(EINVAL)); + rc = -EINVAL; + goto cleanup; + } + + /* Post process the response */ + resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; + for (i = 0; i < size; i++) { + resv[i].type = tfp_le_to_cpu_32(resv_data[i].type); + resv[i].start = tfp_le_to_cpu_16(resv_data[i].start); + resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride); } +cleanup: tf_msg_free_dma_buf(&req_buf); tf_msg_free_dma_buf(&resv_buf); @@ -372,9 +695,31 @@ tf_msg_session_resc_flush(struct tf *tfp, struct tf_msg_dma_buf resv_buf = { 0 }; struct tf_rm_resc_entry *resv_data; int dma_size; + struct tf_dev_info *dev; + struct tf_session *tfs; TF_CHECK_PARMS2(tfp, resv); + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(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(dir), + strerror(-rc)); + return rc; + } + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); if (rc) { TFP_DRV_LOG(ERR, @@ -409,11 +754,9 @@ tf_msg_session_resc_flush(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); - if (rc) - return rc; + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); tf_msg_free_dma_buf(&resv_buf); @@ -431,16 +774,63 @@ tf_msg_insert_em_internal_entry(struct tf *tfp, struct tfp_send_msg_parms parms = { 0 }; struct hwrm_tf_em_insert_input req = { 0 }; struct hwrm_tf_em_insert_output resp = { 0 }; - struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data); struct tf_em_64b_entry *em_result = (struct tf_em_64b_entry *)em_parms->em_record; - uint32_t flags; + uint16_t flags; + uint8_t fw_session_id; + uint8_t msg_key_size; + 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) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(em_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(em_parms->dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + + /* Check for key size conformity */ + msg_key_size = (em_parms->key_sz_in_bits + 7) / 8; + if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "%s: Invalid parameters for msg type, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } - req.fw_session_id = - tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); tfp_memcpy(req.em_key, em_parms->key, - ((em_parms->key_sz_in_bits + 7) / 8)); + msg_key_size); flags = (em_parms->dir == TF_DIR_TX ? HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX : @@ -458,9 +848,104 @@ tf_msg_insert_em_internal_entry(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), + &parms); + if (rc) + return rc; + + *rptr_entry = resp.rptr_entry; + *rptr_index = resp.rptr_index; + *num_of_entries = resp.num_of_entries; + + return 0; +} + +int +tf_msg_hash_insert_em_internal_entry(struct tf *tfp, + struct tf_insert_em_entry_parms *em_parms, + uint32_t key0_hash, + uint32_t key1_hash, + uint16_t *rptr_index, + uint8_t *rptr_entry, + uint8_t *num_of_entries) +{ + int rc; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_em_hash_insert_input req = { 0 }; + struct hwrm_tf_em_hash_insert_output resp = { 0 }; + uint16_t flags; + uint8_t fw_session_id; + uint8_t msg_record_size; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(em_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(em_parms->dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + + /* Check for key size conformity */ + msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8; + + if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "%s: Record size to large, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + tfp_memcpy((char *)req.em_record, + em_parms->em_record, + msg_record_size); + + flags = (em_parms->dir == TF_DIR_TX ? + HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX : + HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX); + req.flags = tfp_cpu_to_le_16(flags); + req.em_record_size_bits = em_parms->em_record_sz_in_bits; + req.em_record_idx = *rptr_index; + req.key0_hash = key0_hash; + req.key1_hash = key1_hash; + + parms.tf_type = HWRM_TF_EM_HASH_INSERT; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); if (rc) return rc; @@ -480,12 +965,42 @@ tf_msg_delete_em_entry(struct tf *tfp, struct tfp_send_msg_parms parms = { 0 }; struct hwrm_tf_em_delete_input req = { 0 }; struct hwrm_tf_em_delete_output resp = { 0 }; - uint32_t flags; - struct tf_session *tfs = - (struct tf_session *)(tfp->session->core_data); + uint16_t flags; + uint8_t fw_session_id; + struct tf_dev_info *dev; + struct tf_session *tfs; - req.fw_session_id = - tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(em_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(em_parms->dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); flags = (em_parms->dir == TF_DIR_TX ? HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX : @@ -498,9 +1013,9 @@ tf_msg_delete_em_entry(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); if (rc) return rc; @@ -510,6 +1025,186 @@ tf_msg_delete_em_entry(struct tf *tfp, return 0; } +int +tf_msg_move_em_entry(struct tf *tfp, + struct tf_move_em_entry_parms *em_parms) +{ + int rc; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_em_move_input req = { 0 }; + struct hwrm_tf_em_move_output resp = { 0 }; + uint16_t flags; + uint8_t fw_session_id; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(em_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(em_parms->dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + + flags = (em_parms->dir == TF_DIR_TX ? + HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX : + HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX); + req.flags = tfp_cpu_to_le_16(flags); + req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle); + req.new_index = tfp_cpu_to_le_32(em_parms->new_index); + + parms.tf_type = HWRM_TF_EM_MOVE; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), + &parms); + if (rc) + return rc; + + em_parms->index = tfp_le_to_cpu_16(resp.em_index); + + return 0; +} + +int tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp, + struct hcapi_cfa_em_table *tbl, + uint64_t *dma_addr, + uint32_t *page_lvl, + uint32_t *page_size) +{ + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_ctxt_mem_alloc_input req = {0}; + struct hwrm_tf_ctxt_mem_alloc_output resp = {0}; + uint32_t mem_size_k; + int rc = 0; + struct tf_dev_info *dev; + struct tf_session *tfs; + uint32_t fw_se_id; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-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; + } + /* Retrieve the session information */ + fw_se_id = tfs->session_id.internal.fw_session_id; + + if (tbl->num_entries && tbl->entry_size) { + /* unit: kbytes */ + mem_size_k = (tbl->num_entries / TF_KILOBYTE) * tbl->entry_size; + req.mem_size = tfp_cpu_to_le_32(mem_size_k); + req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); + parms.tf_type = HWRM_TF_CTXT_MEM_ALLOC; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); + if (rc) { + TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n", + strerror(-rc)); + return rc; + } + + *dma_addr = tfp_le_to_cpu_64(resp.page_dir); + *page_lvl = resp.page_level; + *page_size = resp.page_size; + } + + return rc; +} + +int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp, + uint32_t mem_size_k, + uint64_t dma_addr, + uint8_t page_level, + uint8_t page_size) +{ + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_ctxt_mem_free_input req = {0}; + struct hwrm_tf_ctxt_mem_free_output resp = {0}; + int rc = 0; + struct tf_dev_info *dev; + struct tf_session *tfs; + uint32_t fw_se_id; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-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; + } + /* Retrieve the session information */ + fw_se_id = tfs->session_id.internal.fw_session_id; + + req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); + req.mem_size = tfp_cpu_to_le_32(mem_size_k); + req.page_dir = tfp_cpu_to_le_64(dma_addr); + req.page_level = page_level; + req.page_size = page_size; + parms.tf_type = HWRM_TF_CTXT_MEM_FREE; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); + + return rc; +} + int tf_msg_em_mem_rgtr(struct tf *tfp, int page_lvl, @@ -521,7 +1216,30 @@ tf_msg_em_mem_rgtr(struct tf *tfp, struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 }; struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 }; struct tfp_send_msg_parms parms = { 0 }; + struct tf_dev_info *dev; + struct tf_session *tfs; + uint32_t fw_se_id; + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-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; + } + fw_se_id = tfs->session_id.internal.fw_session_id; + + req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); req.page_level = page_lvl; req.page_size = page_size; req.page_dir = tfp_cpu_to_le_64(dma_addr); @@ -531,9 +1249,9 @@ tf_msg_em_mem_rgtr(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); if (rc) return rc; @@ -551,6 +1269,30 @@ tf_msg_em_mem_unrgtr(struct tf *tfp, struct hwrm_tf_ctxt_mem_unrgtr_input req = {0}; struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0}; struct tfp_send_msg_parms parms = { 0 }; + struct tf_dev_info *dev; + struct tf_session *tfs; + uint32_t fw_se_id; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-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; + } + + fw_se_id = tfs->session_id.internal.fw_session_id; + req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); req.ctx_id = tfp_cpu_to_le_32(*ctx_id); @@ -559,9 +1301,9 @@ tf_msg_em_mem_unrgtr(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); return rc; } @@ -576,19 +1318,44 @@ tf_msg_em_qcaps(struct tf *tfp, struct hwrm_tf_ext_em_qcaps_output resp = { 0 }; uint32_t flags; struct tfp_send_msg_parms parms = { 0 }; + struct tf_dev_info *dev; + struct tf_session *tfs; + uint32_t fw_se_id; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(dir), + strerror(-rc)); + return rc; + } + fw_se_id = tfs->session_id.internal.fw_session_id; + + /* 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(dir), + strerror(-rc)); + return rc; + } flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX : HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX); req.flags = tfp_cpu_to_le_32(flags); parms.tf_type = HWRM_TF_EXT_EM_QCAPS; + req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); parms.req_data = (uint32_t *)&req; parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); if (rc) return rc; @@ -619,6 +1386,28 @@ tf_msg_em_cfg(struct tf *tfp, struct hwrm_tf_ext_em_cfg_output resp = {0}; uint32_t flags; struct tfp_send_msg_parms parms = { 0 }; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(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(dir), + strerror(-rc)); + return rc; + } flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); @@ -639,9 +1428,83 @@ tf_msg_em_cfg(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), + &parms); + return rc; +} + +int +tf_msg_ext_em_cfg(struct tf *tfp, + struct tf_tbl_scope_cb *tbl_scope_cb, + uint32_t st_buckets, + uint8_t flush_interval, + enum tf_dir dir) +{ + struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir]; + struct hcapi_cfa_em_table *lkup_tbl, *act_tbl; + struct hwrm_tf_ext_em_cfg_input req = {0}; + struct hwrm_tf_ext_em_cfg_output resp = {0}; + struct tfp_send_msg_parms parms = { 0 }; + uint32_t flags; + struct tf_dev_info *dev; + struct tf_session *tfs; + uint32_t fw_se_id; + int rc; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(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(dir), + strerror(-rc)); + return rc; + } + fw_se_id = tfs->session_id.internal.fw_session_id; + + lkup_tbl = &ctxp->em_tables[TF_EM_LKUP_TABLE]; + act_tbl = &ctxp->em_tables[TF_ACTION_TABLE]; + flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : + HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); + flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD; + + req.flags = tfp_cpu_to_le_32(flags); + req.num_entries = tfp_cpu_to_le_32(act_tbl->num_entries); + req.lkup_static_buckets = tfp_cpu_to_le_32(st_buckets); + req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); + req.flush_interval = flush_interval; + req.action_ctx_id = tfp_cpu_to_le_16(act_tbl->ctx_id); + req.action_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id); + req.lkup_ctx_id = tfp_cpu_to_le_16(lkup_tbl->ctx_id); + req.lkup_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id); + + req.enables = (HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_CTX_ID | + HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_TBL_SCOPE | + HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_CTX_ID | + HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_TBL_SCOPE | + HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_STATIC_BUCKETS | + HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_NUM_ENTRIES); + + parms.tf_type = HWRM_TF_EXT_EM_CFG; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); return rc; } @@ -656,6 +1519,28 @@ tf_msg_em_op(struct tf *tfp, struct hwrm_tf_ext_em_op_output resp = {0}; uint32_t flags; struct tfp_send_msg_parms parms = { 0 }; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(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(dir), + strerror(-rc)); + return rc; + } flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); @@ -667,15 +1552,16 @@ tf_msg_em_op(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); return rc; } int tf_msg_tcam_entry_set(struct tf *tfp, + struct tf_dev_info *dev, struct tf_tcam_set_parms *parms) { int rc; @@ -685,7 +1571,29 @@ tf_msg_tcam_entry_set(struct tf *tfp, struct tf_msg_dma_buf buf = { 0 }; uint8_t *data = NULL; int data_size = 0; + uint8_t fw_session_id; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); req.type = parms->hcapi_type; req.idx = tfp_cpu_to_le_16(parms->idx); if (parms->dir == TF_DIR_TX) @@ -722,12 +1630,10 @@ tf_msg_tcam_entry_set(struct tf *tfp, mparms.req_size = sizeof(req); mparms.resp_data = (uint32_t *)&resp; mparms.resp_size = sizeof(resp); - mparms.mailbox = TF_KONG_MB; + mparms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &mparms); - if (rc) - goto cleanup; cleanup: tf_msg_free_dma_buf(&buf); @@ -735,15 +1641,108 @@ cleanup: return rc; } +int +tf_msg_tcam_entry_get(struct tf *tfp, + struct tf_dev_info *dev, + struct tf_tcam_get_parms *parms) +{ + int rc; + struct tfp_send_msg_parms mparms = { 0 }; + struct hwrm_tf_tcam_get_input req = { 0 }; + struct hwrm_tf_tcam_get_output resp = { 0 }; + uint8_t fw_session_id; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + req.type = parms->hcapi_type; + req.idx = tfp_cpu_to_le_16(parms->idx); + if (parms->dir == TF_DIR_TX) + req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX; + + mparms.tf_type = HWRM_TF_TCAM_GET; + mparms.req_data = (uint32_t *)&req; + mparms.req_size = sizeof(req); + mparms.resp_data = (uint32_t *)&resp; + mparms.resp_size = sizeof(resp); + mparms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), + &mparms); + + if (rc != 0) + return rc; + + 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); + tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size); + tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size); + + return 0; +} + int tf_msg_tcam_entry_free(struct tf *tfp, + struct tf_dev_info *dev, struct tf_tcam_free_parms *in_parms) { int rc; struct hwrm_tf_tcam_free_input req = { 0 }; struct hwrm_tf_tcam_free_output resp = { 0 }; struct tfp_send_msg_parms parms = { 0 }; + uint8_t fw_session_id; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(in_parms->dir), + strerror(-rc)); + return rc; + } + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); req.type = in_parms->hcapi_type; req.count = 1; req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx); @@ -755,9 +1754,9 @@ tf_msg_tcam_entry_free(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); return rc; } @@ -774,10 +1773,15 @@ tf_msg_set_tbl_entry(struct tf *tfp, struct hwrm_tf_tbl_type_set_input req = { 0 }; struct hwrm_tf_tbl_type_set_output resp = { 0 }; struct tfp_send_msg_parms parms = { 0 }; + uint8_t fw_session_id; + 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(tfp, &tfs); + rc = tf_session_get_session_internal(tfp, &tfs); if (rc) { TFP_DRV_LOG(ERR, "%s: Failed to lookup session, rc:%s\n", @@ -786,14 +1790,42 @@ tf_msg_set_tbl_entry(struct tf *tfp, 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(dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(dir), + strerror(-rc)); + return rc; + } + /* Populate the request */ - req.fw_session_id = - tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); req.flags = tfp_cpu_to_le_16(dir); req.type = tfp_cpu_to_le_32(hcapi_type); req.size = tfp_cpu_to_le_16(size); req.index = tfp_cpu_to_le_32(index); + /* Check for data size conformity */ + if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "%s: Invalid parameters for msg type, rc:%s\n", + tf_dir_2_str(dir), + strerror(-rc)); + return rc; + } + tfp_memcpy(&req.data, data, size); @@ -803,14 +1835,14 @@ tf_msg_set_tbl_entry(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); if (rc) return rc; - return tfp_le_to_cpu_32(parms.tf_resp_code); + return 0; } int @@ -825,10 +1857,12 @@ tf_msg_get_tbl_entry(struct tf *tfp, struct hwrm_tf_tbl_type_get_input req = { 0 }; struct hwrm_tf_tbl_type_get_output resp = { 0 }; struct tfp_send_msg_parms parms = { 0 }; + uint8_t fw_session_id; + struct tf_dev_info *dev; struct tf_session *tfs; /* Retrieve the session information */ - rc = tf_session_get_session(tfp, &tfs); + rc = tf_session_get_session_internal(tfp, &tfs); if (rc) { TFP_DRV_LOG(ERR, "%s: Failed to lookup session, rc:%s\n", @@ -837,9 +1871,27 @@ tf_msg_get_tbl_entry(struct tf *tfp, 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(dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(dir), + strerror(-rc)); + return rc; + } + /* Populate the request */ - req.fw_session_id = - tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); req.flags = tfp_cpu_to_le_16(dir); req.type = tfp_cpu_to_le_32(hcapi_type); req.index = tfp_cpu_to_le_32(index); @@ -849,26 +1901,203 @@ tf_msg_get_tbl_entry(struct tf *tfp, parms.req_size = sizeof(req); parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); - parms.mailbox = TF_KONG_MB; + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); if (rc) return rc; - /* Verify that we got enough buffer to return the requested data */ - if (resp.size < size) + /* + * The response will be 64 bytes long, the response size will + * be in words (16). All we can test for is that the response + * size is < to the requested size. + */ + if ((tfp_le_to_cpu_32(resp.size) * 4) < size) return -EINVAL; + /* + * Copy the requested number of bytes + */ tfp_memcpy(data, &resp.data, - resp.size); + size); - return tfp_le_to_cpu_32(parms.tf_resp_code); + return 0; } /* HWRM Tunneled messages */ +int +tf_msg_get_global_cfg(struct tf *tfp, + struct tf_global_cfg_parms *params) +{ + int rc = 0; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_global_cfg_get_input req = { 0 }; + struct hwrm_tf_global_cfg_get_output resp = { 0 }; + uint32_t flags = 0; + uint8_t fw_session_id; + uint16_t resp_size = 0; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(params->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(params->dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(params->dir), + strerror(-rc)); + return rc; + } + + flags = (params->dir == TF_DIR_TX ? + HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX : + HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX); + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + req.flags = tfp_cpu_to_le_32(flags); + req.type = tfp_cpu_to_le_32(params->type); + req.offset = tfp_cpu_to_le_32(params->offset); + req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); + + parms.tf_type = HWRM_TF_GLOBAL_CFG_GET; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); + if (rc != 0) + return rc; + + /* Verify that we got enough buffer to return the requested data */ + resp_size = tfp_le_to_cpu_16(resp.size); + if (resp_size < params->config_sz_in_bytes) + return -EINVAL; + + if (params->config) + tfp_memcpy(params->config, + resp.data, + resp_size); + else + return -EFAULT; + + return 0; +} + +int +tf_msg_set_global_cfg(struct tf *tfp, + struct tf_global_cfg_parms *params) +{ + int rc = 0; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_global_cfg_set_input req = { 0 }; + struct hwrm_tf_global_cfg_set_output resp = { 0 }; + uint32_t flags = 0; + uint8_t fw_session_id; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(params->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(params->dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(params->dir), + strerror(-rc)); + return rc; + } + + flags = (params->dir == TF_DIR_TX ? + HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX : + HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX); + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + req.flags = tfp_cpu_to_le_32(flags); + req.type = tfp_cpu_to_le_32(params->type); + req.offset = tfp_cpu_to_le_32(params->offset); + + /* Check for data size conformity */ + if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "%s: Invalid parameters for msg type, rc:%s\n", + tf_dir_2_str(params->dir), + strerror(-rc)); + return rc; + } + + tfp_memcpy(req.data, params->config, + params->config_sz_in_bytes); + + /* Only set mask if pointer is provided + */ + if (params->config_mask) { + tfp_memcpy(req.mask, + params->config_mask, + params->config_sz_in_bytes); + } + + req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); + + parms.tf_type = HWRM_TF_GLOBAL_CFG_SET; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); + + if (rc != 0) + return rc; + + return 0; +} + int tf_msg_bulk_get_tbl_entry(struct tf *tfp, enum tf_dir dir, @@ -880,10 +2109,12 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp, { int rc; struct tfp_send_msg_parms parms = { 0 }; - struct tf_tbl_type_bulk_get_input req = { 0 }; - struct tf_tbl_type_bulk_get_output resp = { 0 }; - struct tf_session *tfs; + struct hwrm_tf_tbl_type_bulk_get_input req = { 0 }; + struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 }; int data_size = 0; + uint8_t fw_session_id; + struct tf_dev_info *dev; + struct tf_session *tfs; /* Retrieve the session information */ rc = tf_session_get_session(tfp, &tfs); @@ -895,9 +2126,27 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp, 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(dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(dir), + strerror(-rc)); + return rc; + } + /* Populate the request */ - req.fw_session_id = - tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); req.flags = tfp_cpu_to_le_16(dir); req.type = tfp_cpu_to_le_32(hcapi_type); req.start_index = tfp_cpu_to_le_32(starting_idx); @@ -907,20 +2156,137 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp, req.host_addr = tfp_cpu_to_le_64(physical_mem_addr); - MSG_PREP(parms, - TF_KONG_MB, - HWRM_TF, - HWRM_TFT_TBL_TYPE_BULK_GET, - req, - resp); + parms.tf_type = HWRM_TF_TBL_TYPE_BULK_GET; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_tunneled(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), + &parms); if (rc) return rc; /* Verify that we got enough buffer to return the requested data */ - if (resp.size < data_size) + if (tfp_le_to_cpu_32(resp.size) != data_size) return -EINVAL; - return tfp_le_to_cpu_32(parms.tf_resp_code); + return 0; +} + +int +tf_msg_get_if_tbl_entry(struct tf *tfp, + struct tf_if_tbl_get_parms *params) +{ + int rc = 0; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_if_tbl_get_input req = { 0 }; + struct hwrm_tf_if_tbl_get_output resp = { 0 }; + uint32_t flags = 0; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* 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(params->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(params->dir), + strerror(-rc)); + return rc; + } + + flags = (params->dir == TF_DIR_TX ? + HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX : + HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX); + + /* Populate the request */ + req.fw_session_id = + tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); + req.flags = flags; + req.type = params->hcapi_type; + req.index = tfp_cpu_to_le_16(params->idx); + req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes); + + parms.tf_type = HWRM_TF_IF_TBL_GET; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); + + if (rc != 0) + return rc; + + tfp_memcpy(¶ms->data[0], resp.data, req.size); + + return 0; +} + +int +tf_msg_set_if_tbl_entry(struct tf *tfp, + struct tf_if_tbl_set_parms *params) +{ + int rc = 0; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_if_tbl_set_input req = { 0 }; + struct hwrm_tf_if_tbl_get_output resp = { 0 }; + uint32_t flags = 0; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* 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(params->dir), + strerror(-rc)); + return rc; + } + + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) + return rc; + + flags = (params->dir == TF_DIR_TX ? + HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX : + HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX); + + /* Populate the request */ + req.fw_session_id = + tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); + req.flags = flags; + req.type = params->hcapi_type; + req.index = tfp_cpu_to_le_32(params->idx); + req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes); + tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes); + + parms.tf_type = HWRM_TF_IF_TBL_SET; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); + + if (rc != 0) + return rc; + + return 0; }