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