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