summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/hdd/inc/wlan_hdd_main.h4
-rw-r--r--core/hdd/src/wlan_hdd_main.c12
-rw-r--r--core/hdd/src/wlan_hdd_scan.c92
3 files changed, 73 insertions, 35 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index aba1d43d8dfc..ee03e2118640 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1384,8 +1384,6 @@ struct hdd_adapter_s {
/* TODO Move this to sta Ctx */
struct wireless_dev wdev;
- struct cfg80211_scan_request *request;
- struct cfg80211_scan_request *vendor_request;
/** ops checks if Opportunistic Power Save is Enable or Not
* ctw stores ctWindow value once we receive Opps command from
@@ -1542,6 +1540,8 @@ struct hdd_adapter_s {
struct delayed_work acs_pending_work;
struct work_struct scan_block_work;
+ qdf_list_t blocked_scan_request_q;
+ qdf_mutex_t blocked_scan_request_q_lock;
#ifdef MSM_PLATFORM
unsigned long prev_rx_packets;
unsigned long prev_tx_packets;
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 5da466658294..c577362fb196 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -517,10 +517,13 @@ static int __hdd_netdev_notifier_call(struct notifier_block *nb,
msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
if (!rc)
hdd_err("Timeout occurred while waiting for abortscan");
- } else {
- cds_flush_work(&adapter->scan_block_work);
- hdd_debug("Scan is not Pending from user");
}
+ cds_flush_work(&adapter->scan_block_work);
+ /* Need to clean up blocked scan request */
+ wlan_hdd_cfg80211_scan_block_cb(&adapter->scan_block_work);
+ qdf_list_destroy(&adapter->blocked_scan_request_q);
+ qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
+ hdd_debug("Scan is not Pending from user");
/*
* After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
* of return status of hdd_stop call, kernel resets the IFF_UP
@@ -4442,6 +4445,9 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
}
INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
+ qdf_list_create(&adapter->blocked_scan_request_q,
+ CFG_MAX_SCAN_COUNT_MAX);
+ qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter);
mutex_init(&cfgState->remain_on_chan_ctx_lock);
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
index eb81c2208cc1..de093bd68900 100644
--- a/core/hdd/src/wlan_hdd_scan.c
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -1623,35 +1623,35 @@ static void __wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
hdd_adapter_t *adapter = container_of(work,
hdd_adapter_t, scan_block_work);
struct cfg80211_scan_request *request;
- hdd_context_t *hdd_ctx;
+ struct hdd_scan_req *blocked_scan_req;
+ qdf_list_node_t *node = NULL;
if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
hdd_err("HDD adapter context is invalid");
return;
}
- hdd_ctx = WLAN_HDD_GET_CTX(adapter);
- if (0 != wlan_hdd_validate_context(hdd_ctx))
- return;
+ qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
- request = adapter->request;
- if (request) {
+ while (!qdf_list_empty(&adapter->blocked_scan_request_q)) {
+ qdf_list_remove_front(&adapter->blocked_scan_request_q,
+ &node);
+ blocked_scan_req = qdf_container_of(node, struct hdd_scan_req,
+ node);
+ request = blocked_scan_req->scan_request;
request->n_ssids = 0;
request->n_channels = 0;
-
- hdd_err("##In DFS Master mode. Scan aborted. Null result sent");
- hdd_cfg80211_scan_done(adapter, request, true);
- adapter->request = NULL;
+ if (blocked_scan_req->source == NL_SCAN) {
+ hdd_err("Scan aborted. Null result sent");
+ hdd_cfg80211_scan_done(adapter, request, true);
+ } else {
+ hdd_err("Vendor scan aborted. Null result sent");
+ hdd_vendor_scan_callback(adapter, request, true);
+ }
+ qdf_mem_free(blocked_scan_req);
}
- request = adapter->vendor_request;
- if (request) {
- request->n_ssids = 0;
- request->n_channels = 0;
- hdd_err("In DFS Master mode. Scan aborted. Null result sent");
- hdd_vendor_scan_callback(adapter, request, true);
- adapter->vendor_request = NULL;
- }
+ qdf_mutex_release(&adapter->blocked_scan_request_q_lock);
}
void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
@@ -1916,6 +1916,43 @@ static void wlan_hdd_free_voui(tCsrScanRequest *scan_req)
qdf_mem_free(scan_req->voui);
}
+static int
+wlan_hdd_enqueue_blocked_scan_request(struct net_device *dev,
+ struct cfg80211_scan_request *request,
+ uint8_t source)
+{
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ struct hdd_scan_req *blocked_scan_req =
+ qdf_mem_malloc(sizeof(*blocked_scan_req));
+ int ret = 0;
+
+ if (!blocked_scan_req) {
+ hdd_err("Failed to allocate scan_req");
+ return -EINVAL;
+ }
+
+ blocked_scan_req->adapter = adapter;
+ blocked_scan_req->scan_request = request;
+ blocked_scan_req->source = source;
+ blocked_scan_req->scan_id = 0;
+
+ qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
+ if (qdf_list_size(&adapter->blocked_scan_request_q) <
+ CFG_MAX_SCAN_COUNT_MAX)
+ qdf_list_insert_back(&adapter->blocked_scan_request_q,
+ &blocked_scan_req->node);
+ else
+ ret = -EINVAL;
+ qdf_mutex_release(&adapter->blocked_scan_request_q_lock);
+
+ if (ret) {
+ hdd_err("Maximum number of block scan request reached!");
+ qdf_mem_free(blocked_scan_req);
+ }
+
+ return ret;
+}
+
/* Define short name to use in cds_trigger_recovery */
#define SCAN_FAILURE CDS_SCAN_ATTEMPT_FAILURES
@@ -1983,10 +2020,8 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
conn_info.connState) &&
(!pHddCtx->config->enable_connected_scan)) {
hdd_info("enable_connected_scan is false, Aborting scan");
- if (NL_SCAN == source)
- pAdapter->request = request;
- else
- pAdapter->vendor_request = request;
+ if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
+ return -EAGAIN;
schedule_work(&pAdapter->scan_block_work);
return 0;
}
@@ -2043,10 +2078,9 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
* startup.
*/
hdd_err("##In DFS Master mode. Scan aborted");
- if (NL_SCAN == source)
- pAdapter->request = request;
- else
- pAdapter->vendor_request = request;
+ if (wlan_hdd_enqueue_blocked_scan_request(dev, request,
+ source))
+ return -EAGAIN;
schedule_work(&pAdapter->scan_block_work);
return 0;
}
@@ -2147,10 +2181,8 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
if (pAdapter->device_mode == QDF_SAP_MODE &&
wlan_hdd_sap_skip_scan_check(pHddCtx, request)) {
hdd_debug("sap scan skipped");
- if (NL_SCAN == source)
- pAdapter->request = request;
- else
- pAdapter->vendor_request = request;
+ if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
+ return -EAGAIN;
schedule_work(&pAdapter->scan_block_work);
return 0;
}