xref: /wlan-dirver/qca-wifi-host-cmn/os_if/linux/scan/src/wlan_cfg80211_scan.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: defines driver functions interfacing with linux kernel
21  */
22 
23 #include <qdf_list.h>
24 #include <qdf_status.h>
25 #include <qdf_module.h>
26 #include <linux/wireless.h>
27 #include <linux/netdevice.h>
28 #include <net/cfg80211.h>
29 #include <wlan_scan_utils_api.h>
30 #include <wlan_cfg80211.h>
31 #include <wlan_cfg80211_scan.h>
32 #include <wlan_osif_priv.h>
33 #include <wlan_scan_public_structs.h>
34 #include <wlan_scan_ucfg_api.h>
35 #include <wlan_cfg80211_scan.h>
36 #include <qdf_mem.h>
37 #include <wlan_utility.h>
38 #include "cfg_ucfg_api.h"
39 #ifdef WLAN_POLICY_MGR_ENABLE
40 #include <wlan_policy_mgr_api.h>
41 #endif
42 #include <wlan_reg_services_api.h>
43 #ifdef FEATURE_WLAN_DIAG_SUPPORT
44 #include "host_diag_core_event.h"
45 #endif
46 
47 const struct nla_policy cfg80211_scan_policy[
48 			QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = {
49 	[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32},
50 	[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG},
51 	[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64},
52 };
53 
54 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
55 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
56 /**
57  * wlan_fill_scan_rand_attrs() - Populate the scan randomization attrs
58  * @vdev: pointer to objmgr vdev
59  * @flags: cfg80211 scan flags
60  * @mac_addr: random mac addr from cfg80211
61  * @mac_addr_mask: mac addr mask from cfg80211
62  * @randomize: output variable to check scan randomization status
63  * @addr: output variable to hold random addr
64  * @mask: output variable to hold mac mask
65  *
66  * Return: None
67  */
68 static void wlan_fill_scan_rand_attrs(struct wlan_objmgr_vdev *vdev,
69 				      uint32_t flags,
70 				      uint8_t *mac_addr,
71 				      uint8_t *mac_addr_mask,
72 				      bool *randomize,
73 				      uint8_t *addr,
74 				      uint8_t *mask)
75 {
76 	*randomize = false;
77 	if (!(flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
78 		return;
79 
80 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
81 		return;
82 
83 	if (wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS)
84 		return;
85 
86 	*randomize = true;
87 	memcpy(addr, mac_addr, QDF_MAC_ADDR_SIZE);
88 	memcpy(mask, mac_addr_mask, QDF_MAC_ADDR_SIZE);
89 	osif_debug("Random mac addr: "QDF_MAC_ADDR_FMT" and Random mac mask: "QDF_FULL_MAC_FMT,
90 		   QDF_MAC_ADDR_REF(addr), QDF_FULL_MAC_REF(mask));
91 }
92 
93 /**
94  * wlan_scan_rand_attrs() - Wrapper function to fill scan random attrs
95  * @vdev: pointer to objmgr vdev
96  * @request: pointer to cfg80211 scan request
97  * @req: pointer to cmn module scan request
98  *
99  * This is a wrapper function which invokes wlan_fill_scan_rand_attrs()
100  * to fill random attributes of internal scan request with cfg80211_scan_request
101  *
102  * Return: None
103  */
104 static void wlan_scan_rand_attrs(struct wlan_objmgr_vdev *vdev,
105 				 struct cfg80211_scan_request *request,
106 				 struct scan_start_request *req)
107 {
108 	bool *randomize = &req->scan_req.scan_random.randomize;
109 	uint8_t *mac_addr = req->scan_req.scan_random.mac_addr;
110 	uint8_t *mac_mask = req->scan_req.scan_random.mac_mask;
111 
112 	wlan_fill_scan_rand_attrs(vdev, request->flags, request->mac_addr,
113 				  request->mac_addr_mask, randomize, mac_addr,
114 				  mac_mask);
115 	if (!*randomize)
116 		return;
117 
118 	req->scan_req.scan_f_add_spoofed_mac_in_probe = true;
119 	req->scan_req.scan_f_add_rand_seq_in_probe = true;
120 }
121 #else
122 /**
123  * wlan_scan_rand_attrs() - Wrapper function to fill scan random attrs
124  * @vdev: pointer to objmgr vdev
125  * @request: pointer to cfg80211 scan request
126  * @req: pointer to cmn module scan request
127  *
128  * This is a wrapper function which invokes wlan_fill_scan_rand_attrs()
129  * to fill random attributes of internal scan request with cfg80211_scan_request
130  *
131  * Return: None
132  */
133 static void wlan_scan_rand_attrs(struct wlan_objmgr_vdev *vdev,
134 				 struct cfg80211_scan_request *request,
135 				 struct scan_start_request *req)
136 {
137 }
138 #endif
139 
140 #ifdef FEATURE_WLAN_SCAN_PNO
141 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \
142 	defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT))
143 
144 /**
145  * wlan_config_sched_scan_plan() - configures the sched scan plans
146  *   from the framework.
147  * @pno_req: pointer to PNO scan request
148  * @request: pointer to scan request from framework
149  *
150  * Return: None
151  */
152 static void
153 wlan_config_sched_scan_plan(struct pno_scan_req_params *pno_req,
154 			    struct cfg80211_sched_scan_request *request)
155 {
156 	/*
157 	 * As of now max 2 scan plans were supported by firmware
158 	 * if number of scan plan supported by firmware increased below logic
159 	 * must change.
160 	 */
161 	if (request->n_scan_plans == SCAN_PNO_MAX_PLAN_REQUEST) {
162 		pno_req->fast_scan_period =
163 			request->scan_plans[0].interval * MSEC_PER_SEC;
164 		pno_req->fast_scan_max_cycles =
165 			request->scan_plans[0].iterations;
166 		pno_req->slow_scan_period =
167 			request->scan_plans[1].interval * MSEC_PER_SEC;
168 	} else if (request->n_scan_plans == 1) {
169 		pno_req->fast_scan_period =
170 			request->scan_plans[0].interval * MSEC_PER_SEC;
171 		/*
172 		 * if only one scan plan is configured from framework
173 		 * then both fast and slow scan should be configured with the
174 		 * same value that is why fast scan cycles are hardcoded to one
175 		 */
176 		pno_req->fast_scan_max_cycles = 1;
177 		pno_req->slow_scan_period =
178 			request->scan_plans[0].interval * MSEC_PER_SEC;
179 	} else {
180 		osif_err("Invalid number of scan plans %d !!",
181 			 request->n_scan_plans);
182 	}
183 }
184 #else
185 #define wlan_config_sched_scan_plan(pno_req, request) \
186 	__wlan_config_sched_scan_plan(pno_req, request, psoc)
187 
188 static void
189 __wlan_config_sched_scan_plan(struct pno_scan_req_params *pno_req,
190 			      struct cfg80211_sched_scan_request *request,
191 			      struct wlan_objmgr_psoc *psoc)
192 {
193 	uint32_t scan_timer_repeat_value, slow_scan_multiplier;
194 
195 	scan_timer_repeat_value = ucfg_scan_get_scan_timer_repeat_value(psoc);
196 	slow_scan_multiplier = ucfg_scan_get_slow_scan_multiplier(psoc);
197 
198 	pno_req->fast_scan_period = request->interval;
199 	pno_req->fast_scan_max_cycles = scan_timer_repeat_value;
200 	pno_req->slow_scan_period =
201 		(slow_scan_multiplier * pno_req->fast_scan_period);
202 }
203 #endif
204 
205 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
206 static inline void
207 wlan_cfg80211_sched_scan_results(struct wiphy *wiphy, uint64_t reqid)
208 {
209 	cfg80211_sched_scan_results(wiphy);
210 }
211 #else
212 static inline void
213 wlan_cfg80211_sched_scan_results(struct wiphy *wiphy, uint64_t reqid)
214 {
215 	cfg80211_sched_scan_results(wiphy, reqid);
216 }
217 #endif
218 
219 /**
220  * wlan_cfg80211_pno_callback() - pno callback function to handle
221  * pno events.
222  * @vdev: vdev ptr
223  * @event: scan events
224  * @args: argument
225  *
226  * Return: void
227  */
228 static void wlan_cfg80211_pno_callback(struct wlan_objmgr_vdev *vdev,
229 	struct scan_event *event,
230 	void *args)
231 {
232 	struct wlan_objmgr_pdev *pdev;
233 	struct pdev_osif_priv *pdev_ospriv;
234 
235 	if (event->type != SCAN_EVENT_TYPE_NLO_COMPLETE)
236 		return;
237 
238 	osif_debug("vdev id = %d", event->vdev_id);
239 
240 	pdev = wlan_vdev_get_pdev(vdev);
241 	if (!pdev) {
242 		osif_err("pdev is NULL");
243 		return;
244 	}
245 
246 	pdev_ospriv = wlan_pdev_get_ospriv(pdev);
247 	if (!pdev_ospriv) {
248 		osif_err("pdev_ospriv is NULL");
249 		return;
250 	}
251 	wlan_cfg80211_sched_scan_results(pdev_ospriv->wiphy, 0);
252 }
253 
254 #ifdef WLAN_POLICY_MGR_ENABLE
255 static bool wlan_cfg80211_is_ap_go_present(struct wlan_objmgr_psoc *psoc)
256 {
257 	return policy_mgr_mode_specific_connection_count(psoc,
258 							  PM_SAP_MODE,
259 							  NULL) ||
260 		policy_mgr_mode_specific_connection_count(psoc,
261 							  PM_P2P_GO_MODE,
262 							  NULL);
263 }
264 
265 static QDF_STATUS wlan_cfg80211_is_chan_ok_for_dnbs(
266 			struct wlan_objmgr_psoc *psoc,
267 			u16 chan_freq, bool *ok)
268 {
269 	QDF_STATUS status = policy_mgr_is_chan_ok_for_dnbs(
270 				psoc, chan_freq, ok);
271 
272 	if (QDF_IS_STATUS_ERROR(status)) {
273 		osif_err("DNBS check failed");
274 		return status;
275 	}
276 
277 	return QDF_STATUS_SUCCESS;
278 }
279 #else
280 static bool wlan_cfg80211_is_ap_go_present(struct wlan_objmgr_psoc *psoc)
281 {
282 	return false;
283 }
284 
285 static QDF_STATUS wlan_cfg80211_is_chan_ok_for_dnbs(
286 			struct wlan_objmgr_psoc *psoc,
287 			u16 chan_freq,
288 			bool *ok)
289 {
290 	if (!ok)
291 		return QDF_STATUS_E_INVAL;
292 
293 	*ok = true;
294 	return QDF_STATUS_SUCCESS;
295 }
296 #endif
297 
298 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
299 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
300 /**
301  * wlan_pno_scan_rand_attr() - Wrapper function to fill sched scan random attrs
302  * @vdev: pointer to objmgr vdev
303  * @request: pointer to cfg80211 sched scan request
304  * @req: pointer to cmn module pno scan request
305  *
306  * This is a wrapper function which invokes wlan_fill_scan_rand_attrs()
307  * to fill random attributes of internal pno scan
308  * with cfg80211_sched_scan_request
309  *
310  * Return: None
311  */
312 static void wlan_pno_scan_rand_attr(struct wlan_objmgr_vdev *vdev,
313 				    struct cfg80211_sched_scan_request *request,
314 				    struct pno_scan_req_params *req)
315 {
316 	bool *randomize = &req->scan_random.randomize;
317 	uint8_t *mac_addr = req->scan_random.mac_addr;
318 	uint8_t *mac_mask = req->scan_random.mac_mask;
319 
320 	wlan_fill_scan_rand_attrs(vdev, request->flags, request->mac_addr,
321 				  request->mac_addr_mask, randomize, mac_addr,
322 				  mac_mask);
323 }
324 #else
325 /**
326  * wlan_pno_scan_rand_attr() - Wrapper function to fill sched scan random attrs
327  * @vdev: pointer to objmgr vdev
328  * @request: pointer to cfg80211 sched scan request
329  * @req: pointer to cmn module pno scan request
330  *
331  * This is a wrapper function which invokes wlan_fill_scan_rand_attrs()
332  * to fill random attributes of internal pno scan
333  * with cfg80211_sched_scan_request
334  *
335  * Return: None
336  */
337 static void wlan_pno_scan_rand_attr(struct wlan_objmgr_vdev *vdev,
338 				    struct cfg80211_sched_scan_request *request,
339 				    struct pno_scan_req_params *req)
340 {
341 }
342 #endif
343 
344 /**
345  * wlan_hdd_sched_scan_update_relative_rssi() - update CPNO params
346  * @pno_request: pointer to PNO scan request
347  * @request: Pointer to cfg80211 scheduled scan start request
348  *
349  * This function is used to update Connected PNO params sent by kernel
350  *
351  * Return: None
352  */
353 #if defined(CFG80211_REPORT_BETTER_BSS_IN_SCHED_SCAN) || \
354 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
355 static inline void wlan_hdd_sched_scan_update_relative_rssi(
356 			struct pno_scan_req_params *pno_request,
357 			struct cfg80211_sched_scan_request *request)
358 {
359 	pno_request->relative_rssi_set = request->relative_rssi_set;
360 	pno_request->relative_rssi = request->relative_rssi;
361 	if (NL80211_BAND_2GHZ == request->rssi_adjust.band)
362 		pno_request->band_rssi_pref.band = WLAN_BAND_2_4_GHZ;
363 	else if (NL80211_BAND_5GHZ == request->rssi_adjust.band)
364 		pno_request->band_rssi_pref.band = WLAN_BAND_5_GHZ;
365 	pno_request->band_rssi_pref.rssi = request->rssi_adjust.delta;
366 }
367 #else
368 static inline void wlan_hdd_sched_scan_update_relative_rssi(
369 			struct pno_scan_req_params *pno_request,
370 			struct cfg80211_sched_scan_request *request)
371 {
372 }
373 #endif
374 
375 #ifdef FEATURE_WLAN_SCAN_PNO
376 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
377 static uint32_t wlan_config_sched_scan_start_delay(
378 		struct cfg80211_sched_scan_request *request)
379 {
380 	return request->delay;
381 }
382 #else
383 static uint32_t wlan_config_sched_scan_start_delay(
384 		struct cfg80211_sched_scan_request *request)
385 {
386 	return 0;
387 }
388 #endif /*(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) */
389 #endif /* FEATURE_WLAN_SCAN_PNO */
390 
391 int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev,
392 				   struct cfg80211_sched_scan_request *request,
393 				   uint8_t scan_backoff_multiplier)
394 {
395 	struct pno_scan_req_params *req;
396 	int i, j, ret = 0;
397 	QDF_STATUS status;
398 	uint8_t num_chan = 0;
399 	uint16_t chan_freq;
400 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
401 	struct wlan_objmgr_psoc *psoc;
402 	uint32_t valid_ch[SCAN_PNO_MAX_NETW_CHANNELS_EX] = {0};
403 	bool enable_dfs_pno_chnl_scan;
404 
405 	if (ucfg_scan_get_pno_in_progress(vdev)) {
406 		osif_debug("pno is already in progress");
407 		return -EBUSY;
408 	}
409 
410 	if (ucfg_scan_get_pdev_status(pdev) !=
411 	   SCAN_NOT_IN_PROGRESS) {
412 		status = wlan_abort_scan(pdev,
413 				wlan_objmgr_pdev_get_pdev_id(pdev),
414 				INVAL_VDEV_ID, INVAL_SCAN_ID, true);
415 		if (QDF_IS_STATUS_ERROR(status))
416 			return -EBUSY;
417 	}
418 
419 	req = qdf_mem_malloc(sizeof(*req));
420 	if (!req)
421 		return -ENOMEM;
422 
423 	wlan_pdev_obj_lock(pdev);
424 	psoc = wlan_pdev_get_psoc(pdev);
425 	wlan_pdev_obj_unlock(pdev);
426 
427 	req->networks_cnt = request->n_match_sets;
428 	req->vdev_id = wlan_vdev_get_id(vdev);
429 
430 	if ((!req->networks_cnt) ||
431 	    (req->networks_cnt > SCAN_PNO_MAX_SUPP_NETWORKS)) {
432 		osif_err("Network input is not correct %d",
433 			 req->networks_cnt);
434 		ret = -EINVAL;
435 		goto error;
436 	}
437 
438 	if (request->n_channels > SCAN_PNO_MAX_NETW_CHANNELS_EX) {
439 		osif_err("Incorrect number of channels %d",
440 			 request->n_channels);
441 		ret = -EINVAL;
442 		goto error;
443 	}
444 
445 	enable_dfs_pno_chnl_scan = ucfg_scan_is_dfs_chnl_scan_enabled(psoc);
446 	if (request->n_channels) {
447 		uint32_t buff_len;
448 		char *chl;
449 		int len = 0;
450 		bool ap_or_go_present = wlan_cfg80211_is_ap_go_present(psoc);
451 
452 		buff_len = (request->n_channels * 5) + 1;
453 		chl = qdf_mem_malloc(buff_len);
454 		if (!chl) {
455 			ret = -ENOMEM;
456 			goto error;
457 		}
458 		for (i = 0; i < request->n_channels; i++) {
459 			chan_freq = request->channels[i]->center_freq;
460 			if ((!enable_dfs_pno_chnl_scan) &&
461 			    (wlan_reg_is_dfs_for_freq(pdev, chan_freq))) {
462 				osif_debug("Dropping DFS channel freq :%d",
463 					   chan_freq);
464 				continue;
465 			}
466 			if (wlan_reg_is_dsrc_freq(chan_freq))
467 				continue;
468 
469 			if (ap_or_go_present) {
470 				bool ok;
471 
472 				status =
473 				wlan_cfg80211_is_chan_ok_for_dnbs(psoc,
474 								  chan_freq,
475 								  &ok);
476 				if (QDF_IS_STATUS_ERROR(status)) {
477 					osif_err("DNBS check failed");
478 					qdf_mem_free(chl);
479 					chl = NULL;
480 					ret = -EINVAL;
481 					goto error;
482 				}
483 				if (!ok)
484 					continue;
485 			}
486 			len += qdf_scnprintf(chl + len, buff_len - len, " %d", chan_freq);
487 			valid_ch[num_chan++] = chan_freq;
488 		}
489 		osif_debug("Channel-List[%d]:%s", num_chan, chl);
490 		qdf_mem_free(chl);
491 		chl = NULL;
492 		/* If all channels are DFS and dropped,
493 		 * then ignore the PNO request
494 		 */
495 		if (!num_chan) {
496 			osif_notice("Channel list empty due to filtering of DSRC");
497 			ret = -EINVAL;
498 			goto error;
499 		}
500 	}
501 
502 	/* Filling per profile  params */
503 	for (i = 0; i < req->networks_cnt; i++) {
504 		req->networks_list[i].ssid.length =
505 			request->match_sets[i].ssid.ssid_len;
506 
507 		if ((!req->networks_list[i].ssid.length) ||
508 		    (req->networks_list[i].ssid.length > WLAN_SSID_MAX_LEN)) {
509 			osif_err(" SSID Len %d is not correct for network %d",
510 				 req->networks_list[i].ssid.length, i);
511 			ret = -EINVAL;
512 			goto error;
513 		}
514 
515 		qdf_mem_copy(req->networks_list[i].ssid.ssid,
516 			request->match_sets[i].ssid.ssid,
517 			req->networks_list[i].ssid.length);
518 		req->networks_list[i].authentication = 0;   /*eAUTH_TYPE_ANY */
519 		req->networks_list[i].encryption = 0;       /*eED_ANY */
520 		req->networks_list[i].bc_new_type = 0;    /*eBCAST_UNKNOWN */
521 
522 		/*Copying list of valid channel into request */
523 		qdf_mem_copy(req->networks_list[i].channels, valid_ch,
524 			num_chan * sizeof(uint32_t));
525 		req->networks_list[i].channel_cnt = num_chan;
526 		req->networks_list[i].rssi_thresh =
527 			request->match_sets[i].rssi_thold;
528 	}
529 
530 	/* set scan to passive if no SSIDs are specified in the request */
531 	if (0 == request->n_ssids)
532 		req->do_passive_scan = true;
533 	else
534 		req->do_passive_scan = false;
535 
536 	for (i = 0; i < request->n_ssids; i++) {
537 		j = 0;
538 		while (j < req->networks_cnt) {
539 			if ((req->networks_list[j].ssid.length ==
540 			     request->ssids[i].ssid_len) &&
541 			    (!qdf_mem_cmp(req->networks_list[j].ssid.ssid,
542 					 request->ssids[i].ssid,
543 					 req->networks_list[j].ssid.length))) {
544 				req->networks_list[j].bc_new_type =
545 					SSID_BC_TYPE_HIDDEN;
546 				break;
547 			}
548 			j++;
549 		}
550 	}
551 
552 	/*
553 	 * Before Kernel 4.4
554 	 *   Driver gets only one time interval which is hard coded in
555 	 *   supplicant for 10000ms.
556 	 *
557 	 * After Kernel 4.4
558 	 *   User can configure multiple scan_plans, each scan would have
559 	 *   separate scan cycle and interval. (interval is in unit of second.)
560 	 *   For our use case, we would only have supplicant set one scan_plan,
561 	 *   and firmware also support only one as well, so pick up the first
562 	 *   index.
563 	 *
564 	 *   Taking power consumption into account
565 	 *   firmware after gPNOScanTimerRepeatValue times fast_scan_period
566 	 *   switches slow_scan_period. This is less frequent scans and firmware
567 	 *   shall be in slow_scan_period mode until next PNO Start.
568 	 */
569 	wlan_config_sched_scan_plan(req, request);
570 	req->delay_start_time = wlan_config_sched_scan_start_delay(request);
571 	req->scan_backoff_multiplier = scan_backoff_multiplier;
572 
573 	wlan_hdd_sched_scan_update_relative_rssi(req, request);
574 
575 	psoc = wlan_pdev_get_psoc(pdev);
576 	ucfg_scan_register_pno_cb(psoc,
577 		wlan_cfg80211_pno_callback, NULL);
578 	ucfg_scan_get_pno_def_params(vdev, req);
579 
580 	if (req->scan_random.randomize)
581 		wlan_pno_scan_rand_attr(vdev, request, req);
582 
583 	if (ucfg_ie_whitelist_enabled(psoc, vdev))
584 		ucfg_copy_ie_whitelist_attrs(psoc, &req->ie_whitelist);
585 
586 	osif_debug("Network count %d n_ssids %d fast_scan_period: %d msec slow_scan_period: %d msec, fast_scan_max_cycles: %d, relative_rssi %d band_pref %d, rssi_pref %d",
587 		   req->networks_cnt, request->n_ssids, req->fast_scan_period,
588 		   req->slow_scan_period, req->fast_scan_max_cycles,
589 		   req->relative_rssi, req->band_rssi_pref.band,
590 		   req->band_rssi_pref.rssi);
591 
592 	for (i = 0; i < req->networks_cnt; i++)
593 		osif_debug("[%d] ssid: %.*s, RSSI th %d bc NW type %u",
594 			   i, req->networks_list[i].ssid.length,
595 			   req->networks_list[i].ssid.ssid,
596 			   req->networks_list[i].rssi_thresh,
597 			   req->networks_list[i].bc_new_type);
598 
599 	status = ucfg_scan_pno_start(vdev, req);
600 	if (QDF_IS_STATUS_ERROR(status)) {
601 		osif_err("Failed to enable PNO");
602 		ret = -EINVAL;
603 		goto error;
604 	}
605 
606 error:
607 	qdf_mem_free(req);
608 	return ret;
609 }
610 
611 int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_vdev *vdev)
612 {
613 	QDF_STATUS status;
614 
615 	status = ucfg_scan_pno_stop(vdev);
616 	if (QDF_IS_STATUS_ERROR(status))
617 		osif_debug("Failed to disable PNO");
618 
619 	return 0;
620 }
621 #endif /*FEATURE_WLAN_SCAN_PNO */
622 
623 /**
624  * wlan_copy_bssid_scan_request() - API to copy the bssid to Scan request
625  * @scan_req: Pointer to scan_start_request
626  * @request: scan request from Supplicant
627  *
628  * This API copies the BSSID in scan request from Supplicant and copies it to
629  * the scan_start_request
630  *
631  * Return: None
632  */
633 #if defined(CFG80211_SCAN_BSSID) || \
634 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
635 static inline void
636 wlan_copy_bssid_scan_request(struct scan_start_request *scan_req,
637 		struct cfg80211_scan_request *request)
638 {
639 	qdf_mem_copy(scan_req->scan_req.bssid_list[0].bytes,
640 				request->bssid, QDF_MAC_ADDR_SIZE);
641 }
642 #else
643 static inline void
644 wlan_copy_bssid_scan_request(struct scan_start_request *scan_req,
645 		struct cfg80211_scan_request *request)
646 {
647 
648 }
649 #endif
650 
651 /**
652  * wlan_schedule_scan_start_request() - Schedule scan start request
653  * @pdev: pointer to pdev object
654  * @req: Pointer to the scan request
655  * @source: source of the scan request
656  * @scan_start_req: pointer to scan start request
657  *
658  * Schedule scan start request and enqueue scan request in the global scan
659  * list. This list stores the active scan request information.
660  *
661  * Return: QDF_STATUS
662  */
663 static QDF_STATUS
664 wlan_schedule_scan_start_request(struct wlan_objmgr_pdev *pdev,
665 				 struct cfg80211_scan_request *req,
666 				 uint8_t source,
667 				 struct scan_start_request *scan_start_req)
668 {
669 	struct scan_req *scan_req;
670 	QDF_STATUS status;
671 	struct pdev_osif_priv *osif_ctx;
672 	struct osif_scan_pdev *osif_scan;
673 
674 	scan_req = qdf_mem_malloc(sizeof(*scan_req));
675 	if (!scan_req) {
676 		ucfg_scm_scan_free_scan_request_mem(scan_start_req);
677 		return QDF_STATUS_E_NOMEM;
678 	}
679 
680 	/* Get NL global context from objmgr*/
681 	osif_ctx = wlan_pdev_get_ospriv(pdev);
682 	osif_scan = osif_ctx->osif_scan;
683 	scan_req->scan_request = req;
684 	scan_req->source = source;
685 	scan_req->scan_id = scan_start_req->scan_req.scan_id;
686 	scan_req->dev = req->wdev->netdev;
687 	scan_req->scan_start_timestamp = qdf_get_time_of_the_day_ms();
688 
689 	qdf_mutex_acquire(&osif_scan->scan_req_q_lock);
690 	if (qdf_list_size(&osif_scan->scan_req_q) < WLAN_MAX_SCAN_COUNT) {
691 		status = ucfg_scan_start(scan_start_req);
692 		if (QDF_IS_STATUS_SUCCESS(status)) {
693 			qdf_list_insert_back(&osif_scan->scan_req_q,
694 					     &scan_req->node);
695 		} else {
696 			osif_err("scan req failed with error %d", status);
697 			if (status == QDF_STATUS_E_RESOURCES)
698 				osif_err("HO is in progress.So defer the scan by informing busy");
699 		}
700 	} else {
701 		ucfg_scm_scan_free_scan_request_mem(scan_start_req);
702 		status = QDF_STATUS_E_RESOURCES;
703 	}
704 
705 	qdf_mutex_release(&osif_scan->scan_req_q_lock);
706 	if (QDF_IS_STATUS_ERROR(status)) {
707 		osif_rl_debug("Failed to enqueue Scan Req as max scan %d already queued",
708 			      qdf_list_size(&osif_scan->scan_req_q));
709 		qdf_mem_free(scan_req);
710 	}
711 
712 	return status;
713 }
714 
715 /**
716  * wlan_scan_request_dequeue() - dequeue scan request
717  * @nl_ctx: Global HDD context
718  * @scan_id: scan id
719  * @req: scan request
720  * @dev: net device
721  * @source : returns source of the scan request
722  *
723  * Return: QDF_STATUS
724  */
725 static QDF_STATUS wlan_scan_request_dequeue(
726 	struct wlan_objmgr_pdev *pdev,
727 	uint32_t scan_id, struct cfg80211_scan_request **req,
728 	uint8_t *source, struct net_device **dev,
729 	qdf_time_t *scan_start_timestamp)
730 {
731 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
732 	struct scan_req *scan_req;
733 	qdf_list_node_t *node = NULL, *next_node = NULL;
734 	struct pdev_osif_priv *osif_ctx;
735 	struct osif_scan_pdev *scan_priv;
736 
737 	if ((!source) || (!req)) {
738 		osif_err("source or request is NULL");
739 		return QDF_STATUS_E_NULL_VALUE;
740 	}
741 
742 	/* Get NL global context from objmgr*/
743 	osif_ctx = wlan_pdev_get_ospriv(pdev);
744 	if (!osif_ctx) {
745 		osif_err("Failed to retrieve osif context");
746 		return status;
747 	}
748 	scan_priv = osif_ctx->osif_scan;
749 
750 	qdf_mutex_acquire(&scan_priv->scan_req_q_lock);
751 	if (qdf_list_empty(&scan_priv->scan_req_q)) {
752 		osif_info("Scan List is empty");
753 		qdf_mutex_release(&scan_priv->scan_req_q_lock);
754 		return QDF_STATUS_E_FAILURE;
755 	}
756 
757 	if (QDF_STATUS_SUCCESS !=
758 		qdf_list_peek_front(&scan_priv->scan_req_q, &next_node)) {
759 		qdf_mutex_release(&scan_priv->scan_req_q_lock);
760 		osif_err("Failed to remove Scan Req from queue");
761 		return QDF_STATUS_E_FAILURE;
762 	}
763 
764 	do {
765 		node = next_node;
766 		scan_req = qdf_container_of(node, struct scan_req, node);
767 		if (scan_req->scan_id == scan_id) {
768 			status = qdf_list_remove_node(&scan_priv->scan_req_q,
769 						      node);
770 			if (status == QDF_STATUS_SUCCESS) {
771 				*req = scan_req->scan_request;
772 				*source = scan_req->source;
773 				*dev = scan_req->dev;
774 				*scan_start_timestamp =
775 					scan_req->scan_start_timestamp;
776 				qdf_mem_free(scan_req);
777 				qdf_mutex_release(&scan_priv->scan_req_q_lock);
778 				osif_debug("removed Scan id: %d, req = %pK, pending scans %d",
779 					   scan_id, req,
780 					   qdf_list_size(&scan_priv->scan_req_q));
781 				return QDF_STATUS_SUCCESS;
782 			} else {
783 				qdf_mutex_release(&scan_priv->scan_req_q_lock);
784 				osif_err("Failed to remove scan id %d, pending scans %d",
785 					 scan_id,
786 					 qdf_list_size(&scan_priv->scan_req_q));
787 				return status;
788 			}
789 		}
790 	} while (QDF_STATUS_SUCCESS ==
791 		qdf_list_peek_next(&scan_priv->scan_req_q, node, &next_node));
792 	qdf_mutex_release(&scan_priv->scan_req_q_lock);
793 	osif_debug("Failed to find scan id %d", scan_id);
794 
795 	return status;
796 }
797 
798 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
799 /**
800  * wlan_cfg80211_scan_done() - Scan completed callback to cfg80211
801  * @netdev: Net device
802  * @req : Scan request
803  * @aborted : true scan aborted false scan success
804  *
805  * This function notifies scan done to cfg80211
806  *
807  * Return: none
808  */
809 void wlan_cfg80211_scan_done(struct net_device *netdev,
810 			     struct cfg80211_scan_request *req,
811 			     bool aborted)
812 {
813 	struct cfg80211_scan_info info = {
814 		.aborted = aborted
815 	};
816 
817 	if (netdev->flags & IFF_UP)
818 		cfg80211_scan_done(req, &info);
819 }
820 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
821 /**
822  * wlan_cfg80211_scan_done() - Scan completed callback to cfg80211
823  * @netdev: Net device
824  * @req : Scan request
825  * @aborted : true scan aborted false scan success
826  *
827  * This function notifies scan done to cfg80211
828  *
829  * Return: none
830  */
831 void wlan_cfg80211_scan_done(struct net_device *netdev,
832 			     struct cfg80211_scan_request *req,
833 			     bool aborted)
834 {
835 	if (netdev->flags & IFF_UP)
836 		cfg80211_scan_done(req, aborted);
837 }
838 #endif
839 
840 /**
841  * wlan_vendor_scan_callback() - Scan completed callback event
842  *
843  * @req : Scan request
844  * @aborted : true scan aborted false scan success
845  *
846  * This function sends scan completed callback event to NL.
847  *
848  * Return: none
849  */
850 static void wlan_vendor_scan_callback(struct cfg80211_scan_request *req,
851 					bool aborted)
852 {
853 	struct sk_buff *skb;
854 	struct nlattr *attr;
855 	int i;
856 	uint8_t scan_status;
857 	uint64_t cookie;
858 	int index = QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX;
859 
860 	skb = wlan_cfg80211_vendor_event_alloc(req->wdev->wiphy, req->wdev,
861 					       SCAN_DONE_EVENT_BUF_SIZE + 4 +
862 					       NLMSG_HDRLEN,
863 					       index,
864 					       GFP_ATOMIC);
865 
866 	if (!skb) {
867 		osif_err("skb alloc failed");
868 		qdf_mem_free(req);
869 		return;
870 	}
871 
872 	cookie = (uintptr_t)req;
873 
874 	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS);
875 	if (!attr)
876 		goto nla_put_failure;
877 	for (i = 0; i < req->n_ssids; i++) {
878 		if (nla_put(skb, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
879 			goto nla_put_failure;
880 	}
881 	nla_nest_end(skb, attr);
882 
883 	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES);
884 	if (!attr)
885 		goto nla_put_failure;
886 	for (i = 0; i < req->n_channels; i++) {
887 		if (nla_put_u32(skb, i, req->channels[i]->center_freq))
888 			goto nla_put_failure;
889 	}
890 	nla_nest_end(skb, attr);
891 
892 	if (req->ie &&
893 		nla_put(skb, QCA_WLAN_VENDOR_ATTR_SCAN_IE, req->ie_len,
894 			req->ie))
895 		goto nla_put_failure;
896 
897 	if (req->flags &&
898 		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS, req->flags))
899 		goto nla_put_failure;
900 
901 	if (wlan_cfg80211_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
902 					cookie))
903 		goto nla_put_failure;
904 
905 	scan_status = (aborted == true) ? VENDOR_SCAN_STATUS_ABORTED :
906 		VENDOR_SCAN_STATUS_NEW_RESULTS;
907 	if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status))
908 		goto nla_put_failure;
909 
910 	wlan_cfg80211_vendor_event(skb, GFP_ATOMIC);
911 	qdf_mem_free(req);
912 
913 	return;
914 
915 nla_put_failure:
916 	wlan_cfg80211_vendor_free_skb(skb);
917 	qdf_mem_free(req);
918 }
919 
920 /**
921  * wlan_scan_acquire_wake_lock_timeout() - acquire scan wake lock
922  * @psoc: psoc ptr
923  * @scan_wake_lock: Scan wake lock
924  * @timeout: timeout in ms
925  *
926  * Return: void
927  */
928 static inline
929 void wlan_scan_acquire_wake_lock_timeout(struct wlan_objmgr_psoc *psoc,
930 					 qdf_wake_lock_t *scan_wake_lock,
931 					 uint32_t timeout)
932 {
933 	if (!psoc || !scan_wake_lock)
934 		return;
935 
936 	if (ucfg_scan_wake_lock_in_user_scan(psoc))
937 		qdf_wake_lock_timeout_acquire(scan_wake_lock, timeout);
938 }
939 
940 
941 /**
942  * wlan_scan_release_wake_lock() - release scan wake lock
943  * @psoc: psoc ptr
944  * @scan_wake_lock: Scan wake lock
945  *
946  * Return: void
947  */
948 #ifdef FEATURE_WLAN_DIAG_SUPPORT
949 static inline
950 void wlan_scan_release_wake_lock(struct wlan_objmgr_psoc *psoc,
951 				 qdf_wake_lock_t *scan_wake_lock)
952 {
953 	if (!psoc || !scan_wake_lock)
954 		return;
955 
956 	if (ucfg_scan_wake_lock_in_user_scan(psoc))
957 		qdf_wake_lock_release(scan_wake_lock,
958 				      WIFI_POWER_EVENT_WAKELOCK_SCAN);
959 }
960 #else
961 static inline
962 void wlan_scan_release_wake_lock(struct wlan_objmgr_psoc *psoc,
963 				 qdf_wake_lock_t *scan_wake_lock)
964 {
965 	if (!psoc || !scan_wake_lock)
966 		return;
967 
968 	if (ucfg_scan_wake_lock_in_user_scan(psoc))
969 		qdf_wake_lock_release(scan_wake_lock, 0);
970 }
971 #endif
972 
973 static
974 uint32_t wlan_scan_get_bss_count_for_scan(struct wlan_objmgr_pdev *pdev,
975 					  qdf_time_t scan_start_ts)
976 {
977 	struct scan_filter *filter;
978 	qdf_list_t *list = NULL;
979 	uint32_t count = 0;
980 
981 	if (!scan_start_ts)
982 		return count;
983 
984 	filter = qdf_mem_malloc(sizeof(*filter));
985 	if (!filter)
986 		return count;
987 
988 	filter->ignore_auth_enc_type = true;
989 	filter->age_threshold = qdf_get_time_of_the_day_ms() - scan_start_ts;
990 
991 	list = ucfg_scan_get_result(pdev, filter);
992 
993 	qdf_mem_free(filter);
994 
995 	if (list) {
996 		count = qdf_list_size(list);
997 		ucfg_scan_purge_results(list);
998 	}
999 
1000 	return count;
1001 }
1002 
1003 /**
1004  * wlan_cfg80211_scan_done_callback() - scan done callback function called after
1005  * scan is finished
1006  * @vdev: vdev ptr
1007  * @event: Scan event
1008  * @args: Scan cb arg
1009  *
1010  * Return: void
1011  */
1012 static void wlan_cfg80211_scan_done_callback(
1013 					struct wlan_objmgr_vdev *vdev,
1014 					struct scan_event *event,
1015 					void *args)
1016 {
1017 	struct cfg80211_scan_request *req = NULL;
1018 	bool success = false;
1019 	uint32_t scan_id;
1020 	uint8_t source = NL_SCAN;
1021 	struct wlan_objmgr_pdev *pdev;
1022 	struct pdev_osif_priv *osif_priv;
1023 	struct net_device *netdev = NULL;
1024 	QDF_STATUS status;
1025 	qdf_time_t scan_start_timestamp = 0;
1026 	uint32_t unique_bss_count = 0;
1027 
1028 	if (!event) {
1029 		osif_nofl_err("Invalid scan event received");
1030 		return;
1031 	}
1032 
1033 	scan_id = event->scan_id;
1034 
1035 	qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_OS_IF, event->type,
1036 		   event->vdev_id, scan_id);
1037 
1038 	if (event->type == SCAN_EVENT_TYPE_STARTED)
1039 		osif_nofl_info("scan start scan id %d", scan_id);
1040 
1041 	if (!util_is_scan_completed(event, &success))
1042 		return;
1043 
1044 	pdev = wlan_vdev_get_pdev(vdev);
1045 	status = wlan_scan_request_dequeue(
1046 			pdev, scan_id, &req, &source, &netdev,
1047 			&scan_start_timestamp);
1048 	if (QDF_IS_STATUS_ERROR(status)) {
1049 		osif_err("Dequeue of scan request failed ID: %d", scan_id);
1050 		goto allow_suspend;
1051 	}
1052 
1053 	if (!netdev) {
1054 		osif_err("net dev is NULL,Drop scan event Id: %d", scan_id);
1055 		goto allow_suspend;
1056 	}
1057 
1058 	/* Make sure vdev is active */
1059 	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID);
1060 	if (QDF_IS_STATUS_ERROR(status)) {
1061 		osif_err("Failed to get vdev reference: scan Id: %d", scan_id);
1062 		goto allow_suspend;
1063 	}
1064 
1065 	/*
1066 	 * Scan can be triggred from NL or vendor scan
1067 	 * - If scan is triggered from NL then cfg80211 scan done should be
1068 	 * called to updated scan completion to NL.
1069 	 * - If scan is triggred through vendor command then
1070 	 * scan done event will be posted
1071 	 */
1072 	if (NL_SCAN == source)
1073 		wlan_cfg80211_scan_done(netdev, req, !success);
1074 	else
1075 		wlan_vendor_scan_callback(req, !success);
1076 
1077 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
1078 
1079 	unique_bss_count = wlan_scan_get_bss_count_for_scan(pdev,
1080 							  scan_start_timestamp);
1081 	osif_nofl_info("vdev %d, scan id %d type %s(%d) reason %s(%d) scan found %d bss",
1082 		       event->vdev_id, scan_id,
1083 		       util_scan_get_ev_type_name(event->type), event->type,
1084 		       util_scan_get_ev_reason_name(event->reason),
1085 		       event->reason, unique_bss_count);
1086 allow_suspend:
1087 	osif_priv = wlan_pdev_get_ospriv(pdev);
1088 	qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock);
1089 	if (qdf_list_empty(&osif_priv->osif_scan->scan_req_q)) {
1090 		struct wlan_objmgr_psoc *psoc;
1091 
1092 		qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock);
1093 		qdf_runtime_pm_allow_suspend(
1094 			&osif_priv->osif_scan->runtime_pm_lock);
1095 
1096 		psoc = wlan_pdev_get_psoc(pdev);
1097 		wlan_scan_release_wake_lock(psoc,
1098 					&osif_priv->osif_scan->scan_wake_lock);
1099 		/*
1100 		 * Acquire wakelock to handle the case where APP's tries
1101 		 * to suspend immediately after the driver gets connect
1102 		 * request(i.e after scan) from supplicant, this result in
1103 		 * app's is suspending and not able to process the connect
1104 		 * request to AP
1105 		 */
1106 		wlan_scan_acquire_wake_lock_timeout(psoc,
1107 					&osif_priv->osif_scan->scan_wake_lock,
1108 					SCAN_WAKE_LOCK_CONNECT_DURATION);
1109 	} else {
1110 		qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock);
1111 	}
1112 
1113 }
1114 
1115 QDF_STATUS wlan_scan_runtime_pm_init(struct wlan_objmgr_pdev *pdev)
1116 {
1117 	struct pdev_osif_priv *osif_priv;
1118 	struct osif_scan_pdev *scan_priv;
1119 
1120 	wlan_pdev_obj_lock(pdev);
1121 	osif_priv = wlan_pdev_get_ospriv(pdev);
1122 	wlan_pdev_obj_unlock(pdev);
1123 
1124 	scan_priv = osif_priv->osif_scan;
1125 
1126 	return qdf_runtime_lock_init(&scan_priv->runtime_pm_lock);
1127 }
1128 
1129 void wlan_scan_runtime_pm_deinit(struct wlan_objmgr_pdev *pdev)
1130 {
1131 	struct pdev_osif_priv *osif_priv;
1132 	struct osif_scan_pdev *scan_priv;
1133 
1134 	wlan_pdev_obj_lock(pdev);
1135 	osif_priv = wlan_pdev_get_ospriv(pdev);
1136 	wlan_pdev_obj_unlock(pdev);
1137 
1138 	scan_priv = osif_priv->osif_scan;
1139 	qdf_runtime_lock_deinit(&scan_priv->runtime_pm_lock);
1140 }
1141 
1142 QDF_STATUS wlan_cfg80211_scan_priv_init(struct wlan_objmgr_pdev *pdev)
1143 {
1144 	struct pdev_osif_priv *osif_priv;
1145 	struct osif_scan_pdev *scan_priv;
1146 	struct wlan_objmgr_psoc *psoc;
1147 	wlan_scan_requester req_id;
1148 
1149 	psoc = wlan_pdev_get_psoc(pdev);
1150 
1151 	req_id = ucfg_scan_register_requester(psoc, "CFG",
1152 		wlan_cfg80211_scan_done_callback, NULL);
1153 
1154 	osif_priv = wlan_pdev_get_ospriv(pdev);
1155 	scan_priv = qdf_mem_malloc(sizeof(*scan_priv));
1156 	if (!scan_priv)
1157 		return QDF_STATUS_E_NOMEM;
1158 
1159 	/* Initialize the scan request queue */
1160 	osif_priv->osif_scan = scan_priv;
1161 	scan_priv->req_id = req_id;
1162 	qdf_list_create(&scan_priv->scan_req_q, WLAN_MAX_SCAN_COUNT);
1163 	qdf_mutex_create(&scan_priv->scan_req_q_lock);
1164 	qdf_wake_lock_create(&scan_priv->scan_wake_lock, "scan_wake_lock");
1165 
1166 	return QDF_STATUS_SUCCESS;
1167 }
1168 
1169 QDF_STATUS wlan_cfg80211_scan_priv_deinit(struct wlan_objmgr_pdev *pdev)
1170 {
1171 	struct pdev_osif_priv *osif_priv;
1172 	struct osif_scan_pdev *scan_priv;
1173 	struct wlan_objmgr_psoc *psoc;
1174 
1175 	psoc = wlan_pdev_get_psoc(pdev);
1176 	osif_priv = wlan_pdev_get_ospriv(pdev);
1177 
1178 	wlan_cfg80211_cleanup_scan_queue(pdev, NULL);
1179 	scan_priv = osif_priv->osif_scan;
1180 	qdf_wake_lock_destroy(&scan_priv->scan_wake_lock);
1181 	qdf_mutex_destroy(&scan_priv->scan_req_q_lock);
1182 	qdf_list_destroy(&scan_priv->scan_req_q);
1183 	ucfg_scan_unregister_requester(psoc, scan_priv->req_id);
1184 	osif_priv->osif_scan = NULL;
1185 	qdf_mem_free(scan_priv);
1186 
1187 	return QDF_STATUS_SUCCESS;
1188 }
1189 
1190 /**
1191  * wlan_cfg80211_enqueue_for_cleanup() - Function to populate scan cleanup queue
1192  * @scan_cleanup_q: Scan cleanup queue to be populated
1193  * @scan_priv: Pointer to scan related data used by cfg80211 scan
1194  * @dev: Netdevice pointer
1195  *
1196  * The function synchrounously iterates through the global scan queue to
1197  * identify entries that have to be cleaned up, copies identified entries
1198  * to another queue(to send scan complete event to NL later) and removes the
1199  * entry from the global scan queue.
1200  *
1201  * Return: None
1202  */
1203 static void
1204 wlan_cfg80211_enqueue_for_cleanup(qdf_list_t *scan_cleanup_q,
1205 				  struct osif_scan_pdev *scan_priv,
1206 				  struct net_device *dev)
1207 {
1208 	struct scan_req *scan_req, *scan_cleanup;
1209 	qdf_list_node_t *node = NULL, *next_node = NULL;
1210 
1211 	qdf_mutex_acquire(&scan_priv->scan_req_q_lock);
1212 	if (QDF_STATUS_SUCCESS !=
1213 		qdf_list_peek_front(&scan_priv->scan_req_q,
1214 				    &node)) {
1215 		qdf_mutex_release(&scan_priv->scan_req_q_lock);
1216 		return;
1217 	}
1218 
1219 	while (node) {
1220 		/*
1221 		 * Keep track of the next node, to traverse through the list
1222 		 * in the event of the current node being deleted.
1223 		 */
1224 		qdf_list_peek_next(&scan_priv->scan_req_q,
1225 				   node, &next_node);
1226 		scan_req = qdf_container_of(node, struct scan_req, node);
1227 		if (!dev || (dev == scan_req->dev)) {
1228 			scan_cleanup = qdf_mem_malloc(sizeof(struct scan_req));
1229 			if (!scan_cleanup) {
1230 				qdf_mutex_release(&scan_priv->scan_req_q_lock);
1231 				return;
1232 			}
1233 			scan_cleanup->scan_request = scan_req->scan_request;
1234 			scan_cleanup->scan_id = scan_req->scan_id;
1235 			scan_cleanup->source = scan_req->source;
1236 			scan_cleanup->dev = scan_req->dev;
1237 			qdf_list_insert_back(scan_cleanup_q,
1238 					     &scan_cleanup->node);
1239 			if (QDF_STATUS_SUCCESS !=
1240 				qdf_list_remove_node(&scan_priv->scan_req_q,
1241 						     node)) {
1242 				qdf_mutex_release(&scan_priv->scan_req_q_lock);
1243 				osif_err("Failed to remove scan request");
1244 				return;
1245 			}
1246 			qdf_mem_free(scan_req);
1247 		}
1248 		node = next_node;
1249 		next_node = NULL;
1250 	}
1251 	qdf_mutex_release(&scan_priv->scan_req_q_lock);
1252 }
1253 
1254 void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev,
1255 				      struct net_device *dev)
1256 {
1257 	struct scan_req *scan_req;
1258 	struct cfg80211_scan_request *req;
1259 	uint8_t source;
1260 	bool aborted = true;
1261 	struct pdev_osif_priv *osif_priv;
1262 	qdf_list_t scan_cleanup_q;
1263 	qdf_list_node_t *node = NULL;
1264 
1265 	if (!pdev) {
1266 		osif_err("pdev is Null");
1267 		return;
1268 	}
1269 
1270 	osif_priv = wlan_pdev_get_ospriv(pdev);
1271 
1272 	/*
1273 	 * To avoid any race conditions, create a local list to copy all the
1274 	 * scan entries to be removed and then send scan complete for each of
1275 	 * the identified entries to NL.
1276 	 */
1277 	qdf_list_create(&scan_cleanup_q, WLAN_MAX_SCAN_COUNT);
1278 	wlan_cfg80211_enqueue_for_cleanup(&scan_cleanup_q,
1279 					  osif_priv->osif_scan, dev);
1280 
1281 	while (!qdf_list_empty(&scan_cleanup_q)) {
1282 		if (QDF_STATUS_SUCCESS != qdf_list_remove_front(&scan_cleanup_q,
1283 								&node)) {
1284 			osif_err("Failed to remove scan request");
1285 			return;
1286 		}
1287 		scan_req = container_of(node, struct scan_req, node);
1288 		req = scan_req->scan_request;
1289 		source = scan_req->source;
1290 		if (NL_SCAN == source)
1291 			wlan_cfg80211_scan_done(scan_req->dev, req,
1292 						aborted);
1293 		else
1294 			wlan_vendor_scan_callback(req, aborted);
1295 
1296 		qdf_mem_free(scan_req);
1297 	}
1298 	qdf_list_destroy(&scan_cleanup_q);
1299 
1300 	return;
1301 }
1302 
1303 /**
1304  * wlan_cfg80211_update_scan_policy_type_flags() - Set scan flags according to
1305  * scan request
1306  * @scan_req: Pointer to csr scan req
1307  *
1308  * Return: None
1309  */
1310 #if defined(CFG80211_SCAN_DBS_CONTROL_SUPPORT) || \
1311 	   (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0))
1312 static void wlan_cfg80211_update_scan_policy_type_flags(
1313 	struct cfg80211_scan_request *req,
1314 	struct scan_req_params *scan_req)
1315 {
1316 	if (req->flags & NL80211_SCAN_FLAG_HIGH_ACCURACY)
1317 		scan_req->scan_policy_high_accuracy = true;
1318 	if (req->flags & NL80211_SCAN_FLAG_LOW_SPAN)
1319 		scan_req->scan_policy_low_span = true;
1320 	if (req->flags & NL80211_SCAN_FLAG_LOW_POWER)
1321 		scan_req->scan_policy_low_power = true;
1322 }
1323 #else
1324 static inline void wlan_cfg80211_update_scan_policy_type_flags(
1325 		struct cfg80211_scan_request *req,
1326 		struct scan_req_params *scan_req)
1327 {
1328 }
1329 #endif
1330 
1331 #ifdef WLAN_POLICY_MGR_ENABLE
1332 static bool
1333 wlan_cfg80211_allow_simultaneous_scan(struct wlan_objmgr_psoc *psoc)
1334 {
1335 	return policy_mgr_is_scan_simultaneous_capable(psoc);
1336 }
1337 #else
1338 static bool
1339 wlan_cfg80211_allow_simultaneous_scan(struct wlan_objmgr_psoc *psoc)
1340 {
1341 	return true;
1342 }
1343 #endif
1344 
1345 int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
1346 		       struct cfg80211_scan_request *request,
1347 		       struct scan_params *params)
1348 {
1349 	struct scan_start_request *req;
1350 	struct wlan_ssid *pssid;
1351 	uint8_t i;
1352 	int ret = 0;
1353 	uint8_t num_chan = 0;
1354 	uint32_t c_freq;
1355 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
1356 	wlan_scan_requester req_id;
1357 	struct pdev_osif_priv *osif_priv;
1358 	struct wlan_objmgr_psoc *psoc;
1359 	wlan_scan_id scan_id;
1360 	bool is_p2p_scan = false;
1361 	enum wlan_band band;
1362 	QDF_STATUS qdf_status;
1363 	enum QDF_OPMODE opmode;
1364 	uint32_t extra_ie_len = 0;
1365 
1366 	psoc = wlan_pdev_get_psoc(pdev);
1367 	if (!psoc) {
1368 		osif_err("Invalid psoc object");
1369 		return -EINVAL;
1370 	}
1371 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1372 
1373 	osif_debug("%s(vdev%d): mode %d", request->wdev->netdev->name,
1374 		   wlan_vdev_get_id(vdev), opmode);
1375 
1376 	/* Get NL global context from objmgr*/
1377 	osif_priv = wlan_pdev_get_ospriv(pdev);
1378 	if (!osif_priv) {
1379 		osif_err("Invalid osif priv object");
1380 		return -EINVAL;
1381 	}
1382 
1383 	/*
1384 	 * For a non-SAP vdevs, if a scan is already going on i.e the scan queue
1385 	 * is not empty, and the simultaneous scan is disabled, dont allow 2nd
1386 	 * scan.
1387 	 */
1388 	qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock);
1389 	if (!wlan_cfg80211_allow_simultaneous_scan(psoc) &&
1390 	    !qdf_list_empty(&osif_priv->osif_scan->scan_req_q) &&
1391 	    opmode != QDF_SAP_MODE) {
1392 		qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock);
1393 		osif_err("Simultaneous scan disabled, reject scan");
1394 		return -EBUSY;
1395 	}
1396 	qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock);
1397 
1398 	req = qdf_mem_malloc(sizeof(*req));
1399 	if (!req)
1400 		return -EINVAL;
1401 
1402 	/* Initialize the scan global params */
1403 	ucfg_scan_init_default_params(vdev, req);
1404 
1405 	req_id = osif_priv->osif_scan->req_id;
1406 	scan_id = ucfg_scan_get_scan_id(psoc);
1407 	if (!scan_id) {
1408 		osif_err("Invalid scan id");
1409 		qdf_mem_free(req);
1410 		return -EINVAL;
1411 	}
1412 
1413 	/* fill the scan request structure */
1414 	req->vdev = vdev;
1415 	req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
1416 	req->scan_req.scan_id = scan_id;
1417 	req->scan_req.scan_req_id = req_id;
1418 
1419 	/* Update scan policy type flags according to cfg scan request */
1420 	wlan_cfg80211_update_scan_policy_type_flags(request,
1421 					     &req->scan_req);
1422 	/*
1423 	 * Even though supplicant doesn't provide any SSIDs, n_ssids is
1424 	 * set to 1.  Because of this, driver is assuming that this is not
1425 	 * wildcard scan and so is not aging out the scan results.
1426 	 */
1427 	if ((request->ssids) && (request->n_ssids == 1) &&
1428 	    ('\0' == request->ssids->ssid[0])) {
1429 		request->n_ssids = 0;
1430 	}
1431 
1432 	if ((request->ssids) && (0 < request->n_ssids)) {
1433 		int j;
1434 		req->scan_req.num_ssids = request->n_ssids;
1435 
1436 		if (req->scan_req.num_ssids > WLAN_SCAN_MAX_NUM_SSID) {
1437 			osif_info("number of ssid %d greater than MAX %d",
1438 				  req->scan_req.num_ssids,
1439 				  WLAN_SCAN_MAX_NUM_SSID);
1440 			req->scan_req.num_ssids = WLAN_SCAN_MAX_NUM_SSID;
1441 		}
1442 		/* copy all the ssid's and their length */
1443 		for (j = 0; j < req->scan_req.num_ssids; j++)  {
1444 			pssid = &req->scan_req.ssid[j];
1445 			/* get the ssid length */
1446 			pssid->length = request->ssids[j].ssid_len;
1447 			if (pssid->length > WLAN_SSID_MAX_LEN)
1448 				pssid->length = WLAN_SSID_MAX_LEN;
1449 			qdf_mem_copy(pssid->ssid,
1450 				     &request->ssids[j].ssid[0],
1451 				     pssid->length);
1452 		}
1453 	}
1454 	if (request->ssids ||
1455 	   (opmode == QDF_P2P_GO_MODE) || (opmode == QDF_P2P_DEVICE_MODE))
1456 		req->scan_req.scan_f_passive = false;
1457 
1458 	if (params->half_rate)
1459 		req->scan_req.scan_f_half_rate = true;
1460 	else if (params->quarter_rate)
1461 		req->scan_req.scan_f_quarter_rate = true;
1462 
1463 	if (params->strict_pscan)
1464 		req->scan_req.scan_f_strict_passive_pch = true;
1465 
1466 	if ((request->n_ssids == 1) && request->ssids &&
1467 	   !qdf_mem_cmp(&request->ssids[0], "DIRECT-", 7))
1468 		is_p2p_scan = true;
1469 
1470 	if (is_p2p_scan && request->no_cck)
1471 		req->scan_req.scan_type = SCAN_TYPE_P2P_SEARCH;
1472 
1473 	if (params->dwell_time_active)
1474 		req->scan_req.dwell_time_active = params->dwell_time_active;
1475 
1476 	if (params->dwell_time_active_2g)
1477 		req->scan_req.dwell_time_active_2g =
1478 			params->dwell_time_active_2g;
1479 
1480 	if (params->dwell_time_passive)
1481 		req->scan_req.dwell_time_passive = params->dwell_time_passive;
1482 
1483 	if (params->dwell_time_active_6g)
1484 		req->scan_req.dwell_time_active_6g =
1485 			params->dwell_time_active_6g;
1486 
1487 	if (params->dwell_time_passive_6g)
1488 		req->scan_req.dwell_time_passive_6g =
1489 			params->dwell_time_passive_6g;
1490 
1491 	/* Set dwell time mode according to scan policy type flags */
1492 	if (ucfg_scan_cfg_honour_nl_scan_policy_flags(psoc)) {
1493 		if (req->scan_req.scan_policy_high_accuracy)
1494 			req->scan_req.adaptive_dwell_time_mode =
1495 						SCAN_DWELL_MODE_STATIC;
1496 		if (req->scan_req.scan_policy_low_power ||
1497 		    req->scan_req.scan_policy_low_span)
1498 			req->scan_req.adaptive_dwell_time_mode =
1499 						SCAN_DWELL_MODE_AGGRESSIVE;
1500 	}
1501 
1502 	/*
1503 	 * FW require at least 1 MAC to send probe request.
1504 	 * If MAC is all 0 set it to BC addr as this is the address on
1505 	 * which fw will send probe req.
1506 	 */
1507 	req->scan_req.num_bssid = 1;
1508 	wlan_copy_bssid_scan_request(req, request);
1509 	if (qdf_is_macaddr_zero(&req->scan_req.bssid_list[0]))
1510 		qdf_set_macaddr_broadcast(&req->scan_req.bssid_list[0]);
1511 
1512 	if (request->n_channels) {
1513 #ifdef WLAN_POLICY_MGR_ENABLE
1514 		bool ap_or_go_present =
1515 			policy_mgr_mode_specific_connection_count(
1516 			     psoc, PM_SAP_MODE, NULL) ||
1517 			     policy_mgr_mode_specific_connection_count(
1518 			     psoc, PM_P2P_GO_MODE, NULL);
1519 #endif
1520 		for (i = 0; i < request->n_channels; i++) {
1521 			c_freq = request->channels[i]->center_freq;
1522 			if (wlan_reg_is_dsrc_freq(c_freq))
1523 				continue;
1524 #ifdef WLAN_POLICY_MGR_ENABLE
1525 			if (ap_or_go_present) {
1526 				bool ok;
1527 
1528 				qdf_status = policy_mgr_is_chan_ok_for_dnbs(
1529 							psoc, c_freq, &ok);
1530 
1531 				if (QDF_IS_STATUS_ERROR(qdf_status)) {
1532 					osif_err("DNBS check failed");
1533 					ret = -EINVAL;
1534 					goto err;
1535 				}
1536 				if (!ok)
1537 					continue;
1538 			}
1539 #endif
1540 			req->scan_req.chan_list.chan[num_chan].freq = c_freq;
1541 			band = util_scan_scm_freq_to_band(c_freq);
1542 			if (band == WLAN_BAND_2_4_GHZ)
1543 				req->scan_req.chan_list.chan[num_chan].phymode =
1544 					SCAN_PHY_MODE_11G;
1545 			else
1546 				req->scan_req.chan_list.chan[num_chan].phymode =
1547 					SCAN_PHY_MODE_11A;
1548 			num_chan++;
1549 			if (num_chan >= NUM_CHANNELS)
1550 				break;
1551 		}
1552 	}
1553 	if (!num_chan) {
1554 		osif_err("Received zero non-dsrc channels");
1555 		ret = -EINVAL;
1556 		goto err;
1557 	}
1558 	req->scan_req.chan_list.num_chan = num_chan;
1559 
1560 	/* P2P increase the scan priority */
1561 	if (is_p2p_scan)
1562 		req->scan_req.scan_priority = SCAN_PRIORITY_HIGH;
1563 
1564 	if (params->priority != SCAN_PRIORITY_COUNT)
1565 		req->scan_req.scan_priority = params->priority;
1566 
1567 	if (request->ie_len)
1568 		extra_ie_len = request->ie_len;
1569 	else if (params->default_ie.ptr && params->default_ie.len)
1570 		extra_ie_len = params->default_ie.len;
1571 
1572 	if (params->vendor_ie.ptr && params->vendor_ie.len)
1573 		extra_ie_len += params->vendor_ie.len;
1574 
1575 	if (extra_ie_len) {
1576 		req->scan_req.extraie.ptr = qdf_mem_malloc(extra_ie_len);
1577 		if (!req->scan_req.extraie.ptr) {
1578 			ret = -ENOMEM;
1579 			goto err;
1580 		}
1581 	}
1582 
1583 	if (request->ie_len) {
1584 		req->scan_req.extraie.len = request->ie_len;
1585 		qdf_mem_copy(req->scan_req.extraie.ptr, request->ie,
1586 			     request->ie_len);
1587 	} else if (params->default_ie.ptr && params->default_ie.len) {
1588 		req->scan_req.extraie.len = params->default_ie.len;
1589 		qdf_mem_copy(req->scan_req.extraie.ptr, params->default_ie.ptr,
1590 			     params->default_ie.len);
1591 	}
1592 
1593 	if (params->vendor_ie.ptr && params->vendor_ie.len) {
1594 		qdf_mem_copy((req->scan_req.extraie.ptr +
1595 			      req->scan_req.extraie.len),
1596 			     params->vendor_ie.ptr, params->vendor_ie.len);
1597 
1598 		req->scan_req.extraie.len += params->vendor_ie.len;
1599 	}
1600 
1601 	if (!is_p2p_scan) {
1602 		if (req->scan_req.scan_random.randomize)
1603 			wlan_scan_rand_attrs(vdev, request, req);
1604 		if (ucfg_ie_whitelist_enabled(psoc, vdev) &&
1605 		    ucfg_copy_ie_whitelist_attrs(psoc,
1606 					&req->scan_req.ie_whitelist))
1607 			req->scan_req.scan_f_en_ie_whitelist_in_probe = true;
1608 	}
1609 
1610 	if (request->flags & NL80211_SCAN_FLAG_FLUSH)
1611 		ucfg_scan_flush_results(pdev, NULL);
1612 
1613 	/*
1614 	 * Acquire wakelock to handle the case where APP's send scan to connect.
1615 	 * If suspend is received during scan scan will be aborted and APP will
1616 	 * not get scan result and not connect. eg if PNO is implemented in
1617 	 * framework.
1618 	 */
1619 	wlan_scan_acquire_wake_lock_timeout(psoc,
1620 					&osif_priv->osif_scan->scan_wake_lock,
1621 					SCAN_WAKE_LOCK_SCAN_DURATION);
1622 
1623 	qdf_runtime_pm_prevent_suspend(
1624 		&osif_priv->osif_scan->runtime_pm_lock);
1625 
1626 	qdf_status = wlan_schedule_scan_start_request(pdev, request,
1627 						      params->source, req);
1628 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
1629 		qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock);
1630 		if (qdf_list_empty(&osif_priv->osif_scan->scan_req_q)) {
1631 			qdf_mutex_release(
1632 				&osif_priv->osif_scan->scan_req_q_lock);
1633 			qdf_runtime_pm_allow_suspend(
1634 					&osif_priv->osif_scan->runtime_pm_lock);
1635 			wlan_scan_release_wake_lock(
1636 					psoc,
1637 					&osif_priv->osif_scan->scan_wake_lock);
1638 		} else {
1639 			qdf_mutex_release(
1640 				&osif_priv->osif_scan->scan_req_q_lock);
1641 		}
1642 	}
1643 
1644 	return qdf_status_to_os_return(qdf_status);
1645 
1646 err:
1647 	qdf_mem_free(req);
1648 	return ret;
1649 }
1650 
1651 /**
1652  * wlan_get_scanid() - API to get the scan id
1653  * from the scan cookie attribute.
1654  * @pdev: Pointer to pdev object
1655  * @scan_id: Pointer to scan id
1656  * @cookie : Scan cookie attribute
1657  *
1658  * API to get the scan id from the scan cookie attribute
1659  * sent from supplicant by matching scan request.
1660  *
1661  * Return: 0 for success, non zero for failure
1662  */
1663 static int wlan_get_scanid(struct wlan_objmgr_pdev *pdev,
1664 			       uint32_t *scan_id, uint64_t cookie)
1665 {
1666 	struct scan_req *scan_req;
1667 	qdf_list_node_t *node = NULL;
1668 	qdf_list_node_t *ptr_node = NULL;
1669 	int ret = -EINVAL;
1670 	struct pdev_osif_priv *osif_ctx;
1671 	struct osif_scan_pdev *scan_priv;
1672 
1673 	/* Get NL global context from objmgr*/
1674 	osif_ctx = wlan_pdev_get_ospriv(pdev);
1675 	if (!osif_ctx) {
1676 		osif_err("Failed to retrieve osif context");
1677 		return ret;
1678 	}
1679 	scan_priv = osif_ctx->osif_scan;
1680 	qdf_mutex_acquire(&scan_priv->scan_req_q_lock);
1681 	if (qdf_list_empty(&scan_priv->scan_req_q)) {
1682 		qdf_mutex_release(&scan_priv->scan_req_q_lock);
1683 		osif_err("Failed to retrieve scan id");
1684 		return ret;
1685 	}
1686 
1687 	if (QDF_STATUS_SUCCESS !=
1688 			    qdf_list_peek_front(&scan_priv->scan_req_q,
1689 			    &ptr_node)) {
1690 		qdf_mutex_release(&scan_priv->scan_req_q_lock);
1691 		return ret;
1692 	}
1693 
1694 	do {
1695 		node = ptr_node;
1696 		scan_req = qdf_container_of(node, struct scan_req, node);
1697 		if (cookie ==
1698 		    (uintptr_t)(scan_req->scan_request)) {
1699 			*scan_id = scan_req->scan_id;
1700 			ret = 0;
1701 			break;
1702 		}
1703 	} while (QDF_STATUS_SUCCESS ==
1704 		 qdf_list_peek_next(&scan_priv->scan_req_q,
1705 		 node, &ptr_node));
1706 
1707 	qdf_mutex_release(&scan_priv->scan_req_q_lock);
1708 
1709 	return ret;
1710 }
1711 
1712 QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev,
1713 				   uint32_t pdev_id, uint32_t vdev_id,
1714 				   wlan_scan_id scan_id, bool sync)
1715 {
1716 	struct scan_cancel_request *req;
1717 	struct pdev_osif_priv *osif_ctx;
1718 	struct osif_scan_pdev *scan_priv;
1719 	QDF_STATUS status;
1720 	struct wlan_objmgr_vdev *vdev;
1721 
1722 	req = qdf_mem_malloc(sizeof(*req));
1723 	if (!req)
1724 		return QDF_STATUS_E_NOMEM;
1725 
1726 	/* Get NL global context from objmgr*/
1727 	osif_ctx = wlan_pdev_get_ospriv(pdev);
1728 	if (!osif_ctx) {
1729 		osif_err("Failed to retrieve osif context");
1730 		qdf_mem_free(req);
1731 		return QDF_STATUS_E_FAILURE;
1732 	}
1733 	if (vdev_id == INVAL_VDEV_ID)
1734 		vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_OSIF_ID);
1735 	else
1736 		vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev,
1737 				vdev_id, WLAN_OSIF_ID);
1738 
1739 	if (!vdev) {
1740 		qdf_mem_free(req);
1741 		return QDF_STATUS_E_INVAL;
1742 	}
1743 	scan_priv = osif_ctx->osif_scan;
1744 	req->cancel_req.requester = scan_priv->req_id;
1745 	req->vdev = vdev;
1746 	req->cancel_req.scan_id = scan_id;
1747 	req->cancel_req.pdev_id = pdev_id;
1748 	req->cancel_req.vdev_id = vdev_id;
1749 	if (scan_id != INVAL_SCAN_ID && scan_id != CANCEL_HOST_SCAN_ID)
1750 		req->cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE;
1751 	else if (scan_id == CANCEL_HOST_SCAN_ID)
1752 		req->cancel_req.req_type = WLAN_SCAN_CANCEL_HOST_VDEV_ALL;
1753 	else if (vdev_id == INVAL_VDEV_ID)
1754 		req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
1755 	else
1756 		req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL;
1757 
1758 	osif_debug("Type %d Vdev %d pdev %d scan id %d sync %d",
1759 		   req->cancel_req.req_type, req->cancel_req.vdev_id,
1760 		   req->cancel_req.pdev_id, req->cancel_req.scan_id, sync);
1761 
1762 	if (sync)
1763 		status = ucfg_scan_cancel_sync(req);
1764 	else
1765 		status = ucfg_scan_cancel(req);
1766 	if (QDF_IS_STATUS_ERROR(status))
1767 		osif_err("Cancel scan request failed");
1768 
1769 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
1770 
1771 	return status;
1772 }
1773 
1774 qdf_export_symbol(wlan_abort_scan);
1775 
1776 int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev)
1777 {
1778 	uint8_t pdev_id;
1779 
1780 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1781 
1782 	if (ucfg_scan_get_pdev_status(pdev) !=
1783 	   SCAN_NOT_IN_PROGRESS)
1784 		wlan_abort_scan(pdev, pdev_id,
1785 			INVAL_VDEV_ID, INVAL_SCAN_ID, true);
1786 
1787 	return 0;
1788 }
1789 
1790 int wlan_vendor_abort_scan(struct wlan_objmgr_pdev *pdev,
1791 			const void *data, int data_len)
1792 {
1793 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
1794 	int ret = -EINVAL;
1795 	wlan_scan_id scan_id;
1796 	uint64_t cookie;
1797 	uint8_t pdev_id;
1798 
1799 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1800 	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, data,
1801 				    data_len, cfg80211_scan_policy)) {
1802 		osif_err("Invalid ATTR");
1803 		return ret;
1804 	}
1805 
1806 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]) {
1807 		cookie = nla_get_u64(
1808 			    tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
1809 		ret = wlan_get_scanid(pdev, &scan_id, cookie);
1810 		if (ret != 0)
1811 			return ret;
1812 		if (ucfg_scan_get_pdev_status(pdev) !=
1813 		   SCAN_NOT_IN_PROGRESS)
1814 			wlan_abort_scan(pdev, INVAL_PDEV_ID,
1815 					INVAL_VDEV_ID, scan_id, true);
1816 	}
1817 	return 0;
1818 }
1819 
1820 static inline struct ieee80211_channel *
1821 wlan_get_ieee80211_channel(struct wiphy *wiphy,
1822 		struct wlan_objmgr_pdev *pdev,
1823 		int chan_freq)
1824 {
1825 	struct ieee80211_channel *chan;
1826 
1827 	chan = ieee80211_get_channel(wiphy, chan_freq);
1828 	if (!chan)
1829 		osif_err("chan is NULL, freq: %d", chan_freq);
1830 
1831 	return chan;
1832 }
1833 
1834 #ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
1835 static inline int wlan_get_frame_len(struct scan_cache_entry *scan_params)
1836 {
1837 	return util_scan_entry_frame_len(scan_params) + sizeof(qcom_ie_age);
1838 }
1839 
1840 static inline void wlan_add_age_ie(uint8_t *mgmt_frame,
1841 	struct scan_cache_entry *scan_params)
1842 {
1843 	qcom_ie_age *qie_age = NULL;
1844 
1845 	/* GPS Requirement: need age ie per entry. Using vendor specific. */
1846 	/* Assuming this is the last IE, copy at the end */
1847 	qie_age = (qcom_ie_age *) (mgmt_frame +
1848 		   util_scan_entry_frame_len(scan_params));
1849 	qie_age->element_id = QCOM_VENDOR_IE_ID;
1850 	qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
1851 	qie_age->oui_1 = QCOM_OUI1;
1852 	qie_age->oui_2 = QCOM_OUI2;
1853 	qie_age->oui_3 = QCOM_OUI3;
1854 	qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
1855 	/*
1856 	 * Lowi expects the timestamp of bss in units of 1/10 ms. In driver
1857 	 * all bss related timestamp is in units of ms. Due to this when scan
1858 	 * results are sent to lowi the scan age is high.To address this,
1859 	 * send age in units of 1/10 ms.
1860 	 */
1861 	qie_age->age =
1862 		(uint32_t)(qdf_mc_timer_get_system_time() -
1863 		  scan_params->scan_entry_time)/10;
1864 	qie_age->tsf_delta = scan_params->tsf_delta;
1865 	memcpy(&qie_age->beacon_tsf, scan_params->tsf_info.data,
1866 		  sizeof(qie_age->beacon_tsf));
1867 	memcpy(&qie_age->seq_ctrl, &scan_params->seq_num,
1868 	       sizeof(qie_age->seq_ctrl));
1869 }
1870 #else
1871 static inline int wlan_get_frame_len(struct scan_cache_entry *scan_params)
1872 {
1873 	return util_scan_entry_frame_len(scan_params);
1874 }
1875 
1876 static inline void wlan_add_age_ie(uint8_t *mgmt_frame,
1877 	struct scan_cache_entry *scan_params)
1878 {
1879 }
1880 #endif /* WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS */
1881 
1882 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \
1883 	defined(CFG80211_INFORM_BSS_FRAME_DATA)
1884 /**
1885  * wlan_fill_per_chain_rssi() - fill per chain RSSI in inform bss
1886  * @data: bss data
1887  * @per_chain_snr: per chain RSSI
1888  *
1889  * Return: void
1890  */
1891 #if defined(CFG80211_SCAN_PER_CHAIN_RSSI_SUPPORT) || \
1892 	   (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0))
1893 static void wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data,
1894 	struct wlan_cfg80211_inform_bss *bss)
1895 {
1896 
1897 	uint32_t i;
1898 
1899 	if (!bss || !data) {
1900 		osif_err("Received bss is NULL");
1901 		return;
1902 	}
1903 	for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) {
1904 		if (!bss->per_chain_rssi[i] ||
1905 		    (bss->per_chain_rssi[i] == WLAN_INVALID_PER_CHAIN_RSSI))
1906 			continue;
1907 		data->chain_signal[i] = bss->per_chain_rssi[i];
1908 		data->chains |= BIT(i);
1909 	}
1910 }
1911 #else
1912 static inline void
1913 wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data,
1914 	struct wlan_cfg80211_inform_bss *bss)
1915 {
1916 }
1917 #endif
1918 
1919 struct cfg80211_bss *
1920 wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
1921 		struct wlan_cfg80211_inform_bss *bss)
1922 {
1923 	struct cfg80211_inform_bss data  = {0};
1924 
1925 	if (!bss) {
1926 		osif_err("bss is null");
1927 		return NULL;
1928 	}
1929 	wlan_fill_per_chain_rssi(&data, bss);
1930 
1931 	data.chan = bss->chan;
1932 	data.boottime_ns = bss->boottime_ns;
1933 	data.signal = bss->rssi;
1934 	return cfg80211_inform_bss_frame_data(wiphy, &data, bss->mgmt,
1935 					      bss->frame_len, GFP_ATOMIC);
1936 }
1937 #else
1938 struct cfg80211_bss *
1939 wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
1940 		struct wlan_cfg80211_inform_bss *bss)
1941 
1942 {
1943 	return cfg80211_inform_bss_frame(wiphy, bss->chan, bss->mgmt,
1944 					 bss->frame_len,
1945 					 bss->rssi, GFP_ATOMIC);
1946 }
1947 #endif
1948 
1949 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
1950 static inline void wlan_cfg80211_put_bss(struct wiphy *wiphy,
1951 		struct cfg80211_bss *bss)
1952 {
1953 	cfg80211_put_bss(wiphy, bss);
1954 }
1955 #else
1956 static inline void wlan_cfg80211_put_bss(struct wiphy *wiphy,
1957 		struct cfg80211_bss *bss)
1958 {
1959 	cfg80211_put_bss(bss);
1960 }
1961 #endif
1962 
1963 void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
1964 		struct scan_cache_entry *scan_params)
1965 {
1966 	struct pdev_osif_priv *pdev_ospriv = wlan_pdev_get_ospriv(pdev);
1967 	struct wiphy *wiphy;
1968 	struct cfg80211_bss *bss = NULL;
1969 	struct wlan_cfg80211_inform_bss bss_data = {0};
1970 
1971 	if (!pdev_ospriv) {
1972 		osif_err("os_priv is NULL");
1973 		return;
1974 	}
1975 
1976 	wiphy = pdev_ospriv->wiphy;
1977 
1978 	bss_data.frame_len = wlan_get_frame_len(scan_params);
1979 	bss_data.mgmt = qdf_mem_malloc_atomic(bss_data.frame_len);
1980 	if (!bss_data.mgmt) {
1981 		osif_err("bss mem alloc failed for seq %d",
1982 			 scan_params->seq_num);
1983 		return;
1984 	}
1985 	qdf_mem_copy(bss_data.mgmt,
1986 		 util_scan_entry_frame_ptr(scan_params),
1987 		 util_scan_entry_frame_len(scan_params));
1988 	/*
1989 	 * Android does not want the timestamp from the frame.
1990 	 * Instead it wants a monotonic increasing value
1991 	 */
1992 	bss_data.mgmt->u.probe_resp.timestamp = qdf_get_monotonic_boottime();
1993 	wlan_add_age_ie((uint8_t *)bss_data.mgmt, scan_params);
1994 	/*
1995 	 * Based on .ini configuration, raw rssi can be reported for bss.
1996 	 * Raw rssi is typically used for estimating power.
1997 	 */
1998 	bss_data.rssi = scan_params->rssi_raw;
1999 
2000 	bss_data.chan = wlan_get_ieee80211_channel(wiphy, pdev,
2001 		scan_params->channel.chan_freq);
2002 	if (!bss_data.chan) {
2003 		osif_err("Channel not found for bss "QDF_MAC_ADDR_FMT" seq %d chan_freq %d",
2004 			 QDF_MAC_ADDR_REF(bss_data.mgmt->bssid),
2005 			 scan_params->seq_num,
2006 			 scan_params->channel.chan_freq);
2007 		qdf_mem_free(bss_data.mgmt);
2008 		return;
2009 	}
2010 
2011 	/*
2012 	 * Supplicant takes the signal strength in terms of
2013 	 * mBm (1 dBm = 100 mBm).
2014 	 */
2015 	bss_data.rssi = QDF_MIN(bss_data.rssi, 0) * 100;
2016 
2017 	bss_data.boottime_ns = scan_params->boottime_ns;
2018 
2019 	qdf_mem_copy(bss_data.per_chain_rssi, scan_params->per_chain_rssi,
2020 		     WLAN_MGMT_TXRX_HOST_MAX_ANTENNA);
2021 
2022 	bss = wlan_cfg80211_inform_bss_frame_data(wiphy, &bss_data);
2023 	if (!bss)
2024 		osif_err("failed to inform bss "QDF_MAC_ADDR_FMT" seq %d",
2025 			 QDF_MAC_ADDR_REF(bss_data.mgmt->bssid),
2026 			 scan_params->seq_num);
2027 	else
2028 		wlan_cfg80211_put_bss(wiphy, bss);
2029 
2030 	qdf_mem_free(bss_data.mgmt);
2031 }
2032 
2033 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && \
2034 	!defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
2035 struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy,
2036 					   struct ieee80211_channel *channel,
2037 					   const u8 *bssid, const u8 *ssid,
2038 					   size_t ssid_len)
2039 {
2040 	return cfg80211_get_bss(wiphy, channel, bssid,
2041 				ssid, ssid_len,
2042 				WLAN_CAPABILITY_ESS,
2043 				WLAN_CAPABILITY_ESS);
2044 }
2045 #else
2046 struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy,
2047 					   struct ieee80211_channel *channel,
2048 					   const u8 *bssid, const u8 *ssid,
2049 					   size_t ssid_len)
2050 {
2051 	return cfg80211_get_bss(wiphy, channel, bssid,
2052 				ssid, ssid_len,
2053 				IEEE80211_BSS_TYPE_ESS,
2054 				IEEE80211_PRIVACY_ANY);
2055 }
2056 #endif
2057 
2058 void __wlan_cfg80211_unlink_bss_list(struct wiphy *wiphy, uint8_t *bssid,
2059 				     uint8_t *ssid, uint8_t ssid_len)
2060 {
2061 	struct cfg80211_bss *bss = NULL;
2062 
2063 	bss = wlan_cfg80211_get_bss(wiphy, NULL, bssid,
2064 				    ssid, ssid_len);
2065 	if (!bss) {
2066 		osif_info("BSS "QDF_MAC_ADDR_FMT" not found",
2067 			  QDF_MAC_ADDR_REF(bssid));
2068 	} else {
2069 		osif_debug("unlink entry for ssid:%.*s and BSSID "QDF_MAC_ADDR_FMT,
2070 			   ssid_len, ssid, QDF_MAC_ADDR_REF(bssid));
2071 		cfg80211_unlink_bss(wiphy, bss);
2072 		wlan_cfg80211_put_bss(wiphy, bss);
2073 	}
2074 
2075 	/*
2076 	 * Kernel creates separate entries into it's bss list for probe resp
2077 	 * and beacon for hidden AP. Both have separate ref count and thus
2078 	 * deleting one will not delete other entry.
2079 	 * If beacon entry of the hidden AP is not deleted and AP switch to
2080 	 * broadcasting SSID from Hiding SSID, kernel will reject the beacon
2081 	 * entry. So unlink the hidden beacon entry (if present) as well from
2082 	 * kernel, to avoid such issue.
2083 	 */
2084 	bss = wlan_cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0);
2085 	if (!bss) {
2086 		osif_debug("Hidden bss not found for Ssid:%.*s BSSID: "QDF_MAC_ADDR_FMT" sid_len %d",
2087 			   ssid_len, ssid, QDF_MAC_ADDR_REF(bssid), ssid_len);
2088 	} else {
2089 		osif_debug("unlink entry for Hidden ssid:%.*s and BSSID "QDF_MAC_ADDR_FMT,
2090 			   ssid_len, ssid, QDF_MAC_ADDR_REF(bssid));
2091 
2092 		cfg80211_unlink_bss(wiphy, bss);
2093 		/* cfg80211_get_bss get bss with ref count so release it */
2094 		wlan_cfg80211_put_bss(wiphy, bss);
2095 	}
2096 }
2097 void wlan_cfg80211_unlink_bss_list(struct wlan_objmgr_pdev *pdev,
2098 				   struct scan_cache_entry *scan_entry)
2099 {
2100 	struct pdev_osif_priv *pdev_ospriv = wlan_pdev_get_ospriv(pdev);
2101 	struct wiphy *wiphy;
2102 
2103 	if (!pdev_ospriv) {
2104 		osif_err("os_priv is NULL");
2105 		return;
2106 	}
2107 
2108 	wiphy = pdev_ospriv->wiphy;
2109 
2110 	__wlan_cfg80211_unlink_bss_list(wiphy, scan_entry->bssid.bytes,
2111 					scan_entry->ssid.ssid,
2112 					scan_entry->ssid.length);
2113 }
2114 
2115 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
2116 /*
2117  * wlan_scan_wiphy_set_max_sched_scans() - set maximum number of scheduled scans
2118  * to wiphy.
2119  * @wiphy: pointer to wiphy
2120  * @max_scans: max num scans to be configured
2121  *
2122  */
2123 static inline void
2124 wlan_scan_wiphy_set_max_sched_scans(struct wiphy *wiphy, uint8_t max_scans)
2125 {
2126 	if (max_scans == 0)
2127 		wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
2128 	else
2129 		wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
2130 }
2131 #else
2132 static inline void
2133 wlan_scan_wiphy_set_max_sched_scans(struct wiphy *wiphy, uint8_t max_scans)
2134 {
2135 	wiphy->max_sched_scan_reqs = max_scans;
2136 }
2137 #endif /* KERNEL_VERSION(4, 12, 0) */
2138 
2139 #if defined(CFG80211_REPORT_BETTER_BSS_IN_SCHED_SCAN) || \
2140 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
2141 void wlan_scan_cfg80211_add_connected_pno_support(struct wiphy *wiphy)
2142 {
2143 	wiphy_ext_feature_set(wiphy,
2144 			      NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI);
2145 }
2146 #endif
2147 
2148 #if ((LINUX_VERSION_CODE > KERNEL_VERSION(4, 4, 0)) || \
2149 		defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT)) && \
2150 		defined(FEATURE_WLAN_SCAN_PNO)
2151 void wlan_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
2152 					   struct wlan_objmgr_psoc *psoc)
2153 {
2154 	if (ucfg_scan_get_pno_scan_support(psoc)) {
2155 		wlan_scan_wiphy_set_max_sched_scans(wiphy, 1);
2156 		wiphy->max_sched_scan_ssids = SCAN_PNO_MAX_SUPP_NETWORKS;
2157 		wiphy->max_match_sets = SCAN_PNO_MAX_SUPP_NETWORKS;
2158 		wiphy->max_sched_scan_ie_len = SCAN_MAX_IE_LENGTH;
2159 		wiphy->max_sched_scan_plans = SCAN_PNO_MAX_PLAN_REQUEST;
2160 
2161 		wiphy->max_sched_scan_plan_interval =
2162 			ucfg_scan_get_max_sched_scan_plan_interval(psoc);
2163 
2164 		wiphy->max_sched_scan_plan_iterations =
2165 			ucfg_scan_get_max_sched_scan_plan_iterations(psoc);
2166 	}
2167 }
2168 #endif
2169