net/bnxt: fix out of bound access in bit handling
[dpdk.git] / drivers / net / bnxt / tf_core / tf_msg.c
index d8b80bc..7c2ad17 100644 (file)
@@ -3,6 +3,7 @@
  * All rights reserved.
  */
 
+#include <assert.h>
 #include <inttypes.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include "hwrm_tf.h"
 #include "tf_em.h"
 
+/* Logging defines */
+#define TF_RM_MSG_DEBUG  0
+
+/* 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_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
  */
@@ -81,7 +118,8 @@ tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
 int
 tf_msg_session_open(struct tf *tfp,
                    char *ctrl_chan_name,
-                   uint8_t *fw_session_id)
+                   uint8_t *fw_session_id,
+                   uint8_t *fw_session_client_id)
 {
        int rc;
        struct hwrm_tf_session_open_input req = { 0 };
@@ -103,7 +141,9 @@ tf_msg_session_open(struct tf *tfp,
        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);
 
        return rc;
 }
@@ -116,18 +156,103 @@ tf_msg_session_attach(struct tf *tfp __rte_unused,
        return -1;
 }
 
+int
+tf_msg_session_client_register(struct tf *tfp,
+                              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;
+
+       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);
+       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 = TF_KONG_MB;
+
+       rc = tfp_send_msg_direct(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,
+                                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;
+
+       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 = TF_KONG_MB;
+
+       rc = tfp_send_msg_direct(tfp,
+                                &parms);
+
+       return rc;
+}
+
 int
 tf_msg_session_close(struct tf *tfp)
 {
        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 };
+       uint8_t fw_session_id;
+
+       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_CLOSE;
        parms.req_data = (uint32_t *)&req;
@@ -147,12 +272,19 @@ 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;
+
+       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;
@@ -215,7 +347,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp,
 
        rc = tfp_send_msg_direct(tfp, &parms);
        if (rc)
-               return rc;
+               goto cleanup;
 
        /* Process the response
         * Should always get expected number of entries
@@ -224,32 +356,40 @@ tf_msg_session_resc_qcaps(struct tf *tfp,
                TFP_DRV_LOG(ERR,
                            "%s: QCAPS message size error, rc:%s\n",
                            tf_dir_2_str(dir),
-                           strerror(-EINVAL));
-               return -EINVAL;
+                           strerror(EINVAL));
+               rc = -EINVAL;
+               goto cleanup;
        }
 
+#if (TF_RM_MSG_DEBUG == 1)
        printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
+#endif /* (TF_RM_MSG_DEBUG == 1) */
 
        /* Post process the response */
        data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
 
+#if (TF_RM_MSG_DEBUG == 1)
        printf("\nQCAPS\n");
+#endif /* (TF_RM_MSG_DEBUG == 1) */
        for (i = 0; i < 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);
 
+#if (TF_RM_MSG_DEBUG == 1)
                printf("type: %d(0x%x) %d %d\n",
                       query[i].type,
                       query[i].type,
                       query[i].min,
                       query[i].max);
+#endif /* (TF_RM_MSG_DEBUG == 1) */
 
        }
 
        *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;
@@ -293,8 +433,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);
@@ -320,7 +462,7 @@ tf_msg_session_resc_alloc(struct tf *tfp,
 
        rc = tfp_send_msg_direct(tfp, &parms);
        if (rc)
-               return rc;
+               goto cleanup;
 
        /* Process the response
         * Should always get expected number of entries
@@ -329,12 +471,15 @@ 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;
        }
 
+#if (TF_RM_MSG_DEBUG == 1)
        printf("\nRESV\n");
        printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
+#endif /* (TF_RM_MSG_DEBUG == 1) */
 
        /* Post process the response */
        resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
@@ -343,14 +488,17 @@ tf_msg_session_resc_alloc(struct tf *tfp,
                resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
                resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
 
+#if (TF_RM_MSG_DEBUG == 1)
                printf("%d type: %d(0x%x) %d %d\n",
                       i,
                       resv[i].type,
                       resv[i].type,
                       resv[i].start,
                       resv[i].stride);
+#endif /* (TF_RM_MSG_DEBUG == 1) */
        }
 
+cleanup:
        tf_msg_free_dma_buf(&req_buf);
        tf_msg_free_dma_buf(&resv_buf);
 
@@ -412,8 +560,6 @@ tf_msg_session_resc_flush(struct tf *tfp,
        parms.mailbox = TF_KONG_MB;
 
        rc = tfp_send_msg_direct(tfp, &parms);
-       if (rc)
-               return rc;
 
        tf_msg_free_dma_buf(&resv_buf);
 
@@ -431,16 +577,38 @@ 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;
+
+       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 :
@@ -480,12 +648,20 @@ 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;
 
-       req.fw_session_id =
-               tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
+       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 :
@@ -685,7 +861,19 @@ 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;
+
+       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)
@@ -726,8 +914,6 @@ tf_msg_tcam_entry_set(struct tf *tfp,
 
        rc = tfp_send_msg_direct(tfp,
                                 &mparms);
-       if (rc)
-               goto cleanup;
 
 cleanup:
        tf_msg_free_dma_buf(&buf);
@@ -743,7 +929,19 @@ tf_msg_tcam_entry_free(struct tf *tfp,
        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;
 
+       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);
@@ -774,26 +972,34 @@ 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 };
-       struct tf_session *tfs;
+       uint8_t fw_session_id;
 
-       /* Retrieve the session information */
-       rc = tf_session_get_session(tfp, &tfs);
+       rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
        if (rc) {
                TFP_DRV_LOG(ERR,
-                           "%s: Failed to lookup session, rc:%s\n",
+                           "%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);
@@ -825,21 +1031,19 @@ 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 };
-       struct tf_session *tfs;
+       uint8_t fw_session_id;
 
-       /* Retrieve the session information */
-       rc = tf_session_get_session(tfp, &tfs);
+       rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
        if (rc) {
                TFP_DRV_LOG(ERR,
-                           "%s: Failed to lookup session, rc:%s\n",
+                           "%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);
@@ -857,40 +1061,170 @@ tf_msg_get_tbl_entry(struct tf *tfp,
                return rc;
 
        /* Verify that we got enough buffer to return the requested data */
-       if (resp.size < size)
+       if (tfp_le_to_cpu_32(resp.size) != size)
                return -EINVAL;
 
        tfp_memcpy(data,
                   &resp.data,
-                  resp.size);
+                  size);
 
        return tfp_le_to_cpu_32(parms.tf_resp_code);
 }
 
 /* HWRM Tunneled messages */
 
+int
+tf_msg_get_global_cfg(struct tf *tfp,
+                     struct tf_dev_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;
+
+       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 = TF_KONG_MB;
+
+       rc = tfp_send_msg_direct(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 tfp_le_to_cpu_32(parms.tf_resp_code);
+}
+
+int
+tf_msg_set_global_cfg(struct tf *tfp,
+                     struct tf_dev_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;
+
+       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);
+       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 = TF_KONG_MB;
+
+       rc = tfp_send_msg_direct(tfp, &parms);
+
+       if (rc != 0)
+               return rc;
+
+       return tfp_le_to_cpu_32(parms.tf_resp_code);
+}
+
 int
 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
-                         struct tf_bulk_get_tbl_entry_parms *params)
+                         enum tf_dir dir,
+                         uint16_t hcapi_type,
+                         uint32_t starting_idx,
+                         uint16_t num_entries,
+                         uint16_t entry_sz_in_bytes,
+                         uint64_t physical_mem_addr)
 {
        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 tf_session *)(tfp->session->core_data);
        int data_size = 0;
+       uint8_t fw_session_id;
+
+       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.flags = tfp_cpu_to_le_16(params->dir);
-       req.type = tfp_cpu_to_le_32(params->type);
-       req.start_index = tfp_cpu_to_le_32(params->starting_idx);
-       req.num_entries = tfp_cpu_to_le_32(params->num_entries);
+       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);
+       req.num_entries = tfp_cpu_to_le_32(num_entries);
 
-       data_size = params->num_entries * params->entry_sz_in_bytes;
+       data_size = num_entries * entry_sz_in_bytes;
 
-       req.host_addr = tfp_cpu_to_le_64(params->physical_mem_addr);
+       req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
 
        MSG_PREP(parms,
                 TF_KONG_MB,
@@ -904,8 +1238,111 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp,
                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);
 }
+
+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_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;
+       }
+
+       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 = TF_KONG_MB;
+
+       rc = tfp_send_msg_direct(tfp, &parms);
+
+       if (rc != 0)
+               return rc;
+
+       if (parms.tf_resp_code != 0)
+               return tfp_le_to_cpu_32(parms.tf_resp_code);
+
+       tfp_memcpy(&params->data[0], resp.data, req.size);
+
+       return tfp_le_to_cpu_32(parms.tf_resp_code);
+}
+
+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_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;
+       }
+
+
+       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 = TF_KONG_MB;
+
+       rc = tfp_send_msg_direct(tfp, &parms);
+
+       if (rc != 0)
+               return rc;
+
+       return tfp_le_to_cpu_32(parms.tf_resp_code);
+}