prima: extscan: Update extscan stop API
Add blocking mechanism for ext scan stop APIs at HDD layer
to avoid synchronization problems at HAL layer.
Change-Id: I3ab7ab587fe408523bd28f0cbd58c6a18a830a0c
CRs-Fixed: 834122
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index f618282..562036c 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -2596,52 +2596,35 @@
{
tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
- struct sk_buff *skb = NULL;
+ struct hdd_ext_scan_context *context;
ENTER();
if (wlan_hdd_validate_context(pHddCtx)){
return;
}
+
if (!pMsg)
{
hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
return;
}
- skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
- NULL,
-#endif
- EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
- QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
- GFP_KERNEL);
+ hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
+ pData->status);
- if (!skb) {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- FL("cfg80211_vendor_event_alloc failed"));
- return;
+ context = &pHddCtx->ext_scan_context;
+ spin_lock(&hdd_context_lock);
+ if (context->request_id == pData->requestId) {
+ context->response_status = pData->status ? -EINVAL : 0;
+ complete(&context->response_event);
}
- hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
- hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
+ spin_unlock(&hdd_context_lock);
- if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
- pData->requestId) ||
- nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
- goto nla_put_failure;
- }
-
- cfg80211_vendor_event(skb, GFP_KERNEL);
EXIT();
return;
-
-nla_put_failure:
- kfree_skb(skb);
- return;
}
-
static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
void *pMsg)
{
@@ -4613,9 +4596,18 @@
hdd_context_t *pHddCtx = wiphy_priv(wiphy);
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
eHalStatus status;
+ int retval;
+ unsigned long rc;
+ struct hdd_ext_scan_context *context;
+ tANI_U32 request_id;
ENTER();
+ if (VOS_FTM_MODE == hdd_get_conparam()) {
+ hddLog(LOGE, FL("Command not allowed in FTM mode"));
+ return -EINVAL;
+ }
+
status = wlan_hdd_validate_context(pHddCtx);
if (0 != status)
{
@@ -4650,6 +4642,12 @@
reqMsg.sessionId = pAdapter->sessionId;
hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
+ context = &pHddCtx->ext_scan_context;
+ spin_lock(&hdd_context_lock);
+ INIT_COMPLETION(context->response_event);
+ context->request_id = request_id = reqMsg.sessionId;
+ spin_unlock(&hdd_context_lock);
+
status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
if (!HAL_STATUS_SUCCESS(status)) {
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -4657,6 +4655,24 @@
return -EINVAL;
}
+ /* request was sent -- wait for the response */
+ rc = wait_for_completion_timeout(&context->response_event,
+ msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+
+ if (!rc) {
+ hddLog(LOGE, FL("sme_ExtScanStop timed out"));
+ retval = -ETIMEDOUT;
+ } else {
+ spin_lock(&hdd_context_lock);
+ if (context->request_id == request_id)
+ retval = context->response_status;
+ else
+ retval = -EINVAL;
+ spin_unlock(&hdd_context_lock);
+ }
+
+ return retval;
+
EXIT();
return 0;
}