Browse Source

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
Sandeep Puligilla 9 years ago
parent
commit
e390be5cda
3 changed files with 57 additions and 1 deletions
  1. 2 1
      core/hdd/src/wlan_hdd_power.c
  2. 53 0
      core/hdd/src/wlan_hdd_scan.c
  3. 2 0
      core/hdd/src/wlan_hdd_scan.h

+ 2 - 1
core/hdd/src/wlan_hdd_power.c

@@ -61,6 +61,7 @@
 
 #include <linux/inetdevice.h>
 #include <wlan_hdd_cfg.h>
+#include <wlan_hdd_scan.h>
 #include <wlan_hdd_cfg80211.h>
 #include <net/addrconf.h>
 #include <wlan_hdd_ipa.h>
@@ -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();

+ 53 - 0
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;
+}

+ 2 - 0
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) */