xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /*
18  * DOC: contains scan north bound interface definitions
19  */
20 
21 #include <scheduler_api.h>
22 #include <wlan_scan_ucfg_api.h>
23 #include <wlan_objmgr_global_obj.h>
24 #include <wlan_objmgr_cmn.h>
25 #include <wlan_serialization_api.h>
26 #include <wlan_scan_tgt_api.h>
27 #include <wlan_scan_utils_api.h>
28 #include <wlan_reg_ucfg_api.h>
29 #include <wlan_reg_services_api.h>
30 #include <wlan_utility.h>
31 #include "../../core/src/wlan_scan_main.h"
32 #include "../../core/src/wlan_scan_manager.h"
33 #include "../../core/src/wlan_scan_cache_db.h"
34 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
35 #include <wlan_pmo_obj_mgmt_api.h>
36 #endif
37 #ifdef WLAN_POLICY_MGR_ENABLE
38 #include <wlan_dfs_utils_api.h>
39 #include <wlan_policy_mgr_api.h>
40 #endif
41 #include "cfg_ucfg_api.h"
42 #include "wlan_extscan_api.h"
43 
44 QDF_STATUS ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc,
45 	update_beacon_cb cb, enum scan_cb_type type)
46 {
47 	return scm_scan_register_bcn_cb(psoc, cb, type);
48 }
49 
50 qdf_list_t *ucfg_scan_get_result(struct wlan_objmgr_pdev *pdev,
51 	struct scan_filter *filter)
52 {
53 	return scm_get_scan_result(pdev, filter);
54 }
55 
56 QDF_STATUS ucfg_scan_db_iterate(struct wlan_objmgr_pdev *pdev,
57 	scan_iterator_func func, void *arg)
58 {
59 	return scm_iterate_scan_db(pdev, func, arg);
60 }
61 
62 QDF_STATUS ucfg_scan_purge_results(qdf_list_t *scan_list)
63 {
64 	return scm_purge_scan_results(scan_list);
65 }
66 
67 QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev,
68 	struct scan_filter *filter)
69 {
70 	return scm_flush_results(pdev, filter);
71 }
72 
73 void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev,
74 	uint32_t *chan_freq_list, uint32_t num_chan)
75 {
76 	scm_filter_valid_channel(pdev, chan_freq_list, num_chan);
77 }
78 
79 QDF_STATUS ucfg_scan_init(void)
80 {
81 	QDF_STATUS status;
82 
83 	status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
84 		wlan_scan_psoc_created_notification, NULL);
85 	if (QDF_IS_STATUS_ERROR(status)) {
86 		scm_err("Failed to register psoc create handler");
87 		goto fail_create_psoc;
88 	}
89 
90 	status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
91 		wlan_scan_psoc_destroyed_notification, NULL);
92 	if (QDF_IS_STATUS_ERROR(status)) {
93 		scm_err("Failed to create psoc delete handler");
94 		goto fail_psoc_destroy;
95 	}
96 	scm_debug("scan psoc create and delete handler registered with objmgr");
97 
98 	status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
99 		wlan_scan_vdev_created_notification, NULL);
100 	if (QDF_IS_STATUS_ERROR(status)) {
101 		scm_err("Failed to register vdev create handler");
102 		goto fail_pdev_create;
103 	}
104 
105 	status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_SCAN,
106 		wlan_scan_vdev_destroyed_notification, NULL);
107 	if (QDF_IS_STATUS_SUCCESS(status)) {
108 		scm_debug("scan vdev create and delete handler registered with objmgr");
109 		return QDF_STATUS_SUCCESS;
110 	}
111 
112 	scm_err("Failed to destroy vdev delete handler");
113 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
114 				wlan_scan_vdev_created_notification, NULL);
115 fail_pdev_create:
116 	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
117 				wlan_scan_psoc_destroyed_notification, NULL);
118 fail_psoc_destroy:
119 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
120 			wlan_scan_psoc_created_notification, NULL);
121 fail_create_psoc:
122 	return status;
123 }
124 
125 QDF_STATUS ucfg_scan_deinit(void)
126 {
127 	QDF_STATUS status;
128 
129 	status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
130 		wlan_scan_psoc_created_notification, NULL);
131 	if (status != QDF_STATUS_SUCCESS)
132 		scm_err("Failed to unregister psoc create handler");
133 
134 	status = wlan_objmgr_unregister_psoc_destroy_handler(
135 				WLAN_UMAC_COMP_SCAN,
136 				wlan_scan_psoc_destroyed_notification, NULL);
137 	if (status != QDF_STATUS_SUCCESS)
138 		scm_err("Failed to unregister psoc delete handler");
139 
140 	status = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
141 		wlan_scan_vdev_created_notification, NULL);
142 	if (status != QDF_STATUS_SUCCESS)
143 		scm_err("Failed to unregister vdev create handler");
144 
145 	status = wlan_objmgr_unregister_vdev_destroy_handler(
146 			WLAN_UMAC_COMP_SCAN,
147 			wlan_scan_vdev_destroyed_notification, NULL);
148 	if (status != QDF_STATUS_SUCCESS)
149 		scm_err("Failed to unregister vdev delete handler");
150 
151 	return status;
152 }
153 
154 #ifdef FEATURE_WLAN_SCAN_PNO
155 
156 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
157 	struct pno_scan_req_params *req)
158 {
159 	struct scan_vdev_obj *scan_vdev_obj;
160 	QDF_STATUS status;
161 
162 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
163 	if (!scan_vdev_obj) {
164 		scm_err("null scan_vdev_obj");
165 		return QDF_STATUS_E_INVAL;
166 	}
167 	if (scan_vdev_obj->pno_in_progress) {
168 		scm_err("pno already in progress");
169 		return QDF_STATUS_E_ALREADY;
170 	}
171 
172 	status = tgt_scan_pno_start(vdev, req);
173 	if (QDF_IS_STATUS_ERROR(status))
174 		scm_err("pno start failed");
175 	else
176 		scan_vdev_obj->pno_in_progress = true;
177 
178 	return status;
179 }
180 
181 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev)
182 {
183 	struct scan_vdev_obj *scan_vdev_obj;
184 	QDF_STATUS status;
185 
186 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
187 	if (!scan_vdev_obj) {
188 		scm_err("null scan_vdev_obj");
189 		return QDF_STATUS_E_INVAL;
190 	}
191 	if (!scan_vdev_obj->pno_in_progress) {
192 		scm_debug("pno already stopped");
193 		return QDF_STATUS_SUCCESS;
194 	}
195 
196 	status = tgt_scan_pno_stop(vdev, wlan_vdev_get_id(vdev));
197 	if (QDF_IS_STATUS_ERROR(status))
198 		scm_err("pno stop failed");
199 	else
200 		scan_vdev_obj->pno_in_progress = false;
201 
202 	return status;
203 }
204 
205 bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev)
206 {
207 	struct scan_vdev_obj *scan_vdev_obj;
208 
209 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
210 	if (!scan_vdev_obj) {
211 		scm_err("null scan_vdev_obj");
212 		return false;
213 	}
214 
215 	return scan_vdev_obj->pno_in_progress;
216 }
217 
218 bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev)
219 {
220 	struct scan_vdev_obj *scan_vdev_obj;
221 
222 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
223 	if (!scan_vdev_obj) {
224 		scm_err("null scan_vdev_obj");
225 		return false;
226 	}
227 
228 	return scan_vdev_obj->pno_match_evt_received;
229 }
230 
231 static QDF_STATUS
232 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
233 		     struct wlan_scan_obj *scan_obj)
234 {
235 	struct nlo_mawc_params *mawc_cfg;
236 	struct pno_def_config *pno_def;
237 
238 	pno_def = &scan_obj->pno_cfg;
239 	qdf_wake_lock_create(&pno_def->pno_wake_lock, "wlan_pno_wl");
240 	mawc_cfg = &pno_def->mawc_params;
241 	pno_def->channel_prediction = cfg_get(psoc, CFG_PNO_CHANNEL_PREDICTION);
242 	pno_def->top_k_num_of_channels =
243 			cfg_get(psoc, CFG_TOP_K_NUM_OF_CHANNELS);
244 	pno_def->stationary_thresh = cfg_get(psoc, CFG_STATIONARY_THRESHOLD);
245 	pno_def->channel_prediction_full_scan =
246 			cfg_get(psoc, CFG_CHANNEL_PREDICTION_SCAN_TIMER);
247 	pno_def->adaptive_dwell_mode =
248 			cfg_get(psoc, CFG_ADAPTIVE_PNOSCAN_DWELL_MODE);
249 	pno_def->dfs_chnl_scan_enabled =
250 			cfg_get(psoc, CFG_ENABLE_DFS_PNO_CHNL_SCAN);
251 	pno_def->scan_support_enabled =
252 			cfg_get(psoc, CFG_PNO_SCAN_SUPPORT);
253 	pno_def->scan_timer_repeat_value =
254 			cfg_get(psoc, CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
255 	pno_def->slow_scan_multiplier =
256 			cfg_get(psoc, CFG_PNO_SLOW_SCAN_MULTIPLIER);
257 	pno_def->scan_backoff_multiplier =
258 			cfg_get(psoc, CFG_SCAN_BACKOFF_MULTIPLIER);
259 	pno_def->max_sched_scan_plan_interval =
260 			cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
261 	pno_def->max_sched_scan_plan_iterations =
262 			cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
263 
264 	mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED);
265 	mawc_cfg->exp_backoff_ratio =
266 			cfg_get(psoc, CFG_MAWC_NLO_EXP_BACKOFF_RATIO);
267 	mawc_cfg->init_scan_interval =
268 			cfg_get(psoc, CFG_MAWC_NLO_INIT_SCAN_INTERVAL);
269 	mawc_cfg->max_scan_interval =
270 			cfg_get(psoc, CFG_MAWC_NLO_MAX_SCAN_INTERVAL);
271 
272 	return QDF_STATUS_SUCCESS;
273 }
274 
275 static QDF_STATUS
276 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj)
277 {
278 	qdf_wake_lock_destroy(&scan_obj->pno_cfg.pno_wake_lock);
279 
280 	return QDF_STATUS_SUCCESS;
281 }
282 
283 #ifdef WLAN_POLICY_MGR_ENABLE
284 /*
285  * ucfg_scan_update_pno_dwell_time() - update active and passive dwell time
286  * depending on active concurrency modes
287  * @vdev: vdev object pointer
288  * @req: scan request
289  *
290  * Return: void
291  */
292 static void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
293 	struct pno_scan_req_params *req, struct scan_default_params *scan_def)
294 {
295 	bool sap_or_p2p_present;
296 	struct wlan_objmgr_psoc *psoc;
297 
298 	psoc = wlan_vdev_get_psoc(vdev);
299 
300 	if (!psoc)
301 		return;
302 
303 	sap_or_p2p_present = policy_mgr_mode_specific_connection_count(
304 				psoc, PM_SAP_MODE, NULL) ||
305 				policy_mgr_mode_specific_connection_count(
306 				psoc, PM_P2P_GO_MODE, NULL) ||
307 				policy_mgr_mode_specific_connection_count(
308 				psoc, PM_P2P_CLIENT_MODE, NULL);
309 
310 	if (sap_or_p2p_present) {
311 		req->active_dwell_time = scan_def->conc_active_dwell;
312 		req->passive_dwell_time = scan_def->conc_passive_dwell;
313 	}
314 
315 }
316 #else
317 static inline void ucfg_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
318 	struct pno_scan_req_params *req, struct scan_default_params *scan_def){}
319 #endif
320 
321 QDF_STATUS
322 ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev,
323 	struct pno_scan_req_params *req)
324 {
325 	struct scan_default_params *scan_def;
326 	struct wlan_scan_obj *scan;
327 	struct pno_def_config *pno_def;
328 
329 	if (!vdev || !req) {
330 		scm_err("vdev: 0x%pK, req: 0x%pK",
331 			vdev, req);
332 		return QDF_STATUS_E_INVAL;
333 	}
334 
335 	scan = wlan_vdev_get_scan_obj(vdev);
336 	if (!scan) {
337 		scm_err("scan is NULL");
338 		return QDF_STATUS_E_INVAL;
339 	}
340 	scan_def = wlan_vdev_get_def_scan_params(vdev);
341 	if (!scan_def) {
342 		scm_err("wlan_vdev_get_def_scan_params returned NULL");
343 		return QDF_STATUS_E_NULL_VALUE;
344 	}
345 
346 	pno_def = &scan->pno_cfg;
347 	req->active_dwell_time = scan_def->active_dwell;
348 	req->passive_dwell_time = scan_def->passive_dwell;
349 	req->scan_random.randomize = scan_def->enable_mac_spoofing;
350 
351 	/*
352 	 *  Update active and passive dwell time depending
353 	 *  upon the present active concurrency mode
354 	 */
355 	ucfg_scan_update_pno_dwell_time(vdev, req, scan_def);
356 	req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode;
357 	req->pno_channel_prediction = pno_def->channel_prediction;
358 	req->top_k_num_of_channels = pno_def->top_k_num_of_channels;
359 	req->stationary_thresh = pno_def->stationary_thresh;
360 	req->channel_prediction_full_scan =
361 			pno_def->channel_prediction_full_scan;
362 	req->mawc_params.vdev_id = wlan_vdev_get_id(vdev);
363 	qdf_mem_copy(&req->mawc_params, &pno_def->mawc_params,
364 			sizeof(req->mawc_params));
365 
366 	return QDF_STATUS_SUCCESS;
367 }
368 
369 QDF_STATUS
370 ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc,
371 	scan_event_handler event_cb, void *arg)
372 {
373 	struct wlan_scan_obj *scan;
374 
375 	if (!psoc) {
376 		scm_err("null psoc");
377 		return QDF_STATUS_E_INVAL;
378 	}
379 
380 	scan = wlan_psoc_get_scan_obj(psoc);
381 	if (!scan) {
382 		scm_err("scan object null");
383 		return QDF_STATUS_E_INVAL;
384 	}
385 
386 	qdf_spin_lock_bh(&scan->lock);
387 	scan->pno_cfg.pno_cb.func = event_cb;
388 	scan->pno_cfg.pno_cb.arg = arg;
389 	qdf_spin_unlock_bh(&scan->lock);
390 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
391 
392 	return QDF_STATUS_SUCCESS;
393 }
394 
395 #else
396 
397 static inline QDF_STATUS
398 wlan_pno_global_init(struct wlan_objmgr_psoc *psoc,
399 		     struct wlan_scan_obj *scan_obj)
400 {
401 	return QDF_STATUS_SUCCESS;
402 }
403 
404 static inline QDF_STATUS
405 wlan_pno_global_deinit(struct wlan_scan_obj *scan_obj)
406 {
407 	return QDF_STATUS_SUCCESS;
408 }
409 
410 #endif
411 
412 QDF_STATUS
413 ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev,
414 				    struct chan_list *chan_list)
415 {
416 	uint8_t pdev_id;
417 	struct wlan_scan_obj *scan_obj;
418 
419 	if (!pdev || !chan_list) {
420 		scm_warn("pdev: 0x%pK, chan_list: 0x%pK", pdev, chan_list);
421 		return QDF_STATUS_E_NULL_VALUE;
422 	}
423 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
424 	scan_obj = wlan_pdev_get_scan_obj(pdev);
425 
426 	qdf_mem_copy(&scan_obj->pdev_info[pdev_id].custom_chan_list,
427 			chan_list, sizeof(*chan_list));
428 
429 	return QDF_STATUS_SUCCESS;
430 }
431 
432 QDF_STATUS
433 ucfg_scm_scan_free_scan_request_mem(struct scan_start_request *req)
434 {
435 	return scm_scan_free_scan_request_mem(req);
436 }
437 
438 QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc,
439 				     enum scan_disable_reason reason)
440 {
441 	struct wlan_scan_obj *scan_obj;
442 
443 	scan_obj = wlan_psoc_get_scan_obj(psoc);
444 	if (!scan_obj) {
445 		scm_err("Failed to get scan object");
446 		return QDF_STATUS_E_NULL_VALUE;
447 	}
448 
449 	scan_obj->scan_disabled &= ~reason;
450 	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
451 
452 	return QDF_STATUS_SUCCESS;
453 }
454 
455 QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc,
456 				      enum scan_disable_reason reason)
457 {
458 	struct wlan_scan_obj *scan_obj;
459 
460 	scan_obj = wlan_psoc_get_scan_obj(psoc);
461 	if (!scan_obj) {
462 		scm_err("Failed to get scan object");
463 		return QDF_STATUS_E_NULL_VALUE;
464 	}
465 
466 	scan_obj->scan_disabled |= reason;
467 
468 	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
469 
470 	return QDF_STATUS_SUCCESS;
471 }
472 
473 
474 QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev,
475 				     enum scan_disable_reason reason)
476 {
477 	struct scan_vdev_obj *scan_vdev_obj;
478 
479 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
480 	if (!scan_vdev_obj) {
481 		scm_err("null scan_vdev_obj");
482 		return QDF_STATUS_E_NULL_VALUE;
483 	}
484 
485 	scan_vdev_obj->scan_disabled &= ~reason;
486 
487 	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
488 
489 	return QDF_STATUS_SUCCESS;
490 }
491 
492 QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev,
493 				      enum scan_disable_reason reason)
494 {
495 	struct scan_vdev_obj *scan_vdev_obj;
496 
497 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
498 	if (!scan_vdev_obj) {
499 		scm_err("null scan_vdev_obj");
500 		return QDF_STATUS_E_NULL_VALUE;
501 	}
502 
503 	scan_vdev_obj->scan_disabled |= reason;
504 
505 	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
506 
507 	return QDF_STATUS_SUCCESS;
508 }
509 
510 
511 QDF_STATUS ucfg_scan_set_miracast(
512 	struct wlan_objmgr_psoc *psoc, bool enable)
513 {
514 	struct wlan_scan_obj *scan_obj;
515 
516 	scan_obj = wlan_psoc_get_scan_obj(psoc);
517 	if (!scan_obj) {
518 		scm_err("Failed to get scan object");
519 		return QDF_STATUS_E_NULL_VALUE;
520 	}
521 	scan_obj->miracast_enabled = enable;
522 	scm_debug("set miracast_enable to %d", scan_obj->miracast_enabled);
523 
524 	return QDF_STATUS_SUCCESS;
525 }
526 
527 QDF_STATUS
528 ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable)
529 {
530 	uint8_t pdev_id;
531 	struct wlan_scan_obj *scan_obj;
532 
533 	if (!pdev) {
534 		scm_warn("null vdev");
535 		return QDF_STATUS_E_NULL_VALUE;
536 	}
537 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
538 	scan_obj = wlan_pdev_get_scan_obj(pdev);
539 	if (!scan_obj)
540 		return QDF_STATUS_E_FAILURE;
541 
542 	scm_debug("set wide_band_scan to %d", enable);
543 	scan_obj->pdev_info[pdev_id].wide_band_scan = enable;
544 
545 	return QDF_STATUS_SUCCESS;
546 }
547 
548 bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev)
549 {
550 	uint8_t pdev_id;
551 	struct wlan_scan_obj *scan_obj;
552 
553 	if (!pdev) {
554 		scm_warn("null vdev");
555 		return QDF_STATUS_E_NULL_VALUE;
556 	}
557 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
558 	scan_obj = wlan_pdev_get_scan_obj(pdev);
559 	if (!scan_obj)
560 		return QDF_STATUS_E_FAILURE;
561 
562 	return scan_obj->pdev_info[pdev_id].wide_band_scan;
563 }
564 
565 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID
566 QDF_STATUS
567 ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev,
568 				       uint8_t *bssid, struct wlan_ssid *ssid)
569 {
570 	uint8_t pdev_id;
571 	struct wlan_scan_obj *scan_obj;
572 
573 	if (!pdev) {
574 		scm_warn("null vdev");
575 		return QDF_STATUS_E_NULL_VALUE;
576 	}
577 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
578 	scan_obj = wlan_pdev_get_scan_obj(pdev);
579 	if (!scan_obj)
580 		return QDF_STATUS_E_FAILURE;
581 
582 	scm_debug("Configure bsssid:"QDF_MAC_ADDR_FMT" ssid:%.*s",
583 		  QDF_MAC_ADDR_REF(bssid), ssid->length, ssid->ssid);
584 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid,
585 		     bssid, QDF_MAC_ADDR_SIZE);
586 	scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length;
587 	qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_ssid.ssid,
588 		     ssid->ssid,
589 		     scan_obj->pdev_info[pdev_id].conf_ssid.length);
590 
591 	return QDF_STATUS_SUCCESS;
592 }
593 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */
594 
595 QDF_STATUS
596 ucfg_scan_cancel_sync(struct scan_cancel_request *req)
597 {
598 	QDF_STATUS status;
599 	bool cancel_vdev = false, cancel_pdev = false;
600 	struct wlan_objmgr_vdev *vdev;
601 	struct wlan_objmgr_pdev *pdev;
602 	uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
603 
604 	if (!req || !req->vdev) {
605 		scm_err("req or vdev within req is NULL");
606 		if (req)
607 			qdf_mem_free(req);
608 		return QDF_STATUS_E_NULL_VALUE;
609 	}
610 
611 	if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_PDEV_ALL)
612 		cancel_pdev = true;
613 	else if (req->cancel_req.req_type == WLAN_SCAN_CANCEL_VDEV_ALL ||
614 		 req->cancel_req.req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL)
615 		cancel_vdev = true;
616 
617 	vdev = req->vdev;
618 	status = ucfg_scan_cancel(req);
619 	if (QDF_IS_STATUS_ERROR(status))
620 		return status;
621 
622 	if (cancel_pdev) {
623 		pdev = wlan_vdev_get_pdev(vdev);
624 		while ((ucfg_scan_get_pdev_status(pdev) !=
625 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
626 			scm_debug("wait for all pdev scan to get complete");
627 			qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME);
628 			max_wait_iterations--;
629 		}
630 	} else if (cancel_vdev) {
631 		while ((ucfg_scan_get_vdev_status(vdev) !=
632 		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
633 			scm_debug("wait for all vdev scan to get complete");
634 			qdf_sleep(SCM_CANCEL_SCAN_WAIT_TIME);
635 			max_wait_iterations--;
636 		}
637 	}
638 
639 	if (!max_wait_iterations) {
640 		scm_err("Failed to wait for scans to get complete");
641 		return QDF_STATUS_E_TIMEOUT;
642 	}
643 
644 	return status;
645 }
646 
647 uint8_t*
648 ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc,
649 	wlan_scan_requester requester)
650 {
651 	int idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
652 	struct wlan_scan_obj *scan;
653 	struct scan_requester_info *requesters;
654 
655 	if (!psoc) {
656 		scm_err("null psoc");
657 		return "null";
658 	}
659 	scan = wlan_psoc_get_scan_obj(psoc);
660 	if (!scan)
661 		return "null";
662 
663 	requesters = scan->requesters;
664 
665 	if ((idx < WLAN_MAX_REQUESTORS) &&
666 		(requesters[idx].requester == requester)) {
667 		return requesters[idx].module;
668 	}
669 
670 	return (uint8_t *)"unknown";
671 }
672 
673 static QDF_STATUS
674 scm_add_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
675 	scan_event_handler event_cb, void *arg)
676 {
677 	struct cb_handler *cb_handler;
678 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
679 
680 	/* Assign next available slot to this registration request */
681 	cb_handler = &(pdev_ev_handler->cb_handlers[handler_cnt]);
682 	cb_handler->func = event_cb;
683 	cb_handler->arg = arg;
684 	pdev_ev_handler->handler_cnt++;
685 
686 	return QDF_STATUS_SUCCESS;
687 }
688 
689 QDF_STATUS
690 ucfg_scan_register_event_handler(struct wlan_objmgr_pdev *pdev,
691 	scan_event_handler event_cb, void *arg)
692 {
693 	uint32_t idx;
694 	struct wlan_scan_obj *scan;
695 	struct pdev_scan_ev_handler *pdev_ev_handler;
696 	struct cb_handler *cb_handler;
697 
698 	/* scan event handler call back can't be NULL */
699 	if (!pdev || !event_cb) {
700 		scm_err("pdev: %pK, event_cb: %pK", pdev, event_cb);
701 		return QDF_STATUS_E_NULL_VALUE;
702 	}
703 
704 	scm_debug("pdev: %pK, event_cb: %pK, arg: %pK\n", pdev, event_cb, arg);
705 
706 	scan = wlan_pdev_get_scan_obj(pdev);
707 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
708 	if (!pdev_ev_handler) {
709 		scm_err("null pdev_ev_handler");
710 		return QDF_STATUS_E_NULL_VALUE;
711 	}
712 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
713 
714 	qdf_spin_lock_bh(&scan->lock);
715 	/* Ensure its not a duplicate registration request */
716 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
717 		idx++, cb_handler++) {
718 		if ((cb_handler->func == event_cb) &&
719 			(cb_handler->arg == arg)) {
720 			qdf_spin_unlock_bh(&scan->lock);
721 			scm_debug("func: %pK, arg: %pK already exists",
722 				  event_cb, arg);
723 			return QDF_STATUS_SUCCESS;
724 		}
725 	}
726 
727 	QDF_ASSERT(pdev_ev_handler->handler_cnt <
728 			MAX_SCAN_EVENT_HANDLERS_PER_PDEV);
729 
730 	if (pdev_ev_handler->handler_cnt >= MAX_SCAN_EVENT_HANDLERS_PER_PDEV) {
731 		qdf_spin_unlock_bh(&scan->lock);
732 		scm_warn("No more registrations possible");
733 		return QDF_STATUS_E_NOMEM;
734 	}
735 
736 	scm_add_scan_event_handler(pdev_ev_handler, event_cb, arg);
737 	qdf_spin_unlock_bh(&scan->lock);
738 
739 	scm_debug("event_cb: 0x%pK, arg: 0x%pK", event_cb, arg);
740 
741 	return QDF_STATUS_SUCCESS;
742 }
743 
744 static QDF_STATUS
745 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
746 		      struct wlan_scan_obj *scan_obj)
747 {
748 	scan_obj->scan_disabled = 0;
749 	scan_obj->drop_bcn_on_chan_mismatch =
750 			 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH);
751 	scan_obj->drop_bcn_on_invalid_freq =
752 			 cfg_get(psoc, CFG_DROP_BCN_ON_INVALID_FREQ);
753 	scan_obj->disable_timeout = false;
754 	scan_obj->scan_def.active_dwell =
755 			 cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME);
756 	/* the ini is disallow DFS channel scan if ini is 1, so negate that */
757 	scan_obj->scan_def.allow_dfs_chan_in_first_scan =
758 				!cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN);
759 	scan_obj->scan_def.allow_dfs_chan_in_scan =
760 				cfg_get(psoc, CFG_ENABLE_DFS_SCAN);
761 	scan_obj->scan_def.skip_dfs_chan_in_p2p_search =
762 				cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH);
763 	scan_obj->scan_def.use_wake_lock_in_user_scan =
764 				cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN);
765 	scan_obj->scan_def.active_dwell_2g =
766 			 cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME);
767 	scan_obj->scan_def.active_dwell_6g =
768 			 cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME);
769 	scan_obj->scan_def.passive_dwell_6g =
770 			 cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME);
771 	scan_obj->scan_def.passive_dwell =
772 			 cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME);
773 	scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME;
774 	scan_obj->scan_def.sta_miracast_mcc_rest_time =
775 					SCAN_STA_MIRACAST_MCC_REST_TIME;
776 	scan_obj->scan_def.min_rest_time = SCAN_MIN_REST_TIME;
777 	scan_obj->scan_def.conc_active_dwell =
778 			cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME_CONC);
779 	scan_obj->scan_def.conc_passive_dwell =
780 			cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME_CONC);
781 	scan_obj->scan_def.conc_max_rest_time =
782 			cfg_get(psoc, CFG_MAX_REST_TIME_CONC);
783 	scan_obj->scan_def.conc_min_rest_time =
784 			cfg_get(psoc, CFG_MIN_REST_TIME_CONC);
785 	scan_obj->scan_def.conc_idle_time =
786 			cfg_get(psoc, CFG_IDLE_TIME_CONC);
787 	scan_obj->scan_def.repeat_probe_time =
788 			cfg_get(psoc, CFG_SCAN_PROBE_REPEAT_TIME);
789 	scan_obj->scan_def.probe_spacing_time = SCAN_PROBE_SPACING_TIME;
790 	scan_obj->scan_def.probe_delay = SCAN_PROBE_DELAY;
791 	scan_obj->scan_def.burst_duration = SCAN_BURST_DURATION;
792 	scan_obj->scan_def.max_scan_time = SCAN_MAX_SCAN_TIME;
793 	scan_obj->scan_def.num_probes = cfg_get(psoc, CFG_SCAN_NUM_PROBES);
794 	scan_obj->scan_def.scan_cache_aging_time =
795 			(cfg_get(psoc, CFG_SCAN_AGING_TIME) * 1000);
796 	scan_obj->scan_def.max_bss_per_pdev = SCAN_MAX_BSS_PDEV;
797 	scan_obj->scan_def.scan_priority = SCAN_PRIORITY;
798 	scan_obj->scan_def.idle_time = SCAN_NETWORK_IDLE_TIMEOUT;
799 	scan_obj->scan_def.adaptive_dwell_time_mode =
800 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE);
801 	scan_obj->scan_def.adaptive_dwell_time_mode_nc =
802 			cfg_get(psoc, CFG_ADAPTIVE_SCAN_DWELL_MODE_NC);
803 	scan_obj->scan_def.honour_nl_scan_policy_flags =
804 			cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS);
805 	scan_obj->scan_def.enable_mac_spoofing =
806 			cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING);
807 	scan_obj->scan_def.extscan_adaptive_dwell_mode =
808 			cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
809 
810 	/* init burst durations */
811 	scan_obj->scan_def.sta_scan_burst_duration =
812 				cfg_get(psoc, CFG_STA_SCAN_BURST_DURATION);
813 	scan_obj->scan_def.p2p_scan_burst_duration =
814 				cfg_get(psoc, CFG_P2P_SCAN_BURST_DURATION);
815 	scan_obj->scan_def.go_scan_burst_duration =
816 				cfg_get(psoc, CFG_GO_SCAN_BURST_DURATION);
817 	scan_obj->scan_def.ap_scan_burst_duration =
818 				cfg_get(psoc, CFG_AP_SCAN_BURST_DURATION);
819 	/* scan contrl flags */
820 	scan_obj->scan_def.scan_f_passive = true;
821 	scan_obj->scan_def.scan_f_ofdm_rates = true;
822 	scan_obj->scan_def.scan_f_2ghz = true;
823 	scan_obj->scan_def.scan_f_5ghz = true;
824 	scan_obj->scan_def.scan_f_chan_stat_evnt =
825 				cfg_get(psoc, CFG_ENABLE_SNR_MONITORING);
826 	/* scan event flags */
827 	scan_obj->scan_def.scan_ev_started = true;
828 	scan_obj->scan_def.scan_ev_completed = true;
829 	scan_obj->scan_def.scan_ev_bss_chan = true;
830 	scan_obj->scan_def.scan_ev_foreign_chan = true;
831 	scan_obj->scan_def.scan_ev_foreign_chn_exit = true;
832 	scan_obj->scan_def.scan_ev_dequeued = true;
833 	scan_obj->scan_def.scan_ev_preempted = true;
834 	scan_obj->scan_def.scan_ev_start_failed = true;
835 	scan_obj->scan_def.scan_ev_restarted = true;
836 	scan_obj->scan_def.enable_connected_scan =
837 		cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN);
838 	scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE);
839 	scan_obj->scan_def.duty_cycle_6ghz =
840 		cfg_get(psoc, CFG_6GHZ_SCAN_MODE_DUTY_CYCLE);
841 	scan_obj->allow_bss_with_incomplete_ie =
842 		cfg_get(psoc, CFG_SCAN_ALLOW_BSS_WITH_CORRUPTED_IE);
843 	/* init scan id seed */
844 	qdf_atomic_init(&scan_obj->scan_ids);
845 
846 	/* init extscan */
847 	wlan_extscan_global_init(psoc, scan_obj);
848 
849 	return wlan_pno_global_init(psoc, scan_obj);
850 }
851 
852 static void
853 wlan_scan_global_deinit(struct wlan_objmgr_psoc *psoc)
854 {
855 	struct wlan_scan_obj *scan_obj;
856 
857 	scan_obj = wlan_psoc_get_scan_obj(psoc);
858 	wlan_pno_global_deinit(scan_obj);
859 	wlan_extscan_global_deinit();
860 }
861 
862 static QDF_STATUS
863 scm_remove_scan_event_handler(struct pdev_scan_ev_handler *pdev_ev_handler,
864 	struct cb_handler *entry)
865 {
866 	struct cb_handler *last_entry;
867 	uint32_t handler_cnt = pdev_ev_handler->handler_cnt;
868 
869 	/* Replace event handler being deleted
870 	 * with the last one in the list.
871 	 */
872 	last_entry = &(pdev_ev_handler->cb_handlers[handler_cnt - 1]);
873 	entry->func = last_entry->func;
874 	entry->arg = last_entry->arg;
875 
876 	/* Clear our last entry */
877 	last_entry->func = NULL;
878 	last_entry->arg = NULL;
879 	pdev_ev_handler->handler_cnt--;
880 
881 	return QDF_STATUS_SUCCESS;
882 }
883 
884 void
885 ucfg_scan_unregister_event_handler(struct wlan_objmgr_pdev *pdev,
886 	scan_event_handler event_cb, void *arg)
887 {
888 	uint8_t found = false;
889 	uint32_t idx;
890 	uint32_t handler_cnt;
891 	struct wlan_scan_obj *scan;
892 	struct cb_handler *cb_handler;
893 	struct pdev_scan_ev_handler *pdev_ev_handler;
894 
895 	scm_debug("pdev: %pK, event_cb: 0x%pK, arg: 0x%pK", pdev, event_cb,
896 		  arg);
897 	if (!pdev) {
898 		scm_err("null pdev");
899 		return;
900 	}
901 	scan = wlan_pdev_get_scan_obj(pdev);
902 	if (!scan)
903 		return;
904 
905 	pdev_ev_handler = wlan_pdev_get_pdev_scan_ev_handlers(pdev);
906 	if (!pdev_ev_handler)
907 		return;
908 
909 	cb_handler = &(pdev_ev_handler->cb_handlers[0]);
910 
911 	qdf_spin_lock_bh(&scan->lock);
912 	handler_cnt = pdev_ev_handler->handler_cnt;
913 	if (!handler_cnt) {
914 		qdf_spin_unlock_bh(&scan->lock);
915 		scm_info("No event handlers registered");
916 		return;
917 	}
918 
919 	for (idx = 0; idx < MAX_SCAN_EVENT_HANDLERS_PER_PDEV;
920 		idx++, cb_handler++) {
921 		if ((cb_handler->func == event_cb) &&
922 			(cb_handler->arg == arg)) {
923 			/* Event handler found, remove it
924 			 * from event handler list.
925 			 */
926 			found = true;
927 			scm_remove_scan_event_handler(pdev_ev_handler,
928 				cb_handler);
929 			handler_cnt--;
930 			break;
931 		}
932 	}
933 	qdf_spin_unlock_bh(&scan->lock);
934 
935 	scm_debug("event handler %s, remaining handlers: %d",
936 		  (found ? "removed" : "not found"), handler_cnt);
937 }
938 
939 QDF_STATUS
940 ucfg_scan_init_ssid_params(struct scan_start_request *req,
941 		uint32_t num_ssid, struct wlan_ssid *ssid_list)
942 {
943 	uint32_t max_ssid = sizeof(req->scan_req.ssid) /
944 				sizeof(req->scan_req.ssid[0]);
945 
946 	if (!req) {
947 		scm_err("null request");
948 		return QDF_STATUS_E_NULL_VALUE;
949 	}
950 	if (!num_ssid) {
951 		/* empty channel list provided */
952 		req->scan_req.num_ssids = 0;
953 		qdf_mem_zero(&req->scan_req.ssid[0],
954 			sizeof(req->scan_req.ssid));
955 		return QDF_STATUS_SUCCESS;
956 	}
957 	if (!ssid_list) {
958 		scm_err("null ssid_list while num_ssid: %d", num_ssid);
959 		return QDF_STATUS_E_NULL_VALUE;
960 	}
961 	if (num_ssid > max_ssid) {
962 		/* got a big list. alert and continue */
963 		scm_warn("overflow: received %d, max supported : %d",
964 			num_ssid, max_ssid);
965 		return QDF_STATUS_E_E2BIG;
966 	}
967 
968 	if (max_ssid > num_ssid)
969 		max_ssid = num_ssid;
970 
971 	req->scan_req.num_ssids = max_ssid;
972 	qdf_mem_copy(&req->scan_req.ssid[0], ssid_list,
973 		(req->scan_req.num_ssids * sizeof(req->scan_req.ssid[0])));
974 
975 	return QDF_STATUS_SUCCESS;
976 }
977 
978 QDF_STATUS
979 ucfg_scan_init_bssid_params(struct scan_start_request *req,
980 		uint32_t num_bssid, struct qdf_mac_addr *bssid_list)
981 {
982 	uint32_t max_bssid = sizeof(req->scan_req.bssid_list) /
983 				sizeof(req->scan_req.bssid_list[0]);
984 
985 	if (!req) {
986 		scm_err("null request");
987 		return QDF_STATUS_E_NULL_VALUE;
988 	}
989 	if (!num_bssid) {
990 		/* empty channel list provided */
991 		req->scan_req.num_bssid = 0;
992 		qdf_mem_zero(&req->scan_req.bssid_list[0],
993 			sizeof(req->scan_req.bssid_list));
994 		return QDF_STATUS_SUCCESS;
995 	}
996 	if (!bssid_list) {
997 		scm_err("null bssid_list while num_bssid: %d", num_bssid);
998 		return QDF_STATUS_E_NULL_VALUE;
999 	}
1000 	if (num_bssid > max_bssid) {
1001 		/* got a big list. alert and continue */
1002 		scm_warn("overflow: received %d, max supported : %d",
1003 			num_bssid, max_bssid);
1004 		return QDF_STATUS_E_E2BIG;
1005 	}
1006 
1007 	if (max_bssid > num_bssid)
1008 		max_bssid = num_bssid;
1009 
1010 	req->scan_req.num_bssid = max_bssid;
1011 	qdf_mem_copy(&req->scan_req.bssid_list[0], bssid_list,
1012 		req->scan_req.num_bssid * sizeof(req->scan_req.bssid_list[0]));
1013 
1014 	return QDF_STATUS_SUCCESS;
1015 }
1016 
1017 /**
1018  * is_chan_enabled_for_scan() - helper API to check if a frequency
1019  * is allowed to scan.
1020  * @reg_chan: regulatory_channel object
1021  * @low_2g: lower 2.4 GHz frequency thresold
1022  * @high_2g: upper 2.4 GHz frequency thresold
1023  * @low_5g: lower 5 GHz frequency thresold
1024  * @high_5g: upper 5 GHz frequency thresold
1025  *
1026  * Return: true if scan is allowed. false otherwise.
1027  */
1028 static bool
1029 is_chan_enabled_for_scan(struct regulatory_channel *reg_chan,
1030 		qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g,
1031 		qdf_freq_t high_5g)
1032 {
1033 	if (reg_chan->state == CHANNEL_STATE_DISABLE)
1034 		return false;
1035 	if (reg_chan->nol_chan)
1036 		return false;
1037 	/* 2 GHz channel */
1038 	if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1039 			WLAN_BAND_2_4_GHZ) &&
1040 			((reg_chan->center_freq < low_2g) ||
1041 			(reg_chan->center_freq > high_2g)))
1042 		return false;
1043 	else if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
1044 				WLAN_BAND_5_GHZ) &&
1045 		 ((reg_chan->center_freq < low_5g) ||
1046 		  (reg_chan->center_freq > high_5g)))
1047 		return false;
1048 
1049 	return true;
1050 }
1051 
1052 QDF_STATUS
1053 ucfg_scan_init_chanlist_params(struct scan_start_request *req,
1054 		uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode)
1055 {
1056 	uint32_t idx;
1057 	QDF_STATUS status;
1058 	struct regulatory_channel *reg_chan_list = NULL;
1059 	qdf_freq_t low_2g, high_2g, low_5g, high_5g;
1060 	struct wlan_objmgr_pdev *pdev = NULL;
1061 	uint32_t *scan_freqs = NULL;
1062 	uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) /
1063 				sizeof(req->scan_req.chan_list.chan[0]);
1064 	if (!req) {
1065 		scm_err("null request");
1066 		return QDF_STATUS_E_NULL_VALUE;
1067 	}
1068 
1069 	if (req->vdev)
1070 		pdev = wlan_vdev_get_pdev(req->vdev);
1071 	/*
1072 	 * If 0 channels are provided for scan and
1073 	 * wide band scan is enabled, scan all 20 mhz
1074 	 * available channels. This is required as FW
1075 	 * scans all channel/phy mode combinations
1076 	 * provided in scan channel list if 0 chans are
1077 	 * provided in scan request causing scan to take
1078 	 * too much time to complete.
1079 	 */
1080 	if (pdev && !num_chans) {
1081 		reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS *
1082 				sizeof(struct regulatory_channel));
1083 		if (!reg_chan_list) {
1084 			status = QDF_STATUS_E_NOMEM;
1085 			goto end;
1086 		}
1087 		scan_freqs =
1088 			qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans);
1089 		if (!scan_freqs) {
1090 			status = QDF_STATUS_E_NOMEM;
1091 			goto end;
1092 		}
1093 		status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list);
1094 		if (QDF_IS_STATUS_ERROR(status))
1095 			goto end;
1096 
1097 		status = wlan_reg_get_freq_range(pdev, &low_2g,
1098 				&high_2g, &low_5g, &high_5g);
1099 		if (QDF_IS_STATUS_ERROR(status))
1100 			goto end;
1101 
1102 		for (idx = 0, num_chans = 0;
1103 			(idx < NUM_CHANNELS && num_chans < max_chans); idx++)
1104 			if (is_chan_enabled_for_scan(&reg_chan_list[idx],
1105 					low_2g, high_2g, low_5g, high_5g))
1106 				scan_freqs[num_chans++] =
1107 				reg_chan_list[idx].center_freq;
1108 
1109 		chan_list = scan_freqs;
1110 	}
1111 
1112 	if (!num_chans) {
1113 		/* empty channel list provided */
1114 		qdf_mem_zero(&req->scan_req.chan_list,
1115 			sizeof(req->scan_req.chan_list));
1116 		req->scan_req.chan_list.num_chan = 0;
1117 		status = QDF_STATUS_SUCCESS;
1118 		goto end;
1119 	}
1120 	if (!chan_list) {
1121 		scm_info("null chan_list while num_chans: %d", num_chans);
1122 		status = QDF_STATUS_E_NULL_VALUE;
1123 		goto end;
1124 	}
1125 
1126 	if (num_chans > max_chans) {
1127 		/* got a big list. alert and fail */
1128 		scm_warn("overflow: received %d, max supported : %d",
1129 			num_chans, max_chans);
1130 		status = QDF_STATUS_E_E2BIG;
1131 		goto end;
1132 	}
1133 
1134 	req->scan_req.chan_list.num_chan = num_chans;
1135 	for (idx = 0; idx < num_chans; idx++) {
1136 		req->scan_req.chan_list.chan[idx].freq =
1137 			(chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ?
1138 			chan_list[idx] :
1139 			wlan_reg_legacy_chan_to_freq(pdev, chan_list[idx]);
1140 		if (phymode)
1141 			req->scan_req.chan_list.chan[idx].phymode =
1142 				phymode[idx];
1143 		else if (req->scan_req.chan_list.chan[idx].freq <=
1144 			WLAN_CHAN_15_FREQ)
1145 			req->scan_req.chan_list.chan[idx].phymode =
1146 				SCAN_PHY_MODE_11G;
1147 		else if (req->scan_req.chan_list.chan[idx].freq <=
1148 			 WLAN_REG_MAX_5GHZ_CHAN_FREQ)
1149 			req->scan_req.chan_list.chan[idx].phymode =
1150 				SCAN_PHY_MODE_11A;
1151 		else
1152 			req->scan_req.chan_list.chan[idx].phymode =
1153 				SCAN_PHY_MODE_11AX_HE20;
1154 	}
1155 
1156 end:
1157 	if (scan_freqs)
1158 		qdf_mem_free(scan_freqs);
1159 
1160 	if (reg_chan_list)
1161 		qdf_mem_free(reg_chan_list);
1162 
1163 	return QDF_STATUS_SUCCESS;
1164 }
1165 
1166 static inline enum scm_scan_status
1167 get_scan_status_from_serialization_status(
1168 	enum wlan_serialization_cmd_status status)
1169 {
1170 	enum scm_scan_status scan_status;
1171 
1172 	switch (status) {
1173 	case WLAN_SER_CMD_IN_PENDING_LIST:
1174 		scan_status = SCAN_IS_PENDING;
1175 		break;
1176 	case WLAN_SER_CMD_IN_ACTIVE_LIST:
1177 		scan_status = SCAN_IS_ACTIVE;
1178 		break;
1179 	case WLAN_SER_CMDS_IN_ALL_LISTS:
1180 		scan_status = SCAN_IS_ACTIVE_AND_PENDING;
1181 		break;
1182 	case WLAN_SER_CMD_NOT_FOUND:
1183 		scan_status = SCAN_NOT_IN_PROGRESS;
1184 		break;
1185 	default:
1186 		scm_warn("invalid serialization status %d", status);
1187 		QDF_ASSERT(0);
1188 		scan_status = SCAN_NOT_IN_PROGRESS;
1189 		break;
1190 	}
1191 
1192 	return scan_status;
1193 }
1194 
1195 enum scm_scan_status
1196 ucfg_scan_get_vdev_status(struct wlan_objmgr_vdev *vdev)
1197 {
1198 	enum wlan_serialization_cmd_status status;
1199 
1200 	if (!vdev) {
1201 		scm_err("null vdev");
1202 		return SCAN_NOT_IN_PROGRESS;
1203 	}
1204 	status = wlan_serialization_vdev_scan_status(vdev);
1205 
1206 	return get_scan_status_from_serialization_status(status);
1207 }
1208 
1209 enum scm_scan_status
1210 ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
1211 {
1212 	enum wlan_serialization_cmd_status status;
1213 
1214 	if (!pdev) {
1215 		scm_err("null pdev");
1216 		return SCAN_NOT_IN_PROGRESS;
1217 	}
1218 	status = wlan_serialization_pdev_scan_status(pdev);
1219 
1220 	return get_scan_status_from_serialization_status(status);
1221 }
1222 
1223 static void
1224 ucfg_scan_register_unregister_bcn_cb(struct wlan_objmgr_psoc *psoc,
1225 	bool enable)
1226 {
1227 	QDF_STATUS status;
1228 	struct mgmt_txrx_mgmt_frame_cb_info cb_info[2];
1229 
1230 	cb_info[0].frm_type = MGMT_PROBE_RESP;
1231 	cb_info[0].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1232 	cb_info[1].frm_type = MGMT_BEACON;
1233 	cb_info[1].mgmt_rx_cb = tgt_scan_bcn_probe_rx_callback;
1234 
1235 	if (enable)
1236 		status = wlan_mgmt_txrx_register_rx_cb(psoc,
1237 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1238 	else
1239 		status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
1240 					 WLAN_UMAC_COMP_SCAN, cb_info, 2);
1241 	if (status != QDF_STATUS_SUCCESS)
1242 		scm_err("%s the Handle with MGMT TXRX layer has failed",
1243 			enable ? "Registering" : "Deregistering");
1244 }
1245 
1246 QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
1247 	struct scan_user_cfg *scan_cfg)
1248 {
1249 	struct wlan_scan_obj *scan_obj;
1250 	struct scan_default_params *scan_def;
1251 
1252 	if (!psoc) {
1253 		scm_err("null psoc");
1254 		return QDF_STATUS_E_FAILURE;
1255 	}
1256 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1257 	if (!scan_obj) {
1258 		scm_err("Failed to get scan object");
1259 		return QDF_STATUS_E_FAILURE;
1260 	}
1261 
1262 	scan_def = &scan_obj->scan_def;
1263 	scan_obj->ie_whitelist = scan_cfg->ie_whitelist;
1264 	scan_def->sta_miracast_mcc_rest_time =
1265 				scan_cfg->sta_miracast_mcc_rest_time;
1266 
1267 	return QDF_STATUS_SUCCESS;
1268 }
1269 
1270 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
1271 static QDF_STATUS
1272 ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev)
1273 {
1274 	struct scan_cancel_request *req;
1275 	QDF_STATUS status;
1276 	struct wlan_objmgr_vdev *vdev;
1277 
1278 	req = qdf_mem_malloc_atomic(sizeof(*req));
1279 	if (!req) {
1280 		scm_err("Failed to allocate memory");
1281 		return QDF_STATUS_E_NOMEM;
1282 	}
1283 
1284 	vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SCAN_ID);
1285 	if (!vdev) {
1286 		scm_err("Failed to get vdev");
1287 		qdf_mem_free(req);
1288 		return QDF_STATUS_E_INVAL;
1289 	}
1290 	req->vdev = vdev;
1291 	req->cancel_req.scan_id = INVAL_SCAN_ID;
1292 	req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1293 	req->cancel_req.vdev_id = INVAL_VDEV_ID;
1294 	req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
1295 	status = ucfg_scan_cancel_sync(req);
1296 	if (QDF_IS_STATUS_ERROR(status))
1297 		scm_err("Cancel scan request failed");
1298 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1299 
1300 	return status;
1301 }
1302 
1303 static QDF_STATUS
1304 ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1305 {
1306 	struct wlan_objmgr_pdev *pdev = NULL;
1307 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1308 	int i;
1309 
1310 	ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND);
1311 	/* Check all pdev */
1312 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
1313 		pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID);
1314 		if (!pdev)
1315 			continue;
1316 		if (ucfg_scan_get_pdev_status(pdev) !=
1317 		    SCAN_NOT_IN_PROGRESS)
1318 			status = ucfg_scan_cancel_pdev_scan(pdev);
1319 		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
1320 		if (QDF_IS_STATUS_ERROR(status)) {
1321 			scm_err("failed to cancel scan for pdev_id %d", i);
1322 			return status;
1323 		}
1324 	}
1325 
1326 	return QDF_STATUS_SUCCESS;
1327 }
1328 
1329 static QDF_STATUS
1330 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
1331 {
1332 	ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND);
1333 	return QDF_STATUS_SUCCESS;
1334 }
1335 
1336 static inline void
1337 ucfg_scan_register_pmo_handler(void)
1338 {
1339 	pmo_register_suspend_handler(WLAN_UMAC_COMP_SCAN,
1340 		ucfg_scan_suspend_handler, NULL);
1341 	pmo_register_resume_handler(WLAN_UMAC_COMP_SCAN,
1342 		ucfg_scan_resume_handler, NULL);
1343 }
1344 
1345 static inline void
1346 ucfg_scan_unregister_pmo_handler(void)
1347 {
1348 	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_SCAN,
1349 		ucfg_scan_suspend_handler);
1350 	pmo_unregister_resume_handler(WLAN_UMAC_COMP_SCAN,
1351 		ucfg_scan_resume_handler);
1352 }
1353 
1354 #else
1355 static inline void
1356 ucfg_scan_register_pmo_handler(void)
1357 {
1358 }
1359 
1360 static inline void
1361 ucfg_scan_unregister_pmo_handler(void)
1362 {
1363 }
1364 #endif
1365 
1366 QDF_STATUS
1367 ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc)
1368 {
1369 	struct wlan_scan_obj *scan_obj;
1370 
1371 	scm_debug("psoc open: 0x%pK", psoc);
1372 	if (!psoc) {
1373 		scm_err("null psoc");
1374 		return QDF_STATUS_E_FAILURE;
1375 	}
1376 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1377 	if (!scan_obj) {
1378 		scm_err("Failed to get scan object");
1379 		return QDF_STATUS_E_FAILURE;
1380 	}
1381 	/* Initialize the scan Globals */
1382 	wlan_scan_global_init(psoc, scan_obj);
1383 	qdf_spinlock_create(&scan_obj->lock);
1384 	ucfg_scan_register_pmo_handler();
1385 	scm_db_init(psoc);
1386 	scm_channel_list_db_init(psoc);
1387 
1388 	return QDF_STATUS_SUCCESS;
1389 }
1390 
1391 QDF_STATUS
1392 ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc)
1393 {
1394 	struct wlan_scan_obj *scan_obj;
1395 
1396 	scm_debug("psoc close: 0x%pK", psoc);
1397 	if (!psoc) {
1398 		scm_err("null psoc");
1399 		return QDF_STATUS_E_FAILURE;
1400 	}
1401 	scm_db_deinit(psoc);
1402 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1403 	if (!scan_obj) {
1404 		scm_err("Failed to get scan object");
1405 		return QDF_STATUS_E_FAILURE;
1406 	}
1407 	ucfg_scan_unregister_pmo_handler();
1408 	qdf_spinlock_destroy(&scan_obj->lock);
1409 	wlan_scan_global_deinit(psoc);
1410 	scm_channel_list_db_deinit(psoc);
1411 
1412 	return QDF_STATUS_SUCCESS;
1413 }
1414 
1415 static bool scm_serialization_scan_rules_cb(
1416 		union wlan_serialization_rules_info *comp_info,
1417 		uint8_t comp_id)
1418 {
1419 	switch (comp_id) {
1420 	case WLAN_UMAC_COMP_TDLS:
1421 		if (comp_info->scan_info.is_tdls_in_progress) {
1422 			scm_debug("Cancel scan. Tdls in progress");
1423 			return false;
1424 		}
1425 		break;
1426 	case WLAN_UMAC_COMP_DFS:
1427 		if (comp_info->scan_info.is_cac_in_progress) {
1428 			scm_debug("Cancel scan. CAC in progress");
1429 			return false;
1430 		}
1431 		break;
1432 	case WLAN_UMAC_COMP_MLME:
1433 		if (comp_info->scan_info.is_scan_for_connect) {
1434 			scm_debug("Allow scan request from connect");
1435 			return true;
1436 		}
1437 
1438 		if (comp_info->scan_info.is_mlme_op_in_progress) {
1439 			scm_debug("Cancel scan. MLME operation in progress");
1440 			return false;
1441 		}
1442 		break;
1443 	default:
1444 		scm_debug("not handled comp_id %d", comp_id);
1445 		break;
1446 	}
1447 
1448 	return true;
1449 }
1450 
1451 QDF_STATUS
1452 ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc)
1453 {
1454 	QDF_STATUS status;
1455 
1456 	scm_debug("psoc enable: 0x%pK", psoc);
1457 	if (!psoc) {
1458 		scm_err("null psoc");
1459 		return QDF_STATUS_E_FAILURE;
1460 	}
1461 	/* Subscribe for scan events from lmac layesr */
1462 	status = tgt_scan_register_ev_handler(psoc);
1463 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1464 	if (!wlan_reg_is_11d_offloaded(psoc))
1465 		scm_11d_cc_db_init(psoc);
1466 	ucfg_scan_register_unregister_bcn_cb(psoc, true);
1467 	status = wlan_serialization_register_apply_rules_cb(psoc,
1468 				WLAN_SER_CMD_SCAN,
1469 				scm_serialization_scan_rules_cb);
1470 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1471 	return status;
1472 }
1473 
1474 QDF_STATUS
1475 ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc)
1476 {
1477 	QDF_STATUS status;
1478 
1479 	scm_debug("psoc disable: 0x%pK", psoc);
1480 	if (!psoc) {
1481 		scm_err("null psoc");
1482 		return QDF_STATUS_E_FAILURE;
1483 	}
1484 	/* Unsubscribe for scan events from lmac layesr */
1485 	status = tgt_scan_unregister_ev_handler(psoc);
1486 	QDF_ASSERT(status == QDF_STATUS_SUCCESS);
1487 	ucfg_scan_register_unregister_bcn_cb(psoc, false);
1488 	if (!wlan_reg_is_11d_offloaded(psoc))
1489 		scm_11d_cc_db_deinit(psoc);
1490 
1491 	return status;
1492 }
1493 
1494 uint32_t
1495 ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc)
1496 {
1497 	struct scan_default_params *scan_params = NULL;
1498 
1499 	if (!psoc) {
1500 		scm_err("null psoc");
1501 		return 0;
1502 	}
1503 	scan_params = wlan_scan_psoc_get_def_params(psoc);
1504 	if (!scan_params) {
1505 		scm_err("Failed to get scan object");
1506 		return 0;
1507 	}
1508 
1509 	return scan_params->max_active_scans_allowed;
1510 }
1511 
1512 bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc,
1513 				  struct probe_req_whitelist_attr *ie_whitelist)
1514 {
1515 	struct wlan_scan_obj *scan_obj = NULL;
1516 
1517 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1518 	if (!scan_obj)
1519 		return false;
1520 
1521 	qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist,
1522 		     sizeof(*ie_whitelist));
1523 
1524 	return true;
1525 }
1526 
1527 bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc,
1528 			       struct wlan_objmgr_vdev *vdev)
1529 {
1530 	struct wlan_scan_obj *scan_obj = NULL;
1531 
1532 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1533 	if (!scan_obj)
1534 		return false;
1535 
1536 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
1537 	    wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS)
1538 		return false;
1539 
1540 	if (!scan_obj->ie_whitelist.white_list)
1541 		return false;
1542 
1543 	return true;
1544 }
1545 
1546 void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc,
1547 			       bool bt_a2dp_active)
1548 {
1549 	struct wlan_scan_obj *scan_obj;
1550 
1551 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1552 	if (!scan_obj) {
1553 		scm_err("Failed to get scan object");
1554 		return;
1555 	}
1556 	scan_obj->bt_a2dp_enabled = bt_a2dp_active;
1557 }
1558 
1559 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc)
1560 {
1561 	struct wlan_scan_obj *scan_obj;
1562 
1563 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1564 	if (!scan_obj) {
1565 		scm_err("Failed to get scan object");
1566 		return false;
1567 	}
1568 
1569 	return scan_obj->bt_a2dp_enabled;
1570 }
1571 
1572 bool ucfg_scan_wake_lock_in_user_scan(struct wlan_objmgr_psoc *psoc)
1573 {
1574 	struct wlan_scan_obj *scan_obj;
1575 
1576 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1577 	if (!scan_obj)
1578 		return false;
1579 
1580 	return scan_obj->scan_def.use_wake_lock_in_user_scan;
1581 }
1582 
1583 bool ucfg_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc)
1584 {
1585 	struct wlan_scan_obj *scan_obj;
1586 
1587 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1588 	if (!scan_obj) {
1589 		scm_err("Failed to get scan object");
1590 		return cfg_default(CFG_ENABLE_CONNECTED_SCAN);
1591 	}
1592 
1593 	return scan_obj->scan_def.enable_connected_scan;
1594 }
1595 
1596 bool ucfg_scan_is_mac_spoofing_enabled(struct wlan_objmgr_psoc *psoc)
1597 {
1598 	struct wlan_scan_obj *scan_obj;
1599 
1600 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1601 	if (!scan_obj) {
1602 		scm_err("Failed to get scan object");
1603 		return cfg_default(CFG_ENABLE_MAC_ADDR_SPOOFING);
1604 	}
1605 
1606 	return scan_obj->scan_def.enable_mac_spoofing;
1607 }
1608 
1609 enum scan_dwelltime_adaptive_mode
1610 ucfg_scan_get_extscan_adaptive_dwell_mode(struct wlan_objmgr_psoc *psoc)
1611 {
1612 	struct wlan_scan_obj *scan_obj;
1613 
1614 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1615 	if (!scan_obj) {
1616 		scm_err("Failed to get scan object");
1617 		return cfg_default(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
1618 	}
1619 
1620 	return scan_obj->scan_def.extscan_adaptive_dwell_mode;
1621 }
1622 
1623 QDF_STATUS
1624 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc,
1625 			       enum scan_config config, uint32_t val)
1626 {
1627 	struct wlan_scan_obj *scan_obj;
1628 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1629 
1630 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1631 	if (!scan_obj) {
1632 		scm_err("Failed to get scan object config:%d, val:%d",
1633 				config, val);
1634 		return QDF_STATUS_E_INVAL;
1635 	}
1636 	switch (config) {
1637 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1638 		scan_obj->disable_timeout = !!val;
1639 		break;
1640 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1641 		scan_obj->drop_bcn_on_chan_mismatch = !!val;
1642 		break;
1643 
1644 	default:
1645 		status = QDF_STATUS_E_INVAL;
1646 		break;
1647 	}
1648 
1649 	return status;
1650 }
1651 
1652 QDF_STATUS ucfg_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev,
1653 		struct bss_info *bss_info, struct mlme_info *mlme)
1654 {
1655 	QDF_STATUS status;
1656 
1657 	status = scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme);
1658 
1659 	return status;
1660 }
1661 
1662 QDF_STATUS
1663 ucfg_scan_get_global_config(struct wlan_objmgr_psoc *psoc,
1664 			       enum scan_config config, uint32_t *val)
1665 {
1666 	struct wlan_scan_obj *scan_obj;
1667 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1668 
1669 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1670 	if (!scan_obj || !val) {
1671 		scm_err("scan object:%pK config:%d, val:0x%pK",
1672 				scan_obj, config, val);
1673 		return QDF_STATUS_E_INVAL;
1674 	}
1675 	switch (config) {
1676 	case SCAN_CFG_DISABLE_SCAN_COMMAND_TIMEOUT:
1677 		*val = scan_obj->disable_timeout;
1678 		break;
1679 	case SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH:
1680 		*val = scan_obj->drop_bcn_on_chan_mismatch;
1681 		break;
1682 
1683 	default:
1684 		status = QDF_STATUS_E_INVAL;
1685 		break;
1686 	}
1687 
1688 	return status;
1689 }
1690 
1691 #ifdef FEATURE_WLAN_SCAN_PNO
1692 bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc)
1693 {
1694 	struct wlan_scan_obj *scan_obj;
1695 
1696 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1697 	if (!scan_obj) {
1698 		scm_err("NULL scan obj");
1699 		return false;
1700 	}
1701 
1702 	return scan_obj->pno_cfg.pno_offload_enabled;
1703 }
1704 
1705 void ucfg_scan_set_pno_offload(struct wlan_objmgr_psoc *psoc, bool value)
1706 {
1707 	 struct wlan_scan_obj *scan_obj;
1708 
1709 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1710 	if (!scan_obj) {
1711 		scm_err("NULL scan obj");
1712 		return;
1713 	}
1714 
1715 	scan_obj->pno_cfg.pno_offload_enabled = value;
1716 }
1717 
1718 bool ucfg_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc)
1719 {
1720 	struct wlan_scan_obj *scan_obj;
1721 
1722 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1723 	if (!scan_obj) {
1724 		scm_err("NULL scan obj");
1725 		return cfg_default(CFG_PNO_SCAN_SUPPORT);
1726 	}
1727 
1728 	return scan_obj->pno_cfg.scan_support_enabled;
1729 }
1730 
1731 uint8_t ucfg_get_scan_backoff_multiplier(struct wlan_objmgr_psoc *psoc)
1732 {
1733 	struct wlan_scan_obj *scan_obj;
1734 
1735 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1736 	if (!scan_obj) {
1737 		scm_err("NULL scan obj");
1738 		return cfg_default(CFG_SCAN_BACKOFF_MULTIPLIER);
1739 	}
1740 	return scan_obj->pno_cfg.scan_backoff_multiplier;
1741 }
1742 
1743 bool ucfg_scan_is_dfs_chnl_scan_enabled(struct wlan_objmgr_psoc *psoc)
1744 {
1745 		struct wlan_scan_obj *scan_obj;
1746 
1747 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1748 		if (!scan_obj) {
1749 			scm_err("NULL scan obj");
1750 			return cfg_default(CFG_ENABLE_DFS_PNO_CHNL_SCAN);
1751 		}
1752 		return scan_obj->pno_cfg.dfs_chnl_scan_enabled;
1753 }
1754 
1755 uint32_t ucfg_scan_get_scan_timer_repeat_value(struct wlan_objmgr_psoc *psoc)
1756 {
1757 		struct wlan_scan_obj *scan_obj;
1758 
1759 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1760 		if (!scan_obj) {
1761 			scm_err("NULL scan obj");
1762 			return cfg_default(CFG_PNO_SCAN_TIMER_REPEAT_VALUE);
1763 		}
1764 		return scan_obj->pno_cfg.scan_timer_repeat_value;
1765 }
1766 
1767 uint32_t ucfg_scan_get_slow_scan_multiplier(struct wlan_objmgr_psoc *psoc)
1768 {
1769 		struct wlan_scan_obj *scan_obj;
1770 
1771 		scan_obj = wlan_psoc_get_scan_obj(psoc);
1772 		if (!scan_obj) {
1773 			scm_err("NULL scan obj");
1774 			return cfg_default(CFG_PNO_SLOW_SCAN_MULTIPLIER);
1775 		}
1776 		return scan_obj->pno_cfg.slow_scan_multiplier;
1777 }
1778 
1779 uint32_t
1780 ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc)
1781 {
1782 	struct wlan_scan_obj *scan_obj;
1783 
1784 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1785 	if (!scan_obj) {
1786 		scm_err("Failed to get scan object");
1787 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
1788 	}
1789 
1790 	return scan_obj->pno_cfg.max_sched_scan_plan_interval;
1791 }
1792 
1793 uint32_t
1794 ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc)
1795 {
1796 	struct wlan_scan_obj *scan_obj;
1797 
1798 	scan_obj = wlan_psoc_get_scan_obj(psoc);
1799 	if (!scan_obj) {
1800 		scm_err("Failed to get scan object");
1801 		return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
1802 	}
1803 
1804 	return scan_obj->pno_cfg.max_sched_scan_plan_iterations;
1805 }
1806 
1807 #endif
1808