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