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