prima: extscan: Update Reset BSS Hotlist APIs
Add blocking mechanism for reset hotlist BSS APIs at HDD layer
to avoid synchronization problems at HAL layer.
Change-Id: I78400771057479267a2aca5bb8687d6b3ae2e819
CRs-Fixed: 834122
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 4ad664b..89dbb1e 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -2663,9 +2663,9 @@
void *pMsg)
{
hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
- struct sk_buff *skb = NULL;
tpSirEXTScanResetBssidHotlistRspParams pData =
(tpSirEXTScanResetBssidHotlistRspParams) pMsg;
+ struct hdd_ext_scan_context *context;
ENTER();
@@ -2678,36 +2678,19 @@
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_RESET_BSSID_HOTLIST_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_cached_results_ind(void *ctx,
@@ -4318,12 +4301,22 @@
hdd_context_t *pHddCtx = wiphy_priv(wiphy);
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
eHalStatus status;
+ struct hdd_ext_scan_context *context;
+ tANI_U32 request_id;
+ unsigned long rc;
+ int retval;
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)
{
+ hddLog(LOGE, FL("HDD context is not valid"));
return -EINVAL;
}
/* check the EXTScan Capability */
@@ -4355,14 +4348,36 @@
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.requestId;
+ spin_unlock(&hdd_context_lock);
+
status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
if (!HAL_STATUS_SUCCESS(status)) {
hddLog(VOS_TRACE_LEVEL_ERROR,
FL("sme_ResetBssHotlist failed(err=%d)"), status);
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_ResetBssHotlist 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);
+ }
+
EXIT();
- return 0;
+ return retval;
}
static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,