From e390be5cda04a4d165da4ab6708c92f7d2e6bfaf Mon Sep 17 00:00:00 2001 From: Sandeep Puligilla Date: Mon, 8 Feb 2016 17:07:05 -0800 Subject: [PATCH] qcacld-3.0: Remove pending scans from HDD scan queue Pending scan entries are not cleared during SSR execution which is causing scan failure after SSR recovery. Remove all pendings scans from global scan queue and send scan complete callback to NL with abort flag set. Change-Id: Iebffcf56ace59a3ded4df8141caf639c55f0b278 CRs-Fixed: 966580 --- core/hdd/src/wlan_hdd_power.c | 3 +- core/hdd/src/wlan_hdd_scan.c | 53 +++++++++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_scan.h | 2 ++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index ed1e47a6ce3b..ceba3887ebf4 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -61,6 +61,7 @@ #include #include +#include #include #include #include @@ -1299,7 +1300,7 @@ QDF_STATUS hdd_wlan_shutdown(void) cds_set_recovery_in_progress(true); cds_clear_concurrent_session_count(); - + hdd_cleanup_scan_queue(pHddCtx); hdd_reset_all_adapters(pHddCtx); hdd_ipa_uc_ssr_deinit(); diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index 15518b7d64e7..08c45ccd4ba7 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -2418,3 +2418,56 @@ int hdd_vendor_put_ifindex(struct sk_buff *skb, int ifindex) return 0; } + + +/** + * hdd_cleanup_scan_queue() - remove entries in scan queue + * + * Removes entries in scan queue and sends scan complete event to NL + * Return: None + */ +void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx) +{ + struct hdd_scan_req *hdd_scan_req; + qdf_list_node_t *node = NULL; + struct cfg80211_scan_request *req; + hdd_adapter_t *adapter; + uint8_t source; + bool aborted = true; + + if (NULL == hdd_ctx) { + hdd_err("HDD context is Null"); + return; + } + + qdf_spin_lock(&hdd_ctx->hdd_scan_req_q_lock); + while (!qdf_list_empty(&hdd_ctx->hdd_scan_req_q)) { + if (QDF_STATUS_SUCCESS != + qdf_list_remove_front(&hdd_ctx->hdd_scan_req_q, + &node)) { + qdf_spin_unlock(&hdd_ctx->hdd_scan_req_q_lock); + hdd_err("Failed to remove scan request"); + return; + } + qdf_spin_unlock(&hdd_ctx->hdd_scan_req_q_lock); + hdd_scan_req = (struct hdd_scan_req *)node; + req = hdd_scan_req->scan_request; + source = hdd_scan_req->source; + adapter = hdd_scan_req->adapter; + if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { + hdd_err("HDD adapter magic is invalid"); + } else { + if (NL_SCAN == source) + cfg80211_scan_done(req, aborted); + else + hdd_vendor_scan_callback(adapter, req, aborted); + hdd_info("removed Scan id: %d, req = %p", + hdd_scan_req->scan_id, req); + } + qdf_mem_free(hdd_scan_req); + qdf_spin_lock(&hdd_ctx->hdd_scan_req_q_lock); + } + qdf_spin_unlock(&hdd_ctx->hdd_scan_req_q_lock); + + return; +} diff --git a/core/hdd/src/wlan_hdd_scan.h b/core/hdd/src/wlan_hdd_scan.h index 05bc2754c354..5466d4a7cf86 100644 --- a/core/hdd/src/wlan_hdd_scan.h +++ b/core/hdd/src/wlan_hdd_scan.h @@ -68,5 +68,7 @@ int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, int data_len); int hdd_vendor_put_ifindex(struct sk_buff *skb, int ifindex); +void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx); + #endif /* end #if !defined(WLAN_HDD_SCAN_H) */