prima: extscan: Support for SSID hotlist

Code changes to support SSID hotlist.

Change-Id: Iec3ecd109a454e606f41e12cd2cdffaae9e91b12
CRs-Fixed: 834122
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 89dbb1e..83cea54 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -2693,6 +2693,70 @@
     return;
 }
 
+static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
+                                                        void *pMsg)
+{
+    hdd_context_t *pHddCtx    = (hdd_context_t *)ctx;
+    tpSirEXTScanSetSsidHotListRspParams pData =
+                    (tpSirEXTScanSetSsidHotListRspParams) pMsg;
+    struct hdd_ext_scan_context *context;
+
+    if (wlan_hdd_validate_context(pHddCtx)){
+        return;
+    }
+
+    if (!pMsg)
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
+        return;
+    }
+
+    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
+                                                        pData->status);
+
+    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);
+    }
+    spin_unlock(&hdd_context_lock);
+
+    return;
+}
+
+static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
+                                                          void *pMsg)
+{
+    hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
+    tpSirEXTScanResetSsidHotlistRspParams pData =
+                    (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
+    struct hdd_ext_scan_context *context;
+
+    if (wlan_hdd_validate_context(pHddCtx)) {
+        return;
+    }
+    if (!pMsg)
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
+        return;
+    }
+
+    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
+                                                        pData->status);
+
+    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);
+    }
+    spin_unlock(&hdd_context_lock);
+
+    return;
+}
+
+
 static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
                                                        void *pMsg)
 {
@@ -2992,6 +3056,156 @@
 
 }
 
+/**
+ * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
+ *	Handle an SSID hotlist match event
+ * @ctx: HDD context registered with SME
+ * @event: The SSID hotlist match event
+ *
+ * This function will take an SSID match event that was generated by
+ * firmware and will convert it into a cfg80211 vendor event which is
+ * sent to userspace.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
+                                                void *pMsg)
+{
+   hdd_context_t *hdd_ctx = ctx;
+   struct sk_buff *skb;
+   tANI_U32 i, index;
+   tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
+
+   ENTER();
+
+   if (wlan_hdd_validate_context(hdd_ctx)) {
+       hddLog(LOGE,
+              FL("HDD context is not valid or response"));
+       return;
+   }
+   if (!pMsg)
+   {
+       hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
+       return;
+   }
+
+    if (pData->ssid_found) {
+        index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
+        hddLog(LOG1, "SSID hotlist found");
+    } else {
+        index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
+        hddLog(LOG1, "SSID hotlist lost");
+    }
+
+    skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+                       NULL,
+#endif
+          EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+          index, GFP_KERNEL);
+
+    if (!skb) {
+        hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
+        return;
+    }
+    hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
+           pData->requestId, pData->numHotlistSsid, pData->moreData);
+
+    for (i = 0; i < pData->numHotlistSsid; i++) {
+         hddLog(LOG1, "[i=%d] Timestamp %llu "
+               "Ssid: %s "
+               "Bssid (" MAC_ADDRESS_STR ") "
+               "Channel %u "
+               "Rssi %d "
+               "RTT %u "
+               "RTT_SD %u",
+               i,
+               pData->ssidHotlist[i].ts,
+               pData->ssidHotlist[i].ssid,
+               MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
+               pData->ssidHotlist[i].channel,
+               pData->ssidHotlist[i].rssi,
+               pData->ssidHotlist[i].rtt,
+               pData->ssidHotlist[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->numHotlistSsid)) {
+        hddLog(LOGE, FL("put fail"));
+        goto fail;
+    }
+
+    if (pData->numHotlistSsid) {
+        struct nlattr *aps;
+        aps = nla_nest_start(skb,
+                   QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
+        if (!aps) {
+            hddLog(LOGE, FL("nest fail"));
+            goto fail;
+        }
+
+        for (i = 0; i < pData->numHotlistSsid; i++) {
+            struct nlattr *ap;
+
+            ap = nla_nest_start(skb, i);
+            if (!ap) {
+                hddLog(LOGE, FL("nest fail"));
+                goto fail;
+            }
+
+            if (nla_put_u64(skb,
+                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
+                    pData->ssidHotlist[i].ts) ||
+                nla_put(skb,
+                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
+                    sizeof(pData->ssidHotlist[i].ssid),
+                    pData->ssidHotlist[i].ssid) ||
+                nla_put(skb,
+                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
+                    sizeof(pData->ssidHotlist[i].bssid),
+                    pData->ssidHotlist[i].bssid) ||
+                nla_put_u32(skb,
+                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
+                    pData->ssidHotlist[i].channel) ||
+                nla_put_s32(skb,
+                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
+                    pData->ssidHotlist[i].rssi) ||
+                nla_put_u32(skb,
+                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
+                    pData->ssidHotlist[i].rtt) ||
+                nla_put_u32(skb,
+                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
+                    pData->ssidHotlist[i].rtt_sd)) {
+                hddLog(LOGE, FL("put fail"));
+                goto fail;
+            }
+            nla_nest_end(skb, ap);
+        }
+        nla_nest_end(skb, aps);
+
+        if (nla_put_u8(skb,
+                   QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
+                   pData->moreData)) {
+            hddLog(LOGE, FL("put fail"));
+            goto fail;
+        }
+    }
+
+    cfg80211_vendor_event(skb, GFP_KERNEL);
+    return;
+
+fail:
+    kfree_skb(skb);
+    return;
+
+}
+
+
 static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
                                                            void *pMsg)
 {
@@ -3243,6 +3457,14 @@
         wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
         break;
 
+    case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
+        wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
+        break;
+
+    case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
+        wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
+        break;
+
     case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
         wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
         break;
@@ -3258,6 +3480,9 @@
     case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
         wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
         break;
+    case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
+        wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
+        break;
     case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
         wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
         break;
@@ -3629,6 +3854,355 @@
    return ret;
 }
 
+/*
+ * define short names for the global vendor params
+ * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
+ */
+#define PARAM_MAX \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
+#define PARAM_REQUEST_ID \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
+#define PARAMS_LOST_SSID_SAMPLE_SIZE \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
+#define PARAMS_NUM_SSID \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
+#define THRESHOLD_PARAM \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
+#define PARAM_SSID \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
+#define PARAM_BAND \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
+#define PARAM_RSSI_LOW \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
+#define PARAM_RSSI_HIGH \
+QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
+
+/**
+ * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
+                       struct wireless_dev *wdev,
+                       const void *data,
+                       int data_len)
+{
+    tSirEXTScanSetSsidHotListReqParams *request;
+    struct net_device *dev = wdev->netdev;
+    hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+    struct nlattr *tb[PARAM_MAX + 1];
+    struct nlattr *tb2[PARAM_MAX + 1];
+    struct nlattr *ssids;
+    struct hdd_ext_scan_context *context;
+    uint32_t request_id;
+    char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
+    int ssid_len;
+    eHalStatus status;
+    int i, rem, retval;
+    unsigned long rc;
+
+    ENTER();
+
+    if (VOS_FTM_MODE == hdd_get_conparam()) {
+        hddLog(LOGE, FL("Command not allowed in FTM mode"));
+        return -EINVAL;
+    }
+
+    retval = wlan_hdd_validate_context(hdd_ctx);
+    if (0 != retval) {
+        hddLog(LOGE, FL("HDD context is not valid"));
+        return -EINVAL;
+    }
+
+    /* check the EXTScan Capability */
+    if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
+         (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+               FL("EXTScan not enabled/supported by Firmware"));
+        return -EINVAL;
+    }
+
+    if (nla_parse(tb, PARAM_MAX,
+        data, data_len,
+              wlan_hdd_extscan_config_policy)) {
+        hddLog(LOGE, FL("Invalid ATTR"));
+        return -EINVAL;
+    }
+
+    request = vos_mem_malloc(sizeof(*request));
+    if (!request) {
+        hddLog(LOGE, FL("vos_mem_malloc failed"));
+        return -ENOMEM;
+    }
+
+    /* Parse and fetch request Id */
+    if (!tb[PARAM_REQUEST_ID]) {
+        hddLog(LOGE, FL("attr request id failed"));
+        goto fail;
+    }
+
+    request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
+    hddLog(LOG1, FL("Request Id %d"), request->request_id);
+
+    /* Parse and fetch lost SSID sample size */
+    if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
+        hddLog(LOGE, FL("attr number of Ssid failed"));
+        goto fail;
+    }
+    request->lost_ssid_sample_size =
+        nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
+    hddLog(LOG1, FL("Lost SSID Sample Size %d"),
+           request->lost_ssid_sample_size);
+
+    /* Parse and fetch number of hotlist SSID */
+    if (!tb[PARAMS_NUM_SSID]) {
+        hddLog(LOGE, FL("attr number of Ssid failed"));
+        goto fail;
+    }
+    request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
+    hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
+
+    request->session_id = adapter->sessionId;
+    hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
+
+    i = 0;
+    nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
+        if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
+            hddLog(LOGE,
+                   FL("Too Many SSIDs, %d exceeds %d"),
+                   i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
+            break;
+        }
+        if (nla_parse(tb2, PARAM_MAX,
+                  nla_data(ssids), nla_len(ssids),
+                  wlan_hdd_extscan_config_policy)) {
+            hddLog(LOGE, FL("nla_parse failed"));
+            goto fail;
+        }
+
+        /* Parse and fetch SSID */
+        if (!tb2[PARAM_SSID]) {
+            hddLog(LOGE, FL("attr ssid failed"));
+            goto fail;
+        }
+        nla_memcpy(ssid_string,
+               tb2[PARAM_SSID],
+               sizeof(ssid_string));
+        hddLog(LOG1, FL("SSID %s"),
+               ssid_string);
+        ssid_len = strlen(ssid_string);
+        memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
+        request->ssid[i].ssid.length = ssid_len;
+        request->ssid[i].ssid.ssId[ssid_len] = '\0';
+        hddLog(LOG1, FL("After copying SSID %s"),
+               request->ssid[i].ssid.ssId);
+        hddLog(LOG1, FL("After copying length: %d"),
+                        ssid_len);
+
+        /* Parse and fetch low RSSI */
+        if (!tb2[PARAM_BAND]) {
+            hddLog(LOGE, FL("attr band failed"));
+            goto fail;
+        }
+        request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
+        hddLog(LOG1, FL("band %d"), request->ssid[i].band);
+
+        /* Parse and fetch low RSSI */
+        if (!tb2[PARAM_RSSI_LOW]) {
+            hddLog(LOGE, FL("attr low RSSI failed"));
+            goto fail;
+        }
+        request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
+        hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
+
+        /* Parse and fetch high RSSI */
+        if (!tb2[PARAM_RSSI_HIGH]) {
+            hddLog(LOGE, FL("attr high RSSI failed"));
+            goto fail;
+        }
+        request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
+        hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
+        i++;
+    }
+
+    context = &hdd_ctx->ext_scan_context;
+    spin_lock(&hdd_context_lock);
+    INIT_COMPLETION(context->response_event);
+    context->request_id = request_id = request->request_id;
+    spin_unlock(&hdd_context_lock);
+
+    status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
+    if (!HAL_STATUS_SUCCESS(status)) {
+        hddLog(LOGE,
+               FL("sme_set_ssid_hotlist failed(err=%d)"), status);
+        goto fail;
+    }
+
+    vos_mem_free(request);
+
+    /* 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_set_ssid_hotlist 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;
+
+fail:
+    vos_mem_free(request);
+    return -EINVAL;
+}
+
+/*
+ * done with short names for the global vendor params
+ * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
+ */
+#undef PARAM_MAX
+#undef PARAM_REQUEST_ID
+#undef PARAMS_NUM_SSID
+#undef THRESHOLD_PARAM
+#undef PARAM_SSID
+#undef PARAM_BAND
+#undef PARAM_RSSI_LOW
+#undef PARAM_RSSI_HIGH
+
+static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
+                                        struct wireless_dev *wdev,
+                                        const void *data, int dataLen)
+{
+   int ret = 0;
+
+   vos_ssr_protect(__func__);
+   ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
+                                                       dataLen);
+   vos_ssr_unprotect(__func__);
+
+   return ret;
+}
+
+static int
+__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
+                         struct wireless_dev *wdev,
+                         const void *data,
+                         int data_len)
+{
+    tSirEXTScanResetSsidHotlistReqParams request;
+    struct net_device *dev = wdev->netdev;
+    hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
+    struct hdd_ext_scan_context *context;
+    uint32_t request_id;
+    eHalStatus status;
+    int retval;
+    unsigned long rc;
+
+    ENTER();
+
+    if (VOS_FTM_MODE == hdd_get_conparam()) {
+        hddLog(LOGE, FL("Command not allowed in FTM mode"));
+        return -EINVAL;
+    }
+
+    retval = wlan_hdd_validate_context(hdd_ctx);
+    if (0 != retval) {
+        hddLog(LOGE, FL("HDD context is not valid"));
+        return -EINVAL;
+    }
+
+    /* check the EXTScan Capability */
+    if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
+         (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
+    {
+        hddLog(LOGE,
+               FL("EXTScan not enabled/supported by Firmware"));
+        return -EINVAL;
+    }
+
+    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
+        data, data_len,
+               wlan_hdd_extscan_config_policy)) {
+        hddLog(LOGE, FL("Invalid ATTR"));
+        return -EINVAL;
+    }
+
+    /* Parse and fetch request Id */
+    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
+        hddLog(LOGE, FL("attr request id failed"));
+        return -EINVAL;
+    }
+
+    request.requestId = nla_get_u32(
+            tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
+    request.sessionId = adapter->sessionId;
+    hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
+           request.sessionId);
+
+    context = &hdd_ctx->ext_scan_context;
+    spin_lock(&hdd_context_lock);
+    INIT_COMPLETION(context->response_event);
+    context->request_id = request_id = request.requestId;
+    spin_unlock(&hdd_context_lock);
+
+    status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
+    if (!HAL_STATUS_SUCCESS(status)) {
+        hddLog(LOGE,
+               FL("sme_reset_ssid_hotlist 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_reset_ssid_hotlist 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;
+}
+
+static int
+wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
+                     struct wireless_dev *wdev,
+                     const void *data,
+                     int data_len)
+{
+    int ret;
+
+    vos_ssr_protect(__func__);
+    ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
+                            data, data_len);
+    vos_ssr_unprotect(__func__);
+
+    return ret;
+}
+
 static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
                                         struct wireless_dev *wdev,
                                         const void *data, int dataLen)
@@ -5462,6 +6036,22 @@
                  WIPHY_VENDOR_CMD_NEED_RUNNING,
         .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
     },
+    {
+        .info.vendor_id = QCA_NL80211_VENDOR_ID,
+        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
+        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+                 WIPHY_VENDOR_CMD_NEED_NETDEV |
+                 WIPHY_VENDOR_CMD_NEED_RUNNING,
+        .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
+    },
+    {
+        .info.vendor_id = QCA_NL80211_VENDOR_ID,
+        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
+        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+                 WIPHY_VENDOR_CMD_NEED_NETDEV |
+                 WIPHY_VENDOR_CMD_NEED_RUNNING,
+        .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
+    },
 #endif /* WLAN_FEATURE_EXTSCAN */
 /*EXT TDLS*/
     {
@@ -5608,6 +6198,22 @@
         .vendor_id = QCA_NL80211_VENDOR_ID,
         .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
     },
+    {
+        .vendor_id = QCA_NL80211_VENDOR_ID,
+        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
+    },
+    {
+        .vendor_id = QCA_NL80211_VENDOR_ID,
+        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
+    },
+    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
+        .vendor_id = QCA_NL80211_VENDOR_ID,
+        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
+    },
+    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
+        .vendor_id = QCA_NL80211_VENDOR_ID,
+        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
+    },
 #endif /* WLAN_FEATURE_EXTSCAN */
 /*EXT TDLS*/
     {