summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPadma, Santhosh Kumar <skpadma@codeaurora.org>2016-06-28 18:54:12 +0530
committerqcabuildsw <qcabuildsw@localhost>2016-10-04 12:40:51 -0700
commitd7cc07998351d9e6a4056722320cd7690ce5e2ce (patch)
tree728946504877da57c53ec22caf0be98fec472e31
parent62e91469ab90ae644a035d014392c39802d06cd7 (diff)
qcacld-3.0: Add changes for DISA certification
Add changes to parse DISA parameters received from user space and pass them to firmware for firmware to encrypt data and send back to driver. Also, add changes to print encrypted data received from firmware. Change-Id: Ic6928a93f799c47518fbbad96564062f595287dd CRs-Fixed: 1064970
-rw-r--r--Kbuild11
-rw-r--r--Kconfig4
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c14
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.h41
-rw-r--r--core/hdd/src/wlan_hdd_disa.c496
-rw-r--r--core/hdd/src/wlan_hdd_disa.h70
-rw-r--r--core/hdd/src/wlan_hdd_main.c5
-rw-r--r--core/mac/inc/sir_api.h14
-rw-r--r--core/mac/src/include/sir_params.h1
-rw-r--r--core/sme/inc/sme_api.h40
-rw-r--r--core/sme/inc/sme_internal.h2
-rw-r--r--core/sme/src/common/sme_api.c131
-rw-r--r--core/wma/inc/wma.h3
-rw-r--r--core/wma/inc/wma_api.h2
-rw-r--r--core/wma/inc/wma_internal.h3
-rw-r--r--core/wma/inc/wma_types.h1
-rw-r--r--core/wma/src/wma_features.c105
-rw-r--r--core/wma/src/wma_main.c8
18 files changed, 948 insertions, 3 deletions
diff --git a/Kbuild b/Kbuild
index 90b5a8e59cd7..c6ea5d2042d8 100644
--- a/Kbuild
+++ b/Kbuild
@@ -159,6 +159,9 @@ ifneq ($(CONFIG_ROME_IF),sdio)
#Flag to enable memdump feature
CONFIG_WLAN_FEATURE_MEMDUMP := n
+ #Flag to enable DISA
+ CONFIG_WLAN_FEATURE_DISA := y
+
#Flag to enable Fast Path feature
CONFIG_WLAN_FASTPATH := y
@@ -420,6 +423,10 @@ ifeq ($(CONFIG_WLAN_FEATURE_MEMDUMP),y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_memdump.o
endif
+ifeq ($(CONFIG_WLAN_FEATURE_DISA),y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_disa.o
+endif
+
ifeq ($(CONFIG_LFR_SUBNET_DETECTION), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_subnet_detect.o
endif
@@ -1545,6 +1552,10 @@ ifeq ($(CONFIG_WLAN_FEATURE_MEMDUMP),y)
CDEFINES += -DWLAN_FEATURE_MEMDUMP
endif
+ifeq ($(CONFIG_WLAN_FEATURE_DISA),y)
+CDEFINES += -DWLAN_FEATURE_DISA
+endif
+
ifeq ($(CONFIG_LFR_SUBNET_DETECTION), y)
CDEFINES += -DFEATURE_LFR_SUBNET_DETECTION
endif
diff --git a/Kconfig b/Kconfig
index bac7403f532d..da483769e7f5 100644
--- a/Kconfig
+++ b/Kconfig
@@ -132,4 +132,8 @@ config FEATURE_DP_TRACE
bool "Enable data path trace feature"
default n
+config WLAN_FEATURE_DISA
+ bool "Enable DISA certification feature"
+ default n
+
endif # QCA_CLD_WLAN
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index c534a7dd8e39..ce3e7907bb88 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -98,6 +98,7 @@
#include <wlan_hdd_regulatory.h>
#include "wlan_hdd_lpass.h"
#include "wlan_hdd_nan_datapath.h"
+#include "wlan_hdd_disa.h"
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -8410,7 +8411,18 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
WIPHY_VENDOR_CMD_NEED_NETDEV |
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_set_fast_roaming
- }
+ },
+#ifdef WLAN_FEATURE_DISA
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd =
+ QCA_NL80211_VENDOR_SUBCMD_ENCRYPTION_TEST,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_encrypt_decrypt_msg
+ },
+#endif
};
/**
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
index 7355b4bea69d..80dbc428c50b 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -429,6 +429,9 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START = 122,
QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP = 123,
QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH = 124,
+
+ /* Encrypt/Decrypt command */
+ QCA_NL80211_VENDOR_SUBCMD_ENCRYPTION_TEST = 137,
};
/**
@@ -2896,6 +2899,44 @@ enum qca_wlan_vendor_drv_info {
QCA_WLAN_VENDOR_ATTR_DRV_INFO_AFTER_LAST - 1,
};
+/**
+ * enum qca_wlan_vendor_attr_encryption_test - Attributes to
+ * validate encryption engine
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION: Flag attribute.
+ * This will be included if the request is for decryption; if not included,
+ * the request is treated as a request for encryption by default.
+ * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER: Unsigned 32-bit value
+ * indicating the key cipher suite. Takes same values as
+ * NL80211_ATTR_KEY_CIPHER.
+ * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID: Unsigned 8-bit value
+ * Key Id to be used for encryption
+ * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK: Array of 8-bit values.
+ * Key (TK) to be used for encryption/decryption
+ * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN: Array of 8-bit values.
+ * Packet number to be specified for encryption/decryption
+ * 6 bytes for TKIP/CCMP/GCMP.
+ * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA: Array of 8-bit values
+ * representing the 802.11 packet (header + payload + FCS) that
+ * needs to be encrypted/decrypted.
+ * Encrypted/decrypted response from the driver will also be sent
+ * to userspace with the same attribute.
+ */
+enum qca_wlan_vendor_attr_encryption_test {
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION,
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER,
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID,
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK,
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN,
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX =
+ QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_AFTER_LAST - 1
+};
+
struct cfg80211_bss *wlan_hdd_cfg80211_update_bss_db(hdd_adapter_t *pAdapter,
tCsrRoamInfo *pRoamInfo);
diff --git a/core/hdd/src/wlan_hdd_disa.c b/core/hdd/src/wlan_hdd_disa.c
new file mode 100644
index 000000000000..a4153fc5f1db
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_disa.c
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC : wlan_hdd_disa.c
+ *
+ * WLAN Host Device Driver file for DISA certification
+ *
+ */
+
+#include "wlan_hdd_disa.h"
+#include "sme_api.h"
+
+#define ENCRYPT_DECRYPT_CONTEXT_MAGIC 0x4475354
+#define WLAN_WAIT_TIME_ENCRYPT_DECRYPT 1000
+
+
+/**
+ * hdd_encrypt_decrypt_msg_context - hdd encrypt/decrypt message context
+ *
+ * @magic: magic number
+ * @completion: Completion variable for encrypt/decrypt message
+ * @response_event: encrypt/decrypt message request wait event
+ */
+struct hdd_encrypt_decrypt_msg_context {
+ unsigned int magic;
+ struct completion completion;
+ struct sir_encrypt_decrypt_rsp_params response;
+};
+static struct hdd_encrypt_decrypt_msg_context encrypt_decrypt_msg_context;
+
+/**
+ * hdd_encrypt_decrypt_msg_cb () - sends encrypt/decrypt data to user space
+ * @encrypt_decrypt_rsp_params: encrypt/decrypt response parameters
+ *
+ * Return: none
+ */
+static void hdd_encrypt_decrypt_msg_cb(void *hdd_context,
+ struct sir_encrypt_decrypt_rsp_params *encrypt_decrypt_rsp_params)
+{
+ hdd_context_t *hdd_ctx = hdd_context;
+ int ret;
+ struct hdd_encrypt_decrypt_msg_context *context;
+
+ ENTER();
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret)
+ return;
+
+ if (!encrypt_decrypt_rsp_params) {
+ hdd_err("rsp params is NULL");
+ return;
+ }
+
+ print_hex_dump(KERN_INFO, "Data in hdd_encrypt_decrypt_msg_cb: ",
+ DUMP_PREFIX_NONE, 16, 1,
+ encrypt_decrypt_rsp_params->data,
+ encrypt_decrypt_rsp_params->data_length, 0);
+
+ hdd_err("vdev_id %d,status %d data_length %d",
+ encrypt_decrypt_rsp_params->vdev_id,
+ encrypt_decrypt_rsp_params->status,
+ encrypt_decrypt_rsp_params->data_length);
+
+ spin_lock(&hdd_context_lock);
+
+ context = &encrypt_decrypt_msg_context;
+ /* The caller presumably timed out so there is nothing we can do */
+ if (context->magic != ENCRYPT_DECRYPT_CONTEXT_MAGIC) {
+ spin_unlock(&hdd_context_lock);
+ return;
+ }
+
+ /* context is valid so caller is still waiting */
+ context->response = *encrypt_decrypt_rsp_params;
+
+ if (encrypt_decrypt_rsp_params->data_length) {
+ context->response.data =
+ qdf_mem_malloc(sizeof(uint8_t) *
+ encrypt_decrypt_rsp_params->data_length);
+ if (context->response.data == NULL) {
+ hdd_err("cdf_mem_alloc failed for data");
+ spin_unlock(&hdd_context_lock);
+ return;
+ }
+ qdf_mem_copy(context->response.data,
+ encrypt_decrypt_rsp_params->data,
+ encrypt_decrypt_rsp_params->data_length);
+ }
+
+ /*
+ * Indicate to calling thread that
+ * response data is available
+ */
+ context->magic = 0;
+
+ complete(&context->completion);
+
+ spin_unlock(&hdd_context_lock);
+
+
+ EXIT();
+}
+
+
+/**
+ * hdd_encrypt_decrypt_msg_cb () - sends encrypt/decrypt data to user space
+ * @encrypt_decrypt_rsp_params: encrypt/decrypt response parameters
+ *
+ * Return: none
+ */
+static int hdd_post_encrypt_decrypt_msg_rsp(hdd_context_t *hdd_ctx,
+ struct sir_encrypt_decrypt_rsp_params *encrypt_decrypt_rsp_params)
+{
+ struct sk_buff *skb;
+ uint32_t nl_buf_len;
+
+ ENTER();
+
+ nl_buf_len = encrypt_decrypt_rsp_params->data_length + NLA_HDRLEN;
+
+ skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+ if (!skb) {
+ hdd_err(FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
+ return -ENOMEM;
+ }
+
+ if (encrypt_decrypt_rsp_params->data_length) {
+ if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA,
+ encrypt_decrypt_rsp_params->data_length,
+ encrypt_decrypt_rsp_params->data)) {
+ hdd_err(FL("put fail"));
+ goto nla_put_failure;
+ }
+ }
+
+ cfg80211_vendor_cmd_reply(skb);
+ EXIT();
+ return 0;
+
+nla_put_failure:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+/**
+ * hdd_fill_encrypt_decrypt_params () - parses data from user space
+ * and fills encrypt/decrypt parameters
+ * @encrypt_decrypt_params: encrypt/decrypt request parameters
+ * @adapter : adapter context
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ Return: 0 on success, negative errno on failure
+ */
+static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
+ *encrypt_decrypt_params,
+ hdd_adapter_t *adapter,
+ const void *data,
+ int data_len)
+{
+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX + 1];
+ uint8_t len, mac_hdr_len;
+ uint8_t *tmp;
+ uint8_t fc[2];
+
+ if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX,
+ data, data_len, NULL)) {
+ hdd_err("Invalid ATTR");
+ return -EINVAL;
+ }
+
+ encrypt_decrypt_params->vdev_id = adapter->sessionId;
+ hdd_err("vdev_id : %d", encrypt_decrypt_params->vdev_id);
+
+ if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION]) {
+ hdd_err("attr flag NEEDS_DECRYPTION not present");
+ encrypt_decrypt_params->key_flag = WMI_ENCRYPT;
+ } else {
+ hdd_err("attr flag NEEDS_DECRYPTION present");
+ encrypt_decrypt_params->key_flag = WMI_DECRYPT;
+ }
+ hdd_err("Key flag : %d", encrypt_decrypt_params->key_flag);
+
+ if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID]) {
+ hdd_err("attr key id failed");
+ return -EINVAL;
+ }
+ encrypt_decrypt_params->key_idx = nla_get_u8(tb
+ [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID]);
+ hdd_err("Key Idx : %d", encrypt_decrypt_params->key_idx);
+
+ if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER]) {
+ hdd_err("attr Cipher failed");
+ return -EINVAL;
+ }
+ encrypt_decrypt_params->key_cipher = nla_get_u32(tb
+ [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER]);
+ hdd_err("key_cipher : %d", encrypt_decrypt_params->key_cipher);
+
+ if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]) {
+ hdd_err("attr TK failed");
+ return -EINVAL;
+ }
+ encrypt_decrypt_params->key_len =
+ nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]);
+ if (!encrypt_decrypt_params->key_len) {
+ hdd_err("Invalid TK length");
+ return -EINVAL;
+ }
+ hdd_err("Key len : %d", encrypt_decrypt_params->key_len);
+
+ if (encrypt_decrypt_params->key_len > SIR_MAC_MAX_KEY_LENGTH)
+ encrypt_decrypt_params->key_len = SIR_MAC_MAX_KEY_LENGTH;
+
+ tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]);
+
+ qdf_mem_copy(encrypt_decrypt_params->key_data, tmp,
+ encrypt_decrypt_params->key_len);
+
+ print_hex_dump(KERN_INFO, "Key : ", DUMP_PREFIX_NONE, 16, 1,
+ &encrypt_decrypt_params->key_data,
+ encrypt_decrypt_params->key_len, 0);
+
+ if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]) {
+ hdd_err("attr PN failed");
+ return -EINVAL;
+ }
+ len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
+ if (!len) {
+ hdd_err("Invalid PN length");
+ return -EINVAL;
+ }
+
+ tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
+
+ qdf_mem_copy(encrypt_decrypt_params->pn, tmp, len);
+
+ print_hex_dump(KERN_INFO, "PN received : ", DUMP_PREFIX_NONE, 16, 1,
+ &encrypt_decrypt_params->pn, len, 0);
+
+ if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]) {
+ hdd_err("attr header failed");
+ return -EINVAL;
+ }
+ len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
+ if (!len) {
+ hdd_err("Invalid header and payload length");
+ return -EINVAL;
+ }
+
+ hdd_err("Header and Payload length %d ", len);
+
+ tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
+
+ print_hex_dump(KERN_INFO, "Header and Payload received: ",
+ DUMP_PREFIX_NONE, 16, 1,
+ tmp, len, 0);
+
+ mac_hdr_len = MIN_MAC_HEADER_LEN;
+
+ /*
+ * Check to find out address 4. Address 4 is present if ToDS and FromDS
+ * are 1 and data representation is little endian.
+ */
+ fc[1] = *tmp;
+ fc[0] = *(tmp + 1);
+ if ((fc[0] & 0x03) == 0x03) {
+ hdd_err("Address 4 is present");
+ mac_hdr_len += IEEE80211_ADDR_LEN;
+ }
+
+ /*
+ * Check to find out Qos control field. Qos control field is present
+ * if msb of subtype field is 1 and data representation is
+ * little endian.
+ */
+ if (fc[1] & 0x80) {
+ hdd_err("Qos control is present");
+ mac_hdr_len += QOS_CONTROL_LEN;
+ }
+
+ hdd_err("mac_hdr_len %d", mac_hdr_len);
+
+ qdf_mem_copy(encrypt_decrypt_params->mac_header,
+ tmp, mac_hdr_len);
+
+ print_hex_dump(KERN_INFO, "Header received in request: ",
+ DUMP_PREFIX_NONE, 16, 1,
+ encrypt_decrypt_params->mac_header,
+ mac_hdr_len, 0);
+
+ encrypt_decrypt_params->data_len =
+ len - mac_hdr_len;
+
+ hdd_err("Payload length : %d", encrypt_decrypt_params->data_len);
+
+ if (encrypt_decrypt_params->data_len) {
+ encrypt_decrypt_params->data =
+ qdf_mem_malloc(sizeof(uint8_t) *
+ encrypt_decrypt_params->data_len);
+
+ if (encrypt_decrypt_params->data == NULL) {
+ hdd_err("cdf_mem_alloc failed for data");
+ return -ENOMEM;
+ }
+
+ qdf_mem_copy(encrypt_decrypt_params->data,
+ tmp + mac_hdr_len,
+ encrypt_decrypt_params->data_len);
+
+ print_hex_dump(KERN_INFO, "Data received in request: ",
+ DUMP_PREFIX_NONE, 16, 1,
+ encrypt_decrypt_params->data,
+ encrypt_decrypt_params->data_len, 0);
+ }
+
+ return 0;
+}
+
+/**
+ * hdd_encrypt_decrypt_msg () - process encrypt/decrypt message
+ * @adapter : adapter context
+ * @hdd_ctx: hdd context
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ Return: 0 on success, negative errno on failure
+ */
+static int hdd_encrypt_decrypt_msg(hdd_adapter_t *adapter,
+ hdd_context_t *hdd_ctx,
+ const void *data,
+ int data_len)
+{
+ struct encrypt_decrypt_req_params encrypt_decrypt_params = {0};
+ QDF_STATUS qdf_status;
+ int ret;
+ struct hdd_encrypt_decrypt_msg_context *context;
+ unsigned long rc;
+
+ ret = hdd_fill_encrypt_decrypt_params(&encrypt_decrypt_params,
+ adapter, data, data_len);
+ if (ret)
+ return ret;
+
+ spin_lock(&hdd_context_lock);
+ context = &encrypt_decrypt_msg_context;
+ context->magic = ENCRYPT_DECRYPT_CONTEXT_MAGIC;
+ INIT_COMPLETION(context->completion);
+ spin_unlock(&hdd_context_lock);
+
+ qdf_status = sme_encrypt_decrypt_msg(hdd_ctx->hHal,
+ &encrypt_decrypt_params);
+
+ qdf_mem_free(encrypt_decrypt_params.data);
+
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ hdd_err("Unable to post encrypt/decrypt message");
+ return -EINVAL;
+ }
+
+ rc = wait_for_completion_timeout(&context->completion,
+ msecs_to_jiffies(WLAN_WAIT_TIME_ENCRYPT_DECRYPT));
+
+ spin_lock(&hdd_context_lock);
+ if (!rc && (context->magic ==
+ ENCRYPT_DECRYPT_CONTEXT_MAGIC)) {
+ hdd_err("Target response timed out");
+ context->magic = 0;
+ spin_unlock(&hdd_context_lock);
+ return -ETIMEDOUT;
+ }
+
+ spin_unlock(&hdd_context_lock);
+ ret = hdd_post_encrypt_decrypt_msg_rsp(hdd_ctx,
+ &encrypt_decrypt_msg_context.response);
+ if (ret)
+ hdd_err("Failed to post encrypt/decrypt message response");
+
+ qdf_mem_free(encrypt_decrypt_msg_context.response.data);
+
+ EXIT();
+ return ret;
+}
+
+/**
+ * hdd_encrypt_decrypt_init () - exposes encrypt/decrypt initialization
+ * functionality
+ * @hdd_ctx: hdd context
+ *
+ Return: 0 on success, negative errno on failure
+ */
+int hdd_encrypt_decrypt_init(hdd_context_t *hdd_ctx)
+{
+ QDF_STATUS status;
+
+ init_completion(&encrypt_decrypt_msg_context.completion);
+
+ status = sme_encrypt_decrypt_msg_register_callback(hdd_ctx->hHal,
+ hdd_encrypt_decrypt_msg_cb);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hdd_err("encrypt/decrypt callback failed %d", status);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * hdd_encrypt_decrypt_deinit () - exposes encrypt/decrypt deinitialization
+ * functionality
+ * @hdd_ctx: hdd context
+ *
+ Return: 0 on success, negative errno on failure
+ */
+int hdd_encrypt_decrypt_deinit(hdd_context_t *hdd_ctx)
+{
+ QDF_STATUS status;
+
+ status = sme_encrypt_decrypt_msg_deregister_callback(hdd_ctx->hHal);
+ if (!QDF_IS_STATUS_SUCCESS(status))
+ hdd_err("De-register encrypt/decrypt callback failed: %d",
+ status);
+ return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ struct net_device *dev = wdev->netdev;
+ hdd_adapter_t *adapter = NULL;
+ int ret;
+
+ ENTER_DEV(dev);
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret)
+ return ret;
+
+ adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+ ret = hdd_encrypt_decrypt_msg(adapter, hdd_ctx, data, data_len);
+
+ return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ int ret;
+
+ cds_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_encrypt_decrypt_msg(wiphy, wdev,
+ data, data_len);
+ cds_ssr_unprotect(__func__);
+
+ return ret;
+}
diff --git a/core/hdd/src/wlan_hdd_disa.h b/core/hdd/src/wlan_hdd_disa.h
new file mode 100644
index 000000000000..b35c02c5dbbe
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_disa.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _WLAN_HDD_DISA_H
+#define _WLAN_HDD_DISA_H
+
+#include "wlan_hdd_main.h"
+#include "sir_api.h"
+
+#ifdef WLAN_FEATURE_DISA
+/**
+ * hdd_encrypt_decrypt_init () - exposes encrypt/decrypt initialization
+ * functionality
+ * @hdd_ctx: hdd context
+ *
+ Return: 0 on success, negative errno on failure
+ */
+int hdd_encrypt_decrypt_init(hdd_context_t *hdd_ctx);
+
+/**
+ * hdd_encrypt_decrypt_deinit () - exposes encrypt/decrypt deinitialization
+ * functionality
+ * @hdd_ctx: hdd context
+ *
+ Return: 0 on success, negative errno on failure
+ */
+int hdd_encrypt_decrypt_deinit(hdd_context_t *hdd_ctx);
+#else
+static inline int hdd_encrypt_decrypt_init(hdd_context_t *hdd_ctx)
+{
+ return -ENOTSUPP;
+}
+static inline int hdd_encrypt_decrypt_deinit(hdd_context_t *hdd_ctx)
+{
+ return -ENOTSUPP;
+}
+#endif
+
+#ifdef WLAN_FEATURE_DISA
+/**
+ * wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len);
+#endif
+
+#endif
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 33f9cfc6a96d..9aeee9107f74 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -107,6 +107,7 @@
#include "wlan_hdd_lpass.h"
#include "nan_api.h"
#include <wlan_hdd_napi.h>
+#include "wlan_hdd_disa.h"
#ifdef MODULE
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
@@ -4695,8 +4696,7 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
/* Free up RoC request queue and flush workqueue */
cds_flush_work(&hdd_ctx->roc_req_work);
-
-
+ hdd_encrypt_decrypt_deinit(hdd_ctx);
wlansap_global_deinit();
wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
wiphy_unregister(wiphy);
@@ -7781,6 +7781,7 @@ int hdd_wlan_startup(struct device *dev)
goto err_debugfs_exit;
memdump_init();
+ hdd_encrypt_decrypt_init(hdd_ctx);
if (hdd_ctx->config->fIsImpsEnabled)
hdd_set_idle_ps_config(hdd_ctx, true);
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 43b6ccd0d892..0fdac5c0c888 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -6536,4 +6536,18 @@ struct sme_update_access_policy_vendor_ie {
uint8_t access_policy;
};
+/**
+ * struct sir_encrypt_decrypt_rsp_params - encrypt/decrypt rsp params
+ * @vdev_id: vdev id
+ * @status: status
+ * @data_length: data length
+ * @data: data pointer
+ */
+struct sir_encrypt_decrypt_rsp_params {
+ uint32_t vdev_id;
+ int32_t status;
+ uint32_t data_length;
+ uint8_t *data;
+};
+
#endif /* __SIR_API_H */
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index 903f3a6e9500..2b71b5143209 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -633,6 +633,7 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 360)
#define SIR_HAL_POWER_DBG_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 362)
#define SIR_HAL_SET_DTIM_PERIOD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 363)
+#define SIR_HAL_ENCRYPT_DECRYPT_MSG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 364)
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 9afb984a9d78..15f845510ef9 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -1276,4 +1276,44 @@ QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id,
*/
QDF_STATUS sme_update_session_param(tHalHandle hal, uint8_t session_id,
uint32_t param_type, uint32_t param_val);
+
+/**
+ * sme_encrypt_decrypt_msg_register_callback() - Registers
+ * encrypt/decrypt message callback
+ *
+ * @hal - MAC global handle
+ * @callback_routine - callback routine from HDD
+ *
+ * This API is invoked by HDD to register its callback in SME
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_encrypt_decrypt_msg_register_callback(tHalHandle hal,
+ void (*encrypt_decrypt_cb)(void *hdd_context,
+ struct sir_encrypt_decrypt_rsp_params
+ *encrypt_decrypt_rsp_params));
+
+/**
+ * sme_encrypt_decrypt_msg_deregister_callback() - Registers
+ * encrypt/decrypt message callback
+ *
+ * @h_hal - MAC global handle
+ * @callback_routine - callback routine from HDD
+ *
+ * This API is invoked by HDD to de-register its callback in SME
+ *
+ * Return: QDF_STATUS Enumeration
+ */
+QDF_STATUS sme_encrypt_decrypt_msg_deregister_callback(tHalHandle h_hal);
+
+/**
+ * sme_encrypt_decrypt_msg() - handles encrypt/decrypt mesaage
+ * @hal: HAL handle
+ * @encrypt_decrypt_params: struct to set encryption/decryption params.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_encrypt_decrypt_msg(tHalHandle hal,
+ struct encrypt_decrypt_req_params *encrypt_decrypt_params);
+
#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
index 51c135ec235c..0afada7cdf73 100644
--- a/core/sme/inc/sme_internal.h
+++ b/core/sme/inc/sme_internal.h
@@ -244,6 +244,8 @@ typedef struct tagSmeStruct {
p2p_lo_callback p2p_lo_event_callback;
void *p2p_lo_event_context;
sme_send_oem_data_rsp_msg oem_data_rsp_callback;
+ void (*encrypt_decrypt_cb)(void *,
+ struct sir_encrypt_decrypt_rsp_params *);
} tSmeStruct, *tpSmeStruct;
#endif /* #if !defined( __SMEINTERNAL_H ) */
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 1a04362b8549..2983525148fc 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -16593,3 +16593,134 @@ QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id,
sms_log(mac_ctx, LOG1, FL("Set default scan IE status %d"), status);
return status;
}
+
+/**
+ * sme_encrypt_decrypt_msg() - handles encrypt/decrypt mesaage
+ * @hal: HAL handle
+ * @encrypt_decrypt_params: struct to set encryption/decryption params.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_encrypt_decrypt_msg(tHalHandle hal,
+ struct encrypt_decrypt_req_params *encrypt_decrypt_params)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ cds_msg_t cds_msg;
+ struct encrypt_decrypt_req_params *params;
+ uint8_t *ptr;
+
+ ptr = qdf_mem_malloc(sizeof(*params) +
+ encrypt_decrypt_params->data_len);
+ if (ptr == NULL) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Failed to alloc memory for encrypt/decrypt params"));
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ params = (struct encrypt_decrypt_req_params *)ptr;
+
+ *params = *encrypt_decrypt_params;
+
+ if (params->data_len) {
+ params->data = ptr + sizeof(*params);
+
+ qdf_mem_copy(params->data, encrypt_decrypt_params->data,
+ params->data_len);
+ }
+
+ status = sme_acquire_global_lock(&mac_ctx->sme);
+ if (status == QDF_STATUS_SUCCESS) {
+ /* Serialize the req through MC thread */
+ cds_msg.bodyptr = params;
+ cds_msg.type = WMA_ENCRYPT_DECRYPT_MSG;
+ status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg);
+
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Post encrypt/decrypt msg fail"));
+ status = QDF_STATUS_E_FAILURE;
+ qdf_mem_free(params);
+ }
+ sme_release_global_lock(&mac_ctx->sme);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("sme_acquire_global_lock failed"));
+ qdf_mem_free(params);
+ }
+ return status;
+
+}
+
+/**
+ * sme_encrypt_decrypt_msg_register_callback() - Registers
+ * encrypt/decrypt message callback
+ *
+ * @hal - MAC global handle
+ * @callback_routine - callback routine from HDD
+ *
+ * This API is invoked by HDD to register its callback in SME
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_encrypt_decrypt_msg_register_callback(tHalHandle hal,
+ void (*encrypt_decrypt_cb)(void *hdd_context,
+ struct sir_encrypt_decrypt_rsp_params
+ *encrypt_decrypt_rsp_params))
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac;
+
+ if (!hal) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("hHal is not valid"));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ mac = PMAC_STRUCT(hal);
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ mac->sme.encrypt_decrypt_cb = encrypt_decrypt_cb;
+ sme_release_global_lock(&mac->sme);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("sme_acquire_global_lock failed"));
+ }
+ return status;
+}
+
+/**
+ * sme_encrypt_decrypt_msg_deregister_callback() - Registers
+ * encrypt/decrypt message callback
+ *
+ * @h_hal - MAC global handle
+ * @callback_routine - callback routine from HDD
+ *
+ * This API is invoked by HDD to de-register its callback in SME
+ *
+ * Return: QDF_STATUS Enumeration
+ */
+QDF_STATUS sme_encrypt_decrypt_msg_deregister_callback(tHalHandle h_hal)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac;
+
+ if (!h_hal) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("hHal is not valid"));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ mac = PMAC_STRUCT(h_hal);
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ mac->sme.encrypt_decrypt_cb = NULL;
+ sme_release_global_lock(&mac->sme);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("sme_acquire_global_lock failed"));
+ }
+ return status;
+}
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index 08792473b103..f22aea6dac5d 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -415,6 +415,9 @@ static const t_probeTime_dwellTime
};
typedef void (*txFailIndCallback)(uint8_t *peer_mac, uint8_t seqNo);
+typedef void (*encrypt_decrypt_cb)(struct sir_encrypt_decrypt_rsp_params
+ *encrypt_decrypt_rsp_params);
+
/**
* enum t_wma_drv_type - wma driver type
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
index 951048c535b0..dcd121e37fdb 100644
--- a/core/wma/inc/wma_api.h
+++ b/core/wma/inc/wma_api.h
@@ -301,4 +301,6 @@ void wma_process_pdev_hw_mode_trans_ind(void *wma,
wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry,
struct sir_hw_mode_trans_ind *hw_mode_trans_ind);
QDF_STATUS wma_set_powersave_config(uint8_t val);
+QDF_STATUS wma_encrypt_decrypt_msg(WMA_HANDLE wma,
+ struct encrypt_decrypt_req_params *encrypt_decrypt_params);
#endif
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index dadac756d645..f35044e57d4a 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -1214,4 +1214,7 @@ QDF_STATUS wma_process_hal_pwr_dbg_cmd(WMA_HANDLE handle,
struct sir_mac_pwr_dbg_cmd *
sir_pwr_dbg_params);
+int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data,
+ uint32_t data_len);
+
#endif
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index e0fe6e4eb35a..89f06c9db0b5 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -474,6 +474,7 @@
#define WMA_SET_PDEV_IE_REQ SIR_HAL_SET_PDEV_IE_REQ
#define WMA_UPDATE_WEP_DEFAULT_KEY SIR_HAL_UPDATE_WEP_DEFAULT_KEY
#define WMA_SEND_FREQ_RANGE_CONTROL_IND SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND
+#define WMA_ENCRYPT_DECRYPT_MSG SIR_HAL_ENCRYPT_DECRYPT_MSG
/* Bit 6 will be used to control BD rate for Management frames */
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 9a823e8c7932..7850fa73b903 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -8225,3 +8225,108 @@ QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma, uint8_t val)
return QDF_STATUS_SUCCESS;
}
+
+/**
+ * wma_encrypt_decrypt_msg() -
+ * @encrypt_decrypt_params: encryption/decryption params
+ * @data_len: data length
+ * @encrypt_decrypt_cb: encrypt/decrypt callback
+ *
+ * This function sends WMI command to check encryption/decryption engine.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wma_encrypt_decrypt_msg(WMA_HANDLE handle,
+ struct encrypt_decrypt_req_params *encrypt_decrypt_params)
+{
+ int ret;
+ tp_wma_handle wma = (tp_wma_handle) handle;
+
+ if (!wma || !wma->wmi_handle) {
+ WMA_LOGE("%s: WMA is closed, can not issue encrypt/decrypt msg",
+ __func__);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (encrypt_decrypt_params == NULL) {
+ WMA_LOGE("%s: encrypt/decrypt ptr NULL",
+ __func__);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ ret = wmi_unified_encrypt_decrypt_send_cmd(wma->wmi_handle,
+ encrypt_decrypt_params);
+
+ return ret;
+}
+
+/**
+ * wma_encrypt_decrypt_msg_handler() - handle encrypt/decrypt data
+ * indicated by FW
+ * @handle: wma context
+ * @data: event buffer
+ * @data len: length of event buffer
+ *
+ * Return: 0 on success
+ */
+int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data,
+ uint32_t data_len)
+{
+ WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
+ wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
+ struct sir_encrypt_decrypt_rsp_params encrypt_decrypt_rsp_params;
+ tp_wma_handle wma = handle;
+ u_int8_t *buf_ptr;
+ tpAniSirGlobal pmac;
+
+ if (data == NULL) {
+ WMA_LOGE("%s: invalid pointer", __func__);
+ return -EINVAL;
+ }
+
+ if (wma == NULL) {
+ WMA_LOGE("%s: wma context is NULL", __func__);
+ return -EINVAL;
+ }
+
+ WMA_LOGE("%s: received WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID ",
+ __func__);
+
+ pmac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
+
+ if (!pmac) {
+ WMA_LOGE("%s: Invalid pmac", __func__);
+ return -EINVAL;
+ }
+ if (!pmac->sme.encrypt_decrypt_cb) {
+ WMA_LOGE("%s: Callback not registered", __func__);
+ return -EINVAL;
+ }
+
+ param_buf =
+ (WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *)data;
+ if (!param_buf) {
+ WMA_LOGE("%s: Invalid response data buf", __func__);
+ return -EINVAL;
+ }
+
+ data_event = param_buf->fixed_param;
+
+ encrypt_decrypt_rsp_params.vdev_id = data_event->vdev_id;
+ encrypt_decrypt_rsp_params.status = data_event->status;
+ encrypt_decrypt_rsp_params.data_length = data_event->data_length;
+
+ if (encrypt_decrypt_rsp_params.data_length) {
+ buf_ptr =
+ (uint8_t *)data_event +
+ sizeof(
+ wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param) +
+ WMI_TLV_HDR_SIZE;
+
+ encrypt_decrypt_rsp_params.data = buf_ptr;
+ }
+
+ pmac->sme.encrypt_decrypt_cb(pmac->hHdd, &encrypt_decrypt_rsp_params);
+
+ return 0;
+}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 35cf0b88b049..00f1735cc44e 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -2147,6 +2147,10 @@ QDF_STATUS wma_open(void *cds_context,
WMI_BPF_CAPABILIY_INFO_EVENTID,
wma_get_bpf_caps_event_handler,
WMA_RX_SERIALIZER_CTX);
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID,
+ wma_encrypt_decrypt_msg_handler,
+ WMA_RX_SERIALIZER_CTX);
wma_ndp_register_all_event_handlers(wma_handle);
return QDF_STATUS_SUCCESS;
@@ -6303,6 +6307,10 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
case WMA_SEND_FREQ_RANGE_CONTROL_IND:
wma_enable_disable_caevent_ind(wma_handle, msg->bodyval);
break;
+ case WMA_ENCRYPT_DECRYPT_MSG:
+ wma_encrypt_decrypt_msg(wma_handle, msg->bodyptr);
+ qdf_mem_free(msg->bodyptr);
+ break;
default:
WMA_LOGD("unknow msg type %x", msg->type);
/* Do Nothing? MSG Body should be freed at here */