1  /*
2   * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4   *
5   * Permission to use, copy, modify, and/or distribute this software for
6   * any purpose with or without fee is hereby granted, provided that the
7   * above copyright notice and this permission notice appear in all
8   * copies.
9   *
10   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17   * PERFORMANCE OF THIS SOFTWARE.
18   */
19  
20  /*
21   * DOC: This file contains all SCAN component's APIs
22   */
23  
24  #include "cfg_ucfg_api.h"
25  #include "wlan_scan_api.h"
26  #include "../../core/src/wlan_scan_manager.h"
27  #ifdef WLAN_POLICY_MGR_ENABLE
28  #include <wlan_policy_mgr_api.h>
29  #include "wlan_policy_mgr_public_struct.h"
30  #endif
31  
wlan_scan_cfg_get_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)32  void wlan_scan_cfg_get_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
33  					 uint32_t *dwell_time)
34  {
35  	struct wlan_scan_obj *scan_obj;
36  
37  	scan_obj = wlan_psoc_get_scan_obj(psoc);
38  	if (!scan_obj)
39  		return;
40  	*dwell_time = scan_obj->scan_def.passive_dwell;
41  }
42  
wlan_scan_cfg_set_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)43  void wlan_scan_cfg_set_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
44  					 uint32_t dwell_time)
45  {
46  	struct wlan_scan_obj *scan_obj;
47  
48  	scan_obj = wlan_psoc_get_scan_obj(psoc);
49  	if (!scan_obj)
50  		return;
51  	scan_obj->scan_def.passive_dwell = dwell_time;
52  }
53  
wlan_scan_cfg_get_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)54  void wlan_scan_cfg_get_active_dwelltime(struct wlan_objmgr_psoc *psoc,
55  					uint32_t *dwell_time)
56  {
57  	struct wlan_scan_obj *scan_obj;
58  
59  	scan_obj = wlan_psoc_get_scan_obj(psoc);
60  	if (!scan_obj)
61  		return;
62  	*dwell_time = scan_obj->scan_def.active_dwell;
63  }
64  
wlan_scan_cfg_set_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)65  void wlan_scan_cfg_set_active_dwelltime(struct wlan_objmgr_psoc *psoc,
66  					uint32_t dwell_time)
67  {
68  	struct wlan_scan_obj *scan_obj;
69  
70  	scan_obj = wlan_psoc_get_scan_obj(psoc);
71  	if (!scan_obj)
72  		return;
73  	scan_obj->scan_def.active_dwell = dwell_time;
74  }
75  
wlan_scan_cfg_get_active_2g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)76  void wlan_scan_cfg_get_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc,
77  					   uint32_t *dwell_time)
78  {
79  	struct wlan_scan_obj *scan_obj;
80  
81  	scan_obj = wlan_psoc_get_scan_obj(psoc);
82  	if (!scan_obj)
83  		return;
84  
85  	*dwell_time = scan_obj->scan_def.active_dwell_2g;
86  }
87  
wlan_scan_cfg_set_active_2g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)88  void wlan_scan_cfg_set_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc,
89  					   uint32_t dwell_time)
90  {
91  	struct wlan_scan_obj *scan_obj;
92  
93  	scan_obj = wlan_psoc_get_scan_obj(psoc);
94  	if (!scan_obj)
95  		return;
96  	scan_obj->scan_def.active_dwell_2g = dwell_time;
97  }
98  
99  #ifdef CONFIG_BAND_6GHZ
wlan_scan_cfg_get_active_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)100  QDF_STATUS wlan_scan_cfg_get_active_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
101  						 uint32_t *dwell_time)
102  {
103  	struct wlan_scan_obj *scan_obj;
104  
105  	scan_obj = wlan_psoc_get_scan_obj(psoc);
106  	if (!scan_obj)
107  		return QDF_STATUS_E_INVAL;
108  
109  	*dwell_time = scan_obj->scan_def.active_dwell_6g;
110  
111  	return QDF_STATUS_SUCCESS;
112  }
113  
wlan_scan_cfg_set_active_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)114  QDF_STATUS wlan_scan_cfg_set_active_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
115  						 uint32_t dwell_time)
116  {
117  	struct wlan_scan_obj *scan_obj;
118  
119  	scan_obj = wlan_psoc_get_scan_obj(psoc);
120  	if (!scan_obj)
121  		return QDF_STATUS_E_INVAL;
122  
123  	scan_obj->scan_def.active_dwell_6g = dwell_time;
124  
125  	return QDF_STATUS_SUCCESS;
126  }
127  
wlan_scan_cfg_get_passive_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)128  QDF_STATUS wlan_scan_cfg_get_passive_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
129  						  uint32_t *dwell_time)
130  {
131  	struct wlan_scan_obj *scan_obj;
132  
133  	scan_obj = wlan_psoc_get_scan_obj(psoc);
134  	if (!scan_obj)
135  		return QDF_STATUS_E_INVAL;
136  
137  	*dwell_time = scan_obj->scan_def.passive_dwell_6g;
138  
139  	return QDF_STATUS_SUCCESS;
140  }
141  
wlan_scan_cfg_set_passive_6g_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)142  QDF_STATUS wlan_scan_cfg_set_passive_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
143  						  uint32_t dwell_time)
144  {
145  	struct wlan_scan_obj *scan_obj;
146  
147  	scan_obj = wlan_psoc_get_scan_obj(psoc);
148  	if (!scan_obj)
149  		return QDF_STATUS_E_INVAL;
150  
151  	scan_obj->scan_def.passive_dwell_6g = dwell_time;
152  
153  	return QDF_STATUS_SUCCESS;
154  }
155  
wlan_scan_cfg_get_min_dwelltime_6g(struct wlan_objmgr_psoc * psoc,uint32_t * min_dwell_time_6ghz)156  void wlan_scan_cfg_get_min_dwelltime_6g(struct wlan_objmgr_psoc *psoc,
157  					uint32_t *min_dwell_time_6ghz)
158  {
159  	struct wlan_scan_obj *scan_obj;
160  
161  	scan_obj = wlan_psoc_get_scan_obj(psoc);
162  	if (!scan_obj)
163  		return;
164  	*min_dwell_time_6ghz = scan_obj->scan_def.min_dwell_time_6g;
165  }
166  
wlan_scan_cfg_set_scan_mode_6g(struct wlan_objmgr_psoc * psoc,enum scan_mode_6ghz scan_mode_6g)167  QDF_STATUS wlan_scan_cfg_set_scan_mode_6g(struct wlan_objmgr_psoc *psoc,
168  					  enum scan_mode_6ghz scan_mode_6g)
169  {
170  	struct wlan_scan_obj *scan_obj;
171  
172  	scan_obj = wlan_psoc_get_scan_obj(psoc);
173  	if (!scan_obj)
174  		return QDF_STATUS_E_INVAL;
175  
176  	scan_obj->scan_def.scan_mode_6g = scan_mode_6g;
177  
178  	return QDF_STATUS_SUCCESS;
179  }
180  #endif
181  
182  #ifdef WLAN_POLICY_MGR_ENABLE
wlan_scan_update_pno_dwell_time(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req,struct scan_default_params * scan_def)183  void wlan_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
184  				     struct pno_scan_req_params *req,
185  				     struct scan_default_params *scan_def)
186  {
187  	bool sap_or_p2p_present;
188  	struct wlan_objmgr_psoc *psoc;
189  
190  	psoc = wlan_vdev_get_psoc(vdev);
191  
192  	if (!psoc)
193  		return;
194  
195  	sap_or_p2p_present = policy_mgr_get_beaconing_mode_count(psoc, NULL) ||
196  				policy_mgr_mode_specific_connection_count
197  			       (psoc,
198  				PM_P2P_CLIENT_MODE, NULL);
199  
200  	if (sap_or_p2p_present) {
201  		req->active_dwell_time = scan_def->conc_active_dwell;
202  		req->passive_dwell_time = scan_def->conc_passive_dwell;
203  	}
204  }
205  #endif
206  
wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)207  void wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc,
208  					     uint32_t *dwell_time)
209  {
210  	struct wlan_scan_obj *scan_obj;
211  
212  	scan_obj = wlan_psoc_get_scan_obj(psoc);
213  	if (!scan_obj)
214  		return;
215  
216  	*dwell_time = scan_obj->scan_def.conc_active_dwell;
217  }
218  
wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)219  void wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc,
220  					     uint32_t dwell_time)
221  {
222  	struct wlan_scan_obj *scan_obj;
223  
224  	scan_obj = wlan_psoc_get_scan_obj(psoc);
225  	if (!scan_obj)
226  		return;
227  
228  	scan_obj->scan_def.conc_active_dwell = dwell_time;
229  }
230  
wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t * dwell_time)231  void wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
232  					      uint32_t *dwell_time)
233  {
234  	struct wlan_scan_obj *scan_obj;
235  
236  	scan_obj = wlan_psoc_get_scan_obj(psoc);
237  	if (!scan_obj)
238  		return;
239  
240  	*dwell_time = scan_obj->scan_def.conc_passive_dwell;
241  }
242  
wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc * psoc,uint32_t dwell_time)243  void wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
244  					      uint32_t dwell_time)
245  {
246  	struct wlan_scan_obj *scan_obj;
247  
248  	scan_obj = wlan_psoc_get_scan_obj(psoc);
249  	if (!scan_obj)
250  		return;
251  
252  	scan_obj->scan_def.conc_passive_dwell = dwell_time;
253  }
254  
255  void
wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc * psoc,bool * enable_dfs_scan)256  wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
257  					bool *enable_dfs_scan)
258  {
259  	struct wlan_scan_obj *scan_obj;
260  
261  	scan_obj = wlan_psoc_get_scan_obj(psoc);
262  	if (!scan_obj)
263  		return;
264  
265  	*enable_dfs_scan = scan_obj->scan_def.allow_dfs_chan_in_scan;
266  }
267  
268  void
wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc * psoc,bool enable_dfs_scan)269  wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
270  					bool enable_dfs_scan)
271  {
272  	struct wlan_scan_obj *scan_obj;
273  
274  	scan_obj = wlan_psoc_get_scan_obj(psoc);
275  	if (!scan_obj)
276  		return;
277  
278  	scan_obj->scan_def.allow_dfs_chan_in_scan = enable_dfs_scan;
279  }
280  
wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc * psoc)281  bool wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc *psoc)
282  {
283  	struct wlan_scan_obj *scan_obj;
284  
285  	scan_obj = wlan_psoc_get_scan_obj(psoc);
286  	if (!scan_obj)
287  		return false;
288  
289  	return scan_obj->scan_def.honour_nl_scan_policy_flags;
290  }
291  
wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc * psoc,uint32_t * rest_time)292  void wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc *psoc,
293  					 uint32_t *rest_time)
294  {
295  	struct wlan_scan_obj *scan_obj;
296  
297  	scan_obj = wlan_psoc_get_scan_obj(psoc);
298  	if (!scan_obj)
299  		return;
300  
301  	*rest_time = scan_obj->scan_def.conc_max_rest_time;
302  }
303  
wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc * psoc,uint32_t * rest_time)304  void wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc *psoc,
305  					 uint32_t *rest_time)
306  {
307  	struct wlan_scan_obj *scan_obj;
308  
309  	scan_obj = wlan_psoc_get_scan_obj(psoc);
310  	if (!scan_obj)
311  		return;
312  
313  	*rest_time = scan_obj->scan_def.conc_min_rest_time;
314  }
315  
wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc * psoc)316  bool wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc *psoc)
317  {
318  	struct wlan_scan_obj *scan_obj;
319  
320  	scan_obj = wlan_psoc_get_scan_obj(psoc);
321  	if (!scan_obj)
322  		return cfg_default(CFG_ENABLE_SNR_MONITORING);
323  
324  	return scan_obj->scan_def.scan_f_chan_stat_evnt;
325  }
326  
327  QDF_STATUS
wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc * psoc,qdf_nbuf_t buf,struct mgmt_rx_event_params * rx_param,enum mgmt_frame_type frm_type)328  wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc *psoc,
329  				    qdf_nbuf_t buf,
330  				    struct mgmt_rx_event_params *rx_param,
331  				    enum mgmt_frame_type frm_type)
332  {
333  	struct scan_bcn_probe_event *bcn = NULL;
334  	QDF_STATUS status;
335  
336  	if ((frm_type != MGMT_PROBE_RESP) &&
337  	    (frm_type != MGMT_BEACON)) {
338  		scm_err("frame is not beacon or probe resp");
339  		status = QDF_STATUS_E_INVAL;
340  		goto free;
341  	}
342  
343  	bcn = qdf_mem_malloc_atomic(sizeof(*bcn));
344  	if (!bcn) {
345  		status = QDF_STATUS_E_NOMEM;
346  		goto free;
347  	}
348  	bcn->rx_data =
349  		qdf_mem_malloc_atomic(sizeof(*rx_param));
350  	if (!bcn->rx_data) {
351  		status = QDF_STATUS_E_NOMEM;
352  		goto free;
353  	}
354  
355  	if (frm_type == MGMT_PROBE_RESP)
356  		bcn->frm_type = MGMT_SUBTYPE_PROBE_RESP;
357  	else
358  		bcn->frm_type = MGMT_SUBTYPE_BEACON;
359  
360  	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID);
361  	if (QDF_IS_STATUS_ERROR(status)) {
362  		scm_info("unable to get reference");
363  		goto free;
364  	}
365  
366  	bcn->psoc = psoc;
367  	bcn->buf = buf;
368  
369  	/*
370  	 * Save the rnr entries from the frame into rnr db.
371  	 * The RNR entry would have the partner links as well.
372  	 * If the partner link is a non-tx profile, and if there
373  	 * is no MBSSID info for that partner link, then look up
374  	 * into the rnr db will help to identify if that partner
375  	 * is a non-tx profile.
376  	 */
377  	bcn->save_rnr_info = true;
378  	qdf_mem_copy(bcn->rx_data, rx_param, sizeof(*rx_param));
379  
380  	return __scm_handle_bcn_probe(bcn);
381  free:
382  	if (bcn && bcn->rx_data)
383  		qdf_mem_free(bcn->rx_data);
384  	if (bcn)
385  		qdf_mem_free(bcn);
386  	if (buf)
387  		qdf_nbuf_free(buf);
388  
389  	return status;
390  }
391  
wlan_scan_get_aging_time(struct wlan_objmgr_psoc * psoc)392  qdf_time_t wlan_scan_get_aging_time(struct wlan_objmgr_psoc *psoc)
393  {
394  	struct wlan_scan_obj *scan_obj;
395  
396  	scan_obj = wlan_psoc_get_scan_obj(psoc);
397  	if (!scan_obj)
398  		return cfg_default(CFG_SCAN_AGING_TIME) * 1000;
399  
400  	return scan_obj->scan_def.scan_cache_aging_time;
401  }
402  
wlan_scan_set_aging_time(struct wlan_objmgr_psoc * psoc,qdf_time_t time)403  QDF_STATUS wlan_scan_set_aging_time(struct wlan_objmgr_psoc *psoc,
404  				    qdf_time_t time)
405  {
406  	struct wlan_scan_obj *scan_obj;
407  	QDF_STATUS status = QDF_STATUS_E_FAILURE;
408  
409  	scan_obj = wlan_psoc_get_scan_obj(psoc);
410  	if (!scan_obj)
411  		return status;
412  
413  	if (!cfg_in_range(CFG_SCAN_AGING_TIME, time / 1000)) {
414  		status = QDF_STATUS_E_RANGE;
415  		return status;
416  	}
417  
418  	scan_obj->scan_def.scan_cache_aging_time = time;
419  	status = QDF_STATUS_SUCCESS;
420  	return status;
421  }
422  
wlan_scan_start(struct scan_start_request * req)423  QDF_STATUS wlan_scan_start(struct scan_start_request *req)
424  {
425  	struct scheduler_msg msg = {0};
426  	QDF_STATUS status;
427  
428  	if (!req || !req->vdev) {
429  		scm_err("req or vdev within req is NULL");
430  		scm_scan_free_scan_request_mem(req);
431  		return QDF_STATUS_E_NULL_VALUE;
432  	}
433  
434  	if (!scm_is_scan_allowed(req->vdev)) {
435  		scm_err_rl("scan disabled, rejecting the scan req");
436  		scm_scan_free_scan_request_mem(req);
437  		return QDF_STATUS_E_AGAIN;
438  	}
439  
440  	/*
441  	 * Try to get vdev reference. Return if reference could
442  	 * not be taken. Reference will be released once scan
443  	 * request handling completes along with free of @req.
444  	 */
445  	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
446  	if (QDF_IS_STATUS_ERROR(status)) {
447  		scm_info("unable to get reference");
448  		scm_scan_free_scan_request_mem(req);
449  		return status;
450  	}
451  
452  	msg.bodyptr = req;
453  	msg.callback = scm_scan_start_req;
454  	msg.flush_callback = scm_scan_start_flush_callback;
455  
456  	status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
457  					QDF_MODULE_ID_SCAN,
458  					QDF_MODULE_ID_OS_IF, &msg);
459  	if (QDF_IS_STATUS_ERROR(status)) {
460  		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
461  		scm_scan_free_scan_request_mem(req);
462  	}
463  
464  	return status;
465  }
466  
wlan_scan_cancel(struct scan_cancel_request * req)467  QDF_STATUS wlan_scan_cancel(struct scan_cancel_request *req)
468  {
469  	struct scheduler_msg msg = {0};
470  	QDF_STATUS status;
471  
472  	if (!req || !req->vdev) {
473  		scm_err("req or vdev within req is NULL");
474  		if (req)
475  			qdf_mem_free(req);
476  		return QDF_STATUS_E_NULL_VALUE;
477  	}
478  
479  	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
480  	if (QDF_IS_STATUS_ERROR(status)) {
481  		scm_info("Failed to get vdev ref; status:%d", status);
482  		goto req_free;
483  	}
484  
485  	msg.bodyptr = req;
486  	msg.callback = scm_scan_cancel_req;
487  	msg.flush_callback = scm_scan_cancel_flush_callback;
488  
489  	status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
490  					QDF_MODULE_ID_SCAN,
491  					QDF_MODULE_ID_OS_IF, &msg);
492  	if (QDF_IS_STATUS_ERROR(status))
493  		goto vdev_put;
494  
495  	return QDF_STATUS_SUCCESS;
496  
497  vdev_put:
498  	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
499  
500  req_free:
501  	qdf_mem_free(req);
502  
503  	return status;
504  }
505  
506  wlan_scan_id
wlan_scan_get_scan_id(struct wlan_objmgr_psoc * psoc)507  wlan_scan_get_scan_id(struct wlan_objmgr_psoc *psoc)
508  {
509  	wlan_scan_id id;
510  	struct wlan_scan_obj *scan;
511  
512  	if (!psoc) {
513  		QDF_ASSERT(0);
514  		scm_err("null psoc");
515  		return 0;
516  	}
517  
518  	scan = wlan_psoc_get_scan_obj(psoc);
519  	if (!scan) {
520  		scm_err("scan object null");
521  		return 0;
522  	}
523  
524  	id = qdf_atomic_inc_return(&scan->scan_ids);
525  	id =  id & WLAN_SCAN_ID_MASK;
526  	/* Mark this scan request as triggered by host
527  	 * by setting WLAN_HOST_SCAN_REQ_ID_PREFIX flag.
528  	 */
529  	id =  id | WLAN_HOST_SCAN_REQ_ID_PREFIX;
530  	scm_debug("scan_id: 0x%x", id);
531  
532  	return id;
533  }
534  
535  QDF_STATUS
wlan_scan_init_default_params(struct wlan_objmgr_vdev * vdev,struct scan_start_request * req)536  wlan_scan_init_default_params(struct wlan_objmgr_vdev *vdev,
537  			      struct scan_start_request *req)
538  {
539  	struct scan_default_params *def;
540  
541  	if (!vdev | !req) {
542  		scm_err("vdev: 0x%pK, req: 0x%pK", vdev, req);
543  		return QDF_STATUS_E_INVAL;
544  	}
545  	def = wlan_vdev_get_def_scan_params(vdev);
546  	if (!def) {
547  		scm_err("wlan_vdev_get_def_scan_params returned NULL");
548  		return QDF_STATUS_E_NULL_VALUE;
549  	}
550  
551  	/* Zero out everything and explicitly set fields as required */
552  	qdf_mem_zero(req, sizeof(*req));
553  
554  	req->vdev = vdev;
555  	req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
556  	req->scan_req.scan_type = SCAN_TYPE_DEFAULT;
557  	req->scan_req.scan_priority = def->scan_priority;
558  	req->scan_req.dwell_time_active = def->active_dwell;
559  	req->scan_req.dwell_time_active_2g = def->active_dwell_2g;
560  	req->scan_req.min_dwell_time_6g = def->min_dwell_time_6g;
561  	req->scan_req.dwell_time_active_6g = def->active_dwell_6g;
562  	req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g;
563  	req->scan_req.dwell_time_passive = def->passive_dwell;
564  	req->scan_req.min_rest_time = def->min_rest_time;
565  	req->scan_req.max_rest_time = def->max_rest_time;
566  	req->scan_req.repeat_probe_time = def->repeat_probe_time;
567  	req->scan_req.probe_spacing_time = def->probe_spacing_time;
568  	req->scan_req.idle_time = def->idle_time;
569  	req->scan_req.max_scan_time = def->max_scan_time;
570  	req->scan_req.probe_delay = def->probe_delay;
571  	req->scan_req.burst_duration = def->burst_duration;
572  	req->scan_req.n_probes = def->num_probes;
573  	req->scan_req.adaptive_dwell_time_mode =
574  		def->adaptive_dwell_time_mode;
575  	req->scan_req.scan_flags = def->scan_flags;
576  	req->scan_req.scan_events = def->scan_events;
577  	req->scan_req.scan_random.randomize = def->enable_mac_spoofing;
578  
579  	return QDF_STATUS_SUCCESS;
580  }
581  
582  wlan_scan_requester
wlan_scan_register_requester(struct wlan_objmgr_psoc * psoc,uint8_t * name,scan_event_handler event_cb,void * arg)583  wlan_scan_register_requester(struct wlan_objmgr_psoc *psoc,
584  			     uint8_t *name,
585  			     scan_event_handler event_cb,
586  			     void *arg)
587  {
588  	int i, j;
589  	struct wlan_scan_obj *scan;
590  	struct scan_requester_info *requesters;
591  	wlan_scan_requester requester = {0};
592  
593  	if (!psoc) {
594  		scm_err("null psoc");
595  		return 0;
596  	}
597  	scan = wlan_psoc_get_scan_obj(psoc);
598  	if (!scan)
599  		return 0;
600  
601  	requesters = scan->requesters;
602  	qdf_spin_lock_bh(&scan->lock);
603  	for (i = 0; i < WLAN_MAX_REQUESTORS; ++i) {
604  		if (requesters[i].requester == 0) {
605  			requesters[i].requester =
606  				WLAN_SCAN_REQUESTER_ID_PREFIX | i;
607  			j = 0;
608  			while (name[j] && (j < (WLAN_MAX_MODULE_NAME - 1))) {
609  				requesters[i].module[j] = name[j];
610  				++j;
611  			}
612  			requesters[i].module[j] = 0;
613  			requesters[i].ev_handler.func = event_cb;
614  			requesters[i].ev_handler.arg = arg;
615  			requester = requesters[i].requester;
616  			break;
617  		}
618  	}
619  	qdf_spin_unlock_bh(&scan->lock);
620  	scm_debug("module: %s, event_cb: 0x%pK, arg: 0x%pK, reqid: %d",
621  		  name, event_cb, arg, requester);
622  
623  	return requester;
624  }
625  
626  void
wlan_scan_unregister_requester(struct wlan_objmgr_psoc * psoc,wlan_scan_requester requester)627  wlan_scan_unregister_requester(struct wlan_objmgr_psoc *psoc,
628  			       wlan_scan_requester requester)
629  {
630  	int idx;
631  	struct wlan_scan_obj *scan;
632  	struct scan_requester_info *requesters;
633  
634  	idx = requester & WLAN_SCAN_REQUESTER_ID_PREFIX;
635  	if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) {
636  		scm_err("prefix didn't match for requester id %d", requester);
637  		return;
638  	}
639  
640  	idx = requester & WLAN_SCAN_REQUESTER_ID_MASK;
641  	if (idx >= WLAN_MAX_REQUESTORS) {
642  		scm_err("requester id %d greater than max value", requester);
643  		return;
644  	}
645  
646  	if (!psoc) {
647  		scm_err("null psoc");
648  		return;
649  	}
650  	scan = wlan_psoc_get_scan_obj(psoc);
651  	if (!scan)
652  		return;
653  	requesters = scan->requesters;
654  	scm_debug("reqid: %d", requester);
655  
656  	qdf_spin_lock_bh(&scan->lock);
657  	requesters[idx].requester = 0;
658  	requesters[idx].module[0] = 0;
659  	requesters[idx].ev_handler.func = NULL;
660  	requesters[idx].ev_handler.arg = NULL;
661  	qdf_spin_unlock_bh(&scan->lock);
662  }
663  
wlan_scan_cfg_skip_6g_and_indoor_freq(struct wlan_objmgr_psoc * psoc)664  bool wlan_scan_cfg_skip_6g_and_indoor_freq(struct wlan_objmgr_psoc *psoc)
665  {
666  	struct wlan_scan_obj *scan_obj;
667  
668  	scan_obj = wlan_psoc_get_scan_obj(psoc);
669  	if (!scan_obj)
670  		return false;
671  
672  	return scan_obj->scan_def.skip_6g_and_indoor_freq;
673  }
674  
wlan_scan_get_last_scan_ageout_time(struct wlan_objmgr_psoc * psoc,uint32_t * last_scan_ageout_time)675  void wlan_scan_get_last_scan_ageout_time(struct wlan_objmgr_psoc *psoc,
676  					 uint32_t *last_scan_ageout_time)
677  {
678  	struct wlan_scan_obj *scan_obj;
679  
680  	scan_obj = wlan_psoc_get_scan_obj(psoc);
681  	if (!scan_obj) {
682  		*last_scan_ageout_time = 0;
683  		return;
684  	}
685  	*last_scan_ageout_time =
686  	scan_obj->scan_def.last_scan_ageout_time;
687  }
688  
689  #ifdef FEATURE_SET
690  /**
691   * wlan_scan_get_pno_scan_support() - Check if pno scan support is enabled
692   * @psoc: pointer to psoc object
693   *
694   * Return: pno scan_support_enabled flag
695   */
wlan_scan_get_pno_scan_support(struct wlan_objmgr_psoc * psoc)696  static bool wlan_scan_get_pno_scan_support(struct wlan_objmgr_psoc *psoc)
697  {
698  	struct wlan_scan_obj *scan_obj;
699  
700  	scan_obj = wlan_psoc_get_scan_obj(psoc);
701  	if (!scan_obj) {
702  		scm_err("NULL scan obj");
703  		return cfg_default(CFG_PNO_SCAN_SUPPORT);
704  	}
705  
706  	return scan_obj->pno_cfg.scan_support_enabled;
707  }
708  
709  /**
710   * wlan_scan_is_connected_scan_enabled() - API to get scan enabled after connect
711   * @psoc: pointer to psoc object
712   *
713   * Return: value.
714   */
wlan_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc * psoc)715  static bool wlan_scan_is_connected_scan_enabled(struct wlan_objmgr_psoc *psoc)
716  {
717  	struct wlan_scan_obj *scan_obj;
718  
719  	scan_obj = wlan_psoc_get_scan_obj(psoc);
720  	if (!scan_obj) {
721  		scm_err("Failed to get scan object");
722  		return cfg_default(CFG_ENABLE_CONNECTED_SCAN);
723  	}
724  
725  	return scan_obj->scan_def.enable_connected_scan;
726  }
727  
wlan_scan_get_feature_info(struct wlan_objmgr_psoc * psoc,struct wlan_scan_features * scan_feature_set)728  void wlan_scan_get_feature_info(struct wlan_objmgr_psoc *psoc,
729  				struct wlan_scan_features *scan_feature_set)
730  {
731  	scan_feature_set->pno_in_unassoc_state =
732  					wlan_scan_get_pno_scan_support(psoc);
733  	if (scan_feature_set->pno_in_unassoc_state)
734  		scan_feature_set->pno_in_assoc_state =
735  				wlan_scan_is_connected_scan_enabled(psoc);
736  }
737  #endif
738  
739  #ifdef WLAN_POLICY_MGR_ENABLE
740  /**
741   * wlan_scan_update_hint_bssid() - Update rnr hint bssid info
742   * @psoc: objmgr psoc
743   * @req: Scan request
744   * @ll_sap_freq: ll sap freq
745   *
746   * Use to update hint_bssid if low latency Sap is UP
747   *
748   * Return: void
749   */
750  static void
wlan_scan_update_hint_bssid(struct wlan_objmgr_psoc * psoc,struct scan_start_request * req,qdf_freq_t ll_sap_freq)751  wlan_scan_update_hint_bssid(struct wlan_objmgr_psoc *psoc,
752  			    struct scan_start_request *req,
753  			    qdf_freq_t ll_sap_freq)
754  {
755  	struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID] = {0};
756  	uint32_t i;
757  	uint32_t count = 0;
758  	qdf_freq_t freq;
759  
760  	if (!req->scan_req.num_hint_bssid)
761  		return;
762  
763  	for (i = 0; i < req->scan_req.num_hint_bssid; i++) {
764  		freq = req->scan_req.hint_bssid[i].freq_flags >> 16;
765  		if (!freq)
766  			continue;
767  		if (!policy_mgr_2_freq_always_on_same_mac(psoc,
768  							  ll_sap_freq,
769  							  freq)) {
770  			qdf_mem_copy(
771  				&hint_bssid[count].bssid,
772  				&req->scan_req.hint_bssid[i].bssid,
773  				sizeof(hint_bssid[i].bssid));
774  			hint_bssid[count].freq_flags =
775  				req->scan_req.hint_bssid[i].freq_flags;
776  			count++;
777  		}
778  	}
779  	qdf_mem_zero(req->scan_req.hint_bssid,
780  		     sizeof(req->scan_req.hint_bssid));
781  	if (count)
782  		qdf_mem_copy(req->scan_req.hint_bssid, hint_bssid,
783  			     sizeof(hint_bssid));
784  	req->scan_req.num_hint_bssid = count;
785  }
786  
787  /**
788   * wlan_scan_update_hint_s_ssid() - Update rnr hint short ssid info
789   * @psoc: objmgr psoc
790   * @req: Scan request
791   * @ll_sap_freq: ll sap freq
792   *
793   * Use to update hint_s_ssid if low latency Sap is UP
794   *
795   * Return: void
796   */
797  static
wlan_scan_update_hint_s_ssid(struct wlan_objmgr_psoc * psoc,struct scan_start_request * req,qdf_freq_t ll_sap_freq)798  void wlan_scan_update_hint_s_ssid(struct wlan_objmgr_psoc *psoc,
799  				  struct scan_start_request *req,
800  				  qdf_freq_t ll_sap_freq)
801  {
802  	struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_BSSID] = {0};
803  	uint32_t i;
804  	uint32_t count = 0;
805  	qdf_freq_t freq;
806  
807  	if (!req->scan_req.num_hint_s_ssid)
808  		return;
809  
810  	for (i = 0; i < req->scan_req.num_hint_s_ssid; i++) {
811  		freq = req->scan_req.hint_s_ssid[i].freq_flags >> 16;
812  		if (!freq)
813  			continue;
814  		if (!policy_mgr_2_freq_always_on_same_mac(psoc,
815  							  ll_sap_freq,
816  							  freq)) {
817  			qdf_mem_copy(
818  				&hint_s_ssid[count].short_ssid,
819  				&req->scan_req.hint_s_ssid[i].short_ssid,
820  				sizeof(hint_s_ssid[i].short_ssid));
821  			hint_s_ssid[count].freq_flags =
822  				req->scan_req.hint_s_ssid[i].freq_flags;
823  			count++;
824  		}
825  	}
826  	qdf_mem_zero(req->scan_req.hint_s_ssid,
827  		     sizeof(req->scan_req.hint_s_ssid));
828  	if (count)
829  		qdf_mem_copy(req->scan_req.hint_s_ssid, hint_s_ssid,
830  			     sizeof(hint_s_ssid));
831  	req->scan_req.num_hint_s_ssid = count;
832  }
833  
wlan_scan_update_low_latency_profile_chnlist(struct wlan_objmgr_vdev * vdev,struct scan_start_request * req)834  void wlan_scan_update_low_latency_profile_chnlist(
835  				struct wlan_objmgr_vdev *vdev,
836  				struct scan_start_request *req)
837  {
838  	uint32_t num_scan_channels = 0, i;
839  	struct wlan_objmgr_psoc *psoc;
840  	qdf_freq_t freq, ll_sap_freq;
841  
842  	psoc = wlan_vdev_get_psoc(vdev);
843  	if (!psoc) {
844  		scm_err("psoc is null");
845  		return;
846  	}
847  
848  /*
849   * Get ll_sap freq api will be cleaned up once macro is enabled
850   */
851  #ifndef WLAN_FEATURE_LL_LT_SAP
852  	ll_sap_freq = policy_mgr_get_ll_sap_freq(psoc);
853  #else
854  	ll_sap_freq = policy_mgr_get_ll_ht_sap_freq(psoc);
855  #endif
856  
857  	if (!ll_sap_freq)
858  		return;
859  
860  	wlan_scan_update_hint_bssid(psoc, req, ll_sap_freq);
861  	wlan_scan_update_hint_s_ssid(psoc, req, ll_sap_freq);
862  	/*
863  	 * Scenario: LL SAP is present and scan is requested.
864  	 * Allow scan on freq on mutually exclusive mac.
865  	 */
866  	for (i = 0; i < req->scan_req.chan_list.num_chan; i++) {
867  		freq = req->scan_req.chan_list.chan[i].freq;
868  		if (policy_mgr_2_freq_always_on_same_mac(psoc,
869  							 ll_sap_freq,
870  							 freq))
871  			continue;
872  
873  		req->scan_req.chan_list.chan[num_scan_channels++] =
874  					req->scan_req.chan_list.chan[i];
875  	}
876  	if (num_scan_channels < req->scan_req.chan_list.num_chan)
877  		scm_debug("For DBS: only 2.4Ghz chan and for SBS: mutually exclusive ll-sap 5GHz chan allowed, total-chan %d, remaining-chan %d, ll-sap chan %d",
878  			  req->scan_req.chan_list.num_chan,
879  			  num_scan_channels,
880  			  ll_sap_freq);
881  	req->scan_req.chan_list.num_chan = num_scan_channels;
882  }
883  #endif
884  
885  QDF_STATUS
wlan_scan_get_entry_by_mac_addr(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid,struct element_info * frame)886  wlan_scan_get_entry_by_mac_addr(struct wlan_objmgr_pdev *pdev,
887  				struct qdf_mac_addr *bssid,
888  				struct element_info *frame)
889  {
890  	return scm_scan_get_entry_by_mac_addr(pdev, bssid, frame);
891  }
892  
wlan_scan_register_mbssid_cb(struct wlan_objmgr_psoc * psoc,update_mbssid_bcn_prb_rsp cb)893  QDF_STATUS wlan_scan_register_mbssid_cb(struct wlan_objmgr_psoc *psoc,
894  					update_mbssid_bcn_prb_rsp cb)
895  {
896  	return scm_scan_register_mbssid_cb(psoc, cb);
897  }
898  
899  struct scan_cache_entry *
wlan_scan_get_entry_by_bssid(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid)900  wlan_scan_get_entry_by_bssid(struct wlan_objmgr_pdev *pdev,
901  			     struct qdf_mac_addr *bssid)
902  {
903  	return scm_scan_get_entry_by_bssid(pdev, bssid);
904  }
905  
906  QDF_STATUS
wlan_scan_get_mld_addr_by_link_addr(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * link_addr,struct qdf_mac_addr * mld_mac_addr)907  wlan_scan_get_mld_addr_by_link_addr(struct wlan_objmgr_pdev *pdev,
908  				    struct qdf_mac_addr *link_addr,
909  				    struct qdf_mac_addr *mld_mac_addr)
910  {
911  	return scm_get_mld_addr_by_link_addr(pdev, link_addr, mld_mac_addr);
912  }
913  
914  struct scan_cache_entry *
wlan_scan_get_scan_entry_by_mac_freq(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid,uint16_t freq)915  wlan_scan_get_scan_entry_by_mac_freq(struct wlan_objmgr_pdev *pdev,
916  				     struct qdf_mac_addr *bssid,
917  				     uint16_t freq)
918  {
919  	return scm_scan_get_scan_entry_by_mac_freq(pdev, bssid, freq);
920  }
921  
wlan_scan_get_aux_support(struct wlan_objmgr_psoc * psoc)922  bool wlan_scan_get_aux_support(struct wlan_objmgr_psoc *psoc)
923  
924  {
925  	struct wlan_scan_obj *scan_obj;
926  
927  	scan_obj = wlan_psoc_get_scan_obj(psoc);
928  	if (!scan_obj)
929  		return false;
930  
931  	if (scan_obj->aux_mac_support)
932  		scm_debug("aux mac support: %d", scan_obj->aux_mac_support);
933  	else
934  		scm_debug("aux mac not supported");
935  
936  	return scan_obj->aux_mac_support;
937  }
938  
939