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