xref: /wlan-dirver/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c (revision e22f9adc774eb030715d9a453ec9ea346916ed3b)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_hdd_scan.c
22  *
23  * WLAN Host Device Driver scan implementation
24  */
25 
26 #include <linux/wireless.h>
27 #include <net/cfg80211.h>
28 
29 #include "wlan_hdd_includes.h"
30 #include "cds_api.h"
31 #include "cds_api.h"
32 #include "ani_global.h"
33 #include "dot11f.h"
34 #include "cds_sched.h"
35 #include "osif_sync.h"
36 #include "wlan_hdd_p2p.h"
37 #include "wlan_hdd_trace.h"
38 #include "wlan_hdd_scan.h"
39 #include "wlan_policy_mgr_api.h"
40 #include "wlan_hdd_power.h"
41 #include "wma_api.h"
42 #include "cds_utils.h"
43 #include "wlan_p2p_ucfg_api.h"
44 #include "cfg_ucfg_api.h"
45 
46 #include <qca_vendor.h>
47 #include <wlan_cfg80211_scan.h>
48 #include "wlan_utility.h"
49 #include "wlan_hdd_object_manager.h"
50 #include "nan_ucfg_api.h"
51 
52 #define SCAN_DONE_EVENT_BUF_SIZE 4096
53 #define RATE_MASK 0x7f
54 
55 /**
56  * hdd_vendor_scan_callback() - Scan completed callback event
57  * @adapter: HDD adapter
58  * @req: Scan request
59  * @aborted: true scan aborted false scan success
60  *
61  * This function sends scan completed callback event to NL.
62  *
63  * Return: none
64  */
65 static void hdd_vendor_scan_callback(struct hdd_adapter *adapter,
66 					struct cfg80211_scan_request *req,
67 					bool aborted)
68 {
69 	struct hdd_context *hddctx = WLAN_HDD_GET_CTX(adapter);
70 	struct sk_buff *skb;
71 	struct nlattr *attr;
72 	int i;
73 	uint8_t scan_status;
74 	uint64_t cookie;
75 	enum qca_nl80211_vendor_subcmds_index index =
76 		QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX;
77 
78 	hdd_enter();
79 
80 	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
81 		hdd_err("Invalid adapter magic");
82 		qdf_mem_free(req);
83 		return;
84 	}
85 	skb = wlan_cfg80211_vendor_event_alloc(hddctx->wiphy, &adapter->wdev,
86 					       SCAN_DONE_EVENT_BUF_SIZE +
87 					       4 + NLMSG_HDRLEN,
88 					       index, GFP_KERNEL);
89 	if (!skb) {
90 		hdd_err("skb alloc failed");
91 		qdf_mem_free(req);
92 		return;
93 	}
94 
95 	cookie = (uintptr_t)req;
96 	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS);
97 	if (!attr)
98 		goto nla_put_failure;
99 	for (i = 0; i < req->n_ssids; i++) {
100 		if (nla_put(skb, i, req->ssids[i].ssid_len,
101 			req->ssids[i].ssid)) {
102 			hdd_err("Failed to add ssid");
103 			goto nla_put_failure;
104 		}
105 	}
106 	nla_nest_end(skb, attr);
107 	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES);
108 	if (!attr)
109 		goto nla_put_failure;
110 	for (i = 0; i < req->n_channels; i++) {
111 		if (nla_put_u32(skb, i, req->channels[i]->center_freq)) {
112 			hdd_err("Failed to add channel");
113 			goto nla_put_failure;
114 		}
115 	}
116 	nla_nest_end(skb, attr);
117 
118 	if (req->ie &&
119 		nla_put(skb, QCA_WLAN_VENDOR_ATTR_SCAN_IE, req->ie_len,
120 			req->ie)) {
121 		hdd_err("Failed to add scan ie");
122 		goto nla_put_failure;
123 	}
124 	if (req->flags &&
125 		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS, req->flags)) {
126 		hdd_err("Failed to add scan flags");
127 		goto nla_put_failure;
128 	}
129 	if (hdd_wlan_nla_put_u64(skb,
130 				  QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
131 				  cookie)) {
132 		hdd_err("Failed to add scan cookie");
133 		goto nla_put_failure;
134 	}
135 	scan_status = (aborted == true) ? VENDOR_SCAN_STATUS_ABORTED :
136 		VENDOR_SCAN_STATUS_NEW_RESULTS;
137 	if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status)) {
138 		hdd_err("Failed to add scan status");
139 		goto nla_put_failure;
140 	}
141 	wlan_cfg80211_vendor_event(skb, GFP_KERNEL);
142 	hdd_info("scan complete event sent to NL");
143 	qdf_mem_free(req);
144 	return;
145 
146 nla_put_failure:
147 	wlan_cfg80211_vendor_free_skb(skb);
148 	qdf_mem_free(req);
149 }
150 
151 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
152 /**
153  * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
154  * @adapter: Pointer to the adapter
155  * @req : Scan request
156  * @aborted : true scan aborted false scan success
157  *
158  * This function notifies scan done to cfg80211
159  *
160  * Return: none
161  */
162 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
163 				   struct cfg80211_scan_request *req,
164 				   bool aborted)
165 {
166 	struct cfg80211_scan_info info = {
167 		.aborted = aborted
168 	};
169 
170 	if (adapter->dev->flags & IFF_UP)
171 		cfg80211_scan_done(req, &info);
172 }
173 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
174 /**
175  * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
176  * @adapter: Pointer to the adapter
177  * @req : Scan request
178  * @aborted : true scan aborted false scan success
179  *
180  * This function notifies scan done to cfg80211
181  *
182  * Return: none
183  */
184 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
185 				   struct cfg80211_scan_request *req,
186 				   bool aborted)
187 {
188 	if (adapter->dev->flags & IFF_UP)
189 		cfg80211_scan_done(req, aborted);
190 }
191 #else
192 /**
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  */
202 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
203 				   struct cfg80211_scan_request *req,
204 				   bool aborted)
205 {
206 	cfg80211_scan_done(req, aborted);
207 }
208 #endif
209 
210 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
211 /**
212  * wlan_hdd_sap_skip_scan_check() - The function will check OBSS
213  *         scan skip or not for SAP.
214  * @hdd_ctx: pointer to hdd context.
215  * @request: pointer to scan request.
216  *
217  * This function will check the scan request's chan list against the
218  * previous ACS scan chan list. If all the chan are covered by
219  * previous ACS scan, we can skip the scan and return scan complete
220  * to save the SAP starting time.
221  *
222  * Return: true to skip the scan,
223  *            false to continue the scan
224  */
225 static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx,
226 	struct cfg80211_scan_request *request)
227 {
228 	int i, j;
229 	bool skip;
230 
231 	hdd_debug("HDD_ACS_SKIP_STATUS = %d",
232 		hdd_ctx->skip_acs_scan_status);
233 	if (hdd_ctx->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN)
234 		return false;
235 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
236 	if (!hdd_ctx->last_acs_freq_list ||
237 	    hdd_ctx->num_of_channels == 0 ||
238 	    request->n_channels == 0) {
239 		qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
240 		return false;
241 	}
242 	skip = true;
243 	for (i = 0; i < request->n_channels ; i++) {
244 		bool find = false;
245 
246 		for (j = 0; j < hdd_ctx->num_of_channels; j++) {
247 			if (hdd_ctx->last_acs_freq_list[j] ==
248 			    request->channels[i]->center_freq) {
249 				find = true;
250 				break;
251 			}
252 		}
253 		if (!find) {
254 			skip = false;
255 			hdd_debug("Freq %d isn't in ACS freq list",
256 				  request->channels[i]->center_freq);
257 			break;
258 		}
259 	}
260 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
261 	return skip;
262 }
263 #else
264 static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx,
265 	struct cfg80211_scan_request *request)
266 {
267 	return false;
268 }
269 #endif
270 
271 void wlan_hdd_cfg80211_scan_block(struct hdd_adapter *adapter)
272 {
273 	struct cfg80211_scan_request *request;
274 	struct scan_req *blocked_scan_req;
275 	qdf_list_node_t *node;
276 
277 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
278 		hdd_err("HDD adapter context is invalid");
279 		return;
280 	}
281 
282 	qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
283 
284 	while (!qdf_list_empty(&adapter->blocked_scan_request_q)) {
285 		qdf_list_remove_front(&adapter->blocked_scan_request_q,
286 				      &node);
287 		blocked_scan_req = qdf_container_of(node, struct scan_req,
288 						    node);
289 		request = blocked_scan_req->scan_request;
290 		request->n_ssids = 0;
291 		request->n_channels = 0;
292 		if (blocked_scan_req->source == NL_SCAN) {
293 			hdd_err("Scan aborted. Null result sent");
294 			hdd_cfg80211_scan_done(adapter, request, true);
295 		} else {
296 			hdd_err("Vendor scan aborted. Null result sent");
297 			hdd_vendor_scan_callback(adapter, request, true);
298 		}
299 		qdf_mem_free(blocked_scan_req);
300 	}
301 
302 	qdf_mutex_release(&adapter->blocked_scan_request_q_lock);
303 }
304 
305 void hdd_init_scan_reject_params(struct hdd_context *hdd_ctx)
306 {
307 	if (hdd_ctx) {
308 		hdd_ctx->last_scan_reject_timestamp = 0;
309 		hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
310 		hdd_ctx->last_scan_reject_reason = 0;
311 		hdd_ctx->scan_reject_cnt = 0;
312 	}
313 }
314 
315 /*
316  * wlan_hdd_update_scan_ies() - API to update the scan IEs of scan request
317  * with already stored default scan IEs
318  *
319  * @adapter: Pointer to HDD adapter
320  * @scan_info: Pointer to scan info in HDD adapter
321  * @scan_ie: Pointer to scan IE in scan request
322  * @scan_ie_len: Pointer to scan IE length in scan request
323  *
324  * Return: 0 on success; error number otherwise
325  */
326 static int wlan_hdd_update_scan_ies(struct hdd_adapter *adapter,
327 			struct hdd_scan_info *scan_info, uint8_t *scan_ie,
328 			uint16_t *scan_ie_len)
329 {
330 	uint16_t rem_len = scan_info->default_scan_ies_len;
331 	uint8_t *temp_ie = scan_info->default_scan_ies;
332 	uint8_t *current_ie;
333 	const uint8_t *mbo_ie;
334 	uint8_t elem_id;
335 	uint16_t elem_len;
336 	bool add_ie = false;
337 
338 	if (!scan_info->default_scan_ies_len || !scan_info->default_scan_ies)
339 		return 0;
340 
341 	mbo_ie = wlan_get_vendor_ie_ptr_from_oui(MBO_OUI_TYPE,
342 						 MBO_OUI_TYPE_SIZE, scan_ie,
343 						 *scan_ie_len);
344 	while (rem_len >= 2) {
345 		current_ie = temp_ie;
346 		elem_id = *temp_ie++;
347 		elem_len = *temp_ie++;
348 		rem_len -= 2;
349 
350 		if (elem_len > rem_len) {
351 			hdd_err("Invalid element len %d for elem %d", elem_len,
352 				elem_id);
353 			return 0;
354 		}
355 
356 		switch (elem_id) {
357 		case DOT11F_EID_EXTCAP:
358 			if (!wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP,
359 						      scan_ie, *scan_ie_len))
360 				add_ie = true;
361 			break;
362 		case WLAN_ELEMID_VENDOR:
363 			/* Donot add MBO IE if its already present */
364 			if ((!mbo_ie &&
365 			     0 == qdf_mem_cmp(&temp_ie[0], MBO_OUI_TYPE,
366 					      MBO_OUI_TYPE_SIZE)) ||
367 			    (0 == qdf_mem_cmp(&temp_ie[0], QCN_OUI_TYPE,
368 					      QCN_OUI_TYPE_SIZE)))
369 				add_ie = true;
370 			break;
371 		}
372 
373 		if (add_ie && (((*scan_ie_len) + elem_len) >
374 					SIR_MAC_MAX_ADD_IE_LENGTH)){
375 			hdd_err("Not enough buffer to save default scan IE's");
376 			return 0;
377 		}
378 
379 		if (add_ie) {
380 			qdf_mem_copy(scan_ie + (*scan_ie_len),
381 						current_ie, elem_len + 2);
382 			(*scan_ie_len) += (elem_len + 2);
383 			add_ie = false;
384 		}
385 
386 		temp_ie += elem_len;
387 		rem_len -= elem_len;
388 	}
389 	return 0;
390 }
391 
392 static int
393 wlan_hdd_enqueue_blocked_scan_request(struct net_device *dev,
394 				      struct cfg80211_scan_request *request,
395 				      uint8_t source)
396 {
397 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
398 	struct scan_req *blocked_scan_req =
399 		qdf_mem_malloc(sizeof(*blocked_scan_req));
400 	int ret = 0;
401 
402 	if (!blocked_scan_req)
403 		return -EINVAL;
404 
405 	blocked_scan_req->dev = dev;
406 	blocked_scan_req->scan_request = request;
407 	blocked_scan_req->source = source;
408 	blocked_scan_req->scan_id = 0;
409 
410 	qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
411 	if (qdf_list_size(&adapter->blocked_scan_request_q) <
412 		WLAN_MAX_SCAN_COUNT)
413 		qdf_list_insert_back(&adapter->blocked_scan_request_q,
414 				     &blocked_scan_req->node);
415 	else
416 		ret = -EINVAL;
417 	qdf_mutex_release(&adapter->blocked_scan_request_q_lock);
418 
419 	if (ret) {
420 		hdd_err("Maximum number of block scan request reached!");
421 		qdf_mem_free(blocked_scan_req);
422 	}
423 
424 	return ret;
425 }
426 
427 /* Define short name to use in cds_trigger_recovery */
428 #define SCAN_FAILURE QDF_SCAN_ATTEMPT_FAILURES
429 
430 /**
431  * __wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request
432  * @wiphy: Pointer to wiphy
433  * @request: Pointer to scan request
434  * @source: scan request source(NL/Vendor scan)
435  *
436  * This API responds to scan trigger and update cfg80211 scan database
437  * later, scan dump command can be used to receive scan results
438  *
439  * Return: 0 for success, non zero for failure
440  */
441 static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
442 				    struct cfg80211_scan_request *request,
443 				    uint8_t source)
444 {
445 	struct net_device *dev = request->wdev->netdev;
446 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
447 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
448 	int status;
449 	struct hdd_scan_info *scan_info = NULL;
450 	struct hdd_adapter *con_sap_adapter;
451 	struct hdd_ap_ctx *ap_ctx;
452 	qdf_freq_t con_dfs_ch_freq;
453 	uint8_t curr_vdev_id;
454 	enum scan_reject_states curr_reason;
455 	static uint32_t scan_ebusy_cnt;
456 	struct scan_params params = {0};
457 	bool self_recovery;
458 	struct wlan_objmgr_vdev *vdev;
459 	QDF_STATUS qdf_status;
460 	bool enable_connected_scan;
461 	enum phy_ch_width con_dfs_ch_width;
462 
463 	if (cds_is_fw_down()) {
464 		hdd_err("firmware is down, scan cmd cannot be processed");
465 		return -EINVAL;
466 	}
467 
468 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
469 		hdd_err("Command not allowed in FTM mode");
470 		return -EINVAL;
471 	}
472 
473 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
474 		return -EINVAL;
475 
476 	status = wlan_hdd_validate_context(hdd_ctx);
477 	if (0 != status)
478 		return status;
479 
480 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
481 		   TRACE_CODE_HDD_CFG80211_SCAN,
482 		   adapter->deflink->vdev_id, request->n_channels);
483 
484 	if (!sme_is_session_id_valid(hdd_ctx->mac_handle,
485 				     adapter->deflink->vdev_id))
486 		return -EINVAL;
487 
488 	qdf_status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
489 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
490 		hdd_err("Failed to get self recovery ini config");
491 		return -EIO;
492 	}
493 
494 	enable_connected_scan = ucfg_scan_is_connected_scan_enabled(
495 							hdd_ctx->psoc);
496 	if (!enable_connected_scan &&
497 	    hdd_cm_is_vdev_associated(adapter->deflink)) {
498 		hdd_info("enable_connected_scan is false, Aborting scan");
499 		if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
500 			return -EAGAIN;
501 		schedule_work(&adapter->scan_block_work);
502 		return 0;
503 	}
504 
505 	/*
506 	 * NDI and monitor mode don't need scan from userspace to establish
507 	 * connection and it does not support scan request either.
508 	 */
509 	if (QDF_NDI_MODE == adapter->device_mode ||
510 	    QDF_MONITOR_MODE == adapter->device_mode) {
511 		hdd_err("Scan not supported for %s",
512 			qdf_opmode_str(adapter->device_mode));
513 		return -EINVAL;
514 	}
515 
516 	scan_info = &adapter->scan_info;
517 
518 	/* Block All Scan during DFS operation and send null scan result */
519 
520 	con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
521 	if (con_sap_adapter) {
522 		ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(con_sap_adapter->deflink);
523 		con_dfs_ch_freq = ap_ctx->sap_config.chan_freq;
524 		con_dfs_ch_width = ap_ctx->sap_config.ch_params.ch_width;
525 		if (con_dfs_ch_freq == AUTO_CHANNEL_SELECT)
526 			con_dfs_ch_freq = ap_ctx->operating_chan_freq;
527 
528 		if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) &&
529 		    !policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
530 		    hdd_ctx->psoc) &&
531 		    (wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, con_dfs_ch_freq) ||
532 		    (wlan_reg_is_5ghz_ch_freq(con_dfs_ch_freq) &&
533 		     con_dfs_ch_width == CH_WIDTH_160MHZ))) {
534 			/* Provide empty scan result during DFS operation since
535 			 * scanning not supported during DFS. Reason is
536 			 * following case:
537 			 * DFS is supported only in SCC for MBSSID Mode.
538 			 * We shall not return EBUSY or ENOTSUPP as when Primary
539 			 * AP is operating in DFS channel and secondary AP is
540 			 * started. Though we force SCC in driver, the hostapd
541 			 * issues obss scan before starting secAP. This results
542 			 * in MCC in DFS mode. Thus we return null scan result.
543 			 * If we return scan failure hostapd fails secondary AP
544 			 * startup.
545 			 */
546 			hdd_err("##In DFS Master mode. Scan aborted");
547 			if (wlan_hdd_enqueue_blocked_scan_request(dev, request,
548 								  source))
549 				return -EAGAIN;
550 			schedule_work(&adapter->scan_block_work);
551 			return 0;
552 		}
553 	}
554 
555 	/* Check if scan is allowed at this point of time */
556 	if (hdd_is_connection_in_progress(&curr_vdev_id, &curr_reason)) {
557 		scan_ebusy_cnt++;
558 		hdd_err_rl("Scan not allowed. scan_ebusy_cnt: %d Session %d Reason %d",
559 			   scan_ebusy_cnt, curr_vdev_id, curr_reason);
560 		if (hdd_ctx->last_scan_reject_vdev_id != curr_vdev_id ||
561 		    hdd_ctx->last_scan_reject_reason != curr_reason ||
562 		    !hdd_ctx->last_scan_reject_timestamp) {
563 			hdd_ctx->last_scan_reject_vdev_id = curr_vdev_id;
564 			hdd_ctx->last_scan_reject_reason = curr_reason;
565 			hdd_ctx->last_scan_reject_timestamp = jiffies +
566 				msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
567 			hdd_ctx->scan_reject_cnt = 0;
568 		} else {
569 			hdd_ctx->scan_reject_cnt++;
570 			if ((hdd_ctx->scan_reject_cnt >=
571 			   SCAN_REJECT_THRESHOLD) &&
572 			   qdf_system_time_after(jiffies,
573 			   hdd_ctx->last_scan_reject_timestamp)) {
574 				hdd_err("scan reject threshold reached Session %d Reason %d count %d reject timestamp %lu jiffies %lu",
575 					curr_vdev_id, curr_reason,
576 					hdd_ctx->scan_reject_cnt,
577 					hdd_ctx->last_scan_reject_timestamp,
578 					jiffies);
579 				hdd_ctx->last_scan_reject_timestamp = 0;
580 				hdd_ctx->scan_reject_cnt = 0;
581 				if (cds_is_fatal_event_enabled()) {
582 					cds_flush_logs(WLAN_LOG_TYPE_FATAL,
583 					   WLAN_LOG_INDICATOR_HOST_DRIVER,
584 					   WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
585 					   false,
586 					   self_recovery);
587 				} else {
588 					hdd_err("Triggering SSR due to scan stuck");
589 					cds_trigger_recovery(SCAN_FAILURE);
590 				}
591 			}
592 		}
593 		return -EBUSY;
594 	}
595 
596 	hdd_init_scan_reject_params(hdd_ctx);
597 
598 	/* Check whether SAP scan can be skipped or not */
599 	if (adapter->device_mode == QDF_SAP_MODE &&
600 	   wlan_hdd_sap_skip_scan_check(hdd_ctx, request)) {
601 		hdd_debug("sap scan skipped");
602 		if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
603 			return -EAGAIN;
604 		schedule_work(&adapter->scan_block_work);
605 		return 0;
606 	}
607 
608 	params.source = source;
609 	params.default_ie.len = 0;
610 	/* Store the Scan IE's in Adapter*/
611 	if (request->ie_len) {
612 		if (request->ie_len > SIR_MAC_MAX_ADD_IE_LENGTH) {
613 			hdd_debug("Invalid ie_len: %zu", request->ie_len);
614 			return -EINVAL;
615 		}
616 
617 		/* save this for future association (join requires this) */
618 		memset(&scan_info->scan_add_ie, 0, sizeof(scan_info->scan_add_ie));
619 		memcpy(scan_info->scan_add_ie.addIEdata, request->ie,
620 		       request->ie_len);
621 		scan_info->scan_add_ie.length = request->ie_len;
622 
623 		wlan_hdd_update_scan_ies(adapter, scan_info,
624 				scan_info->scan_add_ie.addIEdata,
625 				&scan_info->scan_add_ie.length);
626 	} else {
627 		if (scan_info->default_scan_ies &&
628 		    scan_info->default_scan_ies_len) {
629 			qdf_mem_copy(scan_info->scan_add_ie.addIEdata,
630 				     scan_info->default_scan_ies,
631 				     scan_info->default_scan_ies_len);
632 			scan_info->scan_add_ie.length =
633 				scan_info->default_scan_ies_len;
634 			params.default_ie.ptr =
635 				qdf_mem_malloc(scan_info->default_scan_ies_len);
636 			if (params.default_ie.ptr) {
637 				qdf_mem_copy(params.default_ie.ptr,
638 					     scan_info->default_scan_ies,
639 					     scan_info->default_scan_ies_len);
640 				params.default_ie.len =
641 						scan_info->default_scan_ies_len;
642 			}
643 		}
644 	}
645 
646 	if (QDF_P2P_CLIENT_MODE == adapter->device_mode ||
647 	    QDF_P2P_DEVICE_MODE == adapter->device_mode) {
648 		/* Disable NAN Discovery if enabled */
649 		ucfg_nan_disable_concurrency(hdd_ctx->psoc);
650 	}
651 
652 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID);
653 	if (!vdev) {
654 		status = -EINVAL;
655 		goto error;
656 	}
657 
658 	if ((request->n_ssids == 1) && (request->ssids) &&
659 	    (request->ssids[0].ssid_len > 7) &&
660 	     !qdf_mem_cmp(&request->ssids[0], "DIRECT-", 7))
661 		ucfg_p2p_status_scan(vdev);
662 
663 	/* If this a scan on SAP adapter, use scan priority high */
664 	if (adapter->device_mode == QDF_SAP_MODE)
665 		params.priority = SCAN_PRIORITY_HIGH;
666 	else
667 		/* Use default scan priority */
668 		params.priority = SCAN_PRIORITY_COUNT;
669 
670 	status = ucfg_mlme_get_scan_probe_unicast_ra(
671 						hdd_ctx->psoc,
672 						&params.scan_probe_unicast_ra);
673 	if (QDF_IS_STATUS_ERROR(status))
674 		hdd_err("Failed to get unicast probe req ra cfg");
675 
676 	status = wlan_cfg80211_scan(vdev, request, &params);
677 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
678 error:
679 	if (params.default_ie.ptr)
680 		qdf_mem_free(params.default_ie.ptr);
681 
682 	return status;
683 }
684 
685 #undef SCAN_FAILURE
686 
687 /**
688  * wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request
689  * @wiphy: Pointer to wiphy
690  * @request: Pointer to scan request
691  *
692  * This API responds to scan trigger and update cfg80211 scan database
693  * later, scan dump command can be used to receive scan results
694  *
695  * Return: 0 for success, non zero for failure
696  */
697 int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
698 			   struct cfg80211_scan_request *request)
699 {
700 	int errno;
701 	struct osif_vdev_sync *vdev_sync;
702 
703 	errno = osif_vdev_sync_op_start(request->wdev->netdev, &vdev_sync);
704 	if (errno)
705 		return errno;
706 
707 	errno = __wlan_hdd_cfg80211_scan(wiphy, request, NL_SCAN);
708 
709 	osif_vdev_sync_op_stop(vdev_sync);
710 
711 	return errno;
712 }
713 
714 /**
715  * wlan_hdd_get_rates() -API to get the rates from scan request
716  * @wiphy: Pointer to wiphy
717  * @band: Band
718  * @rates: array of rates
719  * @rate_count: number of rates
720  *
721  * Return: o for failure, rate bitmap for success
722  */
723 static uint32_t wlan_hdd_get_rates(struct wiphy *wiphy,
724 	enum nl80211_band band,
725 	const u8 *rates, unsigned int rate_count)
726 {
727 	uint32_t j, count, rate_bitmap = 0;
728 	uint32_t rate;
729 	bool found;
730 
731 	for (count = 0; count < rate_count; count++) {
732 		rate = ((rates[count]) & RATE_MASK) * 5;
733 		found = false;
734 		for (j = 0; j < wiphy->bands[band]->n_bitrates; j++) {
735 			if (wiphy->bands[band]->bitrates[j].bitrate == rate) {
736 				found = true;
737 				rate_bitmap |= (1 << j);
738 				break;
739 			}
740 		}
741 		if (!found)
742 			return 0;
743 	}
744 	return rate_bitmap;
745 }
746 
747 /**
748  * wlan_hdd_send_scan_start_event() -API to send the scan start event
749  * @wiphy: Pointer to wiphy
750  * @wdev: Pointer to net device
751  * @cookie: scan identifier
752  *
753  * Return: return 0 on success and negative error code on failure
754  */
755 static int wlan_hdd_send_scan_start_event(struct wiphy *wiphy,
756 		struct wireless_dev *wdev, uint64_t cookie)
757 {
758 	struct sk_buff *skb;
759 	int ret;
760 	enum qca_nl80211_vendor_subcmds_index index =
761 		QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX;
762 
763 	skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) +
764 			NLA_HDRLEN + NLMSG_HDRLEN);
765 	if (!skb) {
766 		hdd_err(" reply skb alloc failed");
767 		return -ENOMEM;
768 	}
769 
770 	if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
771 				 cookie)) {
772 		hdd_err("nla put fail");
773 		wlan_cfg80211_vendor_free_skb(skb);
774 		return -EINVAL;
775 	}
776 
777 	ret = wlan_cfg80211_vendor_cmd_reply(skb);
778 
779 	/* Send a scan started event to supplicant */
780 	skb = wlan_cfg80211_vendor_event_alloc(wiphy, wdev,
781 					       sizeof(u64) + 4 + NLMSG_HDRLEN,
782 					       index, GFP_KERNEL);
783 	if (!skb) {
784 		hdd_err("skb alloc failed");
785 		return -ENOMEM;
786 	}
787 
788 	if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
789 				 cookie)) {
790 		wlan_cfg80211_vendor_free_skb(skb);
791 		return -EINVAL;
792 	}
793 
794 	wlan_cfg80211_vendor_event(skb, GFP_KERNEL);
795 	return ret;
796 }
797 
798 /**
799  * wlan_hdd_copy_bssid() - API to copy the bssid to vendor Scan request
800  * @request: Pointer to vendor scan request
801  * @bssid: Pointer to BSSID
802  *
803  * This API copies the specific BSSID received from Supplicant and copies it to
804  * the vendor Scan request
805  *
806  * Return: None
807  */
808 #if defined(CFG80211_SCAN_BSSID) || \
809 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
810 static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request,
811 					uint8_t *bssid)
812 {
813 	qdf_mem_copy(request->bssid, bssid, QDF_MAC_ADDR_SIZE);
814 }
815 #else
816 static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request,
817 					uint8_t *bssid)
818 {
819 }
820 #endif
821 
822 static void hdd_process_vendor_acs_response(struct hdd_adapter *adapter)
823 {
824 	qdf_mc_timer_t *vendor_acs_timer;
825 
826 	if (!test_bit(VENDOR_ACS_RESPONSE_PENDING,
827 		      &adapter->deflink->link_flags)) {
828 		return;
829 	}
830 
831 	vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer;
832 	if (QDF_TIMER_STATE_RUNNING ==
833 	    qdf_mc_timer_get_current_state(vendor_acs_timer)) {
834 		qdf_mc_timer_stop(vendor_acs_timer);
835 	}
836 }
837 
838 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
839 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
840 /**
841  * wlan_hdd_vendor_scan_random_attr() - check and fill scan randomization attrs
842  * @wiphy: Pointer to wiphy
843  * @request: Pointer to scan request
844  * @adapter: Pointer to hdd adapter
845  * @tb: Pointer to nl attributes
846  *
847  * This function is invoked to check whether vendor scan needs
848  * probe req source addr, if so populates mac_addr and mac_addr_mask
849  * in scan request with nl attrs.
850  *
851  * Return: 0 - on success, negative value on failure
852  */
853 static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy,
854 					struct cfg80211_scan_request *request,
855 					struct hdd_adapter *adapter,
856 					struct nlattr **tb)
857 {
858 	uint32_t i;
859 	int32_t len = QDF_MAC_ADDR_SIZE;
860 
861 	if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
862 		return 0;
863 
864 	if (!(wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR) ||
865 	    (hdd_cm_is_vdev_connected(adapter->deflink))) {
866 		hdd_err("SCAN RANDOMIZATION not supported");
867 		return -EOPNOTSUPP;
868 	}
869 
870 	if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] &&
871 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) {
872 		qdf_mem_zero(request->mac_addr, len);
873 		qdf_mem_zero(request->mac_addr_mask, len);
874 		request->mac_addr[0] = 0x2;
875 		request->mac_addr_mask[0] = 0x3;
876 
877 		return 0;
878 	}
879 
880 	if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] ||
881 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK])
882 		return -EINVAL;
883 
884 	if ((nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]) != len) ||
885 	    (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) != len))
886 		return -EINVAL;
887 
888 	qdf_mem_copy(request->mac_addr,
889 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]), len);
890 
891 	qdf_mem_copy(request->mac_addr_mask,
892 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]), len);
893 
894 	/* avoid configure on multicast address */
895 	if (!cds_is_group_addr(request->mac_addr_mask) ||
896 	    cds_is_group_addr(request->mac_addr))
897 		return -EINVAL;
898 
899 	for (i = 0; i < ETH_ALEN; i++)
900 		request->mac_addr[i] &= request->mac_addr_mask[i];
901 
902 	return 0;
903 }
904 #else
905 static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy,
906 					struct cfg80211_scan_request *request,
907 					struct hdd_adapter *adapter,
908 					struct nlattr **tb)
909 {
910 	return 0;
911 }
912 #endif
913 
914 const
915 struct nla_policy scan_policy[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = {
916 	[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32},
917 	[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG},
918 	[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64},
919 	[QCA_WLAN_VENDOR_ATTR_SCAN_IE] = {.type = NLA_BINARY,
920 					  .len = MAX_DEFAULT_SCAN_IE_LEN},
921 	[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] = VENDOR_NLA_POLICY_MAC_ADDR,
922 	[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK] = VENDOR_NLA_POLICY_MAC_ADDR,
923 	[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES] = {.type = NLA_NESTED},
924 	[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS] = {.type = NLA_NESTED},
925 	[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES] = {.type = NLA_NESTED},
926 	[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID] = {.type = NLA_BINARY},
927 };
928 
929 /**
930  * __wlan_hdd_cfg80211_vendor_scan() - API to process venor scan request
931  * @wiphy: Pointer to wiphy
932  * @wdev: Pointer to net device
933  * @data : Pointer to the data
934  * @data_len : length of the data
935  *
936  * API to process venor scan request.
937  *
938  * Return: return 0 on success and negative error code on failure
939  */
940 static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
941 		struct wireless_dev *wdev, const void *data,
942 		int data_len)
943 {
944 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
945 	struct cfg80211_scan_request *request = NULL;
946 	struct nlattr *attr;
947 	enum nl80211_band band;
948 	uint32_t n_channels = 0, n_ssid = 0;
949 	uint32_t count, j;
950 	int tmp;
951 	size_t len, ie_len = 0;
952 	struct ieee80211_channel *chan;
953 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
954 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
955 	int ret;
956 
957 	hdd_enter_dev(wdev->netdev);
958 
959 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
960 		hdd_err("Command not allowed in FTM mode");
961 		return -EPERM;
962 	}
963 
964 	ret = wlan_hdd_validate_context(hdd_ctx);
965 	if (ret) {
966 		/*
967 		 * During SSR, if -EBUSY is returned then OBSS vendor scan is
968 		 * not issued immediately.
969 		 */
970 		if (ret == -EAGAIN)
971 			return -EBUSY;
972 
973 		return ret;
974 	}
975 
976 	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
977 				    data, data_len, scan_policy)) {
978 		hdd_err("Invalid ATTR");
979 		return -EINVAL;
980 	}
981 
982 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
983 		nla_for_each_nested(attr,
984 			tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES], tmp)
985 			n_channels++;
986 	} else {
987 		for (band = 0; band < HDD_NUM_NL80211_BANDS; band++)
988 			if (wiphy->bands[band])
989 				n_channels += wiphy->bands[band]->n_channels;
990 	}
991 
992 	if (n_channels > NUM_CHANNELS) {
993 		hdd_err("Exceed max number of channels: %d", n_channels);
994 		return -EINVAL;
995 	}
996 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS])
997 		nla_for_each_nested(attr,
998 			tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], tmp)
999 			n_ssid++;
1000 
1001 	if (MAX_SCAN_SSID < n_ssid) {
1002 		hdd_err("Exceed max number of SSID: %d", n_ssid);
1003 		return -EINVAL;
1004 	}
1005 
1006 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE])
1007 		ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]);
1008 
1009 	len = sizeof(*request) + (sizeof(*request->ssids) * n_ssid) +
1010 			(sizeof(*request->channels) * n_channels) + ie_len;
1011 
1012 	request = qdf_mem_malloc(len);
1013 	if (!request)
1014 		goto error;
1015 	if (n_ssid)
1016 		request->ssids = (void *)&request->channels[n_channels];
1017 	request->n_ssids = n_ssid;
1018 	if (ie_len) {
1019 		if (request->ssids)
1020 			request->ie = (void *)(request->ssids + n_ssid);
1021 		else
1022 			request->ie = (void *)(request->channels + n_channels);
1023 	}
1024 
1025 	request->ie_len = ie_len;
1026 	count = 0;
1027 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
1028 		nla_for_each_nested(attr,
1029 				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
1030 				    tmp) {
1031 			if (nla_len(attr) != sizeof(uint32_t)) {
1032 				hdd_err("len is not correct for frequency %d",
1033 					count);
1034 				goto error;
1035 			}
1036 			chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
1037 			if (!chan)
1038 				goto error;
1039 			if (chan->flags & IEEE80211_CHAN_DISABLED)
1040 				continue;
1041 			request->channels[count] = chan;
1042 			count++;
1043 		}
1044 	} else {
1045 		for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) {
1046 			if (!wiphy->bands[band])
1047 				continue;
1048 			for (j = 0; j < wiphy->bands[band]->n_channels;
1049 				j++) {
1050 				chan = &wiphy->bands[band]->channels[j];
1051 				if (chan->flags & IEEE80211_CHAN_DISABLED)
1052 					continue;
1053 				request->channels[count] = chan;
1054 				count++;
1055 			}
1056 		}
1057 	}
1058 
1059 	if (!count)
1060 		goto error;
1061 
1062 	request->n_channels = count;
1063 	count = 0;
1064 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
1065 		int ssid_length;
1066 
1067 		nla_for_each_nested(attr, tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS],
1068 				tmp) {
1069 			ssid_length = nla_len(attr);
1070 			if ((ssid_length > WLAN_SSID_MAX_LEN) ||
1071 			    (ssid_length < 0)) {
1072 				hdd_err("SSID Len %d is not correct for network %d",
1073 					 ssid_length, count);
1074 				goto error;
1075 			}
1076 
1077 			request->ssids[count].ssid_len = ssid_length;
1078 			memcpy(request->ssids[count].ssid, nla_data(attr),
1079 					ssid_length);
1080 			count++;
1081 		}
1082 	}
1083 
1084 	if (ie_len)
1085 		nla_memcpy((void *)request->ie,
1086 			   tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE], ie_len);
1087 
1088 	for (count = 0; count < HDD_NUM_NL80211_BANDS; count++)
1089 		if (wiphy->bands[count])
1090 			request->rates[count] =
1091 				(1 << wiphy->bands[count]->n_bitrates) - 1;
1092 
1093 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES]) {
1094 		nla_for_each_nested(attr,
1095 				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES],
1096 				    tmp) {
1097 			band = nla_type(attr);
1098 			if (band >= HDD_NUM_NL80211_BANDS)
1099 				continue;
1100 			if (!wiphy->bands[band])
1101 				continue;
1102 			request->rates[band] =
1103 				wlan_hdd_get_rates(wiphy,
1104 						   band, nla_data(attr),
1105 						   nla_len(attr));
1106 		}
1107 	}
1108 
1109 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]) {
1110 		request->flags =
1111 			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]);
1112 		if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
1113 		    !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
1114 			hdd_err("LOW PRIORITY SCAN not supported");
1115 			goto error;
1116 		}
1117 
1118 		if (wlan_hdd_vendor_scan_random_attr(wiphy, request,
1119 						     adapter, tb))
1120 			goto error;
1121 	}
1122 
1123 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) {
1124 		if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) <
1125 		    QDF_MAC_ADDR_SIZE) {
1126 			hdd_err("invalid bssid length");
1127 			goto error;
1128 		}
1129 		wlan_hdd_copy_bssid(request,
1130 			nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]));
1131 	}
1132 
1133 	/* Check if external acs was requested on this adapter */
1134 	hdd_process_vendor_acs_response(adapter);
1135 
1136 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE])
1137 		request->no_cck =
1138 		   nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE]);
1139 	request->wdev = wdev;
1140 	request->wiphy = wiphy;
1141 	request->scan_start = jiffies;
1142 
1143 	ret = __wlan_hdd_cfg80211_scan(wiphy, request, VENDOR_SCAN);
1144 	if (0 != ret) {
1145 		hdd_err("Scan Failed. Ret = %d", ret);
1146 		qdf_mem_free(request);
1147 		return ret;
1148 	}
1149 	ret = wlan_hdd_send_scan_start_event(wiphy, wdev, (uintptr_t)request);
1150 
1151 	return ret;
1152 error:
1153 	hdd_err("Scan Request Failed");
1154 	qdf_mem_free(request);
1155 	return -EINVAL;
1156 }
1157 
1158 /**
1159  * wlan_hdd_cfg80211_vendor_scan() -API to process venor scan request
1160  * @wiphy: Pointer to wiphy
1161  * @wdev: Pointer to wireless device
1162  * @data: Pointer to the data
1163  * @data_len: length of the data
1164  *
1165  * This is called from userspace to request scan.
1166  *
1167  * Return: Return the Success or Failure code.
1168  */
1169 int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
1170 		struct wireless_dev *wdev, const void *data,
1171 		int data_len)
1172 {
1173 	int errno;
1174 	struct osif_vdev_sync *vdev_sync;
1175 
1176 	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
1177 	if (errno)
1178 		return errno;
1179 
1180 	errno = __wlan_hdd_cfg80211_vendor_scan(wiphy, wdev, data, data_len);
1181 
1182 	osif_vdev_sync_op_stop(vdev_sync);
1183 
1184 	return errno;
1185 }
1186 
1187 /**
1188  * __wlan_hdd_vendor_abort_scan() - API to process vendor command for
1189  * abort scan
1190  * @wiphy: Pointer to wiphy
1191  * @data: Pointer to the data
1192  * @data_len: length of the data
1193  *
1194  * API to process vendor abort scan
1195  *
1196  * Return: zero for success and non zero for failure
1197  */
1198 static int __wlan_hdd_vendor_abort_scan(
1199 		struct wiphy *wiphy, const void *data,
1200 		int data_len)
1201 {
1202 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
1203 	int ret;
1204 
1205 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1206 		hdd_err("Command not allowed in FTM mode");
1207 		return -EINVAL;
1208 	}
1209 
1210 	ret = wlan_hdd_validate_context(hdd_ctx);
1211 	if (0 != ret)
1212 		return ret;
1213 
1214 	wlan_vendor_abort_scan(hdd_ctx->pdev, data, data_len);
1215 
1216 	return ret;
1217 }
1218 
1219 /**
1220  * wlan_hdd_vendor_abort_scan() - API to process vendor command for
1221  * abort scan
1222  * @wiphy: Pointer to wiphy
1223  * @wdev: Pointer to net device
1224  * @data : Pointer to the data
1225  * @data_len : length of the data
1226  *
1227  * This is called from supplicant to abort scan
1228  *
1229  * Return: zero for success and non zero for failure
1230  */
1231 int wlan_hdd_vendor_abort_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
1232 			       const void *data, int data_len)
1233 {
1234 	struct osif_vdev_sync *vdev_sync;
1235 	int errno;
1236 
1237 	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
1238 	if (errno)
1239 		return errno;
1240 
1241 	errno = __wlan_hdd_vendor_abort_scan(wiphy, data, data_len);
1242 
1243 	osif_vdev_sync_op_stop(vdev_sync);
1244 
1245 	return errno;
1246 }
1247 
1248 int wlan_hdd_scan_abort(struct wlan_hdd_link_info *link_info)
1249 {
1250 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
1251 
1252 	wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
1253 			link_info->vdev_id, INVALID_SCAN_ID, true);
1254 
1255 	return 0;
1256 }
1257 
1258 #ifdef FEATURE_WLAN_SCAN_PNO
1259 /**
1260  * __wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
1261  * @wiphy: Pointer to wiphy
1262  * @dev: Pointer network device
1263  * @request: Pointer to cfg80211 scheduled scan start request
1264  *
1265  * Return: 0 for success, non zero for failure
1266  */
1267 static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
1268 						struct net_device *dev,
1269 						struct
1270 						cfg80211_sched_scan_request
1271 						*request)
1272 {
1273 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1274 	struct hdd_context *hdd_ctx;
1275 	struct wlan_objmgr_vdev *vdev;
1276 	int ret;
1277 	bool pno_offload_enabled;
1278 	uint8_t scan_backoff_multiplier;
1279 	bool enable_connected_scan;
1280 	enum QDF_GLOBAL_MODE curr_mode;
1281 
1282 	curr_mode = hdd_get_conparam();
1283 
1284 	if (QDF_GLOBAL_FTM_MODE == curr_mode ||
1285 	    QDF_GLOBAL_MONITOR_MODE == curr_mode) {
1286 		hdd_err_rl("Command not allowed in FTM/Monitor mode");
1287 		return -EINVAL;
1288 	}
1289 
1290 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
1291 		return -EINVAL;
1292 
1293 	if (adapter->device_mode != QDF_STA_MODE) {
1294 		hdd_info("Sched scans only supported on STA ifaces");
1295 		return -EINVAL;
1296 	}
1297 
1298 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1299 	ret = wlan_hdd_validate_context(hdd_ctx);
1300 	if (ret)
1301 		return ret;
1302 
1303 	pno_offload_enabled = ucfg_scan_is_pno_offload_enabled(hdd_ctx->psoc);
1304 	if (!pno_offload_enabled) {
1305 		hdd_debug("Pno Offload is not enabled");
1306 		return -EINVAL;
1307 	}
1308 
1309 	enable_connected_scan = ucfg_scan_is_connected_scan_enabled(
1310 							hdd_ctx->psoc);
1311 	if (!enable_connected_scan &&
1312 	    hdd_cm_is_vdev_associated(adapter->deflink)) {
1313 		hdd_info("enable_connected_scan is false, Aborting scan");
1314 		return -EBUSY;
1315 	}
1316 
1317 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID);
1318 	if (!vdev)
1319 		return -EINVAL;
1320 
1321 	scan_backoff_multiplier =
1322 			ucfg_get_scan_backoff_multiplier(hdd_ctx->psoc);
1323 	ret = wlan_cfg80211_sched_scan_start(vdev, request,
1324 					     scan_backoff_multiplier);
1325 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
1326 
1327 	return ret;
1328 }
1329 
1330 /**
1331  * wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
1332  * @wiphy: Pointer to wiphy
1333  * @dev: Pointer network device
1334  * @request: Pointer to cfg80211 scheduled scan start request
1335  *
1336  * Return: 0 for success, non zero for failure
1337  */
1338 int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
1339 				       struct net_device *dev,
1340 				       struct cfg80211_sched_scan_request
1341 				       *request)
1342 {
1343 	int errno;
1344 	struct osif_vdev_sync *vdev_sync;
1345 
1346 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1347 	if (errno)
1348 		return errno;
1349 
1350 	errno = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
1351 
1352 	osif_vdev_sync_op_stop(vdev_sync);
1353 
1354 	return errno;
1355 }
1356 
1357 int wlan_hdd_sched_scan_stop(struct net_device *dev)
1358 {
1359 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1360 	struct hdd_context *hdd_ctx;
1361 	struct wlan_objmgr_vdev *vdev;
1362 	int ret;
1363 	bool pno_offload_enabled;
1364 
1365 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1366 		hdd_err("Command not allowed in FTM mode");
1367 		return -EINVAL;
1368 	}
1369 
1370 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
1371 		return -EINVAL;
1372 
1373 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1374 	if (!hdd_ctx) {
1375 		hdd_err("HDD context is Null");
1376 		return -EINVAL;
1377 	}
1378 
1379 	pno_offload_enabled = ucfg_scan_is_pno_offload_enabled(hdd_ctx->psoc);
1380 	if (!pno_offload_enabled) {
1381 		hdd_debug("PnoOffload is not enabled!!!");
1382 		return -EINVAL;
1383 	}
1384 
1385 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID);
1386 	if (!vdev)
1387 		return -EINVAL;
1388 	ret = wlan_cfg80211_sched_scan_stop(vdev);
1389 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
1390 
1391 	return ret;
1392 }
1393 
1394 /**
1395  * __wlan_hdd_cfg80211_sched_scan_stop() - stop cfg80211 scheduled scan(pno)
1396  * @dev: Pointer network device
1397  *
1398  * This is a wrapper around wlan_hdd_sched_scan_stop() that returns success
1399  * in the event that the driver is currently recovering or unloading. This
1400  * prevents a race condition where we get a scan stop from kernel during
1401  * a driver unload from PLD.
1402  *
1403  * Return: 0 for success, non zero for failure
1404  */
1405 static int __wlan_hdd_cfg80211_sched_scan_stop(struct net_device *dev)
1406 {
1407 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1408 	int errno;
1409 	enum QDF_GLOBAL_MODE curr_mode;
1410 
1411 	curr_mode = hdd_get_conparam();
1412 
1413 	if (QDF_GLOBAL_FTM_MODE == curr_mode ||
1414 	    QDF_GLOBAL_MONITOR_MODE == curr_mode) {
1415 		hdd_err_rl("Command not allowed in FTM/Monitor mode");
1416 		return -EINVAL;
1417 	}
1418 
1419 	/* The return 0 is intentional when Recovery and Load/Unload in
1420 	 * progress. We did observe a crash due to a return of
1421 	 * failure in sched_scan_stop , especially for a case where the unload
1422 	 * of the happens at the same time. The function
1423 	 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only
1424 	 * when the sched_scan_stop returns success. If it returns a failure ,
1425 	 * then its next invocation due to the clean up of the second interface
1426 	 * will have the dev pointer corresponding to the first one leading to
1427 	 * a crash.
1428 	 */
1429 	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
1430 		hdd_info("Recovery in Progress. State: 0x%x Ignore!!!",
1431 			 cds_get_driver_state());
1432 		return 0;
1433 	}
1434 
1435 	if (cds_is_load_or_unload_in_progress()) {
1436 		hdd_info("Unload/Load in Progress, state: 0x%x.  Ignore!!!",
1437 			cds_get_driver_state());
1438 		return 0;
1439 	}
1440 
1441 	errno = hdd_validate_adapter(adapter);
1442 	if (errno)
1443 		return errno;
1444 
1445 	if (adapter->device_mode != QDF_STA_MODE) {
1446 		hdd_info("Sched scans only supported on STA ifaces");
1447 		return -EINVAL;
1448 	}
1449 
1450 	errno = wlan_hdd_validate_context(WLAN_HDD_GET_CTX(adapter));
1451 	if (errno)
1452 		return errno;
1453 
1454 	errno = wlan_hdd_sched_scan_stop(dev);
1455 
1456 	return errno;
1457 }
1458 
1459 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
1460 int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
1461 				      struct net_device *dev)
1462 {
1463 	int errno;
1464 	struct osif_vdev_sync *vdev_sync;
1465 
1466 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1467 	if (errno)
1468 		return errno;
1469 
1470 	errno = __wlan_hdd_cfg80211_sched_scan_stop(dev);
1471 
1472 	osif_vdev_sync_op_stop(vdev_sync);
1473 
1474 	/* The return 0 is intentional. We observed a crash due to a return of
1475 	 * failure in sched_scan_stop , especially for a case where the unload
1476 	 * of the happens at the same time. The function
1477 	 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only
1478 	 * when the sched_scan_stop returns success. If it returns a failure ,
1479 	 * then its next invocation due to the clean up of the second interface
1480 	 * will have the dev pointer corresponding to the first one leading to
1481 	 * a crash.
1482 	 */
1483 	return 0;
1484 }
1485 #else
1486 int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
1487 				      struct net_device *dev,
1488 				      uint64_t reqid)
1489 {
1490 	int errno;
1491 	struct osif_vdev_sync *vdev_sync;
1492 
1493 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1494 	if (errno)
1495 		return errno;
1496 
1497 	errno = __wlan_hdd_cfg80211_sched_scan_stop(dev);
1498 
1499 	osif_vdev_sync_op_stop(vdev_sync);
1500 
1501 	/* The return 0 is intentional. We observed a crash due to a return of
1502 	 * failure in sched_scan_stop , especially for a case where the unload
1503 	 * of the happens at the same time. The function
1504 	 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only
1505 	 * when the sched_scan_stop returns success. If it returns a failure ,
1506 	 * then its next invocation due to the clean up of the second interface
1507 	 * will have the dev pointer corresponding to the first one leading to
1508 	 * a crash.
1509 	 */
1510 	return 0;
1511 }
1512 #endif /* KERNEL_VERSION(4, 12, 0) */
1513 #endif /*FEATURE_WLAN_SCAN_PNO */
1514 
1515 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
1516 	defined(CFG80211_ABORT_SCAN)
1517 /**
1518  * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
1519  * @wiphy: Pointer to wiphy
1520  * @wdev: Pointer to wireless device structure
1521  *
1522  * This function is used to abort an ongoing scan
1523  *
1524  * Return: None
1525  */
1526 static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
1527 					   struct wireless_dev *wdev)
1528 {
1529 	struct net_device *dev = wdev->netdev;
1530 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1531 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
1532 	int ret;
1533 
1534 	hdd_enter_dev(dev);
1535 
1536 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1537 		hdd_err("Command not allowed in FTM mode");
1538 		return;
1539 	}
1540 
1541 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
1542 		return;
1543 
1544 	ret = wlan_hdd_validate_context(hdd_ctx);
1545 	if (ret)
1546 		return;
1547 
1548 	wlan_cfg80211_abort_scan(hdd_ctx->pdev);
1549 
1550 	hdd_exit();
1551 }
1552 
1553 /**
1554  * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
1555  * @wiphy: Pointer to wiphy
1556  * @wdev: Pointer to wireless device structure
1557  *
1558  * Wrapper to __wlan_hdd_cfg80211_abort_scan() -
1559  * function is used to abort an ongoing scan
1560  *
1561  * Return: None
1562  */
1563 void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
1564 				  struct wireless_dev *wdev)
1565 {
1566 	struct osif_psoc_sync *psoc_sync;
1567 	int errno;
1568 
1569 	errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
1570 	if (errno)
1571 		return;
1572 
1573 	__wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
1574 
1575 	osif_psoc_sync_op_stop(psoc_sync);
1576 }
1577 #endif
1578 
1579 /**
1580  * hdd_scan_context_destroy() - Destroy scan context
1581  * @hdd_ctx:	HDD context.
1582  *
1583  * Destroy scan context.
1584  *
1585  * Return: None.
1586  */
1587 void hdd_scan_context_destroy(struct hdd_context *hdd_ctx)
1588 {
1589 }
1590 
1591 /**
1592  * hdd_scan_context_init() - Initialize scan context
1593  * @hdd_ctx:	HDD context.
1594  *
1595  * Initialize scan related resources like spin lock and lists.
1596  *
1597  * Return: 0 on success and errno on failure.
1598  */
1599 int hdd_scan_context_init(struct hdd_context *hdd_ctx)
1600 {
1601 	return 0;
1602 }
1603