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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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(¶ms);
+ 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 = ¶m_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 \