diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index a3d6d6012e..1829092f05 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -502,6 +502,9 @@ QDF_STATUS wmi_unified_probe_rsp_tmpl_send_cmd(void *wmi_hdl, QDF_STATUS wmi_unified_setup_install_key_cmd(void *wmi_hdl, struct set_key_params *key_params); +QDF_STATUS wmi_unified_encrypt_decrypt_send_cmd(void *wmi_hdl, + struct encrypt_decrypt_req_params *params); + QDF_STATUS wmi_unified_p2p_go_set_beacon_ie_cmd(void *wmi_hdl, A_UINT32 vdev_id, uint8_t *p2p_ie); diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 5f106114b4..f2ab5ace19 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -32,6 +32,13 @@ #ifndef _WMI_UNIFIED_PARAM_H_ #define _WMI_UNIFIED_PARAM_H_ + +#define MAC_MAX_KEY_LENGTH 32 +#define MAC_PN_LENGTH 8 +#define MAX_MAC_HEADER_LEN 32 +#define MIN_MAC_HEADER_LEN 24 +#define QOS_CONTROL_LEN 2 + #define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ #define WMI_MAC_MAX_SSID_LENGTH 32 #define WMI_SCAN_MAX_NUM_SSID 0x0A @@ -6567,5 +6574,37 @@ enum wmi_userspace_log_level { WMI_LOG_LEVEL_ACTIVE, }; +/** + * struct encrypt_decrypt_req_params - encrypt/decrypt params + * @vdev_id: virtual device id + * @key_flag: This indicates firmware to encrypt/decrypt payload + * see ENCRYPT_DECRYPT_FLAG + * @key_idx: Index used in storing key + * @key_cipher: cipher used for encryption/decryption + * Eg: see WMI_CIPHER_AES_CCM for CCMP + * @key_len: length of key data + * @key_txmic_len: length of Tx MIC + * @key_rxmic_len: length of Rx MIC + * @key_data: Key + * @pn: packet number + * @mac_header: MAC header + * @data_len: length of data + * @data: pointer to payload + */ +struct encrypt_decrypt_req_params { + uint32_t vdev_id; + uint8_t key_flag; + uint32_t key_idx; + uint32_t key_cipher; + uint32_t key_len; + uint32_t key_txmic_len; + uint32_t key_rxmic_len; + uint8_t key_data[MAC_MAX_KEY_LENGTH]; + uint8_t pn[MAC_PN_LENGTH]; + uint8_t mac_header[MAX_MAC_HEADER_LEN]; + uint32_t data_len; + uint8_t *data; +}; + #endif /* _WMI_UNIFIED_PARAM_H_ */ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 2a4c9e90c0..c7efe6bafe 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1129,6 +1129,9 @@ QDF_STATUS (*send_adapt_dwelltime_params_cmd)(wmi_unified_t wmi_handle, QDF_STATUS (*send_fw_test_cmd)(wmi_unified_t wmi_handle, struct set_fwtest_params *wmi_fwtest); + +QDF_STATUS (*send_encrypt_decrypt_send_cmd)(wmi_unified_t wmi_handle, + struct encrypt_decrypt_req_params *params); }; struct target_abi_version { diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 1516e0d9d2..3d9e1854b2 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -6122,3 +6122,23 @@ QDF_STATUS wmi_unified_send_power_dbg_cmd(void *wmi_hdl, return QDF_STATUS_E_FAILURE; } + +/** + * wmi_unified_encrypt_decrypt_send_cmd() - send encryptdecrypt cmd to fw + * @wmi_hdl: wmi handle + * @params: encrypt/decrypt params + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_encrypt_decrypt_send_cmd(void *wmi_hdl, + struct encrypt_decrypt_req_params *params) +{ + wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; + + if (wmi_handle->ops->send_encrypt_decrypt_send_cmd) + return wmi_handle->ops->send_encrypt_decrypt_send_cmd( + wmi_handle, + params); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index ee33ae828c..18bb8e70bc 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -4028,6 +4028,88 @@ QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, return status; } +/** + * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw + * @wmi_handle: wmi handle + * @params: encrypt/decrypt params + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, + struct encrypt_decrypt_req_params *encrypt_decrypt_params) +{ + wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint8_t *buf_ptr; + QDF_STATUS ret; + uint32_t len; + + WMI_LOGD(FL("Send encrypt decrypt cmd")); + + len = sizeof(*cmd) + + roundup(encrypt_decrypt_params->data_len, sizeof(A_UINT32)) + + WMI_TLV_HDR_SIZE; + wmi_buf = wmi_buf_alloc(wmi_handle, len); + if (!wmi_buf) { + WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg", + __func__); + return QDF_STATUS_E_NOMEM; + } + + buf_ptr = wmi_buf_data(wmi_buf); + cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); + + cmd->vdev_id = encrypt_decrypt_params->vdev_id; + cmd->key_flag = encrypt_decrypt_params->key_flag; + cmd->key_idx = encrypt_decrypt_params->key_idx; + cmd->key_cipher = encrypt_decrypt_params->key_cipher; + cmd->key_len = encrypt_decrypt_params->key_len; + cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; + cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; + + qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, + encrypt_decrypt_params->key_len); + + qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, + MAX_MAC_HEADER_LEN); + + cmd->data_len = encrypt_decrypt_params->data_len; + + if (cmd->data_len) { + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + roundup(encrypt_decrypt_params->data_len, + sizeof(A_UINT32))); + buf_ptr += WMI_TLV_HDR_SIZE; + qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, + encrypt_decrypt_params->data_len); + } + + /* This conversion is to facilitate data to FW in little endian */ + cmd->pn[5] = encrypt_decrypt_params->pn[0]; + cmd->pn[4] = encrypt_decrypt_params->pn[1]; + cmd->pn[3] = encrypt_decrypt_params->pn[2]; + cmd->pn[2] = encrypt_decrypt_params->pn[3]; + cmd->pn[1] = encrypt_decrypt_params->pn[4]; + cmd->pn[0] = encrypt_decrypt_params->pn[5]; + + ret = wmi_unified_cmd_send(wmi_handle, + wmi_buf, len, + WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); + if (QDF_IS_STATUS_ERROR(ret)) { + WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); + wmi_buf_free(wmi_buf); + } + + return ret; +} + + /** * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go @@ -12541,6 +12623,8 @@ struct wmi_ops tlv_ops = { .extract_chan_info_event = extract_chan_info_event_tlv, .extract_channel_hopping_event = extract_channel_hopping_event_tlv, .send_fw_test_cmd = send_fw_test_cmd_tlv, + .send_encrypt_decrypt_send_cmd = + send_encrypt_decrypt_send_cmd_tlv, }; #ifndef CONFIG_MCL