xref: /wlan-driver/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_tgt_api.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /*
21*5113495bSYour Name  * DOC: contains scan south bound interface definitions
22*5113495bSYour Name  */
23*5113495bSYour Name 
24*5113495bSYour Name #include <wlan_cmn.h>
25*5113495bSYour Name #include <qdf_list.h>
26*5113495bSYour Name #include "../../core/src/wlan_scan_main.h"
27*5113495bSYour Name #include <wlan_scan_utils_api.h>
28*5113495bSYour Name #include <wlan_scan_ucfg_api.h>
29*5113495bSYour Name #include <wlan_scan_tgt_api.h>
30*5113495bSYour Name #include <wlan_objmgr_cmn.h>
31*5113495bSYour Name #include <wlan_lmac_if_def.h>
32*5113495bSYour Name #include <wlan_objmgr_psoc_obj.h>
33*5113495bSYour Name #include <wlan_objmgr_pdev_obj.h>
34*5113495bSYour Name #include <wlan_objmgr_vdev_obj.h>
35*5113495bSYour Name #include <../../core/src/wlan_scan_manager.h>
36*5113495bSYour Name 
37*5113495bSYour Name static inline struct wlan_lmac_if_scan_tx_ops *
wlan_psoc_get_scan_txops(struct wlan_objmgr_psoc * psoc)38*5113495bSYour Name wlan_psoc_get_scan_txops(struct wlan_objmgr_psoc *psoc)
39*5113495bSYour Name {
40*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
41*5113495bSYour Name 
42*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
43*5113495bSYour Name 	if (!tx_ops) {
44*5113495bSYour Name 		scm_err("tx_ops is NULL");
45*5113495bSYour Name 		return NULL;
46*5113495bSYour Name 	}
47*5113495bSYour Name 
48*5113495bSYour Name 	return &tx_ops->scan;
49*5113495bSYour Name }
50*5113495bSYour Name 
51*5113495bSYour Name static inline struct wlan_lmac_if_scan_tx_ops *
wlan_vdev_get_scan_txops(struct wlan_objmgr_vdev * vdev)52*5113495bSYour Name wlan_vdev_get_scan_txops(struct wlan_objmgr_vdev *vdev)
53*5113495bSYour Name {
54*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = NULL;
55*5113495bSYour Name 
56*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
57*5113495bSYour Name 	if (!psoc) {
58*5113495bSYour Name 		scm_err("NULL psoc");
59*5113495bSYour Name 		return NULL;
60*5113495bSYour Name 	}
61*5113495bSYour Name 
62*5113495bSYour Name 	return wlan_psoc_get_scan_txops(psoc);
63*5113495bSYour Name }
64*5113495bSYour Name 
65*5113495bSYour Name static inline struct wlan_lmac_if_scan_rx_ops *
wlan_vdev_get_scan_rxops(struct wlan_objmgr_vdev * vdev)66*5113495bSYour Name wlan_vdev_get_scan_rxops(struct wlan_objmgr_vdev *vdev)
67*5113495bSYour Name {
68*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = NULL;
69*5113495bSYour Name 	struct wlan_lmac_if_rx_ops *rx_ops;
70*5113495bSYour Name 
71*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
72*5113495bSYour Name 	if (!psoc) {
73*5113495bSYour Name 		scm_err("NULL psoc");
74*5113495bSYour Name 		return NULL;
75*5113495bSYour Name 	}
76*5113495bSYour Name 
77*5113495bSYour Name 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
78*5113495bSYour Name 	if (!rx_ops) {
79*5113495bSYour Name 		scm_err("rx_ops is NULL");
80*5113495bSYour Name 		return NULL;
81*5113495bSYour Name 	}
82*5113495bSYour Name 
83*5113495bSYour Name 	return &rx_ops->scan;
84*5113495bSYour Name }
85*5113495bSYour Name 
86*5113495bSYour Name #ifdef FEATURE_WLAN_SCAN_PNO
87*5113495bSYour Name 
tgt_scan_pno_start(struct wlan_objmgr_vdev * vdev,struct pno_scan_req_params * req)88*5113495bSYour Name QDF_STATUS tgt_scan_pno_start(struct wlan_objmgr_vdev *vdev,
89*5113495bSYour Name 	struct pno_scan_req_params *req)
90*5113495bSYour Name {
91*5113495bSYour Name 	struct wlan_lmac_if_scan_tx_ops *scan_ops;
92*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
93*5113495bSYour Name 
94*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
95*5113495bSYour Name 
96*5113495bSYour Name 	if (!psoc) {
97*5113495bSYour Name 		scm_err("NULL PSOC");
98*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
99*5113495bSYour Name 	}
100*5113495bSYour Name 	scan_ops = wlan_psoc_get_scan_txops(psoc);
101*5113495bSYour Name 	if (!scan_ops) {
102*5113495bSYour Name 		scm_err("NULL scan_ops");
103*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
104*5113495bSYour Name 	}
105*5113495bSYour Name 	/* invoke wmi_unified_pno_start_cmd() */
106*5113495bSYour Name 	QDF_ASSERT(scan_ops->pno_start);
107*5113495bSYour Name 	if (scan_ops->pno_start)
108*5113495bSYour Name 		return scan_ops->pno_start(psoc, req);
109*5113495bSYour Name 
110*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
111*5113495bSYour Name }
112*5113495bSYour Name 
tgt_scan_pno_stop(struct wlan_objmgr_vdev * vdev,uint8_t vdev_id)113*5113495bSYour Name QDF_STATUS tgt_scan_pno_stop(struct wlan_objmgr_vdev *vdev,
114*5113495bSYour Name 	uint8_t vdev_id)
115*5113495bSYour Name {
116*5113495bSYour Name 	struct wlan_lmac_if_scan_tx_ops *scan_ops;
117*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
118*5113495bSYour Name 
119*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
120*5113495bSYour Name 
121*5113495bSYour Name 	if (!psoc) {
122*5113495bSYour Name 		scm_err("NULL PSOC");
123*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
124*5113495bSYour Name 	}
125*5113495bSYour Name 	scan_ops = wlan_psoc_get_scan_txops(psoc);
126*5113495bSYour Name 	if (!scan_ops) {
127*5113495bSYour Name 		scm_err("NULL scan_ops");
128*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
129*5113495bSYour Name 	}
130*5113495bSYour Name 	/* invoke wmi_unified_pno_stop_cmd() */
131*5113495bSYour Name 	QDF_ASSERT(scan_ops->pno_stop);
132*5113495bSYour Name 	if (scan_ops->pno_stop)
133*5113495bSYour Name 		return scan_ops->pno_stop(psoc, vdev_id);
134*5113495bSYour Name 
135*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
136*5113495bSYour Name }
137*5113495bSYour Name #endif
138*5113495bSYour Name 
tgt_scan_obss_disable(struct wlan_objmgr_vdev * vdev)139*5113495bSYour Name QDF_STATUS tgt_scan_obss_disable(struct wlan_objmgr_vdev *vdev)
140*5113495bSYour Name {
141*5113495bSYour Name 	struct wlan_lmac_if_scan_tx_ops *scan_ops;
142*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
143*5113495bSYour Name 	uint8_t vdev_id;
144*5113495bSYour Name 
145*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
146*5113495bSYour Name 
147*5113495bSYour Name 	if (!psoc) {
148*5113495bSYour Name 		scm_err("NULL PSOC");
149*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
150*5113495bSYour Name 	}
151*5113495bSYour Name 	scan_ops = wlan_psoc_get_scan_txops(psoc);
152*5113495bSYour Name 	if (!scan_ops) {
153*5113495bSYour Name 		scm_err("NULL scan_ops");
154*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
155*5113495bSYour Name 	}
156*5113495bSYour Name 
157*5113495bSYour Name 	vdev_id = wlan_vdev_get_id(vdev);
158*5113495bSYour Name 
159*5113495bSYour Name 	/* invoke wmi_unified_obss_disable_cmd() */
160*5113495bSYour Name 	QDF_ASSERT(scan_ops->obss_disable);
161*5113495bSYour Name 	if (scan_ops->obss_disable)
162*5113495bSYour Name 		return scan_ops->obss_disable(psoc, vdev_id);
163*5113495bSYour Name 
164*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
165*5113495bSYour Name }
166*5113495bSYour Name 
167*5113495bSYour Name QDF_STATUS
tgt_scan_start(struct scan_start_request * req)168*5113495bSYour Name tgt_scan_start(struct scan_start_request *req)
169*5113495bSYour Name {
170*5113495bSYour Name 	struct wlan_lmac_if_scan_tx_ops *scan_ops;
171*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
172*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
173*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev = req->vdev;
174*5113495bSYour Name 
175*5113495bSYour Name 	if (!vdev) {
176*5113495bSYour Name 		scm_err("vdev is NULL");
177*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
178*5113495bSYour Name 	}
179*5113495bSYour Name 
180*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
181*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
182*5113495bSYour Name 	if (!psoc || !pdev) {
183*5113495bSYour Name 		scm_err("psoc: 0x%pK or pdev: 0x%pK is NULL", psoc, pdev);
184*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
185*5113495bSYour Name 	}
186*5113495bSYour Name 
187*5113495bSYour Name 	scan_ops = wlan_psoc_get_scan_txops(psoc);
188*5113495bSYour Name 	if (!scan_ops) {
189*5113495bSYour Name 		scm_err("NULL scan_ops");
190*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
191*5113495bSYour Name 	}
192*5113495bSYour Name 
193*5113495bSYour Name 	/* invoke wmi_unified_scan_start_cmd_send() */
194*5113495bSYour Name 	QDF_ASSERT(scan_ops->scan_start);
195*5113495bSYour Name 	if (scan_ops->scan_start)
196*5113495bSYour Name 		return scan_ops->scan_start(pdev, req);
197*5113495bSYour Name 	else
198*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
199*5113495bSYour Name }
200*5113495bSYour Name 
201*5113495bSYour Name 
202*5113495bSYour Name QDF_STATUS
tgt_scan_cancel(struct scan_cancel_request * req)203*5113495bSYour Name tgt_scan_cancel(struct scan_cancel_request *req)
204*5113495bSYour Name {
205*5113495bSYour Name 	struct wlan_lmac_if_scan_tx_ops *scan_ops;
206*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
207*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
208*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev = req->vdev;
209*5113495bSYour Name 
210*5113495bSYour Name 	if (!vdev) {
211*5113495bSYour Name 		scm_err("vdev is NULL");
212*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
213*5113495bSYour Name 	}
214*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
215*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
216*5113495bSYour Name 	if (!psoc || !pdev) {
217*5113495bSYour Name 		scm_err("psoc: 0x%pK or pdev: 0x%pK is NULL", psoc, pdev);
218*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
219*5113495bSYour Name 	}
220*5113495bSYour Name 	scan_ops = wlan_psoc_get_scan_txops(psoc);
221*5113495bSYour Name 	if (!scan_ops) {
222*5113495bSYour Name 		scm_err("NULL scan_ops");
223*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
224*5113495bSYour Name 	}
225*5113495bSYour Name 
226*5113495bSYour Name 	/* invoke wmi_unified_scan_stop_cmd_send() */
227*5113495bSYour Name 	QDF_ASSERT(scan_ops->scan_cancel);
228*5113495bSYour Name 	if (scan_ops->scan_cancel)
229*5113495bSYour Name 		return scan_ops->scan_cancel(pdev, &req->cancel_req);
230*5113495bSYour Name 	else
231*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
232*5113495bSYour Name }
233*5113495bSYour Name 
234*5113495bSYour Name QDF_STATUS
tgt_scan_register_ev_handler(struct wlan_objmgr_psoc * psoc)235*5113495bSYour Name tgt_scan_register_ev_handler(struct wlan_objmgr_psoc *psoc)
236*5113495bSYour Name {
237*5113495bSYour Name 	struct wlan_lmac_if_scan_tx_ops *scan_ops = NULL;
238*5113495bSYour Name 
239*5113495bSYour Name 	scan_ops = wlan_psoc_get_scan_txops(psoc);
240*5113495bSYour Name 	if (!scan_ops) {
241*5113495bSYour Name 		scm_err("NULL scan_ops");
242*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
243*5113495bSYour Name 	}
244*5113495bSYour Name 
245*5113495bSYour Name 	/* invoke wmi_unified_register_event_handler()
246*5113495bSYour Name 	 * since event id, handler function and context is
247*5113495bSYour Name 	 * already known to offload lmac, passing NULL as argument.
248*5113495bSYour Name 	 * DA can pass necessary arguments by clubing then into
249*5113495bSYour Name 	 * some structure.
250*5113495bSYour Name 	 */
251*5113495bSYour Name 	QDF_ASSERT(scan_ops->scan_reg_ev_handler);
252*5113495bSYour Name 	if (scan_ops->scan_reg_ev_handler)
253*5113495bSYour Name 		return scan_ops->scan_reg_ev_handler(psoc, NULL);
254*5113495bSYour Name 	else
255*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
256*5113495bSYour Name }
257*5113495bSYour Name 
258*5113495bSYour Name QDF_STATUS
tgt_scan_unregister_ev_handler(struct wlan_objmgr_psoc * psoc)259*5113495bSYour Name tgt_scan_unregister_ev_handler(struct wlan_objmgr_psoc *psoc)
260*5113495bSYour Name {
261*5113495bSYour Name 	struct wlan_lmac_if_scan_tx_ops *scan_ops = NULL;
262*5113495bSYour Name 
263*5113495bSYour Name 	scan_ops = wlan_psoc_get_scan_txops(psoc);
264*5113495bSYour Name 	if (!scan_ops) {
265*5113495bSYour Name 		scm_err("NULL scan_ops");
266*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
267*5113495bSYour Name 	}
268*5113495bSYour Name 
269*5113495bSYour Name 	/* invoke wmi_unified_register_event_handler()
270*5113495bSYour Name 	 * since event id, handler function and context is
271*5113495bSYour Name 	 * already known to offload lmac, passing NULL as argument.
272*5113495bSYour Name 	 * DA can pass necessary arguments by clubing then into
273*5113495bSYour Name 	 * some structure.
274*5113495bSYour Name 	 */
275*5113495bSYour Name 	QDF_ASSERT(scan_ops->scan_unreg_ev_handler);
276*5113495bSYour Name 	if (scan_ops->scan_unreg_ev_handler)
277*5113495bSYour Name 		return scan_ops->scan_unreg_ev_handler(psoc, NULL);
278*5113495bSYour Name 	else
279*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
280*5113495bSYour Name }
281*5113495bSYour Name 
282*5113495bSYour Name QDF_STATUS
tgt_scan_event_handler(struct wlan_objmgr_psoc * psoc,struct scan_event_info * event_info)283*5113495bSYour Name tgt_scan_event_handler(struct wlan_objmgr_psoc *psoc,
284*5113495bSYour Name 		struct scan_event_info *event_info)
285*5113495bSYour Name {
286*5113495bSYour Name 	struct scheduler_msg msg = {0};
287*5113495bSYour Name 	struct scan_event *event = &event_info->event;
288*5113495bSYour Name 	uint8_t vdev_id = event->vdev_id;
289*5113495bSYour Name 	QDF_STATUS status;
290*5113495bSYour Name 
291*5113495bSYour Name 	if (!psoc || !event_info) {
292*5113495bSYour Name 		scm_err("psoc: 0x%pK, event_info: 0x%pK", psoc, event_info);
293*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
294*5113495bSYour Name 	}
295*5113495bSYour Name 
296*5113495bSYour Name 	event_info->vdev =
297*5113495bSYour Name 		wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
298*5113495bSYour Name 				vdev_id, WLAN_SCAN_ID);
299*5113495bSYour Name 	if (!event_info->vdev) {
300*5113495bSYour Name 		scm_err("null vdev, vdev_id: %d, psoc: 0x%pK", vdev_id, psoc);
301*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
302*5113495bSYour Name 	}
303*5113495bSYour Name 	msg.bodyptr = event_info;
304*5113495bSYour Name 	msg.callback = scm_scan_event_handler;
305*5113495bSYour Name 	msg.flush_callback = scm_scan_event_flush_callback;
306*5113495bSYour Name 
307*5113495bSYour Name 	status = scheduler_post_message(QDF_MODULE_ID_SCAN,
308*5113495bSYour Name 					QDF_MODULE_ID_SCAN,
309*5113495bSYour Name 					QDF_MODULE_ID_SCAN, &msg);
310*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
311*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(event_info->vdev, WLAN_SCAN_ID);
312*5113495bSYour Name 	}
313*5113495bSYour Name 
314*5113495bSYour Name 	return status;
315*5113495bSYour Name }
316*5113495bSYour Name 
tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_peer * peer,qdf_nbuf_t buf,struct mgmt_rx_event_params * rx_param,enum mgmt_frame_type frm_type)317*5113495bSYour Name QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc,
318*5113495bSYour Name 	struct wlan_objmgr_peer *peer, qdf_nbuf_t buf,
319*5113495bSYour Name 	struct mgmt_rx_event_params *rx_param,
320*5113495bSYour Name 	enum mgmt_frame_type frm_type)
321*5113495bSYour Name {
322*5113495bSYour Name 	struct scheduler_msg msg = {0};
323*5113495bSYour Name 	struct scan_bcn_probe_event *bcn = NULL;
324*5113495bSYour Name 	QDF_STATUS status;
325*5113495bSYour Name 	uint32_t scan_queue_size = 0;
326*5113495bSYour Name 
327*5113495bSYour Name 	if ((frm_type != MGMT_PROBE_RESP) &&
328*5113495bSYour Name 	    (frm_type != MGMT_BEACON)) {
329*5113495bSYour Name 		scm_err("frame is not beacon or probe resp");
330*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
331*5113495bSYour Name 		goto free;
332*5113495bSYour Name 	}
333*5113495bSYour Name 
334*5113495bSYour Name 	bcn = qdf_mem_malloc_atomic(sizeof(*bcn));
335*5113495bSYour Name 	if (!bcn) {
336*5113495bSYour Name 		status = QDF_STATUS_E_NOMEM;
337*5113495bSYour Name 		goto free;
338*5113495bSYour Name 	}
339*5113495bSYour Name 	bcn->rx_data =
340*5113495bSYour Name 		qdf_mem_malloc_atomic(sizeof(*rx_param));
341*5113495bSYour Name 	if (!bcn->rx_data) {
342*5113495bSYour Name 		status = QDF_STATUS_E_NOMEM;
343*5113495bSYour Name 		goto free;
344*5113495bSYour Name 	}
345*5113495bSYour Name 
346*5113495bSYour Name 	if (frm_type == MGMT_PROBE_RESP)
347*5113495bSYour Name 		bcn->frm_type = MGMT_SUBTYPE_PROBE_RESP;
348*5113495bSYour Name 	else
349*5113495bSYour Name 		bcn->frm_type = MGMT_SUBTYPE_BEACON;
350*5113495bSYour Name 
351*5113495bSYour Name 	/* Check if the beacon/probe frame can be posted in the scan queue */
352*5113495bSYour Name 	status = scheduler_get_queue_size(QDF_MODULE_ID_SCAN, &scan_queue_size);
353*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(status) ||
354*5113495bSYour Name 	    scan_queue_size > MAX_BCN_PROBE_IN_SCAN_QUEUE) {
355*5113495bSYour Name 		scm_debug_rl("Dropping beacon/probe frame, queue size %d",
356*5113495bSYour Name 			     scan_queue_size);
357*5113495bSYour Name 		status = QDF_STATUS_E_FAILURE;
358*5113495bSYour Name 		goto free;
359*5113495bSYour Name 	}
360*5113495bSYour Name 
361*5113495bSYour Name 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID);
362*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
363*5113495bSYour Name 		scm_info("unable to get reference");
364*5113495bSYour Name 		goto free;
365*5113495bSYour Name 	}
366*5113495bSYour Name 
367*5113495bSYour Name 	bcn->psoc = psoc;
368*5113495bSYour Name 	bcn->buf = buf;
369*5113495bSYour Name 	bcn->save_rnr_info = false;
370*5113495bSYour Name 	qdf_mem_copy(bcn->rx_data, rx_param, sizeof(*rx_param));
371*5113495bSYour Name 
372*5113495bSYour Name 	msg.bodyptr = bcn;
373*5113495bSYour Name 	msg.callback = scm_handle_bcn_probe;
374*5113495bSYour Name 	msg.flush_callback = scm_bcn_probe_flush_callback;
375*5113495bSYour Name 
376*5113495bSYour Name 	status = scheduler_post_message(QDF_MODULE_ID_SCAN,
377*5113495bSYour Name 					QDF_MODULE_ID_SCAN,
378*5113495bSYour Name 					QDF_MODULE_ID_SCAN, &msg);
379*5113495bSYour Name 
380*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(status))
381*5113495bSYour Name 		return status;
382*5113495bSYour Name 
383*5113495bSYour Name 	wlan_objmgr_psoc_release_ref(psoc, WLAN_SCAN_ID);
384*5113495bSYour Name 
385*5113495bSYour Name free:
386*5113495bSYour Name 	if (bcn && bcn->rx_data)
387*5113495bSYour Name 		qdf_mem_free(bcn->rx_data);
388*5113495bSYour Name 	if (bcn)
389*5113495bSYour Name 		qdf_mem_free(bcn);
390*5113495bSYour Name 	if (buf)
391*5113495bSYour Name 		qdf_nbuf_free(buf);
392*5113495bSYour Name 
393*5113495bSYour Name 	return status;
394*5113495bSYour Name }
395*5113495bSYour Name 
396*5113495bSYour Name QDF_STATUS
tgt_scan_set_max_active_scans(struct wlan_objmgr_psoc * psoc,uint32_t max_active_scans)397*5113495bSYour Name tgt_scan_set_max_active_scans(struct wlan_objmgr_psoc *psoc,
398*5113495bSYour Name 		uint32_t max_active_scans)
399*5113495bSYour Name {
400*5113495bSYour Name 	struct scan_default_params *scan_params = NULL;
401*5113495bSYour Name 
402*5113495bSYour Name 	if (!psoc) {
403*5113495bSYour Name 		scm_err("null psoc");
404*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
405*5113495bSYour Name 	}
406*5113495bSYour Name 
407*5113495bSYour Name 	scan_params = wlan_scan_psoc_get_def_params(psoc);
408*5113495bSYour Name 	if (!scan_params) {
409*5113495bSYour Name 		scm_err("wlan_scan_psoc_get_def_params returned NULL");
410*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
411*5113495bSYour Name 	}
412*5113495bSYour Name 
413*5113495bSYour Name 	scan_params->max_active_scans_allowed = max_active_scans;
414*5113495bSYour Name 
415*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
416*5113495bSYour Name }
417