* All rights reserved.
*/
+#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.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
*/
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 };
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;
}
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)
{
TFP_DRV_LOG(ERR,
"%s: QCAPS message size error, rc:%s\n",
tf_dir_2_str(dir),
- strerror(-EINVAL));
+ strerror(EINVAL));
rc = -EINVAL;
goto cleanup;
}
TFP_DRV_LOG(ERR,
"%s: Alloc message size error, rc:%s\n",
tf_dir_2_str(dir),
- strerror(-EINVAL));
+ strerror(EINVAL));
rc = -EINVAL;
goto cleanup;
}
(struct tf_em_64b_entry *)em_parms->em_record;
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) {
/* 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;
+ }
+
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 :
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)
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);
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);
/* 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,
enum tf_dir dir,
return rc;
}
- flags = (params->dir == TF_DIR_TX ? TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
- TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
+ flags = (params->dir == TF_DIR_TX ? TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
+ TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
/* Populate the request */
req.fw_session_id =