Merge branch 'android-msm-bullhead-3.10-security-next' into android-msm-bullhead-3.10

November 2018.1

Bug: 112384927
Change-Id: Ia52c74f4f9a62c020126d98ce2eae9490a6ca47e
Signed-off-by: Siqi Lin <siqilin@google.com>
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h
index 0bd2028..7e893ef 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h
@@ -302,7 +302,6 @@
 #define STATS_CONTEXT_MAGIC 0x53544154   //STAT
 #define RSSI_CONTEXT_MAGIC  0x52535349   //RSSI
 #define POWER_CONTEXT_MAGIC 0x504F5752   //POWR
-#define SNR_CONTEXT_MAGIC   0x534E5200   //SNR
 #define LINK_CONTEXT_MAGIC  0x4C494E4B   //LINKSPEED
 #define LINK_STATUS_MAGIC   0x4C4B5354   //LINKSTATUS(LNST)
 #define TEMP_CONTEXT_MAGIC 0x74656d70   // TEMP (temperature)
@@ -1162,8 +1161,6 @@
     v_TIME_t startRocTs;
 
     /* State for synchronous OCB requests to WMI */
-    struct sir_ocb_set_config_response ocb_set_config_resp;
-    struct sir_ocb_get_tsf_timer_response ocb_get_tsf_timer_resp;
     struct sir_dcc_get_stats_response *dcc_get_stats_resp;
     struct sir_dcc_update_ndl_response dcc_update_ndl_resp;
 
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h
index e18f7f2..20da963 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -425,8 +425,6 @@
 extern VOS_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter,
                                                      tSirMacAddr macAddress);
 void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter);
-void hdd_GetClassA_statisticsCB(void *pStats, void *pContext);
-void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext);
 
 VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter);
 
@@ -477,7 +475,7 @@
 int process_wma_set_command_twoargs(int sessid, int paramid,
                                     int sval, int ssecval, int vpdev);
 
-void hdd_GetTemperatureCB(int temperature, void *pContext);
-VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *pAdapter,
+void hdd_GetTemperatureCB(int temperature, void *cookie);
+VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *adapter_ptr,
         union iwreq_data *wrqu, char *extra);
 #endif // __WEXT_IW_H__
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
index 50b2082..8445c52 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -81,6 +81,7 @@
 #include "wlan_hdd_main.h"
 #include "wlan_hdd_assoc.h"
 #include "wlan_hdd_power.h"
+#include "wlan_hdd_request_manager.h"
 #include "wlan_hdd_trace.h"
 #include "vos_types.h"
 #include "vos_trace.h"
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
index d2e8d58..d690588 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -96,6 +96,7 @@
 #include <wlan_hdd_wowl.h>
 #include "wlan_hdd_tsf.h"
 #include "wlan_hdd_oemdata.h"
+#include "wlan_hdd_request_manager.h"
 
 #define    IS_UP(_dev) \
     (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
@@ -5554,69 +5555,99 @@
 	return ret;
 }
 
+struct linkspeed_priv {
+	tSirLinkSpeedInfo linkspeed_info;
+};
+
+static void
+hdd_get_link_speed_cb(tSirLinkSpeedInfo *linkspeed_info, void *cookie)
+{
+	struct hdd_request *request;
+	struct linkspeed_priv *priv;
+
+	if (NULL == linkspeed_info)
+	{
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s: Bad param, linkspeed_info [%pK] cookie [%pK]",
+		       __func__, linkspeed_info, cookie);
+		return;
+	}
+
+	request = hdd_request_get(cookie);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,"Obsolete request");
+		return;
+	}
+
+	priv = hdd_request_priv(request);
+	priv->linkspeed_info = *linkspeed_info;
+	hdd_request_complete(request);
+	hdd_request_put(request);
+}
 
 VOS_STATUS  wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter,
                                                tSirMacAddr macAddress)
 {
    eHalStatus hstatus;
-   unsigned long rc;
-   struct linkspeedContext context;
-   tSirLinkSpeedInfo *linkspeed_req;
+   VOS_STATUS status = VOS_STATUS_SUCCESS;
+   void *cookie;
+   tSirLinkSpeedInfo *linkspeed_info;
+   int ret;
+   struct hdd_request *request;
+   struct linkspeed_priv *priv;
+   static const struct hdd_request_params params = {
+      .priv_size = sizeof(*priv),
+      .timeout_ms = WLAN_WAIT_TIME_STATS,
+   };
 
    if (NULL == pAdapter)
    {
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
       return VOS_STATUS_E_FAULT;
    }
-   linkspeed_req = (tSirLinkSpeedInfo *)vos_mem_malloc(sizeof(*linkspeed_req));
-   if (NULL == linkspeed_req)
-   {
+
+   request = hdd_request_alloc(&params);
+   if (!request) {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "%s Request Buffer Alloc Fail", __func__);
       return VOS_STATUS_E_INVAL;
    }
-   init_completion(&context.completion);
-   context.pAdapter = pAdapter;
-   context.magic = LINK_CONTEXT_MAGIC;
+   cookie = hdd_request_cookie(request);
+   priv = hdd_request_priv(request);
 
-   vos_mem_copy(linkspeed_req->peer_macaddr, macAddress, sizeof(tSirMacAddr) );
-   hstatus = sme_GetLinkSpeed( WLAN_HDD_GET_HAL_CTX(pAdapter),
-                                  linkspeed_req,
-                                  &context,
-                                  hdd_GetLink_SpeedCB);
+   linkspeed_info = &priv->linkspeed_info;
+   vos_mem_copy(linkspeed_info->peer_macaddr, macAddress, sizeof(tSirMacAddr) );
+   hstatus = sme_GetLinkSpeed(WLAN_HDD_GET_HAL_CTX(pAdapter),
+                              linkspeed_info,
+                              cookie,
+                              hdd_get_link_speed_cb);
+
    if (eHAL_STATUS_SUCCESS != hstatus)
    {
       hddLog(VOS_TRACE_LEVEL_ERROR,
-            "%s: Unable to retrieve statistics for link speed",
-            __func__);
-      vos_mem_free(linkspeed_req);
+            "%s: Unable to retrieve statistics for link speed, ret(%d)",
+            __func__, hstatus);
+      status = VOS_STATUS_E_INVAL;
+      goto cleanup;
    }
-   else
-   {
-      rc = wait_for_completion_timeout(&context.completion,
-            msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
-      if (!rc) {
-         hddLog(VOS_TRACE_LEVEL_ERROR,
-               "%s: SME timed out while retrieving link speed",
-              __func__);
-      }
+   ret = hdd_request_wait_for_response(request);
+   if (!ret) {
+      hddLog(VOS_TRACE_LEVEL_ERROR,
+             "%s: SME timed out while retrieving link speed,ret(%d)",
+             __func__, ret);
+      status = VOS_STATUS_E_INVAL;
+      goto cleanup;
    }
+   pAdapter->ls_stats.estLinkSpeed = linkspeed_info->estLinkSpeed;
 
-   /* either we never sent a request, we sent a request and received a
-     response or we sent a request and timed out.  if we never sent a
-     request or if we sent a request and got a response, we want to
-     clear the magic out of paranoia.  if we timed out there is a
-     race condition such that the callback function could be
-     executing at the same time we are. of primary concern is if the
-     callback function had already verified the "magic" but had not
-     yet set the completion variable when a timeout occurred. we
-     serialize these activities by invalidating the magic while
-     holding a shared spinlock which will cause us to block if the
-     callback is currently executing */
-   spin_lock(&hdd_context_lock);
-   context.magic = 0;
-   spin_unlock(&hdd_context_lock);
-   return VOS_STATUS_SUCCESS;
+cleanup:
+   /*
+    * either we never sent a request, we sent a request and
+    * received a response or we sent a request and timed out.
+    * regardless we are done with the request.
+    */
+   hdd_request_put(request);
+   return status;
 }
 
 
@@ -5722,6 +5753,11 @@
 	return ret;
 }
 
+struct peer_rssi_priv {
+	eHalStatus status;
+	struct sir_peer_sta_info peer_sta_info;
+};
+
 /**
  * hdd_get_rssi_cb() - get station's rssi callback
  * @sta_rssi: pointer of rssi information
@@ -5733,83 +5769,47 @@
  */
 void hdd_get_rssi_cb(struct sir_rssi_resp *sta_rssi, void *context)
 {
-	struct statsContext *get_rssi_context;
+	struct hdd_request *request;
+	struct peer_rssi_priv *priv;
 	struct sir_rssi_info *rssi_info;
 	uint8_t peer_num;
-	int i;
-	int buf = 0;
-	int length = 0;
-	char *rssi_info_output;
-	union iwreq_data *wrqu;
 
-	if ((NULL == sta_rssi) || (NULL == context)) {
-
+	request = hdd_request_get(context);
+	if (!request) {
 		hddLog(VOS_TRACE_LEVEL_ERROR,
-			"%s: Bad param, sta_rssi [%p] context [%p]",
-			__func__, sta_rssi, context);
+		       "Obsolete request %pK", context);
+		return;
+	}
+	priv = hdd_request_priv(request);
+	if (!sta_rssi) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s: Bad param, sta_rssi [%pK] context [%pK]",
+		       __func__, sta_rssi, context);
+		priv->status = eHAL_STATUS_INVALID_PARAMETER;
+		hdd_request_complete(request);
+		hdd_request_put(request);
+
 		return;
 	}
 
-	spin_lock(&hdd_context_lock);
-	/*
-	 * there is a race condition that exists between this callback
-	 * function and the caller since the caller could time out either
-	 * before or while this code is executing.  we use a spinlock to
-	 * serialize these actions
-	 */
-	get_rssi_context = context;
-	if (RSSI_CONTEXT_MAGIC !=
-			get_rssi_context->magic) {
-
-		/*
-		 * the caller presumably timed out so there is nothing
-		 * we can do
-		 */
-		spin_unlock(&hdd_context_lock);
-		hddLog(VOS_TRACE_LEVEL_WARN,
-			"%s: Invalid context, magic [%08x]",
-			__func__,
-			get_rssi_context->magic);
-		return;
-	}
-
-	rssi_info_output = get_rssi_context->extra;
-	wrqu = get_rssi_context->wrqu;
 	peer_num = sta_rssi->count;
 	rssi_info = sta_rssi->info;
-	get_rssi_context->magic = 0;
 
-	hddLog(LOG1, "%s : %d peers", __func__, peer_num);
+	hddLog(VOS_TRACE_LEVEL_INFO,
+	       "%d peers", peer_num);
 
-
-	/*
-	 * The iwpriv tool default print is before mac addr and rssi.
-	 * Add '\n' before first rssi item to align the frist rssi item
-	 * with others
-	 *
-	 * wlan     getRSSI:
-	 * [macaddr1] [rssi1]
-	 * [macaddr2] [rssi2]
-	 * [macaddr3] [rssi3]
-	 */
-	length = scnprintf((rssi_info_output), WE_MAX_STR_LEN, "\n");
-	for (i = 0; i < peer_num; i++) {
-		buf = scnprintf
-			(
-			(rssi_info_output + length), WE_MAX_STR_LEN - length,
-			"[%pM] [%d]\n",
-			rssi_info[i].peer_macaddr,
-			rssi_info[i].rssi
-			);
-			length += buf;
+	if (peer_num > MAX_PEER_STA) {
+		hddLog(VOS_TRACE_LEVEL_WARN,
+		       "Exceed max peer sta to handle one time %d", peer_num);
+		peer_num = MAX_PEER_STA;
 	}
-	wrqu->data.length = length + 1;
+	vos_mem_copy(priv->peer_sta_info.info, rssi_info,
+		     peer_num * sizeof(*rssi_info));
+	priv->peer_sta_info.sta_num = peer_num;
+	priv->status = eHAL_STATUS_SUCCESS;
+	hdd_request_complete(request);
+	hdd_request_put(request);
 
-	/* notify the caller */
-	complete(&get_rssi_context->completion);
-
-	/* serialization is complete */
-	spin_unlock(&hdd_context_lock);
 }
 
 /**
@@ -5824,64 +5824,69 @@
  * Return: 0 on success, otherwise error value
  */
 static int  wlan_hdd_get_peer_rssi(hdd_adapter_t *adapter,
-					v_MACADDR_t macaddress,
-					char *extra,
-					union iwreq_data *wrqu)
+				   v_MACADDR_t macaddress,
+				   struct sir_peer_sta_info *peer_sta_info)
 {
 	eHalStatus hstatus;
+	void *cookie;
 	int ret;
-	struct statsContext context;
 	struct sir_rssi_req rssi_req;
+	struct hdd_request *request;
+	struct peer_rssi_priv *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
 
-	if (NULL == adapter) {
-		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL",
-			__func__);
+	if (!adapter || !peer_sta_info) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "adapter [%pK], peer_sta_info[%pK]",
+		       adapter, peer_sta_info);
 		return -EFAULT;
 	}
 
-	init_completion(&context.completion);
-	context.magic = RSSI_CONTEXT_MAGIC;
-	context.extra = extra;
-	context.wrqu = wrqu;
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "Request allocation failure");
+		return -ENOMEM;
+	}
+
+	cookie = hdd_request_cookie(request);
+	priv = hdd_request_priv(request);
+	priv->status = eHAL_STATUS_FAILURE;
 
 	vos_mem_copy(&(rssi_req.peer_macaddr), &macaddress,
 				VOS_MAC_ADDR_SIZE);
 	rssi_req.sessionId = adapter->sessionId;
+
 	hstatus = sme_get_rssi(WLAN_HDD_GET_HAL_CTX(adapter),
-				rssi_req,
-				&context,
-				hdd_get_rssi_cb);
+				    rssi_req,
+				    cookie,
+				    hdd_get_rssi_cb);
 	if (eHAL_STATUS_SUCCESS != hstatus) {
 		hddLog(VOS_TRACE_LEVEL_ERROR,
-			"%s: Unable to retrieve statistics for rssi",
-			__func__);
+		       "%s: Unable to retrieve statistics for rssi",
+		       __func__);
 		ret = -EFAULT;
 	} else {
-		if (!wait_for_completion_timeout(&context.completion,
-				msecs_to_jiffies(WLAN_WAIT_TIME_STATS))) {
+		ret = hdd_request_wait_for_response(request);
+		if (ret) {
 			hddLog(VOS_TRACE_LEVEL_ERROR,
-				"%s: SME timed out while retrieving rssi",
-				__func__);
+			       "SME timed out while retrieving rssi");
 			ret = -EFAULT;
-		} else
+		} else if (priv->status !=  eHAL_STATUS_SUCCESS) {
+			hddLog(VOS_TRACE_LEVEL_ERROR,
+			       "request failed %d", priv->status);
+			ret = -EFAULT;
+		} else {
+			*peer_sta_info = priv->peer_sta_info;
 			ret = 0;
+		}
 	}
-	/*
-	 * either we never sent a request, we sent a request and received a
-	 * response or we sent a request and timed out.  if we never sent a
-	 * request or if we sent a request and got a response, we want to
-	 * clear the magic out of paranoia.  if we timed out there is a
-	 * race condition such that the callback function could be
-	 * executing at the same time we are. of primary concern is if the
-	 * callback function had already verified the "magic" but had not
-	 * yet set the completion variable when a timeout occurred. we
-	 * serialize these activities by invalidating the magic while
-	 * holding a shared spinlock which will cause us to block if the
-	 * callback is currently executing
-	 */
-	spin_lock(&hdd_context_lock);
-	context.magic = 0;
-	spin_unlock(&hdd_context_lock);
+
+	hdd_request_put(request);
+
 	return ret;
 }
 
@@ -5907,6 +5912,12 @@
 	v_MACADDR_t macaddress = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
 	VOS_STATUS status = VOS_STATUS_E_FAILURE;
 	int ret;
+	char *rssi_info_output = extra;
+	struct sir_peer_sta_info peer_sta_info;
+	struct sir_rssi_info *rssi_info;
+	int i;
+	int buf;
+	int length;
 
 	ENTER();
 
@@ -5916,7 +5927,7 @@
 		return ret;
 
 	hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d",
-			__func__, wrqu->data.length);
+	       __func__, wrqu->data.length);
 
 	if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
 
@@ -5924,24 +5935,56 @@
 			wrqu->data.pointer, MAC_ADDRESS_STR_LEN - 1)) {
 
 			hddLog(LOG1, "%s: failed to copy data to user buffer",
-					__func__);
+			       __func__);
 			return -EFAULT;
 		}
 
 		macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0';
 		hddLog(LOG1, "%s, %s",
-				__func__, macaddrarray);
+		       __func__, macaddrarray);
 
 		status = hdd_string_to_hex(macaddrarray,
 				MAC_ADDRESS_STR_LEN, macaddress.bytes );
 
 		if (!VOS_IS_STATUS_SUCCESS(status)) {
 			hddLog(VOS_TRACE_LEVEL_ERROR,
-				FL("String to Hex conversion Failed"));
+			       FL("String to Hex conversion Failed"));
 		}
 	}
 
-	return wlan_hdd_get_peer_rssi(adapter, macaddress, extra, wrqu);
+	vos_mem_zero(&peer_sta_info, sizeof(peer_sta_info));
+	ret = wlan_hdd_get_peer_rssi(adapter, macaddress, &peer_sta_info);
+	if (ret) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "Unable to retrieve peer rssi: %d", ret);
+		return ret;
+	}
+
+	/*
+	 * The iwpriv tool default print is before mac addr and rssi.
+	 * Add '\n' before first rssi item to align the frist rssi item
+	 * with others
+	 *
+	 * wlan     getRSSI:
+	 * [macaddr1] [rssi1]
+	 * [macaddr2] [rssi2]
+	 * [macaddr3] [rssi3]
+	 */
+	length = scnprintf((rssi_info_output), WE_MAX_STR_LEN, "\n");
+	rssi_info = &peer_sta_info.info[0];
+	for (i = 0; i < peer_sta_info.sta_num; i++) {
+		buf = scnprintf((rssi_info_output + length),
+				WE_MAX_STR_LEN - length,
+				"[%pM] [%d]\n",
+				rssi_info[i].peer_macaddr,
+				rssi_info[i].rssi);
+		length += buf;
+	}
+	wrqu->data.length = length + 1;
+
+	EXIT();
+
+	return 0;
 }
 
 /**
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c
index 58db245..b8a258f 100755
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c
@@ -75,6 +75,7 @@
 #include <wlan_hdd_wowl.h>
 #include <wlan_hdd_misc.h>
 #include <wlan_hdd_wext.h>
+#include "wlan_hdd_request_manager.h"
 #include "wlan_hdd_trace.h"
 #include "vos_types.h"
 #include "vos_trace.h"
@@ -3634,87 +3635,33 @@
 	return;
 }
 
-static void hdd_GetLink_statusCB(v_U8_t status, void *pContext)
-{
-   struct statsContext *pLinkContext;
-   hdd_adapter_t *pAdapter;
-
-   if (NULL == pContext) {
-      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Bad pContext [%p]",
-              __func__, pContext);
-      return;
-   }
-
-   pLinkContext = pContext;
-   pAdapter     = pLinkContext->pAdapter;
-
-   spin_lock(&hdd_context_lock);
-
-   if ((NULL == pAdapter) || (LINK_STATUS_MAGIC != pLinkContext->magic)) {
-      /* the caller presumably timed out so there is nothing we can do */
-      spin_unlock(&hdd_context_lock);
-      hddLog(VOS_TRACE_LEVEL_WARN,
-             "%s: Invalid context, pAdapter [%p] magic [%08x]",
-              __func__, pAdapter, pLinkContext->magic);
-      return;
-   }
-
-   /* context is valid so caller is still waiting */
-
-   /* paranoia: invalidate the magic */
-   pLinkContext->magic = 0;
-
-   /* copy over the status */
-   pAdapter->linkStatus = status;
-
-   /* notify the caller */
-   complete(&pLinkContext->completion);
-
-   /* serialization is complete */
-   spin_unlock(&hdd_context_lock);
-}
+struct fw_state {
+	bool fw_active;
+};
 
 /**
  * hdd_get_fw_state_cb() - validates the context and notifies the caller
- * @callback_context: caller context
+ * @cookie: cookie from the request contest
  *
  * Return: none
  */
-static void hdd_get_fw_state_cb(void *callback_context)
+static void hdd_get_fw_state_cb(void *cookie)
 {
-	struct statsContext *context;
-	hdd_adapter_t *adapter;
+	struct hdd_request *request;
+	struct fw_state *priv;
 
-	if (NULL == callback_context) {
-		hddLog(LOGE, FL("Bad pContext [%p]"), callback_context);
+	request = hdd_request_get(cookie);
+	if (!request) {
+		hddLog(LOGE, FL("Obsolete request"));
 		return;
 	}
 
-	context = callback_context;
-	adapter = context->pAdapter;
+	priv = hdd_request_priv(request);
 
-	spin_lock(&hdd_context_lock);
+	priv->fw_active = true;
 
-	if ((NULL == adapter) || (FW_STATUS_MAGIC != context->magic)) {
-		/* the caller presumably timed out so there is
-		 * nothing we can do
-		 */
-		spin_unlock(&hdd_context_lock);
-		hddLog(LOGE, FL("Invalid context, Adapter [%p] magic [%08x]"),
-			adapter, context->magic);
-		return;
-	}
-
-	/* context is valid so caller is still waiting */
-
-	/* paranoia: invalidate the magic */
-	context->magic = 0;
-
-	/* notify the caller */
-	complete(&context->completion);
-
-	/* serialization is complete */
-	spin_unlock(&hdd_context_lock);
+	hdd_request_complete(request);
+	hdd_request_put(request);
 }
 
 /**
@@ -3731,42 +3678,73 @@
 bool wlan_hdd_get_fw_state(hdd_adapter_t *adapter)
 {
 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	struct statsContext context;
-	eHalStatus hstatus = eHAL_STATUS_SUCCESS;
-	unsigned long rc;
-	bool fw_active = true;
+	eHalStatus hstatus;
+	int ret;
+	void *cookie;
+	struct fw_state *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_LINK_STATUS,
+	};
+	struct hdd_request *request;
+	bool fw_active;
 
 	if (wlan_hdd_validate_context(hdd_ctx) != 0)
 		return false;
 
-	init_completion(&context.completion);
-	context.pAdapter = adapter;
-	context.magic = FW_STATUS_MAGIC;
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(LOGE, FL("Request allocation failure"));
+		return false;
+	}
+
+	cookie = hdd_request_cookie(request);
+
 	hstatus = sme_get_fw_state(WLAN_HDD_GET_HAL_CTX(adapter),
 				   hdd_get_fw_state_cb,
-				   &context);
-
+				   cookie);
 	if (eHAL_STATUS_SUCCESS != hstatus) {
 		hddLog(LOGE, FL("Unable to retrieve firmware status"));
 		fw_active = false;
 	} else {
 		/* request is sent -- wait for the response */
-		rc = wait_for_completion_timeout(&context.completion,
-			msecs_to_jiffies(WLAN_WAIT_TIME_LINK_STATUS));
-		if (!rc) {
+		ret = hdd_request_wait_for_response(request);
+		if (ret) {
 			hddLog(LOGE,
 				FL("SME timed out while retrieving firmware status"));
 			fw_active = false;
+		} else {
+			priv = hdd_request_priv(request);
+			fw_active = priv->fw_active;
 		}
 	}
 
-	spin_lock(&hdd_context_lock);
-	context.magic = 0;
-	spin_unlock(&hdd_context_lock);
+	hdd_request_put(request);
 
 	return fw_active;
 }
 
+struct link_status_priv {
+	uint8_t link_status;
+};
+
+static void hdd_get_link_status_cb(uint8_t status, void *context)
+{
+	struct hdd_request *request;
+	struct link_status_priv *priv;
+
+	request = hdd_request_get(context);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
+		return;
+	}
+
+	priv = hdd_request_priv(request);
+	priv->link_status = status;
+	hdd_request_complete(request);
+	hdd_request_put(request);
+}
+
 /**
  * wlan_hdd_get_link_status() - get link status
  * @pAdapter:     pointer to the adapter
@@ -3781,50 +3759,68 @@
  */
 static int wlan_hdd_get_link_status(hdd_adapter_t *pAdapter)
 {
-   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-   struct statsContext context;
-   eHalStatus hstatus;
-   unsigned long rc;
+	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+	eHalStatus hstatus;
+	int ret;
+	void *cookie;
+	struct hdd_request *request;
+	struct link_status_priv *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_LINK_STATUS,
+	};
 
-   if (pHddCtx->isLogpInProgress) {
-       hddLog(LOGW, FL("LOGP in Progress. Ignore!!!"));
-       return 0;
-   }
+	if (pHddCtx->isLogpInProgress) {
+		hddLog(LOGW, FL("LOGP in Progress. Ignore!!!"));
+		return 0;
+	}
 
-   if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
-       /* If not associated, then expected link status return value is 0 */
-       hddLog(LOG1, FL("Not associated!"));
-       return 0;
-   }
+	if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
+	/* If not associated, then expected link status return value is 0 */
+		hddLog(LOG1, FL("Not associated!"));
+		return 0;
+	}
 
-   init_completion(&context.completion);
-   context.pAdapter = pAdapter;
-   context.magic = LINK_STATUS_MAGIC;
-   hstatus = sme_getLinkStatus(WLAN_HDD_GET_HAL_CTX(pAdapter),
-                               hdd_GetLink_statusCB,
-                               &context,
-                               pAdapter->sessionId);
-   if (eHAL_STATUS_SUCCESS != hstatus) {
-       hddLog(VOS_TRACE_LEVEL_ERROR,
-               "%s: Unable to retrieve link status", __func__);
-       /* return a cached value */
-   } else {
-       /* request is sent -- wait for the response */
-       rc = wait_for_completion_timeout(&context.completion,
-                                msecs_to_jiffies(WLAN_WAIT_TIME_LINK_STATUS));
-       if (!rc) {
-          hddLog(VOS_TRACE_LEVEL_ERROR,
-              FL("SME timed out while retrieving link status"));
-      }
-   }
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Request allocation failure",
+				__func__);
+		return 0;
+	}
+	cookie = hdd_request_cookie(request);
 
-   spin_lock(&hdd_context_lock);
-   context.magic = 0;
-   spin_unlock(&hdd_context_lock);
+	hstatus = sme_getLinkStatus(WLAN_HDD_GET_HAL_CTX(pAdapter),
+				hdd_get_link_status_cb,
+				cookie,
+				pAdapter->sessionId);
+	if (eHAL_STATUS_SUCCESS != hstatus) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Unable to retrieve link status", __func__);
+		/* return a cached value */
+	} else {
+		/* request is sent -- wait for the response */
+		ret = hdd_request_wait_for_response(request);
+		if (ret) {
+			hddLog(VOS_TRACE_LEVEL_ERROR,
+			       "%s: SME timed out while retrieving link status",
+			       __func__);
+			/* return a cached value */
+		} else {
+			/* update the adapter with the fresh results */
+			priv = hdd_request_priv(request);
+			pAdapter->linkStatus = priv->link_status;
+		}
+	}
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	hdd_request_put(request);
 
-   /* either callback updated pAdapter stats or it has cached data */
-   return  pAdapter->linkStatus;
+	/* either callback updated adapter stats or it has cached data */
+	return pAdapter->linkStatus;
 }
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
@@ -4296,135 +4292,90 @@
     return VOS_STATUS_SUCCESS;
 }
 
-static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics,
-                               const tANI_U32 staId,
-                               void *pContext )
+struct tsm_priv {
+	tAniTrafStrmMetrics tsm_metrics;
+};
+
+static void hdd_GetTsmStatsCB(tAniTrafStrmMetrics tsmMetrics,
+			      const tANI_U32 staId,
+			      void *pContext)
 {
-   struct statsContext *pStatsContext = NULL;
-   hdd_adapter_t       *pAdapter = NULL;
+	struct hdd_request *request;
+	struct tsm_priv *priv;
 
-   if (NULL == pContext) {
-      hddLog(VOS_TRACE_LEVEL_ERROR,
-             "%s: Bad param, pContext [%p]",
-             __func__, pContext);
-      return;
-   }
-
-   /* there is a race condition that exists between this callback
-      function and the caller since the caller could time out either
-      before or while this code is executing.  we use a spinlock to
-      serialize these actions */
-   spin_lock(&hdd_context_lock);
-
-   pStatsContext = pContext;
-   pAdapter      = pStatsContext->pAdapter;
-   if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
-      /* the caller presumably timed out so there is nothing we can do */
-      spin_unlock(&hdd_context_lock);
-      hddLog(VOS_TRACE_LEVEL_WARN,
-             "%s: Invalid context, pAdapter [%p] magic [%08x]",
-              __func__, pAdapter, pStatsContext->magic);
-      return;
-   }
-
-   /* context is valid so caller is still waiting */
-
-   /* paranoia: invalidate the magic */
-   pStatsContext->magic = 0;
-
-   /* copy over the tsm stats */
-   pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
-   vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
-                 tsmMetrics.UplinkPktQueueDlyHist,
-                 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
-                 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
-   pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
-   pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
-   pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
-   pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
-   pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
-
-   /* notify the caller */
-   complete(&pStatsContext->completion);
-
-   /* serialization is complete */
-   spin_unlock(&hdd_context_lock);
+	ENTER();
+	request = hdd_request_get(pContext);
+	if (!request) {
+		hddLog(LOGE, FL("Obsolete request"));
+		return;
+	}
+	priv = hdd_request_priv(request);
+	priv->tsm_metrics = tsmMetrics;
+	hdd_request_complete(request);
+	hdd_request_put(request);
+	EXIT();
 }
 
 static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter,
-                                    const tANI_U8 tid,
-                                    tAniTrafStrmMetrics* pTsmMetrics)
+				    const tANI_U8 tid,
+				    tAniTrafStrmMetrics* pTsmMetrics)
 {
-   hdd_station_ctx_t *pHddStaCtx = NULL;
-   eHalStatus         hstatus;
-   VOS_STATUS         vstatus = VOS_STATUS_SUCCESS;
-   unsigned long      rc;
-   struct statsContext context;
-   hdd_context_t     *pHddCtx = NULL;
+	hdd_station_ctx_t  *pHddStaCtx = NULL;
+	eHalStatus          hstatus;
+	VOS_STATUS          vstatus = VOS_STATUS_SUCCESS;
+	int                 ret;
+	hdd_context_t      *pHddCtx = NULL;
+	void               *cookie;
+	struct hdd_request *request;
+	struct tsm_priv    *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
 
-   if (NULL == pAdapter) {
-       hddLog(LOGE, FL("pAdapter is NULL"));
-       return VOS_STATUS_E_FAULT;
-   }
+	if (!pAdapter) {
+		hddLog(LOGE, FL("pAdapter is NULL"));
+		return VOS_STATUS_E_FAULT;
+	}
 
-   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-   pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 
-   /* we are connected prepare our callback context */
-   init_completion(&context.completion);
-   context.pAdapter = pAdapter;
-   context.magic = STATS_CONTEXT_MAGIC;
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(LOGE, FL("Request allocation failure"));
+		return VOS_STATUS_E_NOMEM;
+	}
+	cookie = hdd_request_cookie(request);
 
-   /* query tsm stats */
-   hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
-                         pHddStaCtx->conn_info.staId[ 0 ],
-                         pHddStaCtx->conn_info.bssId,
-                         &context, pHddCtx->pvosContext, tid);
-   if (eHAL_STATUS_SUCCESS != hstatus) {
-      hddLog(VOS_TRACE_LEVEL_ERROR,
-             "%s: Unable to retrieve statistics",
-             __func__);
-      vstatus = VOS_STATUS_E_FAULT;
-   } else {
-      /* request was sent -- wait for the response */
-      rc = wait_for_completion_timeout(&context.completion,
-                                    msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
-      if (!rc) {
-         hddLog(VOS_TRACE_LEVEL_ERROR,
-                "%s: SME timed out while retrieving statistics",
-                __func__);
-         vstatus = VOS_STATUS_E_TIMEOUT;
-      }
-   }
+	/* query tsm stats */
+	hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
+				  pHddStaCtx->conn_info.staId[ 0 ],
+				  pHddStaCtx->conn_info.bssId,
+				  cookie, pHddCtx->pvosContext, tid);
+	if (eHAL_STATUS_SUCCESS != hstatus) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s: Unable to retrieve tsm statistics",
+		       __func__);
+		vstatus = VOS_STATUS_E_FAULT;
+		goto cleanup;
+	}
 
-   /* either we never sent a request, we sent a request and received a
-      response or we sent a request and timed out.  if we never sent a
-      request or if we sent a request and got a response, we want to
-      clear the magic out of paranoia.  if we timed out there is a
-      race condition such that the callback function could be
-      executing at the same time we are. of primary concern is if the
-      callback function had already verified the "magic" but had not
-      yet set the completion variable when a timeout occurred. we
-      serialize these activities by invalidating the magic while
-      holding a shared spinlock which will cause us to block if the
-      callback is currently executing */
-   spin_lock(&hdd_context_lock);
-   context.magic = 0;
-   spin_unlock(&hdd_context_lock);
+	ret = hdd_request_wait_for_response(request);
+	if (ret) {
+		hddLog(LOGE,
+		       FL("SME timed out while retrieving tsm statistics"));
+		vstatus = VOS_STATUS_E_TIMEOUT;
+		goto cleanup;
+	}
 
-   if (VOS_STATUS_SUCCESS == vstatus) {
-      pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
-      vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
-                   pAdapter->tsmStats.UplinkPktQueueDlyHist,
-                   sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
-                   sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
-      pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
-      pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
-      pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
-      pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
-      pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
-   }
-   return vstatus;
+	priv = hdd_request_priv(request);
+	*pTsmMetrics = priv->tsm_metrics;
+
+cleanup:
+	hdd_request_put(request);
+
+	return vstatus;
 }
 
 /**
@@ -12898,6 +12849,8 @@
 
    hdd_wlan_green_ap_deinit(pHddCtx);
 
+   hdd_request_manager_deinit();
+
    //Close Watchdog
    if (pConfig && pConfig->fIsLogpEnabled)
       vos_watchdog_close(pVosContext);
@@ -14453,6 +14406,7 @@
       goto err_wdclose;
    }
 
+   hdd_request_manager_init();
    hdd_wlan_green_ap_init(pHddCtx);
 
    status = vos_open( &pVosContext, 0);
@@ -15208,6 +15162,7 @@
    vos_nv_close();
 
    hdd_wlan_green_ap_deinit(pHddCtx);
+   hdd_request_manager_deinit();
 
 err_wdclose:
    if(pHddCtx->cfg_ini->fIsLogpEnabled)
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c
index eec9b9e..b48959f 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c
@@ -39,6 +39,7 @@
 #include "wlan_tgt_def_config.h"
 #include "schApi.h"
 #include "wma.h"
+#include "wlan_hdd_request_manager.h"
 
 /* Structure definitions for WLAN_SET_DOT11P_CHANNEL_SCHED */
 #define AIFSN_MIN		(2)
@@ -413,7 +414,7 @@
 					  uint32_t ndl_active_state_list_len)
 {
 	struct sir_ocb_config *ret = 0;
-	uint32_t len;
+	size_t len;
 	void *cursor;
 
 	if (num_channels > CFG_TGT_NUM_OCB_CHANNELS ||
@@ -456,6 +457,26 @@
 }
 
 /**
+ * hdd_ocb_set_config_priv - private parameter for ocb set config
+ * @status: status of set config
+ */
+struct hdd_ocb_set_config_priv {
+	int status;
+};
+
+/**
+ * enum ocb_channel_config_status - ocb config status
+ * @OCB_CHANNEL_CONFIG_SUCCESS: success
+ * @OCB_CHANNEL_CONFIG_FAIL: failure
+ * @OCB_CHANNEL_CONFIG_STATUS_MAX: place holder, not a real status
+ */
+enum ocb_channel_config_status {
+	OCB_CHANNEL_CONFIG_SUCCESS = 0,
+	OCB_CHANNEL_CONFIG_FAIL,
+	OCB_CHANNEL_CONFIG_STATUS_MAX
+};
+
+/**
  * hdd_ocb_set_config_callback() - OCB set config callback function
  * @context_ptr: OCB call context
  * @response_ptr: Pointer to response structure
@@ -465,46 +486,27 @@
  */
 static void hdd_ocb_set_config_callback(void *context_ptr, void *response_ptr)
 {
-	struct hdd_ocb_ctxt *context = context_ptr;
-	struct sir_ocb_set_config_response *resp = response_ptr;
+	struct hdd_request *hdd_request;
+	struct hdd_ocb_set_config_priv *priv;
+	struct sir_ocb_set_config_response *response = response_ptr;
 
-	if (!context)
+	hdd_request = hdd_request_get(context_ptr);
+	if (!hdd_request) {
+		hddLog(LOGE, FL("Obsolete request"));
 		return;
-
-	if (resp && resp->status)
-		hddLog(LOGE, FL("Operation failed: %d"), resp->status);
-
-	spin_lock(&hdd_context_lock);
-	if (context->magic == HDD_OCB_MAGIC) {
-		hdd_adapter_t *adapter = context->adapter;
-		if (!resp) {
-			context->status = -EINVAL;
-			complete(&context->completion_evt);
-			spin_unlock(&hdd_context_lock);
-			return;
-		}
-
-		context->adapter->ocb_set_config_resp = *resp;
-		spin_unlock(&hdd_context_lock);
-		if (!resp->status) {
-			/*
-			 * OCB set config command successful.
-			 * Open the TX data path
-			 */
-			if (!hdd_ocb_register_sta(adapter)) {
-				netif_carrier_on(adapter->dev);
-				netif_tx_start_all_queues(
-				    adapter->dev);
-			}
-		}
-
-		spin_lock(&hdd_context_lock);
-		if (context->magic == HDD_OCB_MAGIC)
-			complete(&context->completion_evt);
-		spin_unlock(&hdd_context_lock);
-	} else {
-		spin_unlock(&hdd_context_lock);
 	}
+	priv = hdd_request_priv(hdd_request);
+
+	if (response && (response->status != OCB_CHANNEL_CONFIG_SUCCESS))
+		hddLog(LOGE, FL("Operation failed: %d"), response->status);
+
+	if (response && (response->status == OCB_CHANNEL_CONFIG_SUCCESS))
+		priv->status = 0;
+	else
+		priv->status = -EINVAL;
+
+	hdd_request_complete(hdd_request);
+	hdd_request_put(hdd_request);
 }
 
 /**
@@ -519,16 +521,25 @@
 {
 	int rc;
 	eHalStatus halStatus;
-	struct hdd_ocb_ctxt context = {0};
+	void *cookie;
+	struct hdd_request *hdd_request;
+	struct hdd_ocb_set_config_priv *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
+	};
 
 	if (hdd_ocb_validate_config(adapter, config)) {
 		hddLog(LOGE, FL("The configuration is invalid"));
 		return -EINVAL;
 	}
 
-	init_completion(&context.completion_evt);
-	context.adapter = adapter;
-	context.magic = HDD_OCB_MAGIC;
+	hdd_request = hdd_request_alloc(&params);
+	if (!hdd_request) {
+		hddLog(LOGE, FL("Request allocation failure"));
+		return -ENOMEM;
+	}
+	cookie = hdd_request_cookie(hdd_request);
 
 	hddLog(LOG1, FL("Disabling queues"));
 	netif_tx_disable(adapter->dev);
@@ -536,40 +547,41 @@
 
 	/* Call the SME API to set the config */
 	halStatus = sme_ocb_set_config(
-		((hdd_context_t *)adapter->pHddCtx)->hHal, &context,
+		((hdd_context_t *)adapter->pHddCtx)->hHal, cookie,
 		hdd_ocb_set_config_callback, config);
 	if (halStatus != eHAL_STATUS_SUCCESS) {
 		hddLog(LOGE, FL("Error calling SME function."));
 		/* Convert from eHalStatus to errno */
-		return -EINVAL;
-	}
-
-	/* Wait for the function to complete. */
-	rc = wait_for_completion_timeout(&context.completion_evt,
-		msecs_to_jiffies(WLAN_WAIT_TIME_OCB_CMD));
-	if (rc == 0) {
-		rc = -ETIMEDOUT;
-		goto end;
-	}
-	rc = 0;
-
-	if (context.status) {
-		rc = context.status;
-		goto end;
-	}
-
-	if (adapter->ocb_set_config_resp.status) {
 		rc = -EINVAL;
 		goto end;
 	}
 
+	/* Wait for the function to complete. */
+	rc = hdd_request_wait_for_response(hdd_request);
+	if (rc) {
+		hddLog(LOGE, FL("Operation timed out"));
+		goto end;
+	}
+
+	priv = hdd_request_priv(hdd_request);
+	rc = priv->status;
+	if (rc) {
+		hddLog(LOGE, FL("Operation failed: %d"), rc);
+		goto end;
+	}
+
+	/*
+	 * OCB set config command successful.
+	 * Open the TX data path
+	 */
+	if (!hdd_ocb_register_sta(adapter)) {
+		netif_carrier_on(adapter->dev);
+		netif_tx_start_all_queues(adapter->dev);
+	}
+
 	/* fall through */
 end:
-	spin_lock(&hdd_context_lock);
-	context.magic = 0;
-	spin_unlock(&hdd_context_lock);
-	if (rc)
-		hddLog(LOGE, FL("Operation failed: %d"), rc);
+	hdd_request_put(hdd_request);
 	return rc;
 }
 
@@ -1440,6 +1452,16 @@
 }
 
 /**
+ * hdd_ocb_get_tsf_timer_priv - private parameters for get tsf timer
+ * @response: response from SME
+ * @status: status of response
+ */
+struct hdd_ocb_get_tsf_timer_priv {
+	struct sir_ocb_get_tsf_timer_response response;
+	int status;
+};
+
+/**
  * hdd_ocb_get_tsf_timer_callback() - Callback to get TSF command
  * @context_ptr: request context
  * @response_ptr: response data
@@ -1447,23 +1469,25 @@
 static void hdd_ocb_get_tsf_timer_callback(void *context_ptr,
 					   void *response_ptr)
 {
-	struct hdd_ocb_ctxt *context = context_ptr;
+	struct hdd_request *hdd_request;
+	struct hdd_ocb_get_tsf_timer_priv *priv;
 	struct sir_ocb_get_tsf_timer_response *response = response_ptr;
 
-	if (!context)
+	hdd_request = hdd_request_get(context_ptr);
+	if (!hdd_request) {
+		hddLog(LOGE, FL("Obsolete request"));
 		return;
-
-	spin_lock(&hdd_context_lock);
-	if (context->magic == HDD_OCB_MAGIC) {
-		if (response) {
-			context->adapter->ocb_get_tsf_timer_resp = *response;
-			context->status = 0;
-		} else {
-			context->status = -EINVAL;
-		}
-		complete(&context->completion_evt);
 	}
-	spin_unlock(&hdd_context_lock);
+
+	priv = hdd_request_priv(hdd_request);
+	if (response) {
+		priv->response = *response;
+		priv->status = 0;
+	} else {
+		priv->status = -EINVAL;
+	}
+	hdd_request_complete(hdd_request);
+	hdd_request_put(hdd_request);
 }
 
 /**
@@ -1487,7 +1511,13 @@
 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	int rc = -EINVAL;
 	struct sir_ocb_get_tsf_timer request = {0};
-	struct hdd_ocb_ctxt context = {0};
+	void *cookie;
+	struct hdd_request *hdd_request;
+	struct hdd_ocb_get_tsf_timer_priv *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
+	};
 
 	ENTER();
 
@@ -1510,39 +1540,41 @@
 	}
 
 	/* Initialize the callback context */
-	init_completion(&context.completion_evt);
-	context.adapter = adapter;
-	context.magic = HDD_OCB_MAGIC;
+	hdd_request = hdd_request_alloc(&params);
+	if (!hdd_request) {
+		hddLog(LOGE, FL("Request allocation failure"));
+		return -ENOMEM;
+	}
+	cookie = hdd_request_cookie(hdd_request);
 
 	request.vdev_id = adapter->sessionId;
 	/* Call the SME function */
-	rc = sme_ocb_get_tsf_timer(hdd_ctx->hHal, &context,
+	rc = sme_ocb_get_tsf_timer(hdd_ctx->hHal, cookie,
 				   hdd_ocb_get_tsf_timer_callback,
 				   &request);
 	if (rc) {
 		hddLog(LOGE, FL("Error calling SME function"));
 		/* Need to convert from eHalStatus to errno. */
-		return -EINVAL;
-	}
-
-	rc = wait_for_completion_timeout(&context.completion_evt,
-		msecs_to_jiffies(WLAN_WAIT_TIME_OCB_CMD));
-	if (rc == 0) {
-		hddLog(LOGE, FL("Operation timed out"));
-		rc = -ETIMEDOUT;
+		rc = -EINVAL;
 		goto end;
 	}
-	rc = 0;
 
-	if (context.status) {
-		hddLog(LOGE, FL("Operation failed: %d"), context.status);
-		rc = context.status;
+	rc = hdd_request_wait_for_response(hdd_request);
+	if (rc) {
+		hddLog(LOGE, FL("Operation timed out"));
+		goto end;
+	}
+
+	priv = hdd_request_priv(hdd_request);
+	rc = priv->status;
+	if (rc) {
+		hddLog(LOGE, FL("Operation failed: %d"), rc);
 		goto end;
 	}
 
 	/* Allocate the buffer for the response. */
 	nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
-		2 * sizeof(uint32_t) + NLMSG_HDRLEN);
+		2 * (NLA_HDRLEN + sizeof(uint32_t)) + NLMSG_HDRLEN);
 
 	if (!nl_resp) {
 		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
@@ -1551,18 +1583,18 @@
 	}
 
 	hddLog(LOGE, FL("Got TSF timer response, high=%d, low=%d"),
-	       adapter->ocb_get_tsf_timer_resp.timer_high,
-	       adapter->ocb_get_tsf_timer_resp.timer_low);
+	       priv->response.timer_high,
+	       priv->response.timer_low);
 
 	/* Populate the response. */
 	rc = nla_put_u32(nl_resp,
 			QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH,
-			adapter->ocb_get_tsf_timer_resp.timer_high);
+			priv->response.timer_high);
 	if (rc)
 		goto end;
 	rc = nla_put_u32(nl_resp,
 			    QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW,
-			    adapter->ocb_get_tsf_timer_resp.timer_low);
+			    priv->response.timer_low);
 	if (rc)
 		goto end;
 
@@ -1575,9 +1607,7 @@
 	}
 
 end:
-	spin_lock(&hdd_context_lock);
-	context.magic = 0;
-	spin_unlock(&hdd_context_lock);
+	hdd_request_put(hdd_request);
 	if (nl_resp)
 		kfree_skb(nl_resp);
 	return rc;
@@ -1608,52 +1638,74 @@
 }
 
 /**
- * hdd_dcc_get_stats_callback() - Callback to get stats command
+ * hdd_dcc_stats_priv - DCC stats private parameters
+ * @response: response from SME
+ * @status: status of response
+ */
+struct hdd_dcc_stats_priv {
+	struct sir_dcc_get_stats_response *response;
+	int status;
+};
+
+/**
+ * hdd_dcc_get_stats_dealloc() - Callback when put request
  * @context_ptr: request context
+ *
+ * Return: None
+ */
+static void hdd_dcc_get_stats_dealloc(void *context_ptr)
+{
+	struct hdd_dcc_stats_priv *priv = context_ptr;
+
+	if (priv->response) {
+		vos_mem_free(priv->response);
+		priv->response = NULL;
+	}
+}
+
+/**
+ * hdd_dcc_get_stats_callback() - Callback to get stats command
+ * @context: request context
  * @response_ptr: response data
  */
-static void hdd_dcc_get_stats_callback(void *context_ptr, void *response_ptr)
+static void hdd_dcc_get_stats_callback(void *context, void *response_ptr)
 {
-	struct hdd_ocb_ctxt *context = context_ptr;
+	struct hdd_dcc_stats_priv *priv;
 	struct sir_dcc_get_stats_response *response = response_ptr;
 	struct sir_dcc_get_stats_response *hdd_resp;
+	struct hdd_request *request;
 
-	if (!context)
+	request = hdd_request_get(context);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
 		return;
-
-	spin_lock(&hdd_context_lock);
-	if (context->magic == HDD_OCB_MAGIC) {
-		if (response) {
-			/*
-			 * If the response is hanging around from the previous
-			 * request, delete it
-			 */
-			if (context->adapter->dcc_get_stats_resp) {
-				vos_mem_free(
-				    context->adapter->dcc_get_stats_resp);
-			}
-			context->adapter->dcc_get_stats_resp =
-				vos_mem_malloc(sizeof(
-				    *context->adapter->dcc_get_stats_resp) +
-				    response->channel_stats_array_len);
-			if (context->adapter->dcc_get_stats_resp) {
-				hdd_resp = context->adapter->dcc_get_stats_resp;
-				*hdd_resp = *response;
-				hdd_resp->channel_stats_array =
-					(void *)hdd_resp + sizeof(*hdd_resp);
-				vos_mem_copy(hdd_resp->channel_stats_array,
-					     response->channel_stats_array,
-					     response->channel_stats_array_len);
-				context->status = 0;
-			} else {
-				context->status = -ENOMEM;
-			}
-		} else {
-			context->status = -EINVAL;
-		}
-		complete(&context->completion_evt);
 	}
-	spin_unlock(&hdd_context_lock);
+
+	priv = hdd_request_priv(request);
+
+	priv->response = vos_mem_malloc(sizeof(*response) +
+					response->channel_stats_array_len);
+	if (!priv->response) {
+		priv->status = -ENOMEM;
+		goto end;
+	}
+
+	if (response) {
+		hdd_resp = priv->response;
+		*hdd_resp = *response;
+		hdd_resp->channel_stats_array = (uint8_t *)hdd_resp +
+						sizeof(*hdd_resp);
+		vos_mem_copy(hdd_resp->channel_stats_array,
+			     response->channel_stats_array,
+			     response->channel_stats_array_len);
+		priv->status = 0;
+	} else {
+		priv->status = -EINVAL;
+	}
+
+end:
+	hdd_request_complete(request);
+	hdd_request_put(request);
 }
 
 /**
@@ -1680,7 +1732,15 @@
 	struct sk_buff *nl_resp = 0;
 	int rc = -EINVAL;
 	struct sir_dcc_get_stats request = {0};
-	struct hdd_ocb_ctxt context = {0};
+	void *cookie;
+	struct hdd_request *hdd_request;
+	struct sir_dcc_get_stats_response *response;
+	struct hdd_dcc_stats_priv *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
+		.dealloc = hdd_dcc_get_stats_dealloc,
+	};
 
 	ENTER();
 
@@ -1726,9 +1786,14 @@
 		tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]);
 
 	/* Initialize the callback context */
-	init_completion(&context.completion_evt);
-	context.adapter = adapter;
-	context.magic = HDD_OCB_MAGIC;
+	hdd_request = hdd_request_alloc(&params);
+	if (!hdd_request) {
+		hddLog(LOGE, FL("Request allocation failure"));
+		return -ENOMEM;
+	}
+	priv = hdd_request_priv(hdd_request);
+	priv->response = NULL;
+	cookie = hdd_request_cookie(hdd_request);
 
 	request.vdev_id = adapter->sessionId;
 	request.channel_count = channel_count;
@@ -1736,39 +1801,34 @@
 	request.request_array = request_array;
 
 	/* Call the SME function. */
-	rc = sme_dcc_get_stats(hdd_ctx->hHal, &context,
+	rc = sme_dcc_get_stats(hdd_ctx->hHal, cookie,
 			       hdd_dcc_get_stats_callback,
 			       &request);
 	if (rc) {
 		hddLog(LOGE, FL("Error calling SME function"));
 		/* Need to convert from eHalStatus to errno. */
-		return -EINVAL;
-	}
-
-	/* Wait for the function to complete. */
-	rc = wait_for_completion_timeout(&context.completion_evt,
-				msecs_to_jiffies(WLAN_WAIT_TIME_OCB_CMD));
-	if (rc == 0) {
-		hddLog(LOGE, FL("Operation failed: %d"), rc);
-		rc = -ETIMEDOUT;
-		goto end;
-	}
-
-	if (context.status) {
-		hddLog(LOGE, FL("There was error: %d"), context.status);
-		rc = context.status;
-		goto end;
-	}
-
-	if (!adapter->dcc_get_stats_resp) {
-		hddLog(LOGE, FL("The response was NULL"));
 		rc = -EINVAL;
 		goto end;
 	}
 
+	/* Wait for the function to complete. */
+	rc = hdd_request_wait_for_response(hdd_request);
+	if (rc) {
+		hddLog(LOGE, FL("Operation timed out"));
+		goto end;
+	}
+
+	priv = hdd_request_priv(hdd_request);
+	rc = priv->status;
+	if (rc) {
+		hddLog(LOGE, FL("Operation failed: %d"), rc);
+		goto end;
+	}
+
+	response = priv->response;
 	/* Allocate the buffer for the response. */
 	nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(uint32_t) +
-		adapter->dcc_get_stats_resp->channel_stats_array_len +
+		response->channel_stats_array_len + 2 * NLA_HDRLEN +
 		NLMSG_HDRLEN);
 	if (!nl_resp) {
 		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
@@ -1779,13 +1839,13 @@
 	/* Populate the response. */
 	rc = nla_put_u32(nl_resp,
 			 QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT,
-			 adapter->dcc_get_stats_resp->num_channels);
+			 response->num_channels);
 	if (rc)
 		goto end;
 	rc = nla_put(nl_resp,
 		     QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY,
-		     adapter->dcc_get_stats_resp->channel_stats_array_len,
-		     adapter->dcc_get_stats_resp->channel_stats_array);
+		     response->channel_stats_array_len,
+		     response->channel_stats_array);
 	if (rc)
 		goto end;
 
@@ -1799,11 +1859,7 @@
 
 	/* fall through */
 end:
-	spin_lock(&hdd_context_lock);
-	context.magic = 0;
-	vos_mem_free(adapter->dcc_get_stats_resp);
-	adapter->dcc_get_stats_resp = NULL;
-	spin_unlock(&hdd_context_lock);
+	hdd_request_put(hdd_request);
 	if (nl_resp)
 		kfree_skb(nl_resp);
 	return rc;
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_request_manager.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_request_manager.c
new file mode 100644
index 0000000..2e60791
--- /dev/null
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_request_manager.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include <linux/kernel.h>
+#include "wlan_hdd_request_manager.h"
+#include "wlan_hdd_main.h"
+#include "vos_list.h"
+#include "vos_event.h"
+#include "vos_memory.h"
+#include "adf_os_lock.h"
+
+/* arbitrary value */
+#define MAX_NUM_REQUESTS 20
+
+static bool is_initialized;
+static hdd_list_t requests;
+static adf_os_spinlock_t spinlock;
+static void *cookie;
+
+struct hdd_request {
+	hdd_list_node_t node;
+	void *cookie;
+	uint32_t reference_count;
+	struct hdd_request_params params;
+	vos_event_t completed;
+};
+
+/* must be called with spinlock held */
+static void hdd_request_unlink(struct hdd_request *request)
+{
+	hdd_list_remove_node(&requests, &request->node);
+}
+
+static void hdd_request_destroy(struct hdd_request *request)
+{
+	struct hdd_request_params *params;
+
+	params = &request->params;
+	if (params->dealloc) {
+		void *priv = hdd_request_priv(request);
+
+		params->dealloc(priv);
+	}
+	vos_event_destroy(&request->completed);
+	vos_mem_free(request);
+}
+
+/* must be called with spinlock held */
+static struct hdd_request *hdd_request_find(void *cookie)
+{
+	VOS_STATUS status;
+	struct hdd_request *request;
+	hdd_list_node_t *node;
+
+	status = hdd_list_peek_front(&requests, &node);
+	while (VOS_IS_STATUS_SUCCESS(status)) {
+		request = container_of(node, struct hdd_request, node);
+		if (request->cookie == cookie)
+			return request;
+		status = hdd_list_peek_next(&requests, node, &node);
+	}
+
+	return NULL;
+}
+
+struct hdd_request *hdd_request_alloc(const struct hdd_request_params *params)
+{
+	size_t length;
+	struct hdd_request *request;
+
+	if (!is_initialized) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: invoked when not initialized from %pS",
+			__func__, (void *)_RET_IP_);
+		return NULL;
+	}
+
+	length = sizeof(*request) + params->priv_size;
+	request = vos_mem_malloc(length);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: allocation failed for %pS",
+			__func__, (void *)_RET_IP_);
+		return NULL;
+	}
+	request->reference_count = 1;
+	request->params = *params;
+	vos_event_init(&request->completed);
+	adf_os_spin_lock_bh(&spinlock);
+	request->cookie = cookie++;
+	hdd_list_insert_back(&requests, &request->node);
+	adf_os_spin_unlock_bh(&spinlock);
+	hddLog(VOS_TRACE_LEVEL_DEBUG,
+		"%s: request %pK, cookie %pK, caller %pS",
+		__func__, request, request->cookie, (void *)_RET_IP_);
+
+	return request;
+}
+
+void *hdd_request_priv(struct hdd_request *request)
+{
+	/* private data area immediately follows the struct hdd_request */
+	return request + 1;
+}
+
+void *hdd_request_cookie(struct hdd_request *request)
+{
+	return request->cookie;
+}
+
+struct hdd_request *hdd_request_get(void *cookie)
+{
+	struct hdd_request *request;
+
+	if (!is_initialized) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: invoked when not initialized from %pS",
+			__func__, (void *)_RET_IP_);
+		return NULL;
+	}
+	adf_os_spin_lock_bh(&spinlock);
+	request = hdd_request_find(cookie);
+	if (request)
+		request->reference_count++;
+	adf_os_spin_unlock_bh(&spinlock);
+	hddLog(VOS_TRACE_LEVEL_DEBUG,
+		"%s: cookie %pK, request %pK, caller %pS",
+		__func__, cookie, request, (void *)_RET_IP_);
+
+	return request;
+}
+
+void hdd_request_put(struct hdd_request *request)
+{
+	bool unlinked = false;
+
+	hddLog(VOS_TRACE_LEVEL_DEBUG,
+		"%s: request %pK, cookie %pK, caller %pS",
+		__func__, request, request->cookie, (void *)_RET_IP_);
+	adf_os_spin_lock_bh(&spinlock);
+	request->reference_count--;
+	if (0 == request->reference_count) {
+		hdd_request_unlink(request);
+		unlinked = true;
+	}
+	adf_os_spin_unlock_bh(&spinlock);
+	if (unlinked)
+		hdd_request_destroy(request);
+}
+
+int hdd_request_wait_for_response(struct hdd_request *request)
+{
+	VOS_STATUS status;
+
+	status = vos_wait_single_event(&request->completed,
+				       request->params.timeout_ms);
+
+	return vos_status_to_os_return(status);
+}
+
+void hdd_request_complete(struct hdd_request *request)
+{
+	(void) vos_event_set(&request->completed);
+}
+
+void hdd_request_manager_init(void)
+{
+	hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: %pS", __func__, (void *)_RET_IP_);
+	if (is_initialized)
+		return;
+
+	hdd_list_init(&requests, MAX_NUM_REQUESTS);
+	adf_os_spinlock_init(&spinlock);
+	is_initialized = true;
+}
+
+/*
+ * hdd_request_manager_deinit implementation note:
+ * It is intentional that we do not destroy the list or the spinlock.
+ * This allows threads to still access the infrastructure even when it
+ * has been deinitialized. Since neither lists nor spinlocks consume
+ * resources this does not result in a resource leak.
+ */
+void hdd_request_manager_deinit(void)
+{
+	hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: %pS", __func__, (void *)_RET_IP_);
+	is_initialized = false;
+}
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_request_manager.h b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_request_manager.h
new file mode 100644
index 0000000..357ef2a
--- /dev/null
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_request_manager.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2017-2018 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_REQUEST_MANAGER_H__
+#define __WLAN_HDD_REQUEST_MANAGER_H__
+
+/**
+ * DOC: WLAN HDD REQUEST MANAGER
+ *
+ * Many operations within the wlan driver occur in an asynchronous
+ * manner. Requests are received by HDD via one of the kernel
+ * interfaces (ioctl, nl80211, virtual file system, etc.). The
+ * requests are translated to an internal format and are then passed
+ * to lower layers, usually via SME, for processing. For requests
+ * which require a response, that response comes up from the lower
+ * layers in a separate thread of execution, ultimately resulting in a
+ * call to a callback function that was provided by HDD as part of the
+ * initial request. So a mechanism is needed to synchronize the
+ * request and response. This framework provides that mechanism.
+ *
+ * Once the framework has been initialized, the typical sequence of
+ * events is as follows:
+ *
+ * Request Thread:
+ * 1. Create a &struct hdd_request_params which describes the request.
+ * 2. Call hdd_request_alloc() to allocate a &struct hdd_request.
+ * 3. Call hdd_request_priv() to get a pointer to the private data.
+ * 4. Place any information which must be shared with the Response
+ *    Callback in the private data area.
+ * 5. Call hdd_request_cookie() to get the unique cookie assigned
+ *    to the request.
+ * 6. Call the underlying request handling API, passing the cookie
+ *    as the callback's private context.
+ * 7. Call hdd_request_wait_for_response() to wait for the response
+ *    (or for the request to time out).
+ * 8. Use the return status to see if the request was successful. If
+ *    it was, retrieve any response information from the private
+ *    structure and prepare a response for userspace.
+ * 9. Call hdd_request_put() to relinquish access to the request.
+ * 10. Return status to the caller.
+ *
+ * Response Callback:
+ * 1. Call hdd_request_get() with the provided cookie to see if the
+ *    request structure is still valid.  If it returns %NULL then
+ *    return since this means the request thread has already timed
+ *    out.
+ * 2. Call hdd_request_priv() to get access to the private data area.
+ * 3. Write response data into the private data area.
+ * 4. Call hdd_request_complete() to indicate that the response is
+ *    ready to be processed by the request thread.
+ * 5. Call hdd_request_put() to relinquish the callback function's
+ *    reference to the request.
+ */
+
+/* this is opaque to clients */
+struct hdd_request;
+
+/**
+ * typedef hdd_request_dealloc - Private data deallocation function
+ */
+typedef void (*hdd_request_dealloc)(void *priv);
+
+/**
+ * struct hdd_request_params - HDD request parameters
+ * @priv_size: Size of the private data area required to pass
+ *      information between the request thread and the response callback.
+ * @timeout_ms: The amount of time to wait for a response in milliseconds.
+ * @dealloc: Function to be called when the request is destroyed to
+ *      deallocate any allocations made in the private area of the
+ *      request struct. Can be %NULL if no private allocations are
+ *      made.
+ */
+struct hdd_request_params {
+	uint32_t priv_size;
+	uint32_t timeout_ms;
+	hdd_request_dealloc dealloc;
+};
+
+/**
+ * hdd_request_alloc() - Allocate a request struct
+ * @params: parameter block that specifies the attributes of the
+ *      request
+ *
+ * This function will attempt to allocate a &struct hdd_request with
+ * the specified @params. If successful, the caller can then use
+ * request struct to make an asynchronous request. Once the request is
+ * no longer needed, the reference should be relinquished via a call
+ * to hdd_request_put().
+ *
+ * Return: A pointer to an allocated &struct hdd_request (which also
+ * contains room for the private buffer) if the allocation is
+ * successful, %NULL if the allocation fails.
+ */
+struct hdd_request *hdd_request_alloc(const struct hdd_request_params *params);
+
+/**
+ * hdd_request_priv() - Get pointer to request private data
+ * @request: The request struct that contains the private data
+ *
+ * This function will return a pointer to the private data area that
+ * is part of the request struct. The caller must already have a valid
+ * reference to @request from either hdd_request_alloc() or
+ * hdd_request_get().
+ *
+ * Returns: pointer to the private data area. Note that this pointer
+ * will always be an offset from the input @request pointer and hence
+ * this function will never return %NULL.
+ */
+void *hdd_request_priv(struct hdd_request *request);
+
+/**
+ * hdd_request_cookie() - Get cookie of a request
+ * @request: The request struct associated with the request
+ *
+ * This function will return the unique cookie that has been assigned
+ * to the request. This cookie can subsequently be passed to
+ * hdd_request_get() to retrieve the request.
+ *
+ * Note that the cookie is defined as a void pointer as it is intended
+ * to be passed as an opaque context pointer from HDD to underlying
+ * layers when making a request, and subsequently passed back to HDD
+ * as an opaque pointer in an asynchronous callback.
+ *
+ * Returns: The cookie assigned to the request.
+ */
+void *hdd_request_cookie(struct hdd_request *request);
+
+/**
+ * hdd_request_get() - Get a reference to a request struct
+ * @cookie: The cookie of the request struct that needs to be
+ *      referenced
+ *
+ * This function will use the cookie to determine if the associated
+ * request struct is valid, and if so, will increment the reference
+ * count of the struct. This means the caller is guaranteed that the
+ * request struct is valid and the underlying private data can be
+ * dereferenced.
+ *
+ * Returns: The pointer to the request struct associated with @cookie
+ * if the request is still valid, %NULL if the underlying request
+ * struct is no longer valid.
+ */
+struct hdd_request *hdd_request_get(void *cookie);
+
+/**
+ * hdd_request_put() - Release a reference to a request struct
+ * @request: The request struct that no longer needs to be referenced
+ *
+ * This function will decrement the reference count of the struct, and
+ * will clean up the request if this is the last reference. The caller
+ * must already have a valid reference to @request, either from
+ * hdd_request_alloc() or hdd_request_get().
+ *
+ * Returns: Nothing
+ */
+void hdd_request_put(struct hdd_request *request);
+
+/**
+ * hdd_request_wait_for_response() - Wait for a response
+ * @request: The request struct associated with the request
+ *
+ * This function will wait until either a response is received and
+ * communicated via hdd_request_complete(), or until the request
+ * timeout period expires.
+ *
+ * Returns: 0 if a response was received, -ETIMEDOUT if the response
+ * timed out.
+ */
+int hdd_request_wait_for_response(struct hdd_request *request);
+
+/**
+ * hdd_request_complete() - Complete a request
+ * @request: The request struct associated with the request
+ *
+ * This function is used to indicate that a response has been received
+ * and that any information required by the request thread has been
+ * copied into the private data area of the request struct. This will
+ * unblock any hdd_request_wait_for_response() that is pending on this
+ * @request.
+ *
+ * Returns: Nothing
+ */
+void hdd_request_complete(struct hdd_request *request);
+
+/**
+ * hdd_request_manager_init() - Initialize the HDD Request Manager
+ *
+ * This function must be called during system initialization to
+ * initialize the HDD Request Manager.
+ *
+ * Returns: Nothing
+ */
+void hdd_request_manager_init(void);
+
+/**
+ * hdd_request_manager_deinit() - Deinitialize the HDD Request Manager
+ *
+ * This function must be called during system shutdown to deinitialize
+ * the HDD Request Manager.
+ *
+ * Returns: Nothing
+ */
+void hdd_request_manager_deinit(void);
+
+#endif /* __WLAN_HDD_REQUEST_MANAGER_H__ */
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c
index ab5cc2d..2846027 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c
@@ -112,6 +112,7 @@
 #include "vos_nvitem.h"
 #include "wlan_hdd_nan_datapath.h"
 #include "wlan_hdd_oemdata.h"
+#include "wlan_hdd_request_manager.h"
 
 #define HDD_FINISH_ULA_TIME_OUT         800
 #define HDD_SET_MCBC_FILTERS_TO_FW      1
@@ -1157,278 +1158,253 @@
     return rsnType;
 }
 
-static void hdd_GetRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext )
+struct rssi_priv {
+	v_S7_t rssi;
+};
+
+/**
+ * hdd_get_rssi_cb() - "Get RSSI" callback function
+ * @rssi: Current RSSI of the station
+ * @sta_id: ID of the station
+ * @context: opaque context originally passed to SME.  HDD always passes
+ *	     a cookie for the request context
+ *
+ * Return: None
+ */
+static void hdd_get_rssi_cb(v_S7_t rssi, tANI_U32 sta_id, void *context)
 {
-   struct statsContext *pStatsContext;
-   hdd_adapter_t *pAdapter;
+	struct hdd_request *request;
+	struct rssi_priv *priv;
 
-   if (ioctl_debug)
-   {
-      pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n",
-              __func__, (int)rssi, (int)staId, pContext);
-   }
+	if (ioctl_debug) {
+		pr_info("%s: rssi [%d] sta_id [%d] context [%pK]\n",
+			__func__, (int)rssi, (int)sta_id, context);
+	}
 
-   if (NULL == pContext)
-   {
-      hddLog(VOS_TRACE_LEVEL_ERROR,
-             "%s: Bad param, pContext [%p]",
-             __func__, pContext);
-      return;
-   }
+	request = hdd_request_get(context);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
+		return;
+	}
 
-   pStatsContext = pContext;
-   pAdapter      = pStatsContext->pAdapter;
-
-   /* there is a race condition that exists between this callback
-      function and the caller since the caller could time out either
-      before or while this code is executing.  we use a spinlock to
-      serialize these actions */
-   spin_lock(&hdd_context_lock);
-
-   if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->magic))
-   {
-      /* the caller presumably timed out so there is nothing we can do */
-      spin_unlock(&hdd_context_lock);
-      hddLog(VOS_TRACE_LEVEL_WARN,
-             "%s: Invalid context, pAdapter [%p] magic [%08x]",
-              __func__, pAdapter, pStatsContext->magic);
-      if (ioctl_debug)
-      {
-         pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
-                 __func__, pAdapter, pStatsContext->magic);
-      }
-      return;
-   }
-
-   /* context is valid so caller is still waiting */
-
-   /* paranoia: invalidate the magic */
-   pStatsContext->magic = 0;
-
-   /* copy over the rssi */
-   pAdapter->rssi = rssi;
-
-   if (pAdapter->rssi > 0)
-       pAdapter->rssi = 0;
-   /* notify the caller */
-   complete(&pStatsContext->completion);
-
-   /* serialization is complete */
-   spin_unlock(&hdd_context_lock);
+	priv = hdd_request_priv(request);
+	priv->rssi = rssi;
+	hdd_request_complete(request);
+	hdd_request_put(request);
 }
 
-static void hdd_GetSnrCB(tANI_S8 snr, tANI_U32 staId, void *pContext)
-{
-   struct statsContext *pStatsContext;
-   hdd_adapter_t *pAdapter;
-
-   if (ioctl_debug)
-   {
-      pr_info("%s: snr [%d] STA [%d] pContext [%p]\n",
-              __func__, (int)snr, (int)staId, pContext);
-   }
-
-   if (NULL == pContext)
-   {
-      hddLog(VOS_TRACE_LEVEL_ERROR,
-             "%s: Bad param, pContext [%p]",
-             __func__, pContext);
-      return;
-   }
-
-   pStatsContext = pContext;
-   pAdapter      = pStatsContext->pAdapter;
-
-   /* there is a race condition that exists between this callback
-      function and the caller since the caller could time out either
-      before or while this code is executing.  we use a spinlock to
-      serialize these actions */
-   spin_lock(&hdd_context_lock);
-
-   if ((NULL == pAdapter) || (SNR_CONTEXT_MAGIC != pStatsContext->magic))
-   {
-      /* the caller presumably timed out so there is nothing we can do */
-      spin_unlock(&hdd_context_lock);
-      hddLog(VOS_TRACE_LEVEL_WARN,
-             "%s: Invalid context, pAdapter [%p] magic [%08x]",
-              __func__, pAdapter, pStatsContext->magic);
-      if (ioctl_debug)
-      {
-         pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
-                 __func__, pAdapter, pStatsContext->magic);
-      }
-      return;
-   }
-
-   /* context is valid so caller is still waiting */
-
-   /* paranoia: invalidate the magic */
-   pStatsContext->magic = 0;
-
-   /* copy over the snr */
-   pAdapter->snr = snr;
-
-   /* notify the caller */
-   complete(&pStatsContext->completion);
-
-   /* serialization is complete */
-   spin_unlock(&hdd_context_lock);
-}
-
+/**
+ * wlan_hdd_get_rssi() - Get the current RSSI
+ * @pAdapter: adapter upon which the measurement is requested
+ * @rssi_value: pointer to where the RSSI should be returned
+ *
+ * Return: VOS_STATUS_SUCCESS on success, VOS_STATUS_E_** on error
+ */
 VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value)
 {
-   struct statsContext context;
-   hdd_context_t *pHddCtx;
-   hdd_station_ctx_t *pHddStaCtx;
-   eHalStatus hstatus;
-   unsigned long rc;
+	hdd_context_t *pHddCtx;
+	hdd_station_ctx_t *pHddStaCtx;
+	eHalStatus hstatus;
+	int ret;
+	void *cookie;
+	struct hdd_request *request;
+	struct rssi_priv *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
 
-   if (NULL == pAdapter)
-   {
-       hddLog(VOS_TRACE_LEVEL_WARN,
-              "%s: Invalid context, pAdapter", __func__);
-       return VOS_STATUS_E_FAULT;
-   }
-   if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
-   {
-       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__);
-       /* return a cached value */
-       *rssi_value = pAdapter->rssi;
-       return VOS_STATUS_SUCCESS;
-   }
+	if (NULL == pAdapter) {
+		hddLog(VOS_TRACE_LEVEL_WARN,
+			"%s: Invalid context, pAdapter", __func__);
+		return VOS_STATUS_E_FAULT;
+	}
+	if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
+		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+				"%s:LOGP in Progress. Ignore!!!",__func__);
+		/* return a cached value */
+		*rssi_value = pAdapter->rssi;
+		return VOS_STATUS_SUCCESS;
+	}
 
-   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-   pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 
-   if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
-       hddLog(LOG1, "%s: Not associated, rssi on disconnect %d",
-                    __func__, pAdapter->rssi_on_disconnect);
-       *rssi_value = pAdapter->rssi_on_disconnect;
-       return VOS_STATUS_SUCCESS;
-   }
+	if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
+		hddLog(LOG1, "%s: Not associated, rssi on disconnect %d",
+			__func__, pAdapter->rssi_on_disconnect);
+		*rssi_value = pAdapter->rssi_on_disconnect;
+		return VOS_STATUS_SUCCESS;
+	}
 
-   if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
-   {
-       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-                 "%s: Roaming in progress, return cached RSSI", __func__);
-       *rssi_value = pAdapter->rssi;
-       return VOS_STATUS_SUCCESS;
-   }
+	if (pHddStaCtx->hdd_ReassocScenario) {
+		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+				"%s: Roaming in progress, return cached RSSI",
+				__func__);
+		*rssi_value = pAdapter->rssi;
+		return VOS_STATUS_SUCCESS;
+	}
 
-   init_completion(&context.completion);
-   context.pAdapter = pAdapter;
-   context.magic = RSSI_CONTEXT_MAGIC;
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Request allocation failure, return cached RSSI",
+			__func__);
+		*rssi_value = pAdapter->rssi;
+		return VOS_STATUS_SUCCESS;
+	}
+	cookie = hdd_request_cookie(request);
 
-   hstatus = sme_GetRssi(pHddCtx->hHal, hdd_GetRssiCB,
-                         pHddStaCtx->conn_info.staId[ 0 ],
-                         pHddStaCtx->conn_info.bssId, pAdapter->rssi,
-                         &context, pHddCtx->pvosContext);
-   if (eHAL_STATUS_SUCCESS != hstatus)
-   {
-       hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI",
-              __func__);
-       /* we'll returned a cached value below */
-   }
-   else
-   {
-       /* request was sent -- wait for the response */
-       rc = wait_for_completion_timeout(&context.completion,
-                                    msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
-       if (!rc) {
-          hddLog(VOS_TRACE_LEVEL_ERROR,
-              FL("SME timed out while retrieving RSSI"));
-          /* we'll now returned a cached value below */
-       }
-   }
+	hstatus = sme_GetRssi(pHddCtx->hHal, hdd_get_rssi_cb,
+			      pHddStaCtx->conn_info.staId[0],
+			      pHddStaCtx->conn_info.bssId, pAdapter->rssi,
+			      cookie, pHddCtx->pvosContext);
+	if (eHAL_STATUS_SUCCESS != hstatus) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve RSSI",
+			__func__);
+		/* we'll returned a cached value below */
+	} else {
+		/* request was sent -- wait for the response */
+		ret = hdd_request_wait_for_response(request);
+		if (ret) {
+			hddLog(VOS_TRACE_LEVEL_ERROR,
+				FL("SME timed out while retrieving RSSI"));
+			/* we'll returned a cached value below */
+		} else {
+			/* update the adapter with the fresh results */
+			priv = hdd_request_priv(request);
+			pAdapter->rssi = priv->rssi;
+			if (pAdapter->rssi > 0)
+				pAdapter->rssi = 0;
+		}
+	}
 
-   /* either we never sent a request, we sent a request and received a
-      response or we sent a request and timed out.  if we never sent a
-      request or if we sent a request and got a response, we want to
-      clear the magic out of paranoia.  if we timed out there is a
-      race condition such that the callback function could be
-      executing at the same time we are. of primary concern is if the
-      callback function had already verified the "magic" but had not
-      yet set the completion variable when a timeout occurred. we
-      serialize these activities by invalidating the magic while
-      holding a shared spinlock which will cause us to block if the
-      callback is currently executing */
-   spin_lock(&hdd_context_lock);
-   context.magic = 0;
-   spin_unlock(&hdd_context_lock);
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	hdd_request_put(request);
 
-   *rssi_value = pAdapter->rssi;
+	*rssi_value = pAdapter->rssi;
 
-   return VOS_STATUS_SUCCESS;
+	return VOS_STATUS_SUCCESS;
 }
 
+struct snr_priv {
+	tANI_S8 snr;
+};
+
+/**
+ * hdd_get_snr_cb() - "Get SNR" callback function
+ * @snr: Current SNR of the station
+ * @sta_id: ID of the station
+ * @context: opaque context originally passed to SME.  HDD always passes
+ *	     a cookie for the request context
+ *
+ * Return: None
+ */
+static void hdd_get_snr_cb(tANI_S8 snr, tANI_U32 sta_id, void *context)
+{
+	struct hdd_request *request;
+	struct snr_priv *priv;
+
+	if (ioctl_debug) {
+		pr_info("%s: snr [%d] sta_id [%d] context [%pK]\n",
+			__func__, (int)snr, (int)sta_id, context);
+	}
+
+	request = hdd_request_get(context);
+	if (!request) {
+                hddLog(VOS_TRACE_LEVEL_ERROR,
+                        "%s: Obsolete request", __func__);
+		return;
+	}
+
+	/* propagate response back to requesting thread */
+	priv = hdd_request_priv(request);
+	priv->snr = snr;
+	hdd_request_complete(request);
+	hdd_request_put(request);
+}
+
+/**
+ * wlan_hdd_get_snr() - Get the current SNR
+ * @pAdapter: adapter upon which the measurement is requested
+ * @snr: pointer to where the SNR should be returned
+ *
+ * Return: VOS_STATUS_SUCCESS on success, VOS_STATUS_E_** on error
+ */
 VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr)
 {
-   struct statsContext context;
-   hdd_context_t *pHddCtx;
-   hdd_station_ctx_t *pHddStaCtx;
-   eHalStatus hstatus;
-   unsigned long rc;
-   int valid;
+	hdd_context_t *pHddCtx;
+	hdd_station_ctx_t *pHddStaCtx;
+	eHalStatus hstatus;
+	int valid;
+	int ret;
+	void *cookie;
+	struct hdd_request *request;
+	struct snr_priv *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
 
-   ENTER();
-   if (NULL == pAdapter)
-   {
-       hddLog(VOS_TRACE_LEVEL_ERROR,
-              "%s: Invalid context, pAdapter", __func__);
-       return VOS_STATUS_E_FAULT;
-   }
+	ENTER();
 
-   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-   valid = wlan_hdd_validate_context(pHddCtx);
-   if (0 != valid)
-       return VOS_STATUS_E_FAULT;
+	if (NULL == pAdapter) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Invalid context, pAdapter", __func__);
+		return VOS_STATUS_E_FAULT;
+	}
 
-   pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
 
-   init_completion(&context.completion);
-   context.pAdapter = pAdapter;
-   context.magic = SNR_CONTEXT_MAGIC;
+	valid = wlan_hdd_validate_context(pHddCtx);
+	if (0 != valid)
+		return VOS_STATUS_E_FAULT;
 
-   hstatus = sme_GetSnr(pHddCtx->hHal, hdd_GetSnrCB,
-                         pHddStaCtx->conn_info.staId[ 0 ],
-                         pHddStaCtx->conn_info.bssId,
-                         &context);
-   if (eHAL_STATUS_SUCCESS != hstatus)
-   {
-       hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI",
-              __func__);
-       /* we'll returned a cached value below */
-   }
-   else
-   {
-       /* request was sent -- wait for the response */
-       rc = wait_for_completion_timeout(&context.completion,
-                                    msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
-       if (!rc) {
-          hddLog(VOS_TRACE_LEVEL_ERROR,
-              FL("SME timed out while retrieving SNR"));
-          /* we'll now returned a cached value below */
-       }
-   }
+	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 
-   /* either we never sent a request, we sent a request and received a
-      response or we sent a request and timed out.  if we never sent a
-      request or if we sent a request and got a response, we want to
-      clear the magic out of paranoia.  if we timed out there is a
-      race condition such that the callback function could be
-      executing at the same time we are. of primary concern is if the
-      callback function had already verified the "magic" but had not
-      yet set the completion variable when a timeout occurred. we
-      serialize these activities by invalidating the magic while
-      holding a shared spinlock which will cause us to block if the
-      callback is currently executing */
-   spin_lock(&hdd_context_lock);
-   context.magic = 0;
-   spin_unlock(&hdd_context_lock);
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Request allocation failure", __func__);
+		return VOS_STATUS_E_FAULT;
+	}
+	cookie = hdd_request_cookie(request);
 
-   *snr = pAdapter->snr;
-   EXIT();
-   return VOS_STATUS_SUCCESS;
+	hstatus = sme_GetSnr(pHddCtx->hHal, hdd_get_snr_cb,
+			     pHddStaCtx->conn_info.staId[0],
+			     pHddStaCtx->conn_info.bssId, cookie);
+	if (eHAL_STATUS_SUCCESS != hstatus) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Unable to retrieve SNR", __func__);
+		/* we'll returned a cached value below */
+	} else {
+		/* request was sent -- wait for the response */
+		ret = hdd_request_wait_for_response(request);
+		if (ret) {
+			hddLog(VOS_TRACE_LEVEL_ERROR,
+				FL("SME timed out while retrieving SNR"));
+			/* we'll now returned a cached value below */
+		} else {
+			/* update the adapter with the fresh results */
+			priv = hdd_request_priv(request);
+			pAdapter->snr = priv->snr;
+		}
+	}
+
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	hdd_request_put(request);
+
+	*snr = pAdapter->snr;
+	EXIT();
+	return VOS_STATUS_SUCCESS;
 }
 
 void hdd_StatisticsCB( void *pStats, void *pContext )
@@ -3564,53 +3540,25 @@
 	return ret;
 }
 
-/* Callback function registered with PMC to know status of PMC request */
-static void iw_power_callback_fn (void *pContext, eHalStatus status)
+/**
+ * iw_power_callback_func() - Callback function registered with PMC
+ * @context: cookie originally registered with PMC
+ * @status: status code indicated by PMC state machine
+ *
+ * Return: None
+ */
+static void iw_power_callback_func(void *context, eHalStatus status)
 {
-   struct statsContext *pStatsContext;
+	struct hdd_request *request = hdd_request_get(context);
 
-   if (NULL == pContext)
-   {
-       hddLog(VOS_TRACE_LEVEL_ERROR,
-            "%s: Bad param, pContext [%p]",
-              __func__, pContext);
-       return;
-   }
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s: Obsolete request", __func__);
+		return;
+	}
 
-   pStatsContext = (struct statsContext *)pContext;
-
-   /* there is a race condition that exists between this callback
-      function and the caller since the caller could time out either
-      before or while this code is executing.  we use a spinlock to
-      serialize these actions */
-   spin_lock(&hdd_context_lock);
-
-   if (POWER_CONTEXT_MAGIC != pStatsContext->magic)
-   {
-       /* the caller presumably timed out so there is nothing we can do */
-       spin_unlock(&hdd_context_lock);
-       hddLog(VOS_TRACE_LEVEL_WARN,
-              "%s: Invalid context, magic [%08x]",
-              __func__, pStatsContext->magic);
-
-       if (ioctl_debug)
-       {
-           pr_info("%s: Invalid context, magic [%08x]\n",
-                   __func__, pStatsContext->magic);
-       }
-       return;
-  }
-
-  /* context is valid so caller is still waiting */
-
-  /* paranoia: invalidate the magic */
-  pStatsContext->magic = 0;
-
-  /* notify the caller */
-  complete(&pStatsContext->completion);
-
-  /* serialization is complete */
-  spin_unlock(&hdd_context_lock);
+	hdd_request_complete(request);
+	hdd_request_put(request);
 }
 
 /* Callback function for tx per hit */
@@ -3630,317 +3578,246 @@
     wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, tx_fail);
 }
 
-void hdd_GetClassA_statisticsCB(void *pStats, void *pContext)
+struct class_a_stats {
+	tCsrGlobalClassAStatsInfo class_a_stats;
+};
+
+/**
+ * hdd_get_class_a_statistics_cb() - Get Class A stats callback function
+ * @stats: pointer to Class A stats
+ * @context: user context originally registered with SME (always the
+ *	     cookie from the request context)
+ *
+ * Return: None
+ */
+static void hdd_get_class_a_statistics_cb(void *stats, void *context)
 {
-   struct statsContext *pStatsContext;
-   tCsrGlobalClassAStatsInfo *pClassAStats;
-   hdd_adapter_t *pAdapter;
+	struct hdd_request *request;
+	struct class_a_stats *priv;
+	tCsrGlobalClassAStatsInfo *returned_stats;
 
-   if (ioctl_debug)
-   {
-      pr_info("%s: pStats [%p] pContext [%p]\n",
-              __func__, pStats, pContext);
-   }
+	ENTER();
+	if (ioctl_debug) {
+		pr_info("%s: stats [%pK], context [%pK]\n",
+			__func__, stats, context);
+	}
 
-   if ((NULL == pStats) || (NULL == pContext))
-   {
-      hddLog(VOS_TRACE_LEVEL_ERROR,
-             "%s: Bad param, pStats [%p] pContext [%p]",
-              __func__, pStats, pContext);
-      return;
-   }
+	if (NULL == stats) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Bad param, stats [%pK]", __func__, stats);
+		return;
+	}
 
-   pClassAStats  = pStats;
-   pStatsContext = pContext;
-   pAdapter      = pStatsContext->pAdapter;
+	request = hdd_request_get(context);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
+		return;
+	}
 
-   /* there is a race condition that exists between this callback
-      function and the caller since the caller could time out either
-      before or while this code is executing.  we use a spinlock to
-      serialize these actions */
-   spin_lock(&hdd_context_lock);
-
-   if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
-   {
-      /* the caller presumably timed out so there is nothing we can do */
-      spin_unlock(&hdd_context_lock);
-      hddLog(VOS_TRACE_LEVEL_WARN,
-             "%s: Invalid context, pAdapter [%p] magic [%08x]",
-              __func__, pAdapter, pStatsContext->magic);
-      if (ioctl_debug)
-      {
-         pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
-                 __func__, pAdapter, pStatsContext->magic);
-      }
-      return;
-   }
-
-   /* context is valid so caller is still waiting */
-
-   /* paranoia: invalidate the magic */
-   pStatsContext->magic = 0;
-
-   /* copy over the stats. do so as a struct copy */
-   pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
-
-   /* notify the caller */
-   complete(&pStatsContext->completion);
-
-   /* serialization is complete */
-   spin_unlock(&hdd_context_lock);
+	returned_stats = stats;
+	priv = hdd_request_priv(request);
+	priv->class_a_stats = *returned_stats;
+	hdd_request_complete(request);
+	hdd_request_put(request);
+	EXIT();
 }
 
-void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext)
+/**
+ * wlan_hdd_get_classAstats() - Get Class A statistics
+ * @pAdapter: adapter for which statistics are desired
+ *
+ * Return: VOS_STATUS_SUCCESS if adapter's Class A statistics were updated
+ */
+VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter)
 {
-   struct linkspeedContext *pLinkSpeedContext;
-   hdd_adapter_t *pAdapter;
+	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+	eHalStatus hstatus;
+	int ret;
+	void *cookie;
+	struct hdd_request *request;
+	struct class_a_stats *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
 
-   if ((NULL == pLinkSpeed) || (NULL == pContext))
-   {
-      hddLog(VOS_TRACE_LEVEL_ERROR,
-             "%s: Bad param, pLinkSpeed [%p] pContext [%p]",
-             __func__, pLinkSpeed, pContext);
-      return;
-   }
-   spin_lock(&hdd_context_lock);
-   pLinkSpeedContext = pContext;
-   pAdapter      = pLinkSpeedContext->pAdapter;
+	if (NULL == pAdapter) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
+		return VOS_STATUS_E_FAULT;
+	}
+	if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
+		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+			  "%s:LOGP in Progress. Ignore!!!",__func__);
+		return VOS_STATUS_SUCCESS;
+	}
 
-   /* there is a race condition that exists between this callback
-      function and the caller since the caller could time out either
-      before or while this code is executing.  we use a spinlock to
-      serialize these actions */
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Request allocation failure", __func__);
+		return VOS_STATUS_E_NOMEM;
+	}
+	cookie = hdd_request_cookie(request);
 
-   if ((NULL == pAdapter) || (LINK_CONTEXT_MAGIC != pLinkSpeedContext->magic))
-   {
-       /* the caller presumably timed out so there is nothing we can do */
-      spin_unlock(&hdd_context_lock);
-      hddLog(VOS_TRACE_LEVEL_WARN,
-             "%s: Invalid context, pAdapter [%p] magic [%08x]",
-              __func__, pAdapter, pLinkSpeedContext->magic);
-      if (ioctl_debug)
-      {
-         pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
-                 __func__, pAdapter, pLinkSpeedContext->magic);
-      }
-      return;
-   }
-   /* context is valid so caller is still waiting */
+	/* query only for Class A statistics (which include link speed) */
+	hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
+				    eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
+				    hdd_get_class_a_statistics_cb,
+				    0, /* not periodic */
+				    FALSE, /* non-cached results */
+				    pHddStaCtx->conn_info.staId[0],
+				    cookie, pAdapter->sessionId);
+	if (eHAL_STATUS_SUCCESS != hstatus) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Unable to retrieve Class A statistics",
+			__func__);
+		goto return_cached_results;
+	}
 
-   /* paranoia: invalidate the magic */
-   pLinkSpeedContext->magic = 0;
+	/* request was sent -- wait for the response */
+	ret = hdd_request_wait_for_response(request);
+	if (ret) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       FL("SME timed out while retrieving Class A statistics"));
+		goto return_cached_results;
+	}
 
-   /* copy over the stats. do so as a struct copy */
-   pAdapter->ls_stats = *pLinkSpeed;
+	/* update the adapter with the fresh results */
+	priv = hdd_request_priv(request);
+	pAdapter->hdd_stats.ClassA_stat = priv->class_a_stats;
 
-   /* notify the caller */
-   complete(&pLinkSpeedContext->completion);
+return_cached_results:
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	hdd_request_put(request);
 
-   /* serialization is complete */
-   spin_unlock(&hdd_context_lock);
+	return VOS_STATUS_SUCCESS;
 }
 
-VOS_STATUS  wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter)
+struct station_stats {
+	tCsrSummaryStatsInfo summary_stats;
+	tCsrGlobalClassAStatsInfo class_a_stats;
+};
+
+/**
+ * hdd_get_station_statistics_cb() - Get stats callback function
+ * @stats: pointer to combined station stats
+ * @context: user context originally registered with SME (always the
+ *	     cookie from the request context)
+ *
+ * Return: None
+ */
+static void hdd_get_station_statistics_cb(void *stats, void *context)
 {
-   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-   eHalStatus hstatus;
-   unsigned long rc;
-   struct statsContext context;
+	struct hdd_request *request;
+	struct station_stats *priv;
+	tCsrSummaryStatsInfo *summary_stats;
+	tCsrGlobalClassAStatsInfo *class_a_stats;
 
-   if (NULL == pAdapter)
-   {
-       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
-       return VOS_STATUS_E_FAULT;
-   }
-   if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
-   {
-       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__);
-       return VOS_STATUS_SUCCESS;
-   }
+	if (ioctl_debug) {
+		pr_info("%s: stats [%pK] context [%pK]\n",
+			__func__, stats, context);
+	}
 
-   /* we are connected
-   prepare our callback context */
-   init_completion(&context.completion);
-   context.pAdapter = pAdapter;
-   context.magic = STATS_CONTEXT_MAGIC;
-   /* query only for Class A statistics (which include link speed) */
-   hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
-                                  eCSR_HDD,
-                                  SME_GLOBAL_CLASSA_STATS,
-                                  hdd_GetClassA_statisticsCB,
-                                  0, // not periodic
-                                  FALSE, //non-cached results
-                                  pHddStaCtx->conn_info.staId[0],
-                                  &context,
-                                  pAdapter->sessionId );
-   if (eHAL_STATUS_SUCCESS != hstatus)
-   {
-       hddLog(VOS_TRACE_LEVEL_ERROR,
-               "%s: Unable to retrieve Class A statistics",
-               __func__);
-       /* we'll returned a cached value below */
-   }
-   else
-   {
-       /* request was sent -- wait for the response */
-       rc = wait_for_completion_timeout(&context.completion,
-                                msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
-       if (!rc) {
-          hddLog(VOS_TRACE_LEVEL_ERROR,
-              FL("SME timed out while retrieving Class A statistics"));
-      }
-   }
+	if (NULL == stats) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Bad param, stats [%pK]", __func__, stats);
+		return;
+	}
 
-   /* either we never sent a request, we sent a request and received a
-      response or we sent a request and timed out.  if we never sent a
-      request or if we sent a request and got a response, we want to
-      clear the magic out of paranoia.  if we timed out there is a
-      race condition such that the callback function could be
-      executing at the same time we are. of primary concern is if the
-      callback function had already verified the "magic" but had not
-      yet set the completion variable when a timeout occurred. we
-      serialize these activities by invalidating the magic while
-      holding a shared spinlock which will cause us to block if the
-      callback is currently executing */
-   spin_lock(&hdd_context_lock);
-   context.magic = 0;
-   spin_unlock(&hdd_context_lock);
+	request = hdd_request_get(context);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
+		return;
+	}
 
-   /* either callback updated pAdapter stats or it has cached data */
-   return VOS_STATUS_SUCCESS;
+	summary_stats = (tCsrSummaryStatsInfo *) stats;
+	class_a_stats = (tCsrGlobalClassAStatsInfo *) (summary_stats + 1);
+	priv = hdd_request_priv(request);
+
+	/* copy over the stats. do so as a struct copy */
+	priv->summary_stats = *summary_stats;
+	priv->class_a_stats = *class_a_stats;
+
+	hdd_request_complete(request);
+	hdd_request_put(request);
 }
 
-static void hdd_get_station_statisticsCB(void *pStats, void *pContext)
+/**
+ * wlan_hdd_get_station_stats() - Get station statistics
+ * @pAdapter: adapter for which statistics are desired
+ *
+ * Return: VOS_STATUS_SUCCESS if adapter's statistics were updated
+ */
+VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
 {
-   struct statsContext *pStatsContext;
-   tCsrSummaryStatsInfo      *pSummaryStats;
-   tCsrGlobalClassAStatsInfo *pClassAStats;
-   hdd_adapter_t *pAdapter;
+	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+	eHalStatus hstatus;
+	int ret;
+	void *cookie;
+	struct hdd_request *request;
+	struct station_stats *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
 
-   if (ioctl_debug)
-   {
-      pr_info("%s: pStats [%p] pContext [%p]\n",
-              __func__, pStats, pContext);
-   }
+	if (NULL == pAdapter) {
+		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
+		return VOS_STATUS_SUCCESS;
+	}
 
-   if ((NULL == pStats) || (NULL == pContext))
-   {
-      hddLog(VOS_TRACE_LEVEL_ERROR,
-             "%s: Bad param, pStats [%p] pContext [%p]",
-             __func__, pStats, pContext);
-      return;
-   }
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Request allocation failure", __func__);
+		return VOS_STATUS_E_NOMEM;
+	}
+	cookie = hdd_request_cookie(request);
 
-   /* there is a race condition that exists between this callback
-      function and the caller since the caller could time out either
-      before or while this code is executing.  we use a spinlock to
-      serialize these actions */
-   spin_lock(&hdd_context_lock);
+	/* query only for Summary & Class A statistics */
+	hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
+				     eCSR_HDD,
+				     SME_SUMMARY_STATS |
+				     SME_GLOBAL_CLASSA_STATS,
+				     hdd_get_station_statistics_cb,
+				     0, /* not periodic */
+				     FALSE, /* non-cached results */
+				     pHddStaCtx->conn_info.staId[0],
+				     cookie, pAdapter->sessionId);
+	if (eHAL_STATUS_SUCCESS != hstatus) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Unable to retrieve statistics", __func__);
+		/* we'll return with cached values */
+	} else {
+		/* request was sent -- wait for the response */
+		ret = hdd_request_wait_for_response(request);
+		if (ret) {
+			hddLog(VOS_TRACE_LEVEL_WARN,
+			       FL("SME timed out while retrieving statistics"));
+			/* we'll returned a cached value below */
+		} else {
+			/* update the adapter with the fresh results */
+			priv = hdd_request_priv(request);
+			pAdapter->hdd_stats.summary_stat = priv->summary_stats;
+			pAdapter->hdd_stats.ClassA_stat = priv->class_a_stats;
+		}
+	}
 
-   pSummaryStats = (tCsrSummaryStatsInfo *)pStats;
-   pClassAStats  = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 );
-   pStatsContext = pContext;
-   pAdapter      = pStatsContext->pAdapter;
-   if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
-   {
-      /* the caller presumably timed out so there is nothing we can do */
-      spin_unlock(&hdd_context_lock);
-      hddLog(VOS_TRACE_LEVEL_WARN,
-             "%s: Invalid context, pAdapter [%p] magic [%08x]",
-             __func__, pAdapter, pStatsContext->magic);
-      if (ioctl_debug)
-      {
-         pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
-                 __func__, pAdapter, pStatsContext->magic);
-      }
-      return;
-   }
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	hdd_request_put(request);
 
-   /* context is valid so caller is still waiting */
-
-   /* paranoia: invalidate the magic */
-   pStatsContext->magic = 0;
-
-   /* copy over the stats. do so as a struct copy */
-   pAdapter->hdd_stats.summary_stat = *pSummaryStats;
-   pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
-
-   /* notify the caller */
-   complete(&pStatsContext->completion);
-
-   /* serialization is complete */
-   spin_unlock(&hdd_context_lock);
+	/* either callback updated pAdapter stats or it has cached data */
+	return VOS_STATUS_SUCCESS;
 }
 
-VOS_STATUS  wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
-{
-   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-   eHalStatus hstatus;
-   unsigned long rc;
-   struct statsContext context;
-
-   if (NULL == pAdapter)
-   {
-       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
-       return VOS_STATUS_SUCCESS;
-   }
-
-   /* we are connected
-   prepare our callback context */
-   init_completion(&context.completion);
-   context.pAdapter = pAdapter;
-   context.magic = STATS_CONTEXT_MAGIC;
-
-   /* query only for Summary & Class A statistics */
-   hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
-                               eCSR_HDD,
-                               SME_SUMMARY_STATS |
-                               SME_GLOBAL_CLASSA_STATS,
-                               hdd_get_station_statisticsCB,
-                               0, // not periodic
-                               FALSE, //non-cached results
-                               pHddStaCtx->conn_info.staId[0],
-                               &context,
-                               pAdapter->sessionId);
-   if (eHAL_STATUS_SUCCESS != hstatus)
-   {
-      hddLog(VOS_TRACE_LEVEL_ERROR,
-             "%s: Unable to retrieve statistics",
-             __func__);
-      /* we'll return with cached values */
-   }
-   else
-   {
-      /* request was sent -- wait for the response */
-      rc = wait_for_completion_timeout(&context.completion,
-                           msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
-
-      if (!rc) {
-          hddLog(VOS_TRACE_LEVEL_ERROR,
-              FL("SME timed out while retrieving statistics"));
-      }
-   }
-
-   /* either we never sent a request, we sent a request and received a
-      response or we sent a request and timed out.  if we never sent a
-      request or if we sent a request and got a response, we want to
-      clear the magic out of paranoia.  if we timed out there is a
-      race condition such that the callback function could be
-      executing at the same time we are. of primary concern is if the
-      callback function had already verified the "magic" but had not
-      yet set the completion variable when a timeout occurred. we
-      serialize these activities by invalidating the magic while
-      holding a shared spinlock which will cause us to block if the
-      callback is currently executing */
-   spin_lock(&hdd_context_lock);
-   context.magic = 0;
-   spin_unlock(&hdd_context_lock);
-
-   /* either callback updated pAdapter stats or it has cached data */
-   return VOS_STATUS_SUCCESS;
-}
-
-
 /*
  * Support for the LINKSPEED private command
  * Per the WiFi framework the response must be of the form
@@ -4019,101 +3896,99 @@
 
 VOS_STATUS  wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode)
 {
-   struct statsContext context;
-   eHalStatus status;
-   hdd_context_t *pHddCtx;
+	struct hdd_request *request;
+	void *cookie;
+	eHalStatus status;
+	hdd_context_t *pHddCtx;
+	static const struct hdd_request_params params = {
+		.priv_size = 0,
+		.timeout_ms = WLAN_WAIT_TIME_POWER,
+	};
 
-   if (NULL == pAdapter)
-   {
-       hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL");
-       return VOS_STATUS_E_FAULT;
-   }
+	if (NULL == pAdapter)
+	{
+		hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL");
+		return VOS_STATUS_E_FAULT;
+	}
 
-   hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode);
-   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-   if (pHddCtx->isLogpInProgress) {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                "%s:LOGP in Progress. Ignore!!!", __func__);
-      return VOS_STATUS_E_FAILURE;
-   }
+	hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode);
+	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	if (pHddCtx->isLogpInProgress) {
+		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+			"%s:LOGP in Progress. Ignore!!!", __func__);
+		return VOS_STATUS_E_FAILURE;
+	}
 
-   init_completion(&context.completion);
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+			"%s: Request allocation failure", __func__);
+		return VOS_STATUS_E_NOMEM;
+	}
 
-   context.pAdapter = pAdapter;
-   context.magic = POWER_CONTEXT_MAGIC;
+	cookie = hdd_request_cookie(request);
 
-   if (DRIVER_POWER_MODE_ACTIVE == mode)
-   {
-       hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering "
-               "Full Power", __func__);
-       status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
-                       iw_power_callback_fn, &context,
-                       eSME_FULL_PWR_NEEDED_BY_HDD);
-       // Enter Full power command received from GUI this means we are disconnected
-       // Set PMC remainInPowerActiveTillDHCP flag to disable auto BMPS entry by PMC
-       sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE);
-       if (eHAL_STATUS_PMC_PENDING == status)
-       {
-           unsigned long rc;
-           /* request was sent -- wait for the response */
-           rc = wait_for_completion_timeout(
-                   &context.completion,
-                   msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
+	if (DRIVER_POWER_MODE_ACTIVE == mode)
+	{
+		hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering "
+			"Full Power", __func__);
+		status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
+			iw_power_callback_func, cookie,
+			eSME_FULL_PWR_NEEDED_BY_HDD);
+		/*
+		 * Enter Full power command received from GUI this means we are
+		 * disconnected. Set PMC remainInPowerActiveTillDHCP flag to
+		 * disable auto BMPS entry by PMC
+		 */
+		sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE);
+		if (eHAL_STATUS_PMC_PENDING == status)
+		{
+			int rc;
+			/* request was sent -- wait for the response */
+			rc = hdd_request_wait_for_response(request);
+			if (rc)
+				hddLog(VOS_TRACE_LEVEL_ERROR,
+					FL("SME timed out while requesting full power"));
+		}
+	}
+	else if (DRIVER_POWER_MODE_AUTO == mode)
+	{
+		if (pHddCtx->cfg_ini->fIsBmpsEnabled)
+		{
+			hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ",
+				__func__);
+			/*
+			 * Enter BMPS command received from GUI this means DHCP
+			 * is completed.  Clear PMC remainInPowerActiveTillDHCP
+			 * flag to enable auto BMPS entry.
+			 */
+			sme_SetDHCPTillPowerActiveFlag(
+				WLAN_HDD_GET_HAL_CTX(pAdapter), FALSE);
+			status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
+				iw_power_callback_func, cookie);
+			if (eHAL_STATUS_PMC_PENDING == status)
+			{
+				int rc;
+				/* request was sent -- wait for the response */
+				rc = hdd_request_wait_for_response(request);
+				if (rc)
+					hddLog(VOS_TRACE_LEVEL_ERROR,
+						FL("SME timed out while requesting BMPS"));
+			}
+		} else {
+			hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not "
+				"enabled in the cfg");
+		}
+	}
 
-           if (!rc) {
-               hddLog(VOS_TRACE_LEVEL_ERROR,
-                  FL("SME timed out while requesting full power"));
-           }
-       }
-   }
-   else if (DRIVER_POWER_MODE_AUTO == mode)
-   {
-       if (pHddCtx->cfg_ini->fIsBmpsEnabled)
-       {
-           hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ",
-                  __func__);
-           // Enter BMPS command received from GUI this means DHCP is completed
-           // Clear PMC remainInPowerActiveTillDHCP flag to enable auto BMPS entry
-           sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter),
-                    FALSE);
-           status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
-                           iw_power_callback_fn, &context);
-           if (eHAL_STATUS_PMC_PENDING == status)
-           {
-               unsigned long rc;
-               /* request was sent -- wait for the response */
-               rc = wait_for_completion_timeout(
-                           &context.completion,
-                           msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
-               if (!rc) {
-                   hddLog(VOS_TRACE_LEVEL_ERROR,
-                       FL("SME timed out while requesting BMPS"));
-               }
-           }
-       }
-       else
-       {
-           hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not "
-                   "enabled in the cfg");
-       }
-   }
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	hdd_request_put(request);
 
-   /* either we never sent a request, we sent a request and received a
-      response or we sent a request and timed out.  if we never sent a
-      request or if we sent a request and got a response, we want to
-      clear the magic out of paranoia.  if we timed out there is a
-      race condition such that the callback function could be
-      executing at the same time we are. of primary concern is if the
-      callback function had already verified the "magic" but had not
-      yet set the completion variable when a timeout occurred. we
-      serialize these activities by invalidating the magic while
-      holding a shared spinlock which will cause us to block if the
-      callback is currently executing */
-   spin_lock(&hdd_context_lock);
-   context.magic = 0;
-   spin_unlock(&hdd_context_lock);
-
-   return VOS_STATUS_SUCCESS;
+	return VOS_STATUS_SUCCESS;
 }
 
 VOS_STATUS  wlan_hdd_set_powersave(hdd_adapter_t *pAdapter, int mode)
@@ -5620,111 +5495,101 @@
     return 0;
 }
 
-void hdd_GetTemperatureCB(int temperature, void *pContext)
+struct temperature_info {
+	int temperature;
+};
+
+void hdd_GetTemperatureCB(int temperature, void *cookie)
 {
-    struct statsContext *pTempContext;
-    hdd_adapter_t *pAdapter;
+	struct hdd_request *request;
+	struct temperature_info *priv;
 
-    ENTER();
+	ENTER();
 
-    if (NULL == pContext) {
-        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pContext is NULL"));
-        return;
-    }
+	request = hdd_request_get(cookie);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s: Obsolete request", __func__);
+		return;
+	}
+	priv = hdd_request_priv(request);
 
-    pTempContext = pContext;
-    pAdapter     = pTempContext->pAdapter;
+	priv->temperature = temperature;
 
-    /* there is a race condition that exists between this callback
-       function and the caller since the caller could time out either
-       before or while this code is executing.  we use a spinlock to
-       serialize these actions */
-    spin_lock(&hdd_context_lock);
+	hdd_request_complete(request);
+	hdd_request_put(request);
 
-    if ((NULL == pAdapter) ||
-            (TEMP_CONTEXT_MAGIC != pTempContext->magic))
-    {
-        /* the caller presumably timed out so there is nothing we can do */
-        spin_unlock(&hdd_context_lock);
-        hddLog(VOS_TRACE_LEVEL_WARN,
-                FL("Invalid context, pAdapter [%p] magic [%08x]"),
-                pAdapter, pTempContext->magic);
-        return;
-    }
-
-    /* context is valid, update the temperature, ignore it if this was 0 */
-    if (temperature != 0) {
-        pAdapter->temperature = temperature;
-    }
-
-    /* notify the caller */
-    complete(&pTempContext->completion);
-
-    /* serialization is complete */
-    spin_unlock(&hdd_context_lock);
-
-    EXIT();
+	EXIT();
 }
 
-VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *pAdapter,
+VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *adapter_ptr,
         union iwreq_data *wrqu, char *extra)
 {
-    eHalStatus hstatus;
-    struct statsContext tempContext;
-    unsigned long rc;
-    A_INT32 *pData = (A_INT32 *)extra;
+	eHalStatus hstatus;
+	int ret;
+	A_INT32 *data_ptr = (A_INT32 *)extra;
+	void *cookie;
+	struct hdd_request *request;
+	struct temperature_info *priv;
+	static const struct hdd_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
 
-    ENTER();
+	ENTER();
 
-    if (NULL == pAdapter)
-    {
-        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pAdapter is NULL"));
-        return VOS_STATUS_E_FAULT;
-    }
+	if (NULL == adapter_ptr)
+	{
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       FL("pAdapter is NULL"));
+		return VOS_STATUS_E_FAULT;
+	}
 
-    /* prepare callback context and magic pattern */
-    init_completion(&tempContext.completion);
-    tempContext.pAdapter = pAdapter;
-    tempContext.magic = TEMP_CONTEXT_MAGIC;
+	request = hdd_request_alloc(&params);
+	if (!request) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s: Request allocation failure", __func__);
+		return VOS_STATUS_E_NOMEM;
+	}
+	cookie = hdd_request_cookie(request);
 
-    /* send get temperature request to sme */
-    hstatus = sme_GetTemperature(
-            WLAN_HDD_GET_HAL_CTX(pAdapter),
-            &tempContext,
-            hdd_GetTemperatureCB);
+	/* send get temperature request to sme */
+	hstatus =
+		sme_GetTemperature(WLAN_HDD_GET_HAL_CTX(adapter_ptr),
+				   cookie,
+				   hdd_GetTemperatureCB);
 
-    if (eHAL_STATUS_SUCCESS != hstatus) {
-        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve temperature"));
-    } else {
-        /* request was sent -- wait for the response */
-        rc = wait_for_completion_timeout(&tempContext.completion,
-                msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
-        if (!rc) {
-            hddLog(VOS_TRACE_LEVEL_ERROR,
-                FL("SME timed out while retrieving temperature"));
-        }
-    }
+	if (eHAL_STATUS_SUCCESS != hstatus) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       FL("Unable to retrieve temperature"));
+	} else {
+		/* request was sent -- wait for the response */
+		ret = hdd_request_wait_for_response(request);
+		if (ret) {
+			hddLog(VOS_TRACE_LEVEL_WARN,
+			       FL("timeout when get temperature"));
+			/* we'll returned a cached value below */
+		} else {
+			/* update the adapter with the fresh results */
+			priv = hdd_request_priv(request);
+			/* ignore it if this was 0 */
+			if (priv->temperature != 0)
+				adapter_ptr->temperature =
+						 priv->temperature;
+		}
+	}
+	/*
+	* either we never sent a request, we sent a request and
+	* received a response or we sent a request and timed out.
+	* regardless we are done with the request.
+	*/
+	hdd_request_put(request);
 
-    /* either we never sent a request, we sent a request and received a
-       response or we sent a request and timed out.  if we never sent a
-       request or if we sent a request and got a response, we want to
-       clear the magic out of paranoia.  if we timed out there is a
-       race condition such that the callback function could be
-       executing at the same time we are. of primary concern is if the
-       callback function had already verified the "magic" but had not
-       yet set the completion variable when a timeout occurred. we
-       serialize these activities by invalidating the magic while
-       holding a shared spinlock which will cause us to block if the
-       callback is currently executing */
-    spin_lock(&hdd_context_lock);
-    tempContext.magic = 0;
-    spin_unlock(&hdd_context_lock);
+	/* update temperature */
+	*data_ptr = adapter_ptr->temperature;
 
-    /* update temperature */
-    *pData = pAdapter->temperature;
-
-    EXIT();
-    return VOS_STATUS_SUCCESS;
+	EXIT();
+	return VOS_STATUS_SUCCESS;
 }
 
 /* set param sub-ioctls */
@@ -5811,42 +5676,39 @@
            {
               case  0: //Full Power
               {
-                 struct statsContext context;
-                 eHalStatus status;
+                 struct hdd_request *request;
+                 void *cookie;
+                 static const struct hdd_request_params params = {
+                    .priv_size = 0,
+                    .timeout_ms = WLAN_WAIT_TIME_POWER,
+                 };
+                 eHalStatus status = eHAL_STATUS_FAILURE;
 
-                 init_completion(&context.completion);
+                 if (NULL == hHal)
+                    return -EINVAL;
 
-                 context.pAdapter = pAdapter;
-                 context.magic = POWER_CONTEXT_MAGIC;
-
-                 status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
-                              iw_power_callback_fn, &context,
-                              eSME_FULL_PWR_NEEDED_BY_HDD);
-                 if (eHAL_STATUS_PMC_PENDING == status)
-                 {
-                    unsigned long rc;
-                    rc = wait_for_completion_timeout(
-                                &context.completion,
-                                 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
-
-                    if (!rc) {
-                       hddLog(VOS_TRACE_LEVEL_ERROR,
-                           FL("SME timed out while requesting full power"));
-                    }
+                 request = hdd_request_alloc(&params);
+                 if (!request) {
+                    hddLog(VOS_TRACE_LEVEL_ERROR,
+                           "%s: Request allocation failure", __func__);
+                    return VOS_STATUS_E_NOMEM;
                  }
-                 /* either we have a response or we timed out.  if we timed
-                    out there is a race condition such that the callback
-                    function could be executing at the same time we are. of
-                    primary concern is if the callback function had already
-                    verified the "magic" but had not yet set the completion
-                    variable when a timeout occurred. we serialize these
-                    activities by invalidating the magic while holding a
-                    shared spinlock which will cause us to block if the
-                    callback is currently executing */
-                 spin_lock(&hdd_context_lock);
-                 context.magic = 0;
-                 spin_unlock(&hdd_context_lock);
 
+                 cookie = hdd_request_cookie(request);
+                 status = sme_RequestFullPower(hHal,
+                                               iw_power_callback_func, cookie,
+                                               eSME_FULL_PWR_NEEDED_BY_HDD);
+                 if (eHAL_STATUS_PMC_PENDING == status) {
+                    if(hdd_request_wait_for_response(request))
+                       hddLog(VOS_TRACE_LEVEL_ERROR,
+                              FL("SME timed out while requesting full power"));
+                 }
+                 /*
+                  * either we never sent a request, we sent a request and
+                  * received a response or we sent a request and timed out.
+                  * regardless we are done with the request.
+                  */
+                 hdd_request_put(request);
                  hddLog(LOGE, "iwpriv Full Power completed");
                  break;
               }
@@ -5858,41 +5720,38 @@
                  break;
               case  3: //Request Bmps
               {
-                 struct statsContext context;
-                 eHalStatus status;
+                 struct hdd_request *request;
+                 void *cookie;
+                 static const struct hdd_request_params params = {
+                    .priv_size = 0,
+                    .timeout_ms = WLAN_WAIT_TIME_POWER,
+                 };
+                 eHalStatus status = eHAL_STATUS_FAILURE;
 
-                 init_completion(&context.completion);
+                 if (NULL == hHal)
+                    return -EINVAL;
 
-                 context.pAdapter = pAdapter;
-                 context.magic = POWER_CONTEXT_MAGIC;
-
-                 status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
-                           iw_power_callback_fn, &context);
-                 if (eHAL_STATUS_PMC_PENDING == status)
-                 {
-                    unsigned long rc;
-                    rc = wait_for_completion_timeout(
-                              &context.completion,
-                              msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
-                    if (!rc) {
-                       hddLog(VOS_TRACE_LEVEL_ERROR,
-                           FL("SME timed out while requesting BMPS"));
-                    }
+                 request = hdd_request_alloc(&params);
+                 if (!request) {
+                    hddLog(VOS_TRACE_LEVEL_ERROR,
+                           "%s: Request allocation failure", __func__);
+                    return VOS_STATUS_E_NOMEM;
                  }
-                 /* either we have a response or we timed out.  if we
-                    timed out there is a race condition such that the
-                    callback function could be executing at the same
-                    time we are. of primary concern is if the callback
-                    function had already verified the "magic" but had
-                    not yet set the completion variable when a timeout
-                    occurred. we serialize these activities by
-                    invalidating the magic while holding a shared
-                    spinlock which will cause us to block if the
-                    callback is currently executing */
-                 spin_lock(&hdd_context_lock);
-                 context.magic = 0;
-                 spin_unlock(&hdd_context_lock);
 
+                 cookie = hdd_request_cookie(request);
+                 status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
+                                          iw_power_callback_func, cookie);
+                 if (eHAL_STATUS_PMC_PENDING == status) {
+                    if (hdd_request_wait_for_response(request))
+                       hddLog(VOS_TRACE_LEVEL_ERROR,
+                              FL("SME timed out while requesting BMPS"));
+                 }
+                 /*
+                  * either we never sent a request, we sent a request and
+                  * received a response or we sent a request and timed out.
+                  * regardless we are done with the request.
+                  */
+                 hdd_request_put(request);
                  hddLog(LOGE, "iwpriv Request BMPS completed");
                  break;
               }
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h
index f93fc8a..d582f20 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h
@@ -42,9 +42,9 @@
 #define QWLAN_VERSION_MINOR            4
 #define QWLAN_VERSION_PATCH            23
 #define QWLAN_VERSION_EXTRA            ""
-#define QWLAN_VERSION_BUILD            21
+#define QWLAN_VERSION_BUILD            22
 
-#define QWLAN_VERSIONSTR               "4.4.23.021"
+#define QWLAN_VERSIONSTR               "4.4.23.022"
 
 
 #define AR6320_REV1_VERSION             0x5000000
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirApi.h
index ccc36533..ca336e6 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirApi.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirApi.h
@@ -93,6 +93,9 @@
 
 #define MAX_LEN_UDP_RESP_OFFLOAD 128
 
+/* Maximum peer station number query one time */
+#define MAX_PEER_STA 12
+
 #ifdef FEATURE_WLAN_EXTSCAN
 
 #define WLAN_EXTSCAN_MAX_CHANNELS                 36
@@ -4653,6 +4656,16 @@
 	struct sir_rssi_info info[0];
 };
 
+/**
+ * @sta_num: number of peer station which has valid info
+ * @info: peer information
+ *
+ * all SAP peer station's information retrieved
+ */
+struct sir_peer_sta_info {
+	uint8_t sta_num;
+	struct sir_rssi_info info[MAX_PEER_STA];
+};
 
 typedef struct sSirAddPeriodicTxPtrn
 {
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/dot11f.frms b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
index 06d6a8a..6cb043d 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
@@ -2425,7 +2425,7 @@
 }
 IE ExtCap (EID_EXT_CAP)
 {
-    bytes[8..9];
+    bytes[1..9];
 }
 
 IE HTCaps (EID_HT_CAPABILITIES)
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
index 0b100ae..c310021 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
@@ -36,7 +36,7 @@
   *
   *
   * This file was automatically generated by 'framesc'
-  * Wed Jul 12 16:02:49 2017 from the following file(s):
+  * Thu Dec 28 13:33:15 2017 from the following file(s):
   *
   * dot11f.frms
   *
@@ -3083,7 +3083,7 @@
 #define DOT11F_EID_EXTCAP ( 127 )
 
 // N.B. These #defines do *not* include the EID & length
-#define DOT11F_IE_EXTCAP_MIN_LEN ( 8 )
+#define DOT11F_IE_EXTCAP_MIN_LEN ( 1 )
 
 #define DOT11F_IE_EXTCAP_MAX_LEN ( 9 )
 
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index 41c7709..568c4ab 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -6974,6 +6974,21 @@
                 tANI_U16 new_length = pUpdateAddIEs->updateIE.ieBufferlength +
                                 psessionEntry->addIeParams.probeRespDataLen;
                 tANI_U8 *new_ptr = vos_mem_malloc(new_length);
+                /* Multiple back to back append commands
+                 * can lead to a huge length.So, check
+                 * for the validity of the length.
+                 */
+                if (psessionEntry->addIeParams.probeRespDataLen >
+                     (USHRT_MAX - pUpdateAddIEs->updateIE.ieBufferlength))
+                {
+                    limLog(pMac, LOGE,
+                           FL("IE Length overflow, curr:%d, new:%d."),
+                           psessionEntry->addIeParams.probeRespDataLen,
+                           pUpdateAddIEs->updateIE.ieBufferlength);
+                    vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer);
+                    pUpdateAddIEs->updateIE.pAdditionIEBuffer = NULL;
+                    return;
+                }
                 if (NULL == new_ptr)
                 {
                     limLog(pMac, LOGE, FL("Memory allocation failed."));
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessTdls.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessTdls.c
index 1df76cf..58a8941 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessTdls.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessTdls.c
@@ -2806,8 +2806,7 @@
     p_ext_cap->TDLSProhibited = TDLS_PROHIBITED ;
 
     extCapability->present = 1 ;
-    /* For STA cases we alwasy support 11mc - Allow MAX length */
-    extCapability->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+    extCapability->num_bytes = lim_compute_ext_cap_ie_length(extCapability);
 
     return ;
 }
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c
index 5ddb392..cdb6f13 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -502,7 +502,7 @@
      */
 
     ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
-    if (ieLen <= SIR_MAC_B_PR_SSID_OFFSET)
+    if (ieLen <= (SIR_MAC_B_PR_SSID_OFFSET + 2))
     {
         limLog(pMac, LOGP,
                FL("RX packet has invalid length %d"), ieLen);
@@ -551,18 +551,21 @@
        limLog(pMac, LOG1, FL(" pHdr->addr3:"MAC_ADDRESS_STR),
               MAC_ADDR_ARRAY(pHdr->addr3));
        limLog( pMac, LOG1, FL("Save this entry in LFR cache"));
-       status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll);
+       status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD,
+                                          dontUpdateAll, ieLen - 2);
     }
     else
 #endif
     //If it is not scanning, only save unique results
     if (pMac->lim.gLimReturnUniqueResults || (!fScanning))
     {
-        status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE, dontUpdateAll);
+        status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE,
+                                        dontUpdateAll, ieLen - 2);
     }
     else
     {
-        status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll);
+        status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD,
+                                        dontUpdateAll, ieLen - 2);
     }
 
     if(fScanning)
@@ -703,7 +706,7 @@
 eHalStatus
 limLookupNaddHashEntry(tpAniSirGlobal pMac,
                        tLimScanResultNode *pBssDescr, tANI_U8 action,
-                       tANI_U8 dontUpdateAll)
+                       tANI_U8 dontUpdateAll, tANI_U32 ie_len)
 {
     tANI_U8                  index, ssidLen = 0;
     tANI_U8                found = false;
@@ -719,6 +722,11 @@
 
     //ieFields start with TLV of SSID IE
     ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1);
+    if ((ssidLen > ie_len) || (ssidLen > DOT11F_IE_SSID_MAX_LEN)) {
+        limLog(pMac, LOGE, FL("SSID length %d, IE overall Length %d"),
+               ssidLen, ie_len);
+        return eHAL_STATUS_FAILURE;
+    }
     pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo;
 
     for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next)
@@ -732,6 +740,8 @@
              // matching band to update new channel info
             (vos_chan_to_band(pBssDescr->bssDescription.channelId) ==
                       vos_chan_to_band(ptemp->bssDescription.channelId)) &&
+            (((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1) ==
+                ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1)) &&
             vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1),
                            ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1),
                            (tANI_U8) (ssidLen + 1)) &&
@@ -942,9 +952,9 @@
 eHalStatus
 limLookupNaddLfrHashEntry(tpAniSirGlobal pMac,
                           tLimScanResultNode *pBssDescr, tANI_U8 action,
-                          tANI_U8 dontUpdateAll)
+                          tANI_U8 dontUpdateAll, tANI_U32 ie_len)
 {
-    tANI_U8                  index, ssidLen = 0;
+    tANI_U8 index, ssidLen = 0;
     tLimScanResultNode *ptemp, *pprev;
     tSirMacCapabilityInfo *pSirCap, *pSirCapTemp;
     int idx, len;
@@ -957,6 +967,11 @@
 
     //ieFields start with TLV of SSID IE
     ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1);
+    if ((ssidLen > ie_len) || (ssidLen > DOT11F_IE_SSID_MAX_LEN)) {
+        limLog(pMac, LOGE, FL("SSID length %d, IE overall Length %d"),
+               ssidLen, ie_len);
+        return eHAL_STATUS_FAILURE;
+    }
     pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo;
 
     for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next)
@@ -969,6 +984,8 @@
                       sizeof(tSirMacAddr))) &&   //matching BSSID
             (pBssDescr->bssDescription.channelId ==
                                       ptemp->bssDescription.channelId) &&
+            (((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1) ==
+                ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1)) &&
             vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1),
                            ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1),
                            (tANI_U8) (ssidLen + 1)) &&
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h
index 4d06b9b..946bc8c 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012, 2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -44,7 +44,7 @@
 tANI_U8 limScanHashFunction(tSirMacAddr);
 void    limInitHashTable(tpAniSirGlobal);
 eHalStatus
-   limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8);
+   limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8, tANI_U32);
 void    limDeleteHashEntry(tLimScanResultNode *);
 void    limFlushp2pScanResults(tpAniSirGlobal);
 void    limDeleteCachedScanResults(tpAniSirGlobal);
@@ -54,7 +54,7 @@
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
 void    limInitLfrHashTable(tpAniSirGlobal);
 eHalStatus
-   limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8);
+   limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8, tANI_U32);
 void    limDeleteLfrHashEntry(tLimScanResultNode *);
 void    limDeleteCachedLfrScanResults(tpAniSirGlobal);
 void    limReInitLfrScanResults(tpAniSirGlobal);
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index 2d9b319..6bc4245 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -380,23 +380,6 @@
        limLog(pMac, LOGE,
               FL("session entry null, ext capabilities will not be populated"));
 
-    // That's it-- now we pack it.  First, how much space are we going to
-    // need?
-    nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload );
-    if ( DOT11F_FAILED( nStatus ) )
-    {
-        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
-                               "or a Probe Request (0x%08x)."), nStatus );
-        // We'll fall back on the worst case scenario:
-        nPayload = sizeof( tDot11fProbeRequest );
-    }
-    else if ( DOT11F_WARNED( nStatus ) )
-    {
-        limLog( pMac, LOGW, FL("There were warnings while calculating"
-                               "the packed size for a Probe Request ("
-                               "0x%08x)."), nStatus );
-    }
-
     if (addn_ielen) {
 
         vos_mem_set((tANI_U8 *)&extracted_ext_cap,
@@ -413,11 +396,36 @@
             if (p_ext_cap->interworkingService)
                 p_ext_cap->qosMap = 1;
 
-            extracted_ext_cap_flag = lim_is_ext_cap_ie_present(p_ext_cap);
+            extracted_ext_cap.num_bytes =
+                    lim_compute_ext_cap_ie_length(&extracted_ext_cap);
+            extracted_ext_cap_flag = (extracted_ext_cap.num_bytes > 0);
         }
     }
+    /* merge the ExtCap struct */
+    if (extracted_ext_cap_flag)
+        lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
 
-    nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + addn_ielen;
+    /*
+     * That's it-- now we pack it.
+     * First, how much space are we going to need?
+     */
+    nStatus = dot11fGetPackedProbeRequestSize(pMac, &pr, &nPayload);
+    if (DOT11F_FAILED(nStatus))
+    {
+        limLog(pMac, LOGE,
+             FL("Failed to calculate the packed size for a Probe Request (0x%08x)."),
+             nStatus);
+        /* We'll fall back on the worst case scenario: */
+        nPayload = sizeof(tDot11fProbeRequest);
+    }
+    else if (DOT11F_WARNED(nStatus))
+    {
+        limLog(pMac, LOGW,
+             FL("There were warnings while calculating the packed size for a Probe Request (0x%08x)."),
+             nStatus);
+    }
+
+    nBytes = nPayload + sizeof(tSirMacMgmtHdr) + addn_ielen;
 
     // Ok-- try to allocate some memory:
     halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
@@ -446,10 +454,6 @@
         return nSirStatus;      // allocated!
     }
 
-    /* merge the ExtCap struct*/
-    if (extracted_ext_cap_flag)
-        lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap);
-
     // That done, pack the Probe Request:
     nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame +
                                       sizeof( tSirMacMgmtHdr ),
@@ -575,7 +579,7 @@
 {
     tDot11fProbeResponse *pFrm;
     tSirRetStatus        nSirStatus;
-    tANI_U32             cfg, nPayload, nBytes, nStatus;
+    tANI_U32             cfg, nPayload, nBytes = 0, nStatus;
     tpSirMacMgmtHdr      pMacHdr;
     tANI_U8             *pFrame;
     void                *pPacket;
@@ -741,25 +745,6 @@
 #endif // defined(FEATURE_WLAN_WAPI)
 
 
-    nStatus = dot11fGetPackedProbeResponseSize( pMac, pFrm, &nPayload );
-    if ( DOT11F_FAILED( nStatus ) )
-    {
-        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
-                               "or a Probe Response (0x%08x)."),
-                nStatus );
-        // We'll fall back on the worst case scenario:
-        nPayload = sizeof( tDot11fProbeResponse );
-    }
-    else if ( DOT11F_WARNED( nStatus ) )
-    {
-        limLog( pMac, LOGW, FL("There were warnings while calculating"
-                               "the packed size for a Probe Response "
-                               "(0x%08x)."), nStatus );
-    }
-
-    nBytes = nPayload + sizeof( tSirMacMgmtHdr );
-
-
     if( pMac->lim.gpLimRemainOnChanReq )
     {
         nBytes += (pMac->lim.gpLimRemainOnChanReq->length - sizeof( tSirRemainOnChnReq ) );
@@ -827,6 +812,29 @@
             }
         }
     }
+    /* merge ExtCap IE */
+    if (extractedExtCapFlag)
+    {
+        lim_merge_extcap_struct(&pFrm->ExtCap, &extractedExtCap, true);
+    }
+
+    nStatus = dot11fGetPackedProbeResponseSize(pMac, pFrm, &nPayload);
+    if (DOT11F_FAILED(nStatus))
+    {
+        limLog(pMac, LOGE,
+             FL("Failed to calculate the packed size for a Probe Response (0x%08x)."),
+             nStatus);
+        /* We'll fall back on the worst case scenario: */
+        nPayload = sizeof(tDot11fProbeResponse);
+    }
+    else if (DOT11F_WARNED(nStatus))
+    {
+        limLog(pMac, LOGW,
+             FL("There were warnings while calculating the packed size for a Probe Response (0x%08x)."),
+             nStatus);
+    }
+
+    nBytes += nPayload + sizeof(tSirMacMgmtHdr);
 
     halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                              ( tANI_U16 )nBytes, ( void** ) &pFrame,
@@ -868,11 +876,6 @@
 
     sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
-    /*merge ExtCap IE*/
-    if (extractedExtCapFlag)
-    {
-        lim_merge_extcap_struct(&pFrm->ExtCap, &extractedExtCap);
-    }
     // That done, pack the Probe Response:
     nStatus = dot11fPackProbeResponse( pMac, pFrm, pFrame + sizeof(tSirMacMgmtHdr),
                                        nPayload, &nPayload );
@@ -1224,7 +1227,7 @@
     tSirRetStatus        nSirStatus;
     tANI_U8              lleMode = 0, fAddTS;
     tHalBitVal           qosMode, wmeMode;
-    tANI_U32             nPayload, nBytes, nStatus;
+    tANI_U32             nPayload = 0, nBytes = 0, nStatus;
     void                *pPacket;
     eHalStatus           halstatus;
     tUpdateBeaconParams beaconParams;
@@ -1392,23 +1395,6 @@
     }
 
     // Allocate a buffer for this frame:
-    nStatus = dot11fGetPackedAssocResponseSize( pMac, &frm, &nPayload );
-    if ( DOT11F_FAILED( nStatus ) )
-    {
-        limLog( pMac, LOGE, FL("Failed to calculate the packed size f"
-                               "or an Association Response (0x%08x)."),
-                nStatus );
-        return;
-    }
-    else if ( DOT11F_WARNED( nStatus ) )
-    {
-        limLog( pMac, LOGW, FL("There were warnings while calculating "
-                               "the packed size for an Association Re"
-                               "sponse (0x%08x)."), nStatus );
-    }
-
-    nBytes = sizeof( tSirMacMgmtHdr ) + nPayload;
-
     if ( pAssocReq != NULL )
     {
         addnIEPresent = (psessionEntry->addIeParams.assocRespDataLen != 0);
@@ -1456,6 +1442,29 @@
                                 addnIEPresent, pAssocReq->addIEPresent);
         }
     }
+    /* merge the ExtCap struct */
+    if (extractedExtCapFlag)
+    {
+        lim_merge_extcap_struct(&(frm.ExtCap), &extractedExtCap, true);
+    }
+
+    nStatus = dot11fGetPackedAssocResponseSize(pMac, &frm, &nPayload);
+    if (DOT11F_FAILED(nStatus))
+    {
+        limLog(pMac, LOGE,
+             FL("Failed to calculate the packed size for an Association Response (0x%08x)."),
+             nStatus);
+        return;
+    }
+    else if (DOT11F_WARNED(nStatus))
+    {
+        limLog(pMac, LOGW,
+             FL("There were warnings while calculating the packed size for an Association Response (0x%08x)."),
+             nStatus);
+    }
+
+    nBytes += sizeof(tSirMacMgmtHdr) + nPayload;
+
     halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                              ( tANI_U16 )nBytes, ( void** ) &pFrame,
                              ( void** ) &pPacket );
@@ -1490,11 +1499,6 @@
 
     sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
-    /* merge the ExtCap struct*/
-    if (extractedExtCapFlag)
-    {
-        lim_merge_extcap_struct(&(frm.ExtCap), &extractedExtCap);
-    }
     nStatus = dot11fPackAssocResponse( pMac, &frm,
                                        pFrame + sizeof( tSirMacMgmtHdr ),
                                        nPayload, &nPayload );
@@ -2022,7 +2026,7 @@
     tANI_U8            *pFrame;
     tSirRetStatus       nSirStatus;
     tLimMlmAssocCnf     mlmAssocCnf;
-    tANI_U32            nBytes, nPayload, nStatus;
+    tANI_U32            nBytes = 0, nPayload, nStatus;
     tANI_U8             fQosEnabled, fWmeEnabled, fWsmEnabled;
     void               *pPacket;
     eHalStatus          halstatus;
@@ -2038,6 +2042,11 @@
     tDot11fIEExtCap     extractedExtCap;
     tANI_BOOLEAN        extractedExtCapFlag = eANI_BOOLEAN_TRUE;
     tpSirMacMgmtHdr     pMacHdr;
+    tDot11fIEExtCap     ap_extcap;
+    tANI_U8            *ap_extcap_ptr = NULL;
+    tANI_U8            *pIe = NULL;
+    tANI_U32            ieLen = 0;
+    tANI_U32            fixed_param_len = 0;
 
     if(NULL == psessionEntry)
     {
@@ -2083,7 +2092,10 @@
                                           extractedExtCap.bytes;
             if (p_ext_cap->interworkingService)
                 p_ext_cap->qosMap = 1;
-            extractedExtCapFlag = lim_is_ext_cap_ie_present(p_ext_cap);
+
+            extractedExtCap.num_bytes =
+                    lim_compute_ext_cap_ie_length(&extractedExtCap);
+            extractedExtCapFlag = (extractedExtCap.num_bytes > 0);
         }
     } else {
         limLog(pMac, LOG1,
@@ -2271,24 +2283,50 @@
 #endif
     }
 #endif
-
-    nStatus = dot11fGetPackedAssocRequestSize( pMac, pFrm, &nPayload );
-    if ( DOT11F_FAILED( nStatus ) )
+    /* merge the ExtCap struct */
+    if (extractedExtCapFlag)
     {
-        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
-                    "or an Association Request (0x%08x)."),
-                nStatus );
-        // We'll fall back on the worst case scenario:
-        nPayload = sizeof( tDot11fAssocRequest );
-    }
-    else if ( DOT11F_WARNED( nStatus ) )
-    {
-        limLog( pMac, LOGW, FL("There were warnings while calculating "
-                    "the packed size for an Association Re "
-                    "quest(0x%08x)."), nStatus );
+        lim_merge_extcap_struct(&pFrm->ExtCap, &extractedExtCap, true);
     }
 
-    nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen;
+    /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
+    if (pFrm->ExtCap.present && psessionEntry->is_ext_caps_present)
+    {
+        fixed_param_len = DOT11F_FF_TIMESTAMP_LEN +
+                          DOT11F_FF_BEACONINTERVAL_LEN +
+                          DOT11F_FF_CAPABILITIES_LEN;
+        vos_mem_zero((tANI_U8*)&ap_extcap, sizeof(tDot11fIEExtCap));
+        if (psessionEntry->beacon && psessionEntry->bcnLen > fixed_param_len)
+        {
+            pIe = psessionEntry->beacon + fixed_param_len;
+            ieLen = psessionEntry->bcnLen - fixed_param_len;
+
+            /* Extract EXTCAP IE from beacon frame */
+            ap_extcap_ptr = lim_get_ie_ptr(pIe, ieLen, DOT11F_EID_EXTCAP);
+            lim_update_extcap_struct(pMac, ap_extcap_ptr, &ap_extcap);
+
+            /* Clear the bits if AP not advertise it in beacon */
+            lim_merge_extcap_struct(&pFrm->ExtCap, &ap_extcap, false);
+        }
+    }
+
+    nStatus = dot11fGetPackedAssocRequestSize(pMac, pFrm, &nPayload);
+    if (DOT11F_FAILED(nStatus))
+    {
+        limLog(pMac, LOGE,
+             FL("Failed to calculate the packed size for an Association Request (0x%08x)."),
+             nStatus);
+        /* We'll fall back on the worst case scenario: */
+        nPayload = sizeof(tDot11fAssocRequest);
+    }
+    else if (DOT11F_WARNED(nStatus))
+    {
+        limLog(pMac, LOGW,
+             FL("There were warnings while calculating the packed size for an Association Request(0x%08x)."),
+             nStatus);
+    }
+
+    nBytes = nPayload + sizeof(tSirMacMgmtHdr) + nAddIELen;
 
     halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
             ( tANI_U16 )nBytes, ( void** ) &pFrame,
@@ -2333,12 +2371,6 @@
         vos_mem_free(pFrm);
         return;
     }
-    /* merge the ExtCap struct*/
-    if (extractedExtCapFlag)
-    {
-        lim_merge_extcap_struct(&pFrm->ExtCap, &extractedExtCap);
-    }
-
     // That done, pack the Assoc Request:
     nStatus = dot11fPackAssocRequest( pMac, pFrm, pFrame +
             sizeof(tSirMacMgmtHdr),
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.c
index 7259dd9..5bb66e0 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.c
@@ -8419,7 +8419,7 @@
 	if (merge && NULL != extra_extcap && extra_extcap->num_bytes > 0) {
 		if (extra_extcap->num_bytes > ext_cap_data.num_bytes)
 			num_bytes = extra_extcap->num_bytes;
-		lim_merge_extcap_struct(&ext_cap_data, extra_extcap);
+		lim_merge_extcap_struct(&ext_cap_data, extra_extcap, true);
 	}
 
 	/* Allocate memory for the WMI request, and copy the parameter */
@@ -8556,10 +8556,10 @@
 	}
 
 	vos_mem_set((uint8_t *)&out[0], DOT11F_IE_EXTCAP_MAX_LEN, 0);
-	vos_mem_copy(&out[0], &buf[2], DOT11F_IE_EXTCAP_MAX_LEN);
+	vos_mem_copy(&out[0], &buf[2], buf[1]);
 
 	if (DOT11F_PARSE_SUCCESS != dot11fUnpackIeExtCap(mac_ctx, &out[0],
-					DOT11F_IE_EXTCAP_MAX_LEN, dst))
+                                        buf[1], dst))
 		limLog(mac_ctx, LOGE, FL("dot11fUnpackIeExtCap Parse Error "));
 }
 
@@ -8601,24 +8601,43 @@
  * lim_merge_extcap_struct() - merge extended capabilities info
  * @dst: destination extended capabilities
  * @src: source extended capabilities
+ * @add: true if add the capabilites, false if strip the capabilites.
  *
- * This function is used to take @src info and merge it with @dst
- * extended capabilities info.
+ * This function is used to take @src info and add/strip it to/from
+ * @dst extended capabilities info.
  *
  * Return: None
  */
 void lim_merge_extcap_struct(tDot11fIEExtCap *dst,
-			     tDot11fIEExtCap *src)
+			     tDot11fIEExtCap *src,
+			     bool add)
 {
 	uint8_t *tempdst = (uint8_t *)dst->bytes;
 	uint8_t *tempsrc = (uint8_t *)src->bytes;
 	uint8_t structlen = member_size(tDot11fIEExtCap, bytes);
 
-	while(tempdst && tempsrc && structlen--) {
-		*tempdst |= *tempsrc;
+	/* Return if @src not present */
+	if (!src->present)
+		return;
+
+	/* Return if strip the capabilites from @dst which not present */
+	if (!dst->present && !add)
+		return;
+
+	/* Merge the capabilites info in other cases */
+	while (tempdst && tempsrc && structlen--) {
+		if (add)
+			*tempdst |= *tempsrc;
+		else
+			*tempdst &= *tempsrc;
 		tempdst++;
 		tempsrc++;
 	}
+	dst->num_bytes = lim_compute_ext_cap_ie_length(dst);
+        if (dst->num_bytes == 0)
+		dst->present = 0;
+	else
+		dst->present = 1;
 }
 
 /**
@@ -8653,24 +8672,23 @@
 }
 
 /**
- * lim_is_ext_cap_ie_present - checks if ext ie is present
+ * lim_compute_ext_cap_ie_length - compute the length of ext cap ie
+ * based on the bits set
  * @ext_cap: extended IEs structure
  *
- * Return: true if ext IEs are present else false
+ * Return: length of the ext cap ie, 0 means should not present
  */
-bool lim_is_ext_cap_ie_present (struct s_ext_cap *ext_cap)
-{
-	int i, size;
-	uint8_t *tmp_buf;
+tANI_U8 lim_compute_ext_cap_ie_length (tDot11fIEExtCap *ext_cap) {
+	tANI_U8 i = DOT11F_IE_EXTCAP_MAX_LEN;
 
-	tmp_buf = (uint8_t *) ext_cap;
-	size = sizeof(*ext_cap);
+	while (i) {
+		if (ext_cap->bytes[i-1]) {
+			break;
+		}
+		i --;
+	}
 
-	for (i = 0; i < size; i++)
-		if (tmp_buf[i])
-			return true;
-
-	return false;
+	return i;
 }
 
 /**
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.h
index 8ff6cc1..983fccf 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.h
@@ -662,10 +662,11 @@
 			       tDot11fIEExtCap *ext_cap);
 tSirRetStatus lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx,
 		uint8_t* addn_ie, uint16_t *addn_ielen, tDot11fIEExtCap *dst);
-void lim_merge_extcap_struct(tDot11fIEExtCap *dst, tDot11fIEExtCap *src);
+void lim_merge_extcap_struct(tDot11fIEExtCap *dst, tDot11fIEExtCap *src,
+			bool add);
 uint8_t
 lim_get_80Mhz_center_channel(uint8_t primary_channel);
-bool lim_is_ext_cap_ie_present (struct s_ext_cap *ext_cap);
+tANI_U8 lim_compute_ext_cap_ie_length (tDot11fIEExtCap *ext_cap);
 bool lim_is_robust_mgmt_action_frame(uint8_t action_catagory);
 void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx,
 				uint16_t *caps, uint16_t bss_caps);
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schApi.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schApi.c
index 4820f645..f9ca560 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schApi.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schApi.c
@@ -412,7 +412,7 @@
     tANI_U8 *pFrame2Hal = psessionEntry->pSchProbeRspTemplate;
     tpSendProbeRespParams pprobeRespParams=NULL;
     tANI_U32  retCode = eSIR_FAILURE;
-    tANI_U32             nPayload,nBytes,nStatus;
+    tANI_U32             nPayload, nBytes = 0, nStatus;
     tpSirMacMgmtHdr      pMacHdr;
     tANI_U32             addnIEPresent = VOS_FALSE;
     tSirRetStatus        nSirStatus;
@@ -426,24 +426,6 @@
     tSirRetStatus status;
     uint16_t addn_ielen = 0;
 
-    nStatus = dot11fGetPackedProbeResponseSize( pMac, &psessionEntry->probeRespFrame, &nPayload );
-    if ( DOT11F_FAILED( nStatus ) )
-    {
-        schLog( pMac, LOGE, FL("Failed to calculate the packed size f"
-                               "or a Probe Response (0x%08x)."),
-                nStatus );
-        // We'll fall back on the worst case scenario:
-        nPayload = sizeof( tDot11fProbeResponse );
-    }
-    else if ( DOT11F_WARNED( nStatus ) )
-    {
-        schLog( pMac, LOGE, FL("There were warnings while calculating"
-                               "the packed size for a Probe Response "
-                               "(0x%08x)."), nStatus );
-    }
-
-    nBytes = nPayload + sizeof( tSirMacMgmtHdr );
-
     //Check if probe response IE is present or not
     addnIEPresent = (psessionEntry->addIeParams.probeRespDataLen != 0);
     if (addnIEPresent)
@@ -512,6 +494,28 @@
             addnIEPresent = false; //Dont include the IE.
     }
 
+    /* merge extcap IE */
+    prb_rsp_frm = &psessionEntry->probeRespFrame;
+    if (extcap_present)
+        lim_merge_extcap_struct(&prb_rsp_frm->ExtCap, &extracted_extcap, true);
+
+    nStatus = dot11fGetPackedProbeResponseSize(pMac, &psessionEntry->probeRespFrame, &nPayload);
+    if (DOT11F_FAILED(nStatus))
+    {
+        schLog(pMac, LOGE,
+             FL("Failed to calculate the packed size for a Probe Response (0x%08x)."),
+             nStatus);
+        /* We'll fall back on the worst case scenario: */
+        nPayload = sizeof(tDot11fProbeResponse);
+    }
+    else if (DOT11F_WARNED(nStatus))
+    {
+        schLog(pMac, LOGE,
+             FL("There were warnings while calculating the packed size for a Probe Response (0x%08x)."),
+             nStatus);
+    }
+
+    nBytes += nPayload + sizeof(tSirMacMgmtHdr);
 
     // Paranoia:
     vos_mem_set(pFrame2Hal, nBytes, 0);
@@ -534,11 +538,6 @@
 
     sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
-    /* merge extcap IE */
-    prb_rsp_frm = &psessionEntry->probeRespFrame;
-    if (extcap_present)
-        lim_merge_extcap_struct(&prb_rsp_frm->ExtCap, &extracted_extcap);
-
     // That done, pack the Probe Response:
     nStatus = dot11fPackProbeResponse( pMac, &psessionEntry->probeRespFrame, pFrame2Hal + sizeof(tSirMacMgmtHdr),
                                        nPayload, &nPayload );
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconGen.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconGen.c
index d225fca..1835fd9 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconGen.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconGen.c
@@ -490,8 +490,7 @@
         }
         /* merge extcap IE */
         if (extcap_present)
-            lim_merge_extcap_struct(&pBcn2->ExtCap, &extracted_extcap);
-
+            lim_merge_extcap_struct(&pBcn2->ExtCap, &extracted_extcap, true);
     }
 
     nStatus = dot11fPackBeacon2( pMac, pBcn2,
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
index 7b6c3db..7114be4 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
@@ -855,6 +855,11 @@
 	struct sir_lost_link_info *lost_link_info;
 	VOS_STATUS vos_status;
 	vos_msg_t sme_msg = {0};
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: received invalid vdev_id %d",
+			 __func__, vdev_id);
+		return;
+	}
 	/* report lost link information only for STA mode */
 	if (wma->interfaces[vdev_id].vdev_up &&
 	    (WMI_VDEV_TYPE_STA == wma->interfaces[vdev_id].type) &&
@@ -31542,6 +31547,11 @@
 		/* FW had the tlv_header len calculated into the data_len */
 		buf = &param_buf->data[WMI_MAX_SSID_LEN + IEEE80211_ADDR_LEN];
 		vdev_id = *(u_int32_t*) buf;
+		if (vdev_id >= wma->max_bssid) {
+			WMA_LOGE("%s: received invalid vdev_id %d",
+				 __func__, vdev_id);
+			return -EINVAL;
+		}
 
 		/* to trigger AP re-connection after QRF wakeup*/
 		WMA_LOGA("%s, trigger AP re-connection at QRF wakeup (APFIND_WAKEUP_EVENT), vdev_id=%d, SSID=%s",
diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiRoam.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiRoam.c
index 14fca6d..15341c4 100644
--- a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiRoam.c
+++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiRoam.c
@@ -102,6 +102,8 @@
 
 #define MAX_SOCIAL_CHANNELS  3
 
+#define HOST_LOG_MAX_SSID_SIZE 32
+
 /* packet dump timer duration of 60 secs */
 #define PKT_DUMP_TIMER_DURATION 60
 
@@ -10691,11 +10693,10 @@
                                 if(pNewBss)
                                 {
                                     vos_mem_copy(pIbssLog->bssid, pNewBss->bssId, 6);
-                                    if(pNewBss->ssId.length)
-                                    {
-                                        vos_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId,
-                                                     pNewBss->ssId.length);
-                                    }
+                                    if (pNewBss->ssId.length > HOST_LOG_MAX_SSID_SIZE)
+                                        pNewBss->ssId.length = HOST_LOG_MAX_SSID_SIZE;
+                                    vos_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId,
+                                                 pNewBss->ssId.length);
                                     pIbssLog->operatingChannel = pNewBss->channelNumber;
                                 }
                                 if(HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &bi)))
diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
index 7a94d1f..ad0a061 100644
--- a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
+++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
@@ -35,7 +35,7 @@
   *
   *
   * This file was automatically generated by 'framesc'
-  * Wed Jul 12 16:02:49 2017 from the following file(s):
+  * Thu Dec 28 13:33:15 2017 from the following file(s):
   *
   * dot11f.frms
   *
@@ -489,7 +489,7 @@
     len += 2;
     while ( len < nBuf )
     {
-        if( NULL == (pIe =  FindIEDefn(pCtx, pBufRemaining, nBuf + len, IEs)))
+        if( NULL == (pIe =  FindIEDefn(pCtx, pBufRemaining, nBuf - len, IEs)))
              break;
         if( pIe->eid == pIeFirst->eid )
              break;
@@ -497,6 +497,8 @@
         pBufRemaining += *(pBufRemaining + 1) + 2;
     }
 
+    if ((len > 0xFF) || (len > nBuf))
+        return DOT11F_INTERNAL_ERROR;
     *pnConsumed = len;
     return DOT11F_PARSE_SUCCESS;
 
@@ -6003,7 +6005,7 @@
         {offsetof(tDot11fAssocRequest, P2PIEOpaque), offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque" , 0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PIEOPAQUE, 0, },
         {offsetof(tDot11fAssocRequest, WFDIEOpaque), offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque" , 0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0}, 4, DOT11F_EID_WFDIEOPAQUE, 0, },
         {offsetof(tDot11fAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
-        {offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fAssocRequest, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
         {offsetof(tDot11fAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, },
     {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },    };
@@ -6444,7 +6446,7 @@
         {offsetof(tDot11fAssocResponse, P2PAssocRes), offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes" , 0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PASSOCRES, 0, },
         {offsetof(tDot11fAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
         {offsetof(tDot11fAssocResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, },
-        {offsetof(tDot11fAssocResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fAssocResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fAssocResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
         {offsetof(tDot11fAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, },
     {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },    };
@@ -7806,7 +7808,7 @@
         {offsetof(tDot11fBeacon, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
         {offsetof(tDot11fBeacon, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, },
         {offsetof(tDot11fBeacon, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
-        {offsetof(tDot11fBeacon, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fBeacon, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fBeacon, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
         {offsetof(tDot11fBeacon, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
         {offsetof(tDot11fBeacon, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
@@ -8874,7 +8876,7 @@
         {offsetof(tDot11fBeacon2, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
         {offsetof(tDot11fBeacon2, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, },
         {offsetof(tDot11fBeacon2, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
-        {offsetof(tDot11fBeacon2, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fBeacon2, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fBeacon2, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
         {offsetof(tDot11fBeacon2, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
         {offsetof(tDot11fBeacon2, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
@@ -9710,7 +9712,7 @@
         {offsetof(tDot11fBeaconIEs, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
         {offsetof(tDot11fBeaconIEs, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, },
         {offsetof(tDot11fBeaconIEs, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
-        {offsetof(tDot11fBeaconIEs, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fBeaconIEs, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fBeaconIEs, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
         {offsetof(tDot11fBeaconIEs, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
         {offsetof(tDot11fBeaconIEs, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
@@ -12620,7 +12622,7 @@
         {offsetof(tDot11fProbeRequest, WFATPC), offsetof(tDot11fIEWFATPC, present), 0, "WFATPC" , 0, 9, 9, SigIeWFATPC, {0, 80, 242, 8, 0}, 5, DOT11F_EID_WFATPC, 0, },
         {offsetof(tDot11fProbeRequest, P2PProbeReq), offsetof(tDot11fIEP2PProbeReq, present), 0, "P2PProbeReq" , 0, 6, 43, SigIeP2PProbeReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPROBEREQ, 0, },
         {offsetof(tDot11fProbeRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
-        {offsetof(tDot11fProbeRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fProbeRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
     {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },    };
 
 tANI_U32 dot11fUnpackProbeRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeRequest *pFrm)
@@ -13088,7 +13090,7 @@
         {offsetof(tDot11fProbeResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
         {offsetof(tDot11fProbeResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, },
         {offsetof(tDot11fProbeResponse, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
-        {offsetof(tDot11fProbeResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fProbeResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fProbeResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
         {offsetof(tDot11fProbeResponse, Vendor1IE), offsetof(tDot11fIEVendor1IE, present), 0, "Vendor1IE" , 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0}, 3, DOT11F_EID_VENDOR1IE, 0, },
         {offsetof(tDot11fProbeResponse, Vendor2IE), offsetof(tDot11fIEVendor2IE, present), 0, "Vendor2IE" , 0, 5, 5, SigIeVendor2IE, {0, 144, 76, 0, 0}, 3, DOT11F_EID_VENDOR2IE, 0, },
@@ -14492,7 +14494,7 @@
         {offsetof(tDot11fReAssocRequest, P2PIEOpaque), offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque" , 0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PIEOPAQUE, 0, },
         {offsetof(tDot11fReAssocRequest, WFDIEOpaque), offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque" , 0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0}, 4, DOT11F_EID_WFDIEOPAQUE, 0, },
         {offsetof(tDot11fReAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
-        {offsetof(tDot11fReAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fReAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fReAssocRequest, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
         {offsetof(tDot11fReAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, },
     {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },    };
@@ -15321,7 +15323,7 @@
         {offsetof(tDot11fReAssocResponse, P2PAssocRes), offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes" , 0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PASSOCRES, 0, },
         {offsetof(tDot11fReAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, },
         {offsetof(tDot11fReAssocResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, },
-        {offsetof(tDot11fReAssocResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fReAssocResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fReAssocResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
         {offsetof(tDot11fReAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, },
     {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },    };
@@ -16400,7 +16402,7 @@
         {offsetof(tDot11fTDLSDisRsp, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, },
         {offsetof(tDot11fTDLSDisRsp, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, },
         {offsetof(tDot11fTDLSDisRsp, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
-        {offsetof(tDot11fTDLSDisRsp, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fTDLSDisRsp, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fTDLSDisRsp, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, },
         {offsetof(tDot11fTDLSDisRsp, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, },
         {offsetof(tDot11fTDLSDisRsp, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 0, },
@@ -17122,7 +17124,7 @@
         {offsetof(tDot11fTDLSSetupReq, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, },
         {offsetof(tDot11fTDLSSetupReq, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, },
         {offsetof(tDot11fTDLSSetupReq, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
-        {offsetof(tDot11fTDLSSetupReq, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fTDLSSetupReq, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fTDLSSetupReq, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, },
         {offsetof(tDot11fTDLSSetupReq, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, },
         {offsetof(tDot11fTDLSSetupReq, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, },
@@ -17507,7 +17509,7 @@
         {offsetof(tDot11fTDLSSetupRsp, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, },
         {offsetof(tDot11fTDLSSetupRsp, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, },
         {offsetof(tDot11fTDLSSetupRsp, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
-        {offsetof(tDot11fTDLSSetupRsp, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fTDLSSetupRsp, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fTDLSSetupRsp, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, },
         {offsetof(tDot11fTDLSSetupRsp, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, },
         {offsetof(tDot11fTDLSSetupRsp, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, },
@@ -18098,7 +18100,7 @@
         {offsetof(tDot11fTimingAdvertisementFrame, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, },
         {offsetof(tDot11fTimingAdvertisementFrame, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, },
         {offsetof(tDot11fTimingAdvertisementFrame, TimeAdvertisement), offsetof(tDot11fIETimeAdvertisement, present), 0, "TimeAdvertisement" , 0, 18, 18, SigIeTimeAdvertisement, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEADVERTISEMENT, 0, },
-        {offsetof(tDot11fTimingAdvertisementFrame, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+        {offsetof(tDot11fTimingAdvertisementFrame, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
         {offsetof(tDot11fTimingAdvertisementFrame, Vendor1IE), offsetof(tDot11fIEVendor1IE, present), 0, "Vendor1IE" , 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0}, 3, DOT11F_EID_VENDOR1IE, 0, },
         {offsetof(tDot11fTimingAdvertisementFrame, Vendor2IE), offsetof(tDot11fIEVendor2IE, present), 0, "Vendor2IE" , 0, 5, 5, SigIeVendor2IE, {0, 144, 76, 0, 0}, 3, DOT11F_EID_VENDOR2IE, 0, },
         {offsetof(tDot11fTimingAdvertisementFrame, Vendor3IE), offsetof(tDot11fIEVendor3IE, present), 0, "Vendor3IE" , 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0}, 3, DOT11F_EID_VENDOR3IE, 0, },
@@ -18755,7 +18757,8 @@
 
         if (pIe)
         {
-            if (nBufRemaining < pIe->minSize - pIe->noui - 2U)
+            if ((nBufRemaining < pIe->minSize - pIe->noui - 2U) ||
+                (len < pIe->minSize - pIe->noui - 2U))
             {
                 FRAMES_LOG3(pCtx, FRLOGW, FRFL("The IE %s must be "
                     "at least %d bytes in size, but there are onl"
diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/parserApi.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/parserApi.c
index d84d584..42641fb 100644
--- a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/parserApi.c
+++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/parserApi.c
@@ -1226,6 +1226,12 @@
 #endif
     p_ext_cap->extChanSwitch = 1;
 
+    if (pDot11f->present)
+    {
+        /* Need to compute the num_bytes based on bits set */
+        pDot11f->num_bytes = lim_compute_ext_cap_ie_length(pDot11f);
+    }
+
     return eSIR_SUCCESS;
 }
 
@@ -3144,6 +3150,8 @@
         limLog(pMac, LOGE, FL("Failed to allocate memory"));
         return eSIR_FAILURE;
     }
+    vos_mem_zero(pBies, sizeof(tDot11fBeaconIEs));
+
     // delegate to the framesc-generated code,
     status = dot11fUnpackBeaconIEs( pMac, pPayload, nPayload, pBies );
 
@@ -3448,6 +3456,8 @@
         limLog(pMac, LOGE, FL("Failed to allocate memory"));
         return eSIR_FAILURE;
     }
+    vos_mem_zero(pBies, sizeof(tDot11fBeaconIEs));
+
     // delegate to the framesc-generated code,
     status = dot11fUnpackBeaconIEs( pMac, pPayload, nPayload, pBies );
 
diff --git a/drivers/staging/qcacld-2.0/Kbuild b/drivers/staging/qcacld-2.0/Kbuild
index 5773ae0..29145fc 100644
--- a/drivers/staging/qcacld-2.0/Kbuild
+++ b/drivers/staging/qcacld-2.0/Kbuild
@@ -397,6 +397,7 @@
 		$(HDD_SRC_DIR)/wlan_hdd_memdump.o \
 		$(HDD_SRC_DIR)/wlan_hdd_ocb.o \
 		$(HDD_SRC_DIR)/wlan_hdd_oemdata.o \
+		$(HDD_SRC_DIR)/wlan_hdd_request_manager.o \
 		$(HDD_SRC_DIR)/wlan_hdd_scan.o \
 		$(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \
 		$(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \