xref: /wlan-dirver/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_utils_api.c (revision 6d768494e5ce14eb1603a695c86739d12ecc6ec2)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  *
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 #include <wlan_spectral_utils_api.h>
21 #include <qdf_module.h>
22 #include "../../core/spectral_cmn_api_i.h"
23 #include <wlan_spectral_tgt_api.h>
24 #include <cfg_ucfg_api.h>
25 
26 bool wlan_spectral_is_feature_disabled(struct wlan_objmgr_psoc *psoc)
27 {
28 	if (!psoc) {
29 		spectral_err("PSOC is NULL!");
30 		return true;
31 	}
32 
33 	if (wlan_psoc_nif_feat_cap_get(psoc, WLAN_SOC_F_SPECTRAL_DISABLE))
34 		return true;
35 
36 	return false;
37 }
38 
39 QDF_STATUS
40 wlan_spectral_init(void)
41 {
42 	if (wlan_objmgr_register_psoc_create_handler(
43 		WLAN_UMAC_COMP_SPECTRAL,
44 		wlan_spectral_psoc_obj_create_handler,
45 		NULL) !=
46 	    QDF_STATUS_SUCCESS) {
47 		return QDF_STATUS_E_FAILURE;
48 	}
49 	if (wlan_objmgr_register_psoc_destroy_handler(
50 		WLAN_UMAC_COMP_SPECTRAL,
51 		wlan_spectral_psoc_obj_destroy_handler,
52 		NULL) !=
53 	    QDF_STATUS_SUCCESS) {
54 		return QDF_STATUS_E_FAILURE;
55 	}
56 	if (wlan_objmgr_register_pdev_create_handler(
57 		WLAN_UMAC_COMP_SPECTRAL,
58 		wlan_spectral_pdev_obj_create_handler,
59 		NULL) !=
60 	    QDF_STATUS_SUCCESS) {
61 		return QDF_STATUS_E_FAILURE;
62 	}
63 	if (wlan_objmgr_register_pdev_destroy_handler(
64 		WLAN_UMAC_COMP_SPECTRAL,
65 		wlan_spectral_pdev_obj_destroy_handler,
66 		NULL) !=
67 	    QDF_STATUS_SUCCESS) {
68 		return QDF_STATUS_E_FAILURE;
69 	}
70 
71 	return QDF_STATUS_SUCCESS;
72 }
73 
74 QDF_STATUS
75 wlan_spectral_deinit(void)
76 {
77 	if (wlan_objmgr_unregister_psoc_create_handler(
78 		WLAN_UMAC_COMP_SPECTRAL,
79 		wlan_spectral_psoc_obj_create_handler,
80 		NULL) !=
81 	    QDF_STATUS_SUCCESS) {
82 		return QDF_STATUS_E_FAILURE;
83 	}
84 	if (wlan_objmgr_unregister_psoc_destroy_handler(
85 		WLAN_UMAC_COMP_SPECTRAL,
86 		wlan_spectral_psoc_obj_destroy_handler,
87 		NULL) !=
88 	    QDF_STATUS_SUCCESS) {
89 		return QDF_STATUS_E_FAILURE;
90 	}
91 	if (wlan_objmgr_unregister_pdev_create_handler(
92 		WLAN_UMAC_COMP_SPECTRAL,
93 		wlan_spectral_pdev_obj_create_handler,
94 		NULL) !=
95 	    QDF_STATUS_SUCCESS) {
96 		return QDF_STATUS_E_FAILURE;
97 	}
98 	if (wlan_objmgr_unregister_pdev_destroy_handler(
99 		WLAN_UMAC_COMP_SPECTRAL,
100 		wlan_spectral_pdev_obj_destroy_handler,
101 		NULL) !=
102 	    QDF_STATUS_SUCCESS) {
103 		return QDF_STATUS_E_FAILURE;
104 	}
105 	return QDF_STATUS_SUCCESS;
106 }
107 
108 QDF_STATUS
109 spectral_register_legacy_cb(struct wlan_objmgr_psoc *psoc,
110 			    struct spectral_legacy_cbacks *legacy_cbacks)
111 {
112 	struct spectral_context *sc;
113 
114 	sc = spectral_get_spectral_ctx_from_psoc(psoc);
115 	if (!sc) {
116 		spectral_err("Invalid Context");
117 		return QDF_STATUS_E_FAILURE;
118 	}
119 
120 	sc->legacy_cbacks.vdev_get_chan_freq =
121 	    legacy_cbacks->vdev_get_chan_freq;
122 	sc->legacy_cbacks.vdev_get_chan_freq_seg2 =
123 	    legacy_cbacks->vdev_get_chan_freq_seg2;
124 	sc->legacy_cbacks.vdev_get_ch_width = legacy_cbacks->vdev_get_ch_width;
125 	sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz =
126 	    legacy_cbacks->vdev_get_sec20chan_freq_mhz;
127 
128 	return QDF_STATUS_SUCCESS;
129 }
130 qdf_export_symbol(spectral_register_legacy_cb);
131 
132 int16_t
133 spectral_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev)
134 {
135 	struct spectral_context *sc;
136 
137 	sc = spectral_get_spectral_ctx_from_vdev(vdev);
138 	if (!sc) {
139 		spectral_err("spectral context is Null");
140 		return -EINVAL;
141 	}
142 
143 	return sc->legacy_cbacks.vdev_get_chan_freq(vdev);
144 }
145 
146 int16_t
147 spectral_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev)
148 {
149 	struct spectral_context *sc;
150 
151 	sc = spectral_get_spectral_ctx_from_vdev(vdev);
152 	if (!sc) {
153 		spectral_err("spectral context is null");
154 		return -EINVAL;
155 	}
156 
157 	return sc->legacy_cbacks.vdev_get_chan_freq_seg2(vdev);
158 }
159 
160 enum phy_ch_width
161 spectral_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev)
162 {
163 	struct spectral_context *sc;
164 
165 	sc = spectral_get_spectral_ctx_from_vdev(vdev);
166 	if (!sc) {
167 		spectral_err("spectral context is Null");
168 		return CH_WIDTH_INVALID;
169 	}
170 
171 	return sc->legacy_cbacks.vdev_get_ch_width(vdev);
172 }
173 
174 int
175 spectral_vdev_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
176 				     uint16_t *sec20chan_freq)
177 {
178 	struct spectral_context *sc;
179 
180 	sc = spectral_get_spectral_ctx_from_vdev(vdev);
181 	if (!sc) {
182 		spectral_err("spectral context is Null");
183 		return -EINVAL;
184 	}
185 
186 	return sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz(vdev,
187 							     sec20chan_freq);
188 }
189 
190 void
191 wlan_lmac_if_sptrl_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
192 {
193 	struct wlan_lmac_if_sptrl_rx_ops *sptrl_rx_ops = &rx_ops->sptrl_rx_ops;
194 
195 	/* Spectral rx ops */
196 	sptrl_rx_ops->sptrlro_get_pdev_target_handle =
197 					tgt_get_pdev_target_handle;
198 	sptrl_rx_ops->sptrlro_get_psoc_target_handle =
199 					tgt_get_psoc_target_handle;
200 	sptrl_rx_ops->sptrlro_vdev_get_chan_freq = spectral_vdev_get_chan_freq;
201 	sptrl_rx_ops->sptrlro_vdev_get_chan_freq_seg2 =
202 					spectral_vdev_get_chan_freq_seg2;
203 	sptrl_rx_ops->sptrlro_vdev_get_ch_width = spectral_vdev_get_ch_width;
204 	sptrl_rx_ops->sptrlro_vdev_get_sec20chan_freq_mhz =
205 	    spectral_vdev_get_sec20chan_freq_mhz;
206 	sptrl_rx_ops->sptrlro_spectral_is_feature_disabled =
207 		wlan_spectral_is_feature_disabled;
208 }
209 
210 QDF_STATUS
211 wlan_register_spectral_wmi_ops(struct wlan_objmgr_psoc *psoc,
212 			       struct spectral_wmi_ops *wmi_ops)
213 {
214 	struct spectral_context *sc;
215 
216 	if (!psoc) {
217 		spectral_err("psoc is NULL!");
218 		return QDF_STATUS_E_INVAL;
219 	}
220 
221 	sc = spectral_get_spectral_ctx_from_psoc(psoc);
222 	if (!sc) {
223 		spectral_err("spectral context is NULL!");
224 		return QDF_STATUS_E_FAILURE;
225 	}
226 
227 	return sc->sptrlc_register_spectral_wmi_ops(psoc, wmi_ops);
228 }
229 
230 qdf_export_symbol(wlan_register_spectral_wmi_ops);
231 
232 QDF_STATUS
233 wlan_register_spectral_tgt_ops(struct wlan_objmgr_psoc *psoc,
234 			       struct spectral_tgt_ops *tgt_ops)
235 {
236 	struct spectral_context *sc;
237 
238 	if (!psoc) {
239 		spectral_err("psoc is NULL!");
240 		return QDF_STATUS_E_INVAL;
241 	}
242 
243 	sc = spectral_get_spectral_ctx_from_psoc(psoc);
244 	if (!sc) {
245 		spectral_err("spectral context is NULL!");
246 		return QDF_STATUS_E_FAILURE;
247 	}
248 
249 	return sc->sptrlc_register_spectral_tgt_ops(psoc, tgt_ops);
250 }
251 
252 qdf_export_symbol(wlan_register_spectral_tgt_ops);
253 
254 /**
255  * wlan_spectral_psoc_target_attach() - Spectral psoc target attach
256  * @psoc:  pointer to psoc object
257  *
258  * API to initialize Spectral psoc target object
259  *
260  * Return: QDF_STATUS_SUCCESS upon successful registration,
261  *         QDF_STATUS_E_FAILURE upon failure
262  */
263 static QDF_STATUS
264 wlan_spectral_psoc_target_attach(struct wlan_objmgr_psoc *psoc)
265 {
266 	struct spectral_context *sc = NULL;
267 
268 	if (!psoc) {
269 		spectral_err("psoc is null");
270 		return QDF_STATUS_E_FAILURE;
271 	}
272 
273 	sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
274 						   WLAN_UMAC_COMP_SPECTRAL);
275 	if (!sc) {
276 		spectral_err("Spectral context is null");
277 		return QDF_STATUS_E_NOMEM;
278 	}
279 
280 	if (sc->sptrlc_psoc_spectral_init) {
281 		void *target_handle;
282 
283 		target_handle = sc->sptrlc_psoc_spectral_init(psoc);
284 		if (!target_handle) {
285 			spectral_err("Spectral psoc lmac object is NULL!");
286 			return QDF_STATUS_E_FAILURE;
287 		}
288 		sc->psoc_target_handle = target_handle;
289 	}
290 
291 	return QDF_STATUS_SUCCESS;
292 }
293 
294 /**
295  * wlan_spectral_psoc_target_detach() - Spectral psoc target detach
296  * @psoc:  pointer to psoc object
297  *
298  * API to destroy Spectral psoc target object
299  *
300  * Return: QDF_STATUS_SUCCESS upon successful registration,
301  *         QDF_STATUS_E_FAILURE upon failure
302  */
303 static QDF_STATUS
304 wlan_spectral_psoc_target_detach(struct wlan_objmgr_psoc *psoc)
305 {
306 	struct spectral_context *sc = NULL;
307 
308 	if (!psoc) {
309 		spectral_err("psoc is null");
310 		return QDF_STATUS_E_FAILURE;
311 	}
312 
313 	sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
314 						   WLAN_UMAC_COMP_SPECTRAL);
315 	if (!sc) {
316 		spectral_err("Spectral context is null");
317 		return QDF_STATUS_E_INVAL;
318 	}
319 
320 	if (sc->sptrlc_psoc_spectral_deinit)
321 		sc->sptrlc_psoc_spectral_deinit(psoc);
322 	sc->psoc_target_handle = NULL;
323 
324 	return QDF_STATUS_SUCCESS;
325 }
326 
327 #ifdef DIRECT_BUF_RX_ENABLE
328 bool spectral_dbr_event_handler(struct wlan_objmgr_pdev *pdev,
329 				struct direct_buf_rx_data *payload)
330 {
331 	struct spectral_context *sc;
332 
333 	if (!pdev) {
334 		spectral_err("PDEV is NULL!");
335 		return -EINVAL;
336 	}
337 	sc = spectral_get_spectral_ctx_from_pdev(pdev);
338 	if (!sc) {
339 		spectral_err("spectral context is NULL!");
340 		return -EINVAL;
341 	}
342 
343 	sc->sptrlc_process_spectral_report(pdev, payload);
344 
345 	return true;
346 }
347 #endif
348 
349 QDF_STATUS spectral_pdev_open(struct wlan_objmgr_pdev *pdev)
350 {
351 	struct wlan_objmgr_psoc *psoc;
352 	QDF_STATUS status;
353 
354 	psoc = wlan_pdev_get_psoc(pdev);
355 
356 	if (wlan_spectral_is_feature_disabled(psoc)) {
357 		spectral_info("Spectral is disabled");
358 		return QDF_STATUS_COMP_DISABLED;
359 	}
360 
361 	if (cfg_get(psoc, CFG_SPECTRAL_POISON_BUFS))
362 		tgt_set_spectral_dma_debug(pdev, SPECTRAL_DMA_BUFFER_DEBUG, 1);
363 
364 	status = tgt_spectral_register_to_dbr(pdev);
365 	return QDF_STATUS_SUCCESS;
366 }
367 
368 QDF_STATUS spectral_register_dbr(struct wlan_objmgr_pdev *pdev)
369 {
370 	return tgt_spectral_register_to_dbr(pdev);
371 }
372 
373 qdf_export_symbol(spectral_register_dbr);
374 
375 QDF_STATUS spectral_unregister_dbr(struct wlan_objmgr_pdev *pdev)
376 {
377 	QDF_STATUS status;
378 
379 	status = tgt_spectral_unregister_to_dbr(pdev);
380 
381 	return status;
382 }
383 
384 qdf_export_symbol(spectral_unregister_dbr);
385 
386 QDF_STATUS wlan_spectral_psoc_open(struct wlan_objmgr_psoc *psoc)
387 {
388 	if (!psoc) {
389 		spectral_err("psoc is null");
390 		return QDF_STATUS_E_INVAL;
391 	}
392 
393 	if (wlan_spectral_is_feature_disabled(psoc)) {
394 		spectral_info("Spectral is disabled");
395 		return QDF_STATUS_COMP_DISABLED;
396 	}
397 
398 	return wlan_spectral_psoc_target_attach(psoc);
399 }
400 
401 QDF_STATUS wlan_spectral_psoc_close(struct wlan_objmgr_psoc *psoc)
402 {
403 	if (!psoc) {
404 		spectral_err("psoc is null");
405 		return QDF_STATUS_E_INVAL;
406 	}
407 
408 	if (wlan_spectral_is_feature_disabled(psoc)) {
409 		spectral_info("Spectral is disabled");
410 		return QDF_STATUS_COMP_DISABLED;
411 	}
412 
413 	return wlan_spectral_psoc_target_detach(psoc);
414 }
415 
416 QDF_STATUS wlan_spectral_psoc_enable(struct wlan_objmgr_psoc *psoc)
417 {
418 	if (!psoc) {
419 		spectral_err("psoc is null");
420 		return QDF_STATUS_E_INVAL;
421 	}
422 
423 	if (wlan_spectral_is_feature_disabled(psoc)) {
424 		spectral_info("Spectral is disabled");
425 		return QDF_STATUS_COMP_DISABLED;
426 	}
427 
428 	return tgt_spectral_register_events(psoc);
429 }
430 
431 QDF_STATUS wlan_spectral_psoc_disable(struct wlan_objmgr_psoc *psoc)
432 {
433 	if (!psoc) {
434 		spectral_err("psoc is null");
435 		return QDF_STATUS_E_INVAL;
436 	}
437 
438 	if (wlan_spectral_is_feature_disabled(psoc)) {
439 		spectral_info("Spectral is disabled");
440 		return QDF_STATUS_COMP_DISABLED;
441 	}
442 
443 	return tgt_spectral_unregister_events(psoc);
444 }
445