blob: d3b17a3ff80cb701b7accbd6cd334d2f7608bbe7 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Paul Zhang3a210c52016-12-08 10:18:12 +08002 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_scan.c
30 *
31 * WLAN Host Device Driver scan implementation
32 */
33
34#include <linux/wireless.h>
35#include <net/cfg80211.h>
36
37#include "wlan_hdd_includes.h"
38#include "cds_api.h"
39#include "cds_api.h"
40#include "ani_global.h"
41#include "dot11f.h"
42#include "cds_sched.h"
43#include "wlan_hdd_p2p.h"
44#include "wlan_hdd_trace.h"
45#include "wlan_hdd_scan.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080046#include "wlan_policy_mgr_api.h"
Dustin Brownceed67e2017-05-26 11:57:31 -070047#include "wlan_hdd_power.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080048#include "wma_api.h"
Sreelakshmi Konamki752f5b12016-07-13 11:16:38 +053049#include "cds_utils.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050
Paul Zhang3a210c52016-12-08 10:18:12 +080051#ifdef WLAN_UMAC_CONVERGENCE
52#include "wlan_cfg80211.h"
53#endif
Sandeep Puligillafdd201e2017-02-02 18:43:46 -080054#include <qca_vendor.h>
Sandeep Puligillad0004212017-02-26 18:34:56 -080055#include <wlan_cfg80211_scan.h>
Sandeep Puligillad0004212017-02-26 18:34:56 -080056
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080057#define MAX_RATES 12
58#define HDD_WAKE_LOCK_SCAN_DURATION (5 * 1000) /* in msec */
59
60#define SCAN_DONE_EVENT_BUF_SIZE 4096
61#define RATE_MASK 0x7f
62
63/**
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +053064 * enum essid_bcast_type - SSID broadcast type
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065 * @eBCAST_UNKNOWN: Broadcast unknown
66 * @eBCAST_NORMAL: Broadcast normal
67 * @eBCAST_HIDDEN: Broadcast hidden
68 */
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +053069enum essid_bcast_type {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080070 eBCAST_UNKNOWN = 0,
71 eBCAST_NORMAL = 1,
72 eBCAST_HIDDEN = 2,
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +053073};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080074
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080075/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080076 * hdd_vendor_scan_callback() - Scan completed callback event
77 * @hddctx: HDD context
78 * @req : Scan request
79 * @aborted : true scan aborted false scan success
80 *
81 * This function sends scan completed callback event to NL.
82 *
83 * Return: none
84 */
Jeff Johnson7f803c62017-08-29 14:23:20 -070085static void hdd_vendor_scan_callback(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080086 struct cfg80211_scan_request *req,
87 bool aborted)
88{
Jeff Johnson24d267e2017-08-28 11:43:07 -070089 struct hdd_context *hddctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080090 struct sk_buff *skb;
91 struct nlattr *attr;
92 int i;
93 uint8_t scan_status;
94 uint64_t cookie;
95
96 ENTER();
97
98 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
99 hdd_err("Invalid adapter magic");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530100 qdf_mem_free(req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800101 return;
102 }
Ryan Hsu9206a4e2016-01-19 17:23:13 -0800103 skb = cfg80211_vendor_event_alloc(hddctx->wiphy, &(adapter->wdev),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800104 SCAN_DONE_EVENT_BUF_SIZE + 4 + NLMSG_HDRLEN,
105 QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX,
106 GFP_KERNEL);
107
108 if (!skb) {
109 hdd_err("skb alloc failed");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530110 qdf_mem_free(req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800111 return;
112 }
113
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800114 cookie = (uintptr_t)req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800115 attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS);
116 if (!attr)
117 goto nla_put_failure;
118 for (i = 0; i < req->n_ssids; i++) {
Sandeep Puligilla75992052017-03-15 19:36:55 -0700119 if (nla_put(skb, i, req->ssids[i].ssid_len,
120 req->ssids[i].ssid)) {
121 hdd_err("Failed to add ssid");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800122 goto nla_put_failure;
Sandeep Puligilla75992052017-03-15 19:36:55 -0700123 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800124 }
125 nla_nest_end(skb, attr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800126 attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES);
127 if (!attr)
128 goto nla_put_failure;
129 for (i = 0; i < req->n_channels; i++) {
Sandeep Puligilla75992052017-03-15 19:36:55 -0700130 if (nla_put_u32(skb, i, req->channels[i]->center_freq)) {
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530131 hdd_err("Failed to add channel");
132 goto nla_put_failure;
133 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800134 }
135 nla_nest_end(skb, attr);
136
137 if (req->ie &&
138 nla_put(skb, QCA_WLAN_VENDOR_ATTR_SCAN_IE, req->ie_len,
Sandeep Puligilla75992052017-03-15 19:36:55 -0700139 req->ie)) {
140 hdd_err("Failed to add scan ie");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800141 goto nla_put_failure;
Sandeep Puligilla75992052017-03-15 19:36:55 -0700142 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800143 if (req->flags &&
Sandeep Puligilla75992052017-03-15 19:36:55 -0700144 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS, req->flags)) {
145 hdd_err("Failed to add scan flags");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800146 goto nla_put_failure;
Sandeep Puligilla75992052017-03-15 19:36:55 -0700147 }
148 if (hdd_wlan_nla_put_u64(skb,
149 QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
150 cookie)) {
151 hdd_err("Failed to add scan cookie");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800152 goto nla_put_failure;
Sandeep Puligilla75992052017-03-15 19:36:55 -0700153 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800154 scan_status = (aborted == true) ? VENDOR_SCAN_STATUS_ABORTED :
155 VENDOR_SCAN_STATUS_NEW_RESULTS;
Sandeep Puligilla75992052017-03-15 19:36:55 -0700156 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status)) {
157 hdd_err("Failed to add scan staus");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800158 goto nla_put_failure;
Sandeep Puligilla75992052017-03-15 19:36:55 -0700159 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800160 cfg80211_vendor_event(skb, GFP_KERNEL);
Sandeep Puligilla75992052017-03-15 19:36:55 -0700161 hdd_info("scan complete event sent to NL");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530162 qdf_mem_free(req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800163 return;
164
165nla_put_failure:
166 kfree_skb(skb);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530167 qdf_mem_free(req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800168}
Dustin Brown5df441e2016-10-17 15:05:36 -0700169#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
170/**
171 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
172 * @adapter: Pointer to the adapter
173 * @req : Scan request
174 * @aborted : true scan aborted false scan success
175 *
176 * This function notifies scan done to cfg80211
177 *
178 * Return: none
179 */
Jeff Johnson7f803c62017-08-29 14:23:20 -0700180static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
Dustin Brown5df441e2016-10-17 15:05:36 -0700181 struct cfg80211_scan_request *req,
182 bool aborted)
183{
184 struct cfg80211_scan_info info = {
185 .aborted = aborted
186 };
187
188 if (adapter->dev->flags & IFF_UP)
189 cfg80211_scan_done(req, &info);
190}
191#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
Rajeev Kumar Sirasanagandla043f4832016-09-08 18:21:50 +0530192/**
193 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
194 * @adapter: Pointer to the adapter
195 * @req : Scan request
196 * @aborted : true scan aborted false scan success
197 *
198 * This function notifies scan done to cfg80211
199 *
200 * Return: none
201 */
Jeff Johnson7f803c62017-08-29 14:23:20 -0700202static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
Rajeev Kumar Sirasanagandla043f4832016-09-08 18:21:50 +0530203 struct cfg80211_scan_request *req,
204 bool aborted)
205{
206 if (adapter->dev->flags & IFF_UP)
207 cfg80211_scan_done(req, aborted);
208}
209#else
210/**
211 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
212 * @adapter: Pointer to the adapter
213 * @req : Scan request
214 * @aborted : true scan aborted false scan success
215 *
216 * This function notifies scan done to cfg80211
217 *
218 * Return: none
219 */
Jeff Johnson7f803c62017-08-29 14:23:20 -0700220static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
Rajeev Kumar Sirasanagandla043f4832016-09-08 18:21:50 +0530221 struct cfg80211_scan_request *req,
222 bool aborted)
223{
224 cfg80211_scan_done(req, aborted);
225}
226#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227
Liangwei Dongaef84342016-10-21 05:28:00 -0400228#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
229/**
230 * wlan_hdd_sap_skip_scan_check() - The function will check OBSS
231 * scan skip or not for SAP.
232 * @hdd_ctx: pointer to hdd context.
233 * @request: pointer to scan request.
234 *
235 * This function will check the scan request's chan list against the
236 * previous ACS scan chan list. If all the chan are covered by
237 * previous ACS scan, we can skip the scan and return scan complete
238 * to save the SAP starting time.
239 *
240 * Return: true to skip the scan,
241 * false to continue the scan
242 */
Jeff Johnson24d267e2017-08-28 11:43:07 -0700243static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx,
Liangwei Dongaef84342016-10-21 05:28:00 -0400244 struct cfg80211_scan_request *request)
245{
246 int i, j;
247 bool skip;
248
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800249 hdd_debug("HDD_ACS_SKIP_STATUS = %d",
Liangwei Dongaef84342016-10-21 05:28:00 -0400250 hdd_ctx->skip_acs_scan_status);
251 if (hdd_ctx->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN)
252 return false;
253 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
254 if (hdd_ctx->last_acs_channel_list == NULL ||
255 hdd_ctx->num_of_channels == 0 ||
256 request->n_channels == 0) {
257 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
258 return false;
259 }
260 skip = true;
261 for (i = 0; i < request->n_channels ; i++) {
262 bool find = false;
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530263
Liangwei Dongaef84342016-10-21 05:28:00 -0400264 for (j = 0; j < hdd_ctx->num_of_channels; j++) {
265 if (hdd_ctx->last_acs_channel_list[j] ==
266 request->channels[i]->hw_value) {
267 find = true;
268 break;
269 }
270 }
271 if (!find) {
272 skip = false;
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800273 hdd_debug("Chan %d isn't in ACS chan list",
Liangwei Dongaef84342016-10-21 05:28:00 -0400274 request->channels[i]->hw_value);
275 break;
276 }
277 }
278 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
279 return skip;
280}
281#else
Jeff Johnson24d267e2017-08-28 11:43:07 -0700282static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx,
Liangwei Dongaef84342016-10-21 05:28:00 -0400283 struct cfg80211_scan_request *request)
284{
285 return false;
286}
287#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800288
Kabilan Kannan98440ce2017-06-27 00:28:27 -0700289static void __wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290{
Jeff Johnson7f803c62017-08-29 14:23:20 -0700291 struct hdd_adapter *adapter;
Mukul Sharma06adf262015-10-30 21:26:40 +0530292 struct cfg80211_scan_request *request;
Jeff Johnson24d267e2017-08-28 11:43:07 -0700293 struct hdd_context *hdd_ctx;
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530294
Jeff Johnson7f803c62017-08-29 14:23:20 -0700295 adapter = container_of(work, struct hdd_adapter, scan_block_work);
Mukul Sharma06adf262015-10-30 21:26:40 +0530296 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700297 hdd_err("HDD adapter context is invalid");
Mukul Sharma06adf262015-10-30 21:26:40 +0530298 return;
299 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800300
Kabilan Kannan98440ce2017-06-27 00:28:27 -0700301 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
302 if (0 != wlan_hdd_validate_context(hdd_ctx))
303 return;
304
Mukul Sharma06adf262015-10-30 21:26:40 +0530305 request = adapter->request;
306 if (request) {
307 request->n_ssids = 0;
308 request->n_channels = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800309
Jeff Johnsonb492d752016-06-28 14:29:35 -0700310 hdd_err("##In DFS Master mode. Scan aborted. Null result sent");
bings4c6cecf2017-04-05 08:24:29 +0800311 if (NL_SCAN == adapter->scan_source)
312 hdd_cfg80211_scan_done(adapter, request, true);
313 else
314 hdd_vendor_scan_callback(adapter, request, true);
Mukul Sharma06adf262015-10-30 21:26:40 +0530315 adapter->request = NULL;
316 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800317}
318
Kabilan Kannan98440ce2017-06-27 00:28:27 -0700319void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
320{
321 cds_ssr_protect(__func__);
322 __wlan_hdd_cfg80211_scan_block_cb(work);
323 cds_ssr_unprotect(__func__);
324}
325
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800326/**
Selvaraj, Sridhara9c72432016-06-24 17:08:42 +0530327 * wlan_hdd_copy_bssid_scan_request() - API to copy the bssid to Scan request
328 * @scan_req: Pointer to CSR Scan Request
329 * @request: scan request from Supplicant
330 *
331 * This API copies the BSSID in scan request from Supplicant and copies it to
332 * the CSR Scan request
333 *
334 * Return: None
335 */
Selvaraj, Sridhara11edcb2016-09-07 18:49:14 +0530336#if defined(CFG80211_SCAN_BSSID) || \
337 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
Selvaraj, Sridhara9c72432016-06-24 17:08:42 +0530338static inline void wlan_hdd_copy_bssid_scan_request(tCsrScanRequest *scan_req,
339 struct cfg80211_scan_request *request)
340{
Selvaraj, Sridhar11d49852016-08-29 10:56:32 +0530341 qdf_mem_copy(scan_req->bssid.bytes, request->bssid, QDF_MAC_ADDR_SIZE);
Selvaraj, Sridhara9c72432016-06-24 17:08:42 +0530342}
343#else
344static inline void wlan_hdd_copy_bssid_scan_request(tCsrScanRequest *scan_req,
345 struct cfg80211_scan_request *request)
346{
347}
348#endif
349
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530350/*
351 * wlan_hdd_update_scan_ies() - API to update the scan IEs of scan request
352 * with already stored default scan IEs
353 *
354 * @adapter: Pointer to HDD adapter
355 * @scan_info: Pointer to scan info in HDD adapter
356 * @scan_ie: Pointer to scan IE in scan request
357 * @scan_ie_len: Pointer to scan IE length in scan request
358 *
359 * Return: 0 on success; error number otherwise
360 */
Jeff Johnson7f803c62017-08-29 14:23:20 -0700361static int wlan_hdd_update_scan_ies(struct hdd_adapter *adapter,
Jeff Johnson37588942017-08-15 16:11:41 -0700362 struct hdd_scan_info *scan_info, uint8_t *scan_ie,
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +0530363 uint16_t *scan_ie_len)
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530364{
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +0530365 uint16_t rem_len = scan_info->default_scan_ies_len;
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530366 uint8_t *temp_ie = scan_info->default_scan_ies;
367 uint8_t *current_ie;
368 uint8_t elem_id;
369 uint16_t elem_len;
Selvaraj, Sridhar1472b592017-05-05 10:52:55 +0530370 bool add_ie = false;
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530371
372 if (!scan_info->default_scan_ies_len || !scan_info->default_scan_ies)
Jeff Johnsonb7a168b2017-03-06 15:33:52 -0800373 return 0;
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530374
375 while (rem_len >= 2) {
376 current_ie = temp_ie;
377 elem_id = *temp_ie++;
378 elem_len = *temp_ie++;
379 rem_len -= 2;
380
381 switch (elem_id) {
382 case DOT11F_EID_EXTCAP:
383 if (!wlan_hdd_cfg80211_get_ie_ptr(scan_ie, *scan_ie_len,
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +0530384 DOT11F_EID_EXTCAP))
385 add_ie = true;
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530386 break;
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +0530387 case IE_EID_VENDOR:
Agrawal Ashishb114b672017-05-09 17:24:39 +0530388 if ((0 != qdf_mem_cmp(&temp_ie[0], MBO_OUI_TYPE,
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +0530389 MBO_OUI_TYPE_SIZE)) ||
390 (0 == qdf_mem_cmp(&temp_ie[0], QCN_OUI_TYPE,
391 QCN_OUI_TYPE_SIZE)))
392 add_ie = true;
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530393 break;
394 }
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +0530395
396 if (add_ie && (((*scan_ie_len) + elem_len) >
397 SIR_MAC_MAX_ADD_IE_LENGTH)){
398 hdd_err("Not enough buffer to save default scan IE's");
399 return 0;
400 }
401
402 if (add_ie) {
403 qdf_mem_copy(scan_ie + (*scan_ie_len),
404 current_ie, elem_len + 2);
405 (*scan_ie_len) += (elem_len + 2);
406 add_ie = false;
407 }
408
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530409 temp_ie += elem_len;
410 rem_len -= elem_len;
411 }
412 return 0;
413}
414
Selvaraj, Sridhara9c72432016-06-24 17:08:42 +0530415/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800416 * __wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request
417 * @wiphy: Pointer to wiphy
418 * @dev: Pointer to net device
419 * @request: Pointer to scan request
420 * @source: scan request source(NL/Vendor scan)
421 *
422 * This API responds to scan trigger and update cfg80211 scan database
423 * later, scan dump command can be used to recieve scan results
424 *
425 * Return: 0 for success, non zero for failure
426 */
427static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 struct cfg80211_scan_request *request,
429 uint8_t source)
430{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 struct net_device *dev = request->wdev->netdev;
Jeff Johnson7f803c62017-08-29 14:23:20 -0700432 struct hdd_adapter *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson24d267e2017-08-28 11:43:07 -0700433 struct hdd_context *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800434 struct hdd_config *cfg_param = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800435 int status;
Jeff Johnson37588942017-08-15 16:11:41 -0700436 struct hdd_scan_info *pScanInfo = NULL;
Jeff Johnson7f803c62017-08-29 14:23:20 -0700437 struct hdd_adapter *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800438 uint16_t con_dfs_ch;
Sandeep Puligillad0004212017-02-26 18:34:56 -0800439 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +0530440 uint8_t curr_session_id;
441 enum scan_reject_states curr_reason;
Srinivas Girigowda28c776b2017-03-08 00:09:34 -0800442 static uint32_t scan_ebusy_cnt;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800443
444 ENTER();
445
Anurag Chouhan6d760662016-02-20 16:05:43 +0530446 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700447 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800448 return -EINVAL;
449 }
450
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +0530451 if (wlan_hdd_validate_session_id(pAdapter->sessionId)) {
452 hdd_err("invalid session id: %d", pAdapter->sessionId);
453 return -EINVAL;
454 }
455
Rajeev Kumar46d26b72016-06-07 13:32:10 -0700456 status = wlan_hdd_validate_context(pHddCtx);
Rajeev Kumar46d26b72016-06-07 13:32:10 -0700457 if (0 != status)
458 return status;
459
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530460 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 TRACE_CODE_HDD_CFG80211_SCAN,
462 pAdapter->sessionId, request->n_channels));
463
Chandrasekaran, Manishekar2859de42016-02-11 16:17:38 +0530464 if (!sme_is_session_id_valid(pHddCtx->hHal, pAdapter->sessionId))
465 return -EINVAL;
466
Ashish Kumar Dhanotiya470af292017-05-31 20:46:00 +0530467 if ((eConnectionState_Associated ==
468 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)->
469 conn_info.connState) &&
470 (!pHddCtx->config->enable_connected_scan)) {
471 hdd_info("enable_connected_scan is false, Aborting scan");
472 pAdapter->request = request;
473 pAdapter->scan_source = source;
474 schedule_work(&pAdapter->scan_block_work);
475 return 0;
476 }
477
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800478 hdd_debug("Device_mode %s(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800479 hdd_device_mode_to_string(pAdapter->device_mode),
480 pAdapter->device_mode);
481
Abhishek Singh995a53b2017-04-07 12:12:47 +0530482 /*
yeshwanth sriram guntuka479e4c02017-04-26 13:12:44 +0530483 * IBSS vdev does not need to scan to establish
Abhishek Singh995a53b2017-04-07 12:12:47 +0530484 * IBSS connection. If IBSS vdev need to support scan,
485 * Firmware need to make the change to add self peer
486 * per mac for IBSS vdev.
487 */
yeshwanth sriram guntuka479e4c02017-04-26 13:12:44 +0530488 if (QDF_IBSS_MODE == pAdapter->device_mode) {
489 hdd_err("Scan not supported for IBSS");
Abhishek Singh995a53b2017-04-07 12:12:47 +0530490 return -EINVAL;
491 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800492
493 cfg_param = pHddCtx->config;
494 pScanInfo = &pAdapter->scan_info;
495
496 /* Block All Scan during DFS operation and send null scan result */
497 con_sap_adapter = hdd_get_con_sap_adapter(pAdapter, true);
498 if (con_sap_adapter) {
499 con_dfs_ch = con_sap_adapter->sessionCtx.ap.sapConfig.channel;
500 if (con_dfs_ch == AUTO_CHANNEL_SELECT)
501 con_dfs_ch =
502 con_sap_adapter->sessionCtx.ap.operatingChannel;
503
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700504 if (!policy_mgr_is_hw_dbs_capable(pHddCtx->hdd_psoc) &&
505 wlan_reg_is_dfs_ch(pHddCtx->hdd_pdev, con_dfs_ch)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800506 /* Provide empty scan result during DFS operation since
507 * scanning not supported during DFS. Reason is
508 * following case:
509 * DFS is supported only in SCC for MBSSID Mode.
510 * We shall not return EBUSY or ENOTSUPP as when Primary
511 * AP is operating in DFS channel and secondary AP is
512 * started. Though we force SCC in driver, the hostapd
513 * issues obss scan before starting secAP. This results
514 * in MCC in DFS mode. Thus we return null scan result.
515 * If we return scan failure hostapd fails secondary AP
516 * startup.
517 */
Liangwei Dongaef84342016-10-21 05:28:00 -0400518 hdd_err("##In DFS Master mode. Scan aborted");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800519 pAdapter->request = request;
bings4c6cecf2017-04-05 08:24:29 +0800520 pAdapter->scan_source = source;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800521
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522 schedule_work(&pAdapter->scan_block_work);
523 return 0;
524 }
525 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526#ifdef FEATURE_WLAN_TDLS
527 /* if tdls disagree scan right now, return immediately.
528 * tdls will schedule the scan when scan is allowed.
529 * (return SUCCESS)
530 * or will reject the scan if any TDLS is in progress.
531 * (return -EBUSY)
532 */
533 status = wlan_hdd_tdls_scan_callback(pAdapter, wiphy,
Nitesh Shah9ed1a9f2017-01-05 18:55:05 +0530534 request, source);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535 if (status <= 0) {
536 if (!status)
Jeff Johnsonb492d752016-06-28 14:29:35 -0700537 hdd_err("TDLS in progress.scan rejected %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800538 status);
539 else
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800540 hdd_warn("TDLS teardown is ongoing %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800541 status);
Abhishek Singhaf1d0c92016-04-27 13:46:59 +0530542 hdd_wlan_block_scan_by_tdls_event();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800543 return status;
544 }
545#endif
546
547 /* Check if scan is allowed at this point of time */
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -0800548 if (hdd_is_connection_in_progress(&curr_session_id, &curr_reason)) {
Srinivas Girigowda28c776b2017-03-08 00:09:34 -0800549 scan_ebusy_cnt++;
550 hdd_err("Scan not allowed. scan_ebusy_cnt: %d", scan_ebusy_cnt);
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +0530551 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
552 pHddCtx->last_scan_reject_reason != curr_reason ||
553 !pHddCtx->last_scan_reject_timestamp) {
554 pHddCtx->last_scan_reject_session_id = curr_session_id;
555 pHddCtx->last_scan_reject_reason = curr_reason;
556 pHddCtx->last_scan_reject_timestamp =
Abhishek Singh6451c232017-07-12 18:04:36 +0530557 jiffies_to_msecs(jiffies) +
558 SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singh00130682017-07-14 10:46:17 +0530559 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +0530560 } else {
Abhishek Singh00130682017-07-14 10:46:17 +0530561 pHddCtx->scan_reject_cnt++;
562 hdd_debug("curr_session id %d curr_reason %d count %d threshold time has elapsed? %d",
563 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhishek Singh6451c232017-07-12 18:04:36 +0530564 qdf_system_time_after(jiffies_to_msecs(jiffies),
565 pHddCtx->last_scan_reject_timestamp));
Abhishek Singh00130682017-07-14 10:46:17 +0530566 if ((pHddCtx->scan_reject_cnt >=
567 SCAN_REJECT_THRESHOLD) &&
568 qdf_system_time_after(jiffies_to_msecs(jiffies),
Abhishek Singh6451c232017-07-12 18:04:36 +0530569 pHddCtx->last_scan_reject_timestamp)) {
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +0530570 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singh00130682017-07-14 10:46:17 +0530571 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +0530572 if (pHddCtx->config->enable_fatal_event) {
573 cds_flush_logs(WLAN_LOG_TYPE_FATAL,
yeshwanth sriram guntukaf4f1bdc2017-02-28 13:14:30 +0530574 WLAN_LOG_INDICATOR_HOST_DRIVER,
575 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
576 false,
577 pHddCtx->config->enableSelfRecovery);
yeshwanth sriram guntukaf4f1bdc2017-02-28 13:14:30 +0530578 } else {
Dustin Brown100201e2017-07-10 11:48:40 -0700579 hdd_err("Triggering SSR due to scan stuck");
580 cds_trigger_recovery();
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +0530581 }
582 }
583 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584 return -EBUSY;
585 }
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +0530586 pHddCtx->last_scan_reject_timestamp = 0;
587 pHddCtx->last_scan_reject_session_id = 0xFF;
588 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singh00130682017-07-14 10:46:17 +0530589 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +0530590
Liangwei Dongaef84342016-10-21 05:28:00 -0400591 /* Check whether SAP scan can be skipped or not */
592 if (pAdapter->device_mode == QDF_SAP_MODE &&
593 wlan_hdd_sap_skip_scan_check(pHddCtx, request)) {
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800594 hdd_debug("sap scan skipped");
Liangwei Dongaef84342016-10-21 05:28:00 -0400595 pAdapter->request = request;
bings4c6cecf2017-04-05 08:24:29 +0800596 pAdapter->scan_source = source;
Liangwei Dongaef84342016-10-21 05:28:00 -0400597 schedule_work(&pAdapter->scan_block_work);
598 return 0;
599 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600
Sandeep Puligillad0004212017-02-26 18:34:56 -0800601 /* Store the Scan IE's in Adapter*/
602 if (request->ie_len) {
603 /* save this for future association (join requires this) */
604 memset(&pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE));
605 memcpy(pScanInfo->scanAddIE.addIEdata, request->ie,
606 request->ie_len);
607 pScanInfo->scanAddIE.length = request->ie_len;
608
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +0530609 wlan_hdd_update_scan_ies(pAdapter, pScanInfo,
Sandeep Puligillad0004212017-02-26 18:34:56 -0800610 pScanInfo->scanAddIE.addIEdata,
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +0530611 &pScanInfo->scanAddIE.length);
Sandeep Puligillad0004212017-02-26 18:34:56 -0800612
613 if ((QDF_STA_MODE == pAdapter->device_mode) ||
614 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode) ||
615 (QDF_P2P_DEVICE_MODE == pAdapter->device_mode)
616 ) {
617 pwextBuf->roamProfile.pAddIEScan =
618 pScanInfo->scanAddIE.addIEdata;
619 pwextBuf->roamProfile.nAddIEScanLength =
620 pScanInfo->scanAddIE.length;
621 }
622 }
623#ifdef NAPIER_SCAN
624 return wlan_cfg80211_scan(pHddCtx->hdd_pdev, request, source);
625#else
626 /* Below code will be removed once common scan module is available.*/
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530627 qdf_mem_zero(&scan_req, sizeof(scan_req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628
Deepthi Gowri6acee342016-10-28 15:00:38 +0530629 scan_req.timestamp = qdf_mc_timer_get_system_time();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630
631 /* Even though supplicant doesn't provide any SSIDs, n_ssids is
632 * set to 1. Because of this, driver is assuming that this is not
633 * wildcard scan and so is not aging out the scan results.
634 */
635 if ((request->ssids) && (request->n_ssids == 1) &&
636 ('\0' == request->ssids->ssid[0])) {
637 request->n_ssids = 0;
638 }
639
640 if ((request->ssids) && (0 < request->n_ssids)) {
641 tCsrSSIDInfo *SsidInfo;
642 int j;
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530643
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800644 scan_req.SSIDs.numOfSSIDs = request->n_ssids;
645 /* Allocate num_ssid tCsrSSIDInfo structure */
646 SsidInfo = scan_req.SSIDs.SSIDList =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530647 qdf_mem_malloc(request->n_ssids * sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800648
649 if (NULL == scan_req.SSIDs.SSIDList) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700650 hdd_err("memory alloc failed SSIDInfo buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651 return -ENOMEM;
652 }
653
654 /* copy all the ssid's and their length */
655 for (j = 0; j < request->n_ssids; j++, SsidInfo++) {
656 /* get the ssid length */
657 SsidInfo->SSID.length = request->ssids[j].ssid_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530658 qdf_mem_copy(SsidInfo->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659 &request->ssids[j].ssid[0],
660 SsidInfo->SSID.length);
661 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800662 hdd_debug("SSID number %d: %s", j,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663 SsidInfo->SSID.ssId);
664 }
665 /* set the scan type to active */
666 scan_req.scanType = eSIR_ACTIVE_SCAN;
Krunal Sonif07bb382016-03-10 13:02:11 -0800667 } else if (QDF_P2P_GO_MODE == pAdapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800668 /* set the scan type to active */
669 scan_req.scanType = eSIR_ACTIVE_SCAN;
670 } else {
671 /*
672 * Set the scan type to passive if there is no ssid list
673 * provided else set default type configured in the driver.
674 */
675 if (!request->ssids)
676 scan_req.scanType = eSIR_PASSIVE_SCAN;
677 else
678 scan_req.scanType = pHddCtx->ioctl_scan_mode;
679 }
Liangwei Dongcf7fcf02016-12-28 02:13:38 -0500680 if (scan_req.scanType == eSIR_PASSIVE_SCAN) {
681 scan_req.minChnTime = cfg_param->nPassiveMinChnTime;
682 scan_req.maxChnTime = cfg_param->nPassiveMaxChnTime;
683 } else {
684 scan_req.minChnTime = cfg_param->nActiveMinChnTime;
685 scan_req.maxChnTime = cfg_param->nActiveMaxChnTime;
686 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800687
Selvaraj, Sridhara9c72432016-06-24 17:08:42 +0530688 wlan_hdd_copy_bssid_scan_request(&scan_req, request);
689
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800690 /* set BSSType to default type */
691 scan_req.BSSType = eCSR_BSS_TYPE_ANY;
692
693 if (MAX_CHANNEL < request->n_channels) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700694 hdd_warn("No of Scan Channels exceeded limit: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695 request->n_channels);
696 request->n_channels = MAX_CHANNEL;
697 }
698
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800699 if (request->n_channels) {
700 char chList[(request->n_channels * 5) + 1];
701 int len;
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530702
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530703 channelList = qdf_mem_malloc(request->n_channels);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800704 if (NULL == channelList) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700705 hdd_err("channelList malloc failed channelList");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800706 status = -ENOMEM;
707 goto free_mem;
708 }
709 for (i = 0, len = 0; i < request->n_channels; i++) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700710 if (WLAN_REG_IS_11P_CH(
711 pHddCrequest->channels[i]->hw_value))
Sreelakshmi Konamki752f5b12016-07-13 11:16:38 +0530712 continue;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700713
Sreelakshmi Konamki752f5b12016-07-13 11:16:38 +0530714 channelList[num_chan] = request->channels[i]->hw_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715 len += snprintf(chList + len, 5, "%d ", channelList[i]);
Sreelakshmi Konamki752f5b12016-07-13 11:16:38 +0530716 num_chan++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717 }
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800718 hdd_debug("Channel-List: %s", chList);
719 hdd_debug("No. of Scan Channels: %d", num_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800720 }
Sreelakshmi Konamki752f5b12016-07-13 11:16:38 +0530721 if (!num_chan) {
722 hdd_err("Received zero non-dsrc channels");
723 status = -EINVAL;
724 goto free_mem;
725 }
726
727 scan_req.ChannelInfo.numOfChannels = num_chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800728 scan_req.ChannelInfo.ChannelList = channelList;
729
730 /* set requestType to full scan */
731 scan_req.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
732
733 /* Flush the scan results(only p2p beacons) for STA scan and P2P
734 * search (Flush on both full scan and social scan but not on single
735 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
736 */
737
738 /* Supplicant does single channel scan after 8-way handshake
739 * and in that case driver shoudnt flush scan results. If
740 * driver flushes the scan results here and unfortunately if
741 * the AP doesnt respond to our probe req then association
742 * fails which is not desired
743 */
744
Deepthi Gowri7e11bc32016-08-26 18:18:47 +0530745 if ((request->n_ssids == 1) &&
746 (request->ssids != NULL) &&
747 qdf_mem_cmp(&request->ssids[0], "DIRECT-", 7))
748 is_p2p_scan = true;
749
750 if (is_p2p_scan ||
751 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN)) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700752 hdd_debug("Flushing P2P Results");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753 sme_scan_flush_p2p_result(WLAN_HDD_GET_HAL_CTX(pAdapter),
Deepthi Gowri7e11bc32016-08-26 18:18:47 +0530754 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756 if (request->ie_len) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757 scan_req.uIEFieldLen = pScanInfo->scanAddIE.length;
758 scan_req.pIEField = pScanInfo->scanAddIE.addIEdata;
759
760 pP2pIe = wlan_hdd_get_p2p_ie_ptr((uint8_t *) request->ie,
761 request->ie_len);
762 if (pP2pIe != NULL) {
763#ifdef WLAN_FEATURE_P2P_DEBUG
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530764 if (((global_p2p_connection_status ==
765 P2P_GO_NEG_COMPLETED)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766 || (global_p2p_connection_status ==
767 P2P_GO_NEG_PROCESS))
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530768 && (QDF_P2P_CLIENT_MODE ==
769 pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 global_p2p_connection_status =
771 P2P_CLIENT_CONNECTING_STATE_1;
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800772 hdd_debug("[P2P State] Changing state from Go nego completed to Connection is started");
773 hdd_debug("[P2P]P2P Scanning is started for 8way Handshake");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774 } else
775 if ((global_p2p_connection_status ==
776 P2P_CLIENT_DISCONNECTED_STATE)
Krunal Sonif07bb382016-03-10 13:02:11 -0800777 && (QDF_P2P_CLIENT_MODE ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 pAdapter->device_mode)) {
779 global_p2p_connection_status =
780 P2P_CLIENT_CONNECTING_STATE_2;
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800781 hdd_debug("[P2P State] Changing state from Disconnected state to Connection is started");
782 hdd_debug("[P2P]P2P Scanning is started for 4way Handshake");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800783 }
784#endif
785
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530786 /* no_cck will be set during p2p find to
787 * disable 11b rates
788 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800789 if (request->no_cck) {
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800790 hdd_debug("This is a P2P Search");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800791 scan_req.p2pSearch = 1;
792
793 if (request->n_channels ==
794 WLAN_HDD_P2P_SOCIAL_CHANNELS) {
795 /* set requestType to P2P Discovery */
796 scan_req.requestType =
797 eCSR_SCAN_P2P_DISCOVERY;
798 }
799
800 /*
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530801 * Skip Dfs Channel in case of P2P Search if
802 * it is set in ini file
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 */
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530804 if (cfg_param->skipDfsChnlInP2pSearch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805 scan_req.skipDfsChnlInP2pSearch = 1;
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530806 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807 scan_req.skipDfsChnlInP2pSearch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808 }
809 }
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +0530810 } else {
811 if (pScanInfo->default_scan_ies &&
812 pScanInfo->default_scan_ies_len) {
813 qdf_mem_copy(pScanInfo->scanAddIE.addIEdata,
814 pScanInfo->default_scan_ies,
815 pScanInfo->default_scan_ies_len);
816 pScanInfo->scanAddIE.length =
817 pScanInfo->default_scan_ies_len;
818 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800819 }
820
821 /* acquire the wakelock to avoid the apps suspend during the scan. To
822 * address the following issues.
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530823 * 1) Disconnected scenario: we are not allowing the suspend as WLAN
824 * is not in BMPS/IMPS this result in android trying to suspend
825 * aggressively and backing off for long time, this result in apps
826 * running at full power for long time.
827 * 2) Connected scenario: If we allow the suspend during the scan,
828 * RIVA will be stuck in full power because of resume BMPS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800829 */
830 hdd_prevent_suspend_timeout(HDD_WAKE_LOCK_SCAN_DURATION,
831 WIFI_POWER_EVENT_WAKELOCK_SCAN);
832
Srinivas Girigowdadf41e122017-03-06 18:51:21 -0800833 hdd_debug("requestType %d, scanType %d, minChnTime %d, maxChnTime %d,p2pSearch %d, skipDfsChnlIn P2pSearch %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800834 scan_req.requestType, scan_req.scanType,
835 scan_req.minChnTime, scan_req.maxChnTime,
836 scan_req.p2pSearch, scan_req.skipDfsChnlInP2pSearch);
Edhar, Mahesh Kumar6a501522015-11-20 10:14:13 +0530837#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 0))
838 if (request->flags & NL80211_SCAN_FLAG_FLUSH)
839 sme_scan_flush_result(WLAN_HDD_GET_HAL_CTX(pAdapter));
840#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800841 status = sme_scan_request(WLAN_HDD_GET_HAL_CTX(pAdapter),
842 pAdapter->sessionId, &scan_req,
843 &hdd_cfg80211_scan_done_callback, dev);
844
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530845 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700846 hdd_err("sme_scan_request returned error %d", status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530847 if (QDF_STATUS_E_RESOURCES == status) {
Srinivas Girigowda28c776b2017-03-08 00:09:34 -0800848 scan_ebusy_cnt++;
849 hdd_err("HO is in progress. Defer scan scan_ebusy_cnt: %d",
850 scan_ebusy_cnt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800851 status = -EBUSY;
852 } else {
853 status = -EIO;
854 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800855 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
856 goto free_mem;
857 }
858 wlan_hdd_scan_request_enqueue(pAdapter, request, source,
859 scan_req.scan_id, scan_req.timestamp);
860 pAdapter->scan_info.mScanPending = true;
Padma, Santhosh Kumar31bac742017-01-16 19:34:45 +0530861 pHddCtx->beacon_probe_rsp_cnt_per_scan = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800862free_mem:
863 if (scan_req.SSIDs.SSIDList)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530864 qdf_mem_free(scan_req.SSIDs.SSIDList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865
866 if (channelList)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530867 qdf_mem_free(channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800868
Srinivas Girigowda28c776b2017-03-08 00:09:34 -0800869 if (status == 0)
870 scan_ebusy_cnt = 0;
871
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872 EXIT();
873 return status;
Paul Zhang3a210c52016-12-08 10:18:12 +0800874#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875
Sandeep Puligillad0004212017-02-26 18:34:56 -0800876}
877
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878/**
879 * wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request
880 * @wiphy: Pointer to wiphy
881 * @dev: Pointer to net device
882 * @request: Pointer to scan request
883 *
884 * This API responds to scan trigger and update cfg80211 scan database
885 * later, scan dump command can be used to recieve scan results
886 *
887 * Return: 0 for success, non zero for failure
888 */
889int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800890 struct cfg80211_scan_request *request)
891{
892 int ret;
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530893
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800894 cds_ssr_protect(__func__);
895 ret = __wlan_hdd_cfg80211_scan(wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896 request, NL_SCAN);
897 cds_ssr_unprotect(__func__);
898 return ret;
899}
900
901/**
Nitesh Shah9ed1a9f2017-01-05 18:55:05 +0530902 * wlan_hdd_cfg80211_tdls_scan() - API to process cfg80211 scan request
903 * @wiphy: Pointer to wiphy
904 * @request: Pointer to scan request
905 * @source: scan request source(NL/Vendor scan)
906 *
907 * This API responds to scan trigger and update cfg80211 scan database
908 * later, scan dump command can be used to recieve scan results. This
909 * function gets called when tdls module queues the scan request.
910 *
911 * Return: 0 for success, non zero for failure.
912 */
913int wlan_hdd_cfg80211_tdls_scan(struct wiphy *wiphy,
914 struct cfg80211_scan_request *request,
915 uint8_t source)
916{
917 int ret;
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +0530918
Nitesh Shah9ed1a9f2017-01-05 18:55:05 +0530919 cds_ssr_protect(__func__);
920 ret = __wlan_hdd_cfg80211_scan(wiphy,
921 request, source);
922 cds_ssr_unprotect(__func__);
923 return ret;
924}
925
926/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927 * wlan_hdd_get_rates() -API to get the rates from scan request
928 * @wiphy: Pointer to wiphy
929 * @band: Band
930 * @rates: array of rates
931 * @rate_count: number of rates
932 *
933 * Return: o for failure, rate bitmap for success
934 */
935static uint32_t wlan_hdd_get_rates(struct wiphy *wiphy,
Dustin Browna30892e2016-10-12 17:28:36 -0700936 enum nl80211_band band,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937 const u8 *rates, unsigned int rate_count)
938{
939 uint32_t j, count, rate_bitmap = 0;
940 uint32_t rate;
941 bool found;
942
943 for (count = 0; count < rate_count; count++) {
944 rate = ((rates[count]) & RATE_MASK) * 5;
945 found = false;
946 for (j = 0; j < wiphy->bands[band]->n_bitrates; j++) {
947 if (wiphy->bands[band]->bitrates[j].bitrate == rate) {
948 found = true;
949 rate_bitmap |= (1 << j);
950 break;
951 }
952 }
953 if (!found)
954 return 0;
955 }
956 return rate_bitmap;
957}
958
959/**
960 * wlan_hdd_send_scan_start_event() -API to send the scan start event
961 * @wiphy: Pointer to wiphy
962 * @wdev: Pointer to net device
963 * @cookie: scan identifier
964 *
965 * Return: return 0 on success and negative error code on failure
966 */
967static int wlan_hdd_send_scan_start_event(struct wiphy *wiphy,
968 struct wireless_dev *wdev, uint64_t cookie)
969{
970 struct sk_buff *skb;
971 int ret;
972
973 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) +
974 NLA_HDRLEN + NLMSG_HDRLEN);
975 if (!skb) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700976 hdd_err(" reply skb alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800977 return -ENOMEM;
978 }
979
Dustin Brownbb7e2f52016-10-17 12:16:35 -0700980 if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
981 cookie)) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700982 hdd_err("nla put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800983 kfree_skb(skb);
984 return -EINVAL;
985 }
986
987 ret = cfg80211_vendor_cmd_reply(skb);
988
989 /* Send a scan started event to supplicant */
990 skb = cfg80211_vendor_event_alloc(wiphy, wdev,
991 sizeof(u64) + 4 + NLMSG_HDRLEN,
992 QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX, GFP_KERNEL);
993 if (!skb) {
Jeff Johnsonb492d752016-06-28 14:29:35 -0700994 hdd_err("skb alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995 return -ENOMEM;
996 }
997
Dustin Brownbb7e2f52016-10-17 12:16:35 -0700998 if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
999 cookie)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001000 kfree_skb(skb);
1001 return -EINVAL;
1002 }
1003 cfg80211_vendor_event(skb, GFP_KERNEL);
1004
1005 return ret;
1006}
Sreelakshmi Konamki8b8257c2016-12-12 15:44:54 +05301007
1008/**
1009 * wlan_hdd_copy_bssid() - API to copy the bssid to vendor Scan request
1010 * @request: Pointer to vendor scan request
1011 * @bssid: Pointer to BSSID
1012 *
1013 * This API copies the specific BSSID received from Supplicant and copies it to
1014 * the vendor Scan request
1015 *
1016 * Return: None
1017 */
1018#if defined(CFG80211_SCAN_BSSID) || \
1019 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
1020static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request,
1021 uint8_t *bssid)
1022{
1023 qdf_mem_copy(request->bssid, bssid, QDF_MAC_ADDR_SIZE);
1024}
1025#else
1026static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request,
1027 uint8_t *bssid)
1028{
1029}
1030#endif
1031
Jeff Johnson7f803c62017-08-29 14:23:20 -07001032static void hdd_process_vendor_acs_response(struct hdd_adapter *adapter)
Kapil Gupta8878ad92017-02-13 11:56:04 +05301033{
1034 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags)) {
1035 if (QDF_TIMER_STATE_RUNNING ==
1036 qdf_mc_timer_get_current_state(&adapter->sessionCtx.
1037 ap.vendor_acs_timer)) {
1038 qdf_mc_timer_stop(&adapter->sessionCtx.
1039 ap.vendor_acs_timer);
1040 }
1041 }
1042}
1043
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +05301044#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
1045 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
1046/**
1047 * wlan_hdd_vendor_scan_random_attr() - check and fill scan randomization attrs
1048 * @wiphy: Pointer to wiphy
1049 * @request: Pointer to scan request
1050 * @wdev: Pointer to wireless device
1051 * @tb: Pointer to nl attributes
1052 *
1053 * This function is invoked to check whether vendor scan needs
1054 * probe req source addr, if so populates mac_addr and mac_addr_mask
1055 * in scan request with nl attrs.
1056 *
1057 * Return: 0 - on success, negative value on failure
1058 */
1059static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy,
1060 struct cfg80211_scan_request *request,
1061 struct wireless_dev *wdev,
1062 struct nlattr **tb)
1063{
1064 uint32_t i;
1065 int32_t len = QDF_MAC_ADDR_SIZE;
1066
1067 if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
1068 return 0;
1069
1070 if (!(wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR) ||
1071 (wdev->current_bss)) {
1072 hdd_err("SCAN RANDOMIZATION not supported");
1073 return -EOPNOTSUPP;
1074 }
1075
1076 if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] ||
1077 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK])
1078 return -EINVAL;
1079
1080 if ((nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]) != len) ||
1081 (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) != len))
1082 return -EINVAL;
1083
1084 qdf_mem_copy(request->mac_addr,
1085 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]), len);
1086
1087 qdf_mem_copy(request->mac_addr_mask,
1088 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]), len);
1089
1090 /* avoid configure on multicast address */
1091 if (!cds_is_group_addr(request->mac_addr_mask) ||
1092 cds_is_group_addr(request->mac_addr))
1093 return -EINVAL;
1094
1095 for (i = 0; i < ETH_ALEN; i++)
1096 request->mac_addr[i] &= request->mac_addr_mask[i];
1097
1098 return 0;
1099}
1100#else
1101static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy,
1102 struct cfg80211_scan_request *request,
1103 struct wireless_dev *wdev,
1104 struct nlattr **tb)
1105{
1106 return 0;
1107}
1108#endif
1109
Jeff Johnson45caf632017-06-06 16:38:04 -07001110static const
1111struct nla_policy scan_policy[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = {
1112 [QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32},
1113 [QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG},
1114 [QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64},
1115};
1116
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001117/**
1118 * __wlan_hdd_cfg80211_vendor_scan() - API to process venor scan request
1119 * @wiphy: Pointer to wiphy
1120 * @wdev: Pointer to net device
1121 * @data : Pointer to the data
1122 * @data_len : length of the data
1123 *
1124 * API to process venor scan request.
1125 *
1126 * Return: return 0 on success and negative error code on failure
1127 */
1128static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
1129 struct wireless_dev *wdev, const void *data,
1130 int data_len)
1131{
1132 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
1133 struct cfg80211_scan_request *request = NULL;
1134 struct nlattr *attr;
Dustin Browna30892e2016-10-12 17:28:36 -07001135 enum nl80211_band band;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001136 uint8_t n_channels = 0, n_ssid = 0, ie_len = 0;
1137 uint32_t tmp, count, j;
1138 unsigned int len;
1139 struct ieee80211_channel *chan;
Jeff Johnson24d267e2017-08-28 11:43:07 -07001140 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Jeff Johnson7f803c62017-08-29 14:23:20 -07001141 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001142 int ret;
1143
Jeff Johnson1f61b612016-02-12 16:28:33 -08001144 ENTER_DEV(wdev->netdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001145
1146 ret = wlan_hdd_validate_context(hdd_ctx);
1147 if (0 != ret)
1148 return ret;
1149
Dustin Brown3fb15042017-08-15 15:54:49 -07001150 if (hdd_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, data, data_len,
1151 scan_policy)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001152 hdd_err("Invalid ATTR");
1153 return -EINVAL;
1154 }
1155
1156 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
1157 nla_for_each_nested(attr,
1158 tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES], tmp)
1159 n_channels++;
1160 } else {
Srinivas Girigowda5da651b2017-08-04 11:22:54 -07001161 for (band = 0; band < HDD_NUM_NL80211_BANDS; band++)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001162 if (wiphy->bands[band])
1163 n_channels += wiphy->bands[band]->n_channels;
1164 }
1165
1166 if (MAX_CHANNEL < n_channels) {
1167 hdd_err("Exceed max number of channels: %d", n_channels);
1168 return -EINVAL;
1169 }
1170 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS])
1171 nla_for_each_nested(attr,
1172 tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], tmp)
1173 n_ssid++;
1174
1175 if (MAX_SCAN_SSID < n_ssid) {
1176 hdd_err("Exceed max number of SSID: %d", n_ssid);
1177 return -EINVAL;
1178 }
1179
1180 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE])
1181 ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]);
1182 else
1183 ie_len = 0;
1184
1185 len = sizeof(*request) + (sizeof(*request->ssids) * n_ssid) +
1186 (sizeof(*request->channels) * n_channels) + ie_len;
1187
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301188 request = qdf_mem_malloc(len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001189 if (!request)
1190 goto error;
1191 if (n_ssid)
1192 request->ssids = (void *)&request->channels[n_channels];
1193 request->n_ssids = n_ssid;
1194 if (ie_len) {
1195 if (request->ssids)
1196 request->ie = (void *)(request->ssids + n_ssid);
1197 else
1198 request->ie = (void *)(request->channels + n_channels);
1199 }
1200
1201 count = 0;
1202 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
1203 nla_for_each_nested(attr,
Jeff Johnson45caf632017-06-06 16:38:04 -07001204 tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
1205 tmp) {
1206 if (nla_len(attr) != sizeof(uint32_t)) {
1207 hdd_err("len is not correct for frequency %d",
1208 count);
1209 goto error;
1210 }
Dustin Brown2eb1e452017-08-15 12:40:34 -07001211 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001212 if (!chan)
1213 goto error;
1214 if (chan->flags & IEEE80211_CHAN_DISABLED)
1215 continue;
1216 request->channels[count] = chan;
1217 count++;
1218 }
1219 } else {
Srinivas Girigowda5da651b2017-08-04 11:22:54 -07001220 for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221 if (!wiphy->bands[band])
1222 continue;
1223 for (j = 0; j < wiphy->bands[band]->n_channels;
1224 j++) {
1225 chan = &wiphy->bands[band]->channels[j];
1226 if (chan->flags & IEEE80211_CHAN_DISABLED)
1227 continue;
1228 request->channels[count] = chan;
1229 count++;
1230 }
1231 }
1232 }
1233
1234 if (!count)
1235 goto error;
1236
1237 request->n_channels = count;
1238 count = 0;
1239 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
1240 nla_for_each_nested(attr, tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS],
1241 tmp) {
1242 request->ssids[count].ssid_len = nla_len(attr);
SaidiReddy Yenuga89c58d22016-09-21 13:44:35 +05301243 if (request->ssids[count].ssid_len >
1244 SIR_MAC_MAX_SSID_LENGTH) {
1245 hdd_err("SSID Len %d is not correct for network %d",
1246 request->ssids[count].ssid_len, count);
1247 goto error;
1248 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001249 memcpy(request->ssids[count].ssid, nla_data(attr),
1250 nla_len(attr));
1251 count++;
1252 }
1253 }
1254
1255 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]) {
1256 request->ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]);
1257 memcpy((void *)request->ie,
1258 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]),
1259 request->ie_len);
1260 }
1261
Srinivas Girigowda5da651b2017-08-04 11:22:54 -07001262 for (count = 0; count < HDD_NUM_NL80211_BANDS; count++)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001263 if (wiphy->bands[count])
1264 request->rates[count] =
1265 (1 << wiphy->bands[count]->n_bitrates) - 1;
1266
1267 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES]) {
1268 nla_for_each_nested(attr,
Jeff Johnson1c7c51d2016-11-02 11:34:12 -07001269 tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES],
1270 tmp) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001271 band = nla_type(attr);
Srinivas Girigowda5da651b2017-08-04 11:22:54 -07001272 if (band >= HDD_NUM_NL80211_BANDS)
Jeff Johnson1c7c51d2016-11-02 11:34:12 -07001273 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001274 if (!wiphy->bands[band])
1275 continue;
Jeff Johnson1c7c51d2016-11-02 11:34:12 -07001276 request->rates[band] =
1277 wlan_hdd_get_rates(wiphy,
1278 band, nla_data(attr),
1279 nla_len(attr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001280 }
1281 }
1282
1283 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]) {
1284 request->flags =
1285 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]);
1286 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
Jeff Johnson1c7c51d2016-11-02 11:34:12 -07001287 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
Jeff Johnsonb492d752016-06-28 14:29:35 -07001288 hdd_err("LOW PRIORITY SCAN not supported");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001289 goto error;
1290 }
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +05301291
1292 if (wlan_hdd_vendor_scan_random_attr(wiphy, request, wdev, tb))
1293 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001294 }
Sreelakshmi Konamki8b8257c2016-12-12 15:44:54 +05301295
1296 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) {
1297 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) <
1298 QDF_MAC_ADDR_SIZE) {
1299 hdd_err("invalid bssid length");
1300 goto error;
1301 }
1302 wlan_hdd_copy_bssid(request,
1303 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]));
1304 }
Kapil Gupta8878ad92017-02-13 11:56:04 +05301305
1306 /* Check if external acs was requested on this adapter */
1307 hdd_process_vendor_acs_response(adapter);
1308
SaidiReddy Yenuga39ac0cd2017-03-28 17:31:51 +05301309 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE])
1310 request->no_cck =
1311 nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001312 request->wdev = wdev;
1313 request->wiphy = wiphy;
1314 request->scan_start = jiffies;
1315
Sandeep Puligilla09a19a42017-03-29 16:10:07 -07001316 ret = __wlan_hdd_cfg80211_scan(wiphy, request, VENDOR_SCAN);
1317 if (0 != ret) {
1318 hdd_err("Scan Failed. Ret = %d", ret);
1319 qdf_mem_free(request);
1320 return ret;
1321 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001322 ret = wlan_hdd_send_scan_start_event(wiphy, wdev, (uintptr_t)request);
1323
1324 return ret;
1325error:
1326 hdd_err("Scan Request Failed");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301327 qdf_mem_free(request);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001328 return -EINVAL;
1329}
1330
1331/**
1332 * wlan_hdd_cfg80211_vendor_scan() -API to process venor scan request
1333 * @wiphy: Pointer to wiphy
1334 * @dev: Pointer to net device
1335 * @data : Pointer to the data
1336 * @data_len : length of the data
1337 *
1338 * This is called from userspace to request scan.
1339 *
1340 * Return: Return the Success or Failure code.
1341 */
1342int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
1343 struct wireless_dev *wdev, const void *data,
1344 int data_len)
1345{
1346 int ret;
1347
1348 cds_ssr_protect(__func__);
1349 ret = __wlan_hdd_cfg80211_vendor_scan(wiphy, wdev,
1350 data, data_len);
1351 cds_ssr_unprotect(__func__);
1352
1353 return ret;
1354}
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +05301355
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +05301356/**
1357 * __wlan_hdd_vendor_abort_scan() - API to process vendor command for
1358 * abort scan
1359 * @wiphy: Pointer to wiphy
1360 * @wdev: Pointer to net device
1361 * @data : Pointer to the data
1362 * @data_len : length of the data
1363 *
1364 * API to process vendor abort scan
1365 *
1366 * Return: zero for success and non zero for failure
1367 */
1368static int __wlan_hdd_vendor_abort_scan(
1369 struct wiphy *wiphy, const void *data,
1370 int data_len)
1371{
Jeff Johnson24d267e2017-08-28 11:43:07 -07001372 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +05301373 int ret;
1374
1375 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1376 hdd_err("Command not allowed in FTM mode");
1377 return -EINVAL;
1378 }
1379
1380 ret = wlan_hdd_validate_context(hdd_ctx);
1381 if (0 != ret)
1382 return ret;
1383
Dustin Brown3fb15042017-08-15 15:54:49 -07001384 wlan_vendor_abort_scan(hdd_ctx->hdd_pdev, data, data_len);
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -07001385
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +05301386 return ret;
1387}
1388
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +05301389/**
1390 * wlan_hdd_vendor_abort_scan() - API to process vendor command for
1391 * abort scan
1392 * @wiphy: Pointer to wiphy
1393 * @wdev: Pointer to net device
1394 * @data : Pointer to the data
1395 * @data_len : length of the data
1396 *
1397 * This is called from supplicant to abort scan
1398 *
1399 * Return: zero for success and non zero for failure
1400 */
1401int wlan_hdd_vendor_abort_scan(
1402 struct wiphy *wiphy, struct wireless_dev *wdev,
1403 const void *data, int data_len)
1404{
1405 int ret;
1406
1407 cds_ssr_protect(__func__);
1408 ret = __wlan_hdd_vendor_abort_scan(wiphy,
1409 data,
1410 data_len);
1411 cds_ssr_unprotect(__func__);
1412
1413 return ret;
1414}
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +05301415
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001416/**
1417 * wlan_hdd_scan_abort() - abort ongoing scan
1418 * @pAdapter: Pointer to interface adapter
1419 *
1420 * Return: 0 for success, non zero for failure
1421 */
Jeff Johnson7f803c62017-08-29 14:23:20 -07001422int wlan_hdd_scan_abort(struct hdd_adapter *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001423{
Jeff Johnson24d267e2017-08-28 11:43:07 -07001424 struct hdd_context *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson37588942017-08-15 16:11:41 -07001425 struct hdd_scan_info *pScanInfo = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001426
1427 pScanInfo = &pAdapter->scan_info;
1428
Abhishek Singh69ccb512017-04-25 11:58:16 +05301429 if (pScanInfo->mScanPending)
1430 wlan_abort_scan(pHddCtx->hdd_pdev, INVAL_PDEV_ID,
1431 pAdapter->sessionId, INVALID_SCAN_ID, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001432 return 0;
1433}
1434
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +05301435#ifdef FEATURE_WLAN_SCAN_PNO
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437 * __wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
1438 * @wiphy: Pointer to wiphy
1439 * @dev: Pointer network device
1440 * @request: Pointer to cfg80211 scheduled scan start request
1441 *
1442 * Return: 0 for success, non zero for failure
1443 */
1444static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
1445 struct net_device *dev,
1446 struct
1447 cfg80211_sched_scan_request
1448 *request)
1449{
Jeff Johnson7f803c62017-08-29 14:23:20 -07001450 struct hdd_adapter *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson24d267e2017-08-28 11:43:07 -07001451 struct hdd_context *pHddCtx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452 tHalHandle hHal;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001453 int ret = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001454
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301455 ENTER();
1456
Anurag Chouhan6d760662016-02-20 16:05:43 +05301457 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb492d752016-06-28 14:29:35 -07001458 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001459 return -EINVAL;
1460 }
1461
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05301462 if (wlan_hdd_validate_session_id(pAdapter->sessionId)) {
1463 hdd_err("invalid session id: %d", pAdapter->sessionId);
1464 return -EINVAL;
1465 }
1466
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1468 ret = wlan_hdd_validate_context(pHddCtx);
1469
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301470 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001471 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001472
Abhishek Singh0481d662017-04-11 18:20:11 +05301473 if (!pHddCtx->config->PnoOffload) {
1474 hdd_debug("PnoOffloadis not enabled!!!");
1475 return -EINVAL;
1476 }
1477
Ashish Kumar Dhanotiya470af292017-05-31 20:46:00 +05301478 if ((eConnectionState_Associated ==
1479 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)->
1480 conn_info.connState) &&
1481 (!pHddCtx->config->enable_connected_scan)) {
1482 hdd_info("enable_connected_scan is false, Aborting scan");
1483 return -EBUSY;
1484 }
1485
Arif Hussain0060bef2017-02-17 13:56:34 -08001486 if (!sme_is_session_id_valid(pHddCtx->hHal, pAdapter->sessionId))
1487 return -EINVAL;
1488
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001489 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1490 if (NULL == hHal) {
Jeff Johnsonb492d752016-06-28 14:29:35 -07001491 hdd_err("HAL context is Null!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001492 return -EINVAL;
1493 }
1494
Dustin Brown20b6fcf2017-05-17 15:35:17 -07001495 return wlan_cfg80211_sched_scan_start(pHddCtx->hdd_pdev, dev, request,
1496 pHddCtx->config->scan_backoff_multiplier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001497}
1498
1499/**
1500 * wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
1501 * @wiphy: Pointer to wiphy
1502 * @dev: Pointer network device
1503 * @request: Pointer to cfg80211 scheduled scan start request
1504 *
1505 * Return: 0 for success, non zero for failure
1506 */
1507int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
1508 struct net_device *dev,
1509 struct cfg80211_sched_scan_request
1510 *request)
1511{
1512 int ret;
1513
1514 cds_ssr_protect(__func__);
1515 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
1516 cds_ssr_unprotect(__func__);
1517
1518 return ret;
1519}
1520
Dustin Brownf27bce82016-11-03 12:52:27 -07001521int wlan_hdd_sched_scan_stop(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522{
Jeff Johnson7f803c62017-08-29 14:23:20 -07001523 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson24d267e2017-08-28 11:43:07 -07001524 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001525 tHalHandle hHal;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526
Dustin Brownf27bce82016-11-03 12:52:27 -07001527 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528
Anurag Chouhan6d760662016-02-20 16:05:43 +05301529 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb492d752016-06-28 14:29:35 -07001530 hdd_err("Command not allowed in FTM mode");
Abhishek Singh0481d662017-04-11 18:20:11 +05301531 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532 }
1533
Dustin Brownf27bce82016-11-03 12:52:27 -07001534 if (wlan_hdd_validate_session_id(adapter->sessionId)) {
1535 hdd_err("invalid session id: %d", adapter->sessionId);
Abhishek Singh0481d662017-04-11 18:20:11 +05301536 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05301537 }
1538
Dustin Brownf27bce82016-11-03 12:52:27 -07001539 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1540 if (NULL == hdd_ctx) {
Jeff Johnsonb492d752016-06-28 14:29:35 -07001541 hdd_err("HDD context is Null");
Abhishek Singh0481d662017-04-11 18:20:11 +05301542 return -EINVAL;
1543 }
1544 if (!hdd_ctx->config->PnoOffload) {
1545 hdd_debug("PnoOffloadis not enabled!!!");
1546 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547 }
1548
Dustin Brownf27bce82016-11-03 12:52:27 -07001549 hHal = WLAN_HDD_GET_HAL_CTX(adapter);
1550 if (NULL == hHal) {
1551 hdd_err(" HAL context is Null!!!");
Abhishek Singh0481d662017-04-11 18:20:11 +05301552 return -EINVAL;
Dustin Brownf27bce82016-11-03 12:52:27 -07001553 }
1554
Abhishek Singhb20db962017-03-03 21:28:46 +05301555 return wlan_cfg80211_sched_scan_stop(hdd_ctx->hdd_pdev, dev);
Dustin Brownf27bce82016-11-03 12:52:27 -07001556}
1557
1558/**
1559 * __wlan_hdd_cfg80211_sched_scan_stop() - stop cfg80211 scheduled scan(pno)
1560 * @dev: Pointer network device
1561 *
1562 * This is a wrapper around wlan_hdd_sched_scan_stop() that returns success
1563 * in the event that the driver is currently recovering or unloading. This
1564 * prevents a race condition where we get a scan stop from kernel during
1565 * a driver unload from PLD.
1566 *
1567 * Return: 0 for success, non zero for failure
1568 */
1569static int __wlan_hdd_cfg80211_sched_scan_stop(struct net_device *dev)
1570{
1571 int err;
1572
1573 ENTER_DEV(dev);
1574
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001575 /* The return 0 is intentional when Recovery and Load/Unload in
1576 * progress. We did observe a crash due to a return of
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001577 * failure in sched_scan_stop , especially for a case where the unload
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +05301578 * of the happens at the same time. The function
1579 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only
1580 * when the sched_scan_stop returns success. If it returns a failure ,
1581 * then its next invocation due to the clean up of the second interface
1582 * will have the dev pointer corresponding to the first one leading to
1583 * a crash.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 */
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301585 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Srinivas Girigowdadf41e122017-03-06 18:51:21 -08001586 hdd_info("Recovery in Progress. State: 0x%x Ignore!!!",
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001587 cds_get_driver_state());
Dustin Brownf27bce82016-11-03 12:52:27 -07001588 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589 }
1590
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001591 if (cds_is_load_or_unload_in_progress()) {
Srinivas Girigowdadf41e122017-03-06 18:51:21 -08001592 hdd_info("Unload/Load in Progress, state: 0x%x. Ignore!!!",
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001593 cds_get_driver_state());
Dustin Brownf27bce82016-11-03 12:52:27 -07001594 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595 }
1596
Dustin Brownf27bce82016-11-03 12:52:27 -07001597 err = wlan_hdd_sched_scan_stop(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001598
1599 EXIT();
Dustin Brownf27bce82016-11-03 12:52:27 -07001600 return err;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001601}
1602
Dustin Browndfc5ef62017-08-16 15:20:11 -07001603#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
1605 struct net_device *dev)
1606{
1607 int ret;
1608
1609 cds_ssr_protect(__func__);
Dustin Brownf27bce82016-11-03 12:52:27 -07001610 ret = __wlan_hdd_cfg80211_sched_scan_stop(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001611 cds_ssr_unprotect(__func__);
1612
1613 return ret;
1614}
Dustin Browndfc5ef62017-08-16 15:20:11 -07001615#else
1616int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
1617 struct net_device *dev,
1618 uint64_t reqid)
1619{
1620 int ret;
1621
1622 cds_ssr_protect(__func__);
1623 ret = __wlan_hdd_cfg80211_sched_scan_stop(dev);
1624 cds_ssr_unprotect(__func__);
1625
1626 return ret;
1627}
1628#endif /* KERNEL_VERSION(4, 12, 0) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629#endif /*FEATURE_WLAN_SCAN_PNO */
1630
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +05301631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
Ashish Kumar Dhanotiya0f2ef952017-04-07 02:22:13 +05301632 defined(CFG80211_ABORT_SCAN)
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +05301633/**
1634 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
1635 * @wiphy: Pointer to wiphy
1636 * @wdev: Pointer to wireless device structure
1637 *
1638 * This function is used to abort an ongoing scan
1639 *
1640 * Return: None
1641 */
1642static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
1643 struct wireless_dev *wdev)
1644{
1645 struct net_device *dev = wdev->netdev;
Jeff Johnson7f803c62017-08-29 14:23:20 -07001646 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson24d267e2017-08-28 11:43:07 -07001647 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +05301648 int ret;
1649
1650 ENTER_DEV(dev);
1651
1652 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1653 hdd_err("Command not allowed in FTM mode");
1654 return;
1655 }
1656
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05301657 if (wlan_hdd_validate_session_id(adapter->sessionId)) {
1658 hdd_err("invalid session id: %d", adapter->sessionId);
1659 return;
1660 }
1661
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +05301662 ret = wlan_hdd_validate_context(hdd_ctx);
Kabilan Kannan703fc292017-05-18 18:06:09 -07001663 if (ret)
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +05301664 return;
1665
Sandeep Puligillad0004212017-02-26 18:34:56 -08001666 wlan_cfg80211_abort_scan(hdd_ctx->hdd_pdev);
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -07001667
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +05301668 EXIT();
1669}
1670
1671/**
1672 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
1673 * @wiphy: Pointer to wiphy
1674 * @wdev: Pointer to wireless device structure
1675 *
1676 * Wrapper to __wlan_hdd_cfg80211_abort_scan() -
1677 * function is used to abort an ongoing scan
1678 *
1679 * Return: None
1680 */
1681void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
1682 struct wireless_dev *wdev)
1683{
1684 cds_ssr_protect(__func__);
1685 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
1686 cds_ssr_unprotect(__func__);
1687}
1688#endif
Prashanth Bhatta527fd752016-04-28 12:35:23 -07001689
1690/**
1691 * hdd_scan_context_destroy() - Destroy scan context
1692 * @hdd_ctx: HDD context.
1693 *
1694 * Destroy scan context.
1695 *
1696 * Return: None.
1697 */
Jeff Johnson24d267e2017-08-28 11:43:07 -07001698void hdd_scan_context_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07001699{
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05301700 qdf_spinlock_destroy(&hdd_ctx->sched_scan_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07001701}
1702
1703/**
1704 * hdd_scan_context_init() - Initialize scan context
1705 * @hdd_ctx: HDD context.
1706 *
1707 * Initialize scan related resources like spin lock and lists.
1708 *
1709 * Return: 0 on success and errno on failure.
1710 */
Jeff Johnson24d267e2017-08-28 11:43:07 -07001711int hdd_scan_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07001712{
1713 qdf_spinlock_create(&hdd_ctx->sched_scan_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07001714 return 0;
1715}