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