diff options
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 4 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 12 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_scan.c | 92 |
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; } |
