prima: extscan: Update APIs related to set BSSID Hotlist

1. Add new variables related to set BSSID Hotlist.
2. Remove channel hint from hotlist parameters.
3. Add blocking mechanism to send BSSID hotlist results
   to the upper layer in same context.

Change-Id: I87f13368d04dee2891fe4bbf191934039d5bbd94
CRs-Fixed: 834122
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 562036c..e3581a5 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -2629,52 +2629,35 @@
                                                         void *pMsg)
 {
     hdd_context_t *pHddCtx    = (hdd_context_t *)ctx;
-    struct sk_buff *skb       = NULL;
     tpSirEXTScanSetBssidHotListRspParams pData =
                     (tpSirEXTScanSetBssidHotListRspParams) pMsg;
+    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_SET_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);
-    hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
+    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_reset_bss_hotlist_rsp(void *ctx,
@@ -3006,14 +2989,16 @@
 static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
                                                       void *pMsg)
 {
-    tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
+    tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
     hdd_context_t *pHddCtx         = (hdd_context_t *)ctx;
     struct sk_buff *skb            = NULL;
-    tANI_U32 i;
+    tANI_U32 i, index;
 
     ENTER();
 
     if (wlan_hdd_validate_context(pHddCtx)) {
+        hddLog(LOGE,
+               FL("HDD context is not valid or response"));
         return;
     }
     if (!pMsg)
@@ -3022,25 +3007,30 @@
         return;
     }
 
+    if (pData->bss_found)
+        index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
+    else
+        index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
+
     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_HOTLIST_AP_FOUND_INDEX,
-                      GFP_KERNEL);
+                      index, GFP_KERNEL);
 
     if (!skb) {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                   FL("cfg80211_vendor_event_alloc failed"));
         return;
     }
-    hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
-    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
-    hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
-    hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
 
-    for (i = 0; i < pData->numOfAps; i++) {
+    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
+    hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
+    hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
+    hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
+
+    for (i = 0; i < pData->numHotlistBss; i++) {
         hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
                               "Ssid (%s) "
                               "Bssid (" MAC_ADDRESS_STR ") "
@@ -3049,24 +3039,24 @@
                               "RTT (%u) "
                               "RTT_SD (%u) ",
                               i,
-                              pData->ap[i].ts,
-                              pData->ap[i].ssid,
-                              MAC_ADDR_ARRAY(pData->ap[i].bssid),
-                              pData->ap[i].channel,
-                              pData->ap[i].rssi,
-                              pData->ap[i].rtt,
-                              pData->ap[i].rtt_sd);
+                              pData->bssHotlist[i].ts,
+                              pData->bssHotlist[i].ssid,
+                              MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
+                              pData->bssHotlist[i].channel,
+                              pData->bssHotlist[i].rssi,
+                              pData->bssHotlist[i].rtt,
+                              pData->bssHotlist[i].rtt_sd);
     }
 
     if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
                       pData->requestId) ||
         nla_put_u32(skb,
                     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
-                      pData->numOfAps)) {
+                      pData->numHotlistBss)) {
         hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
         goto fail;
     }
-    if (pData->numOfAps) {
+    if (pData->numHotlistBss) {
         struct nlattr *aps;
 
         aps = nla_nest_start(skb,
@@ -3074,7 +3064,7 @@
         if (!aps)
             goto fail;
 
-        for (i = 0; i < pData->numOfAps; i++) {
+        for (i = 0; i < pData->numHotlistBss; i++) {
             struct nlattr *ap;
 
             ap = nla_nest_start(skb, i + 1);
@@ -3083,27 +3073,27 @@
 
             if (nla_put_u64(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
-                    pData->ap[i].ts) ||
+                    pData->bssHotlist[i].ts) ||
                 nla_put(skb,
                      QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
-                     sizeof(pData->ap[i].ssid),
-                     pData->ap[i].ssid) ||
+                     sizeof(pData->bssHotlist[i].ssid),
+                     pData->bssHotlist[i].ssid) ||
                 nla_put(skb,
                      QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
-                     sizeof(pData->ap[i].bssid),
-                     pData->ap[i].bssid) ||
+                     sizeof(pData->bssHotlist[i].bssid),
+                     pData->bssHotlist[i].bssid) ||
                 nla_put_u32(skb,
                      QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
-                     pData->ap[i].channel) ||
+                     pData->bssHotlist[i].channel) ||
                 nla_put_s32(skb,
                      QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
-                     pData->ap[i].rssi) ||
+                     pData->bssHotlist[i].rssi) ||
                 nla_put_u32(skb,
                      QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
-                     pData->ap[i].rtt) ||
+                     pData->bssHotlist[i].rtt) ||
                 nla_put_u32(skb,
                      QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
-                     pData->ap[i].rtt_sd))
+                     pData->bssHotlist[i].rtt_sd))
                 goto fail;
 
               nla_nest_end(skb, ap);
@@ -3713,9 +3703,18 @@
     eHalStatus status;
     tANI_U8 i = 0;
     int rem;
+    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)
     {
@@ -3760,12 +3759,22 @@
         goto fail;
     }
 
+    /* Parse and fetch lost ap sample size */
+    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
+        hddLog(LOGE, FL("attr lost ap sample size failed"));
+        goto fail;
+    }
+
+    pReqMsg->lostBssidSampleSize = nla_get_u32(
+              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
+    hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
+
     pReqMsg->sessionId = pAdapter->sessionId;
     hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
 
-    pReqMsg->numAp = nla_get_u32(
+    pReqMsg->numBssid = nla_get_u32(
               tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
-    hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
+    hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
 
     nla_for_each_nested(apTh,
                 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
@@ -3804,18 +3813,15 @@
             tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
         hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
                                          pReqMsg->ap[i].high);
-
-        /* Parse and fetch channel */
-        if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
-            hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
-            goto fail;
-        }
-        pReqMsg->ap[i].channel = nla_get_u32(
-              tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
-        hddLog(VOS_TRACE_LEVEL_INFO,
-                FL("Channel (%u)"), pReqMsg->ap[i].channel);
         i++;
     }
+
+    context = &pHddCtx->ext_scan_context;
+    spin_lock(&hdd_context_lock);
+    INIT_COMPLETION(context->response_event);
+    context->request_id = request_id = pReqMsg->requestId;
+    spin_unlock(&hdd_context_lock);
+
     status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
     if (!HAL_STATUS_SUCCESS(status)) {
         hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -3824,9 +3830,25 @@
         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_SetBssHotlist 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);
+    }
+
     vos_mem_free(pReqMsg);
     EXIT();
-    return 0;
+    return retval;
 
 fail:
     vos_mem_free(pReqMsg);
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 2317969..baf7148 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -5126,7 +5126,6 @@
    tSirMacAddr  bssid;   // AP BSSID
    tANI_S32     low;     // low threshold
    tANI_S32     high;    // high threshold
-   tANI_U32     channel; // channel hint
 } tSirAPThresholdParam, *tpSirAPThresholdParam;
 
 typedef struct
@@ -5190,6 +5189,21 @@
 typedef PACKED_PRE struct PACKED_POST
 {
     tANI_U32             requestId;
+    tANI_BOOLEAN         bss_found;
+    tANI_U32             numHotlistBss;     // numbers of APs
+
+    /*
+     * 0 for last fragment
+     * 1 still more fragment(s) coming
+     */
+    tANI_BOOLEAN         moreData;
+    tSirWifiScanResult   bssHotlist[1];
+} tSirEXTScanHotlistMatch, *tpSirEXTScanHotlistMatch;
+
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    tANI_U32             requestId;
     tANI_U32             numOfAps;     // numbers of APs
 
     /*
@@ -5306,8 +5320,8 @@
 {
     tANI_U32               requestId;
     tANI_U8                sessionId;    // session Id mapped to vdev_id
-
-    tANI_U32               numAp;        // number of hotlist APs
+    tANI_U32               lostBssidSampleSize;
+    tANI_U32               numBssid;        // number of hotlist APs
     tSirAPThresholdParam   ap[WLAN_EXTSCAN_MAX_HOTLIST_APS];    // hotlist APs
 } tSirEXTScanSetBssidHotListReqParams, *tpSirEXTScanSetBssidHotListReqParams;
 
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 2e0f58e..6ea371f 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -5946,15 +5946,14 @@
    wpt_uint8   bssid[6];     /* BSSID */
    wpt_int32    low;     // low threshold
    wpt_int32    high;    // high threshold
-   wpt_uint32   channel; // channel hint
 } WDI_APThresholdParam;
 
 typedef struct
 {
     wpt_int32   requestId;
     wpt_int8    sessionId;    // session Id mapped to vdev_id
-
-    wpt_int32   numAp;        // number of hotlist APs
+    wpt_uint32  lostBssidSampleSize;
+    wpt_int32   numBssid;        // number of hotlist APs
     WDI_APThresholdParam   ap[WDI_WLAN_EXTSCAN_MAX_HOTLIST_APS];    // hotlist APs
 } WDI_EXTScanSetBSSIDHotlistReqParams;
 
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index fec7828..2bf3b12 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -33375,8 +33375,11 @@
   pHalBssidHotlistSetReqParams->sessionId =
                     pwdiEXTScanSetBSSIDHotlistReqParams->sessionId;
 
-  pHalBssidHotlistSetReqParams->numAp =
-                    pwdiEXTScanSetBSSIDHotlistReqParams->numAp;
+  pHalBssidHotlistSetReqParams->lostBssidSampleSize =
+                    pwdiEXTScanSetBSSIDHotlistReqParams->lostBssidSampleSize;
+
+  pHalBssidHotlistSetReqParams->numBssid =
+                    pwdiEXTScanSetBSSIDHotlistReqParams->numBssid;
 
   for( i = 0; i < WLAN_HAL_EXT_SCAN_MAX_HOTLIST_APS; i++){
 
@@ -33390,26 +33393,23 @@
     pHalBssidHotlistSetReqParams->ap[i].highRssiThreshold =
         pwdiEXTScanSetBSSIDHotlistReqParams->ap[i].high;
 
-    pHalBssidHotlistSetReqParams->ap[i].channel =
-        pwdiEXTScanSetBSSIDHotlistReqParams->ap[i].channel;
-
   }
 
   VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
-          "ReqID %u sessionId %u numAp %u ",
+          "ReqID %u sessionId %u numBssid %u lostBssidSampleSize: %u",
       pHalBssidHotlistSetReqParams->requestId,
       pHalBssidHotlistSetReqParams->sessionId,
-      pHalBssidHotlistSetReqParams->numAp);
+      pHalBssidHotlistSetReqParams->numBssid,
+      pHalBssidHotlistSetReqParams->lostBssidSampleSize);
 
-  for( i = 0; i < pHalBssidHotlistSetReqParams->numAp; i++){
+  for( i = 0; i < pHalBssidHotlistSetReqParams->numBssid; i++){
 
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
-         "%s %d %d) BSSID: %pM lowRssiThreshold %d highRssiThreshold %d Channel %u ",
+         "%s %d %d) BSSID: %pM lowRssiThreshold %d highRssiThreshold %d",
             __func__, __LINE__, i,
             pHalBssidHotlistSetReqParams->ap[i].bssid,
             pHalBssidHotlistSetReqParams->ap[i].lowRssiThreshold,
-            pHalBssidHotlistSetReqParams->ap[i].highRssiThreshold,
-            pHalBssidHotlistSetReqParams->ap[i].channel);
+            pHalBssidHotlistSetReqParams->ap[i].highRssiThreshold);
 
   }
 
diff --git a/riva/inc/wlan_hal_msg.h b/riva/inc/wlan_hal_msg.h
index 601b475..7eae478 100644
--- a/riva/inc/wlan_hal_msg.h
+++ b/riva/inc/wlan_hal_msg.h
@@ -8296,8 +8296,6 @@
    tANI_S32 lowRssiThreshold;
    /* high threshold - used in L for significant rssi - used in L for hotlist */
    tANI_S32 highRssiThreshold;
-   /* channel hint */
-   tANI_U32 channel;
 } tApThresholdParams, *tpApThresholdParams;
 
 typedef PACKED_PRE struct PACKED_POST
@@ -8403,8 +8401,9 @@
 {
    tANI_U32 requestId;
    tANI_U8 sessionId;
+   tANI_U32 lostBssidSampleSize;
    // number of hotlist APs
-   tANI_U32 numAp;
+   tANI_U32 numBssid;
    // hotlist APs
    tApThresholdParams ap[WLAN_HAL_EXT_SCAN_MAX_HOTLIST_APS];
 } tHalBssidHotlistSetReq, *tpHalBssidHotlistSetReq;