xref: /wlan-dirver/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_utils_api.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
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 	if (!sc->legacy_cbacks.vdev_get_chan_freq) {
144 		spectral_err("vdev_get_chan_freq is not supported");
145 		return -ENOTSUPP;
146 	}
147 
148 	return sc->legacy_cbacks.vdev_get_chan_freq(vdev);
149 }
150 
151 int16_t
152 spectral_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev)
153 {
154 	struct spectral_context *sc;
155 
156 	sc = spectral_get_spectral_ctx_from_vdev(vdev);
157 	if (!sc) {
158 		spectral_err("spectral context is null");
159 		return -EINVAL;
160 	}
161 
162 	if (!sc->legacy_cbacks.vdev_get_chan_freq_seg2) {
163 		spectral_err("vdev_get_chan_freq_seg2 is not supported");
164 		return -ENOTSUPP;
165 	}
166 
167 	return sc->legacy_cbacks.vdev_get_chan_freq_seg2(vdev);
168 }
169 
170 enum phy_ch_width
171 spectral_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev)
172 {
173 	struct spectral_context *sc;
174 
175 	sc = spectral_get_spectral_ctx_from_vdev(vdev);
176 	if (!sc) {
177 		spectral_err("spectral context is Null");
178 		return CH_WIDTH_INVALID;
179 	}
180 
181 	if (!sc->legacy_cbacks.vdev_get_ch_width) {
182 		spectral_err("vdev_get_ch_width is not supported");
183 		return -ENOTSUPP;
184 	}
185 
186 	return sc->legacy_cbacks.vdev_get_ch_width(vdev);
187 }
188 
189 int
190 spectral_vdev_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
191 				     uint16_t *sec20chan_freq)
192 {
193 	struct spectral_context *sc;
194 
195 	sc = spectral_get_spectral_ctx_from_vdev(vdev);
196 	if (!sc) {
197 		spectral_err("spectral context is Null");
198 		return -EINVAL;
199 	}
200 
201 	if (!sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz) {
202 		spectral_err("vdev_get_sec20chan_freq_mhz is not supported");
203 		return -ENOTSUPP;
204 	}
205 
206 	return sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz(vdev,
207 							     sec20chan_freq);
208 }
209 
210 void
211 wlan_lmac_if_sptrl_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
212 {
213 	struct wlan_lmac_if_sptrl_rx_ops *sptrl_rx_ops = &rx_ops->sptrl_rx_ops;
214 
215 	/* Spectral rx ops */
216 	sptrl_rx_ops->sptrlro_get_pdev_target_handle =
217 					tgt_get_pdev_target_handle;
218 	sptrl_rx_ops->sptrlro_get_psoc_target_handle =
219 					tgt_get_psoc_target_handle;
220 	sptrl_rx_ops->sptrlro_vdev_get_chan_freq = spectral_vdev_get_chan_freq;
221 	sptrl_rx_ops->sptrlro_vdev_get_chan_freq_seg2 =
222 					spectral_vdev_get_chan_freq_seg2;
223 	sptrl_rx_ops->sptrlro_vdev_get_ch_width = spectral_vdev_get_ch_width;
224 	sptrl_rx_ops->sptrlro_vdev_get_sec20chan_freq_mhz =
225 	    spectral_vdev_get_sec20chan_freq_mhz;
226 	sptrl_rx_ops->sptrlro_spectral_is_feature_disabled =
227 		wlan_spectral_is_feature_disabled;
228 }
229 
230 QDF_STATUS
231 wlan_register_spectral_wmi_ops(struct wlan_objmgr_psoc *psoc,
232 			       struct spectral_wmi_ops *wmi_ops)
233 {
234 	struct spectral_context *sc;
235 
236 	if (!psoc) {
237 		spectral_err("psoc is NULL!");
238 		return QDF_STATUS_E_INVAL;
239 	}
240 
241 	sc = spectral_get_spectral_ctx_from_psoc(psoc);
242 	if (!sc) {
243 		spectral_err("spectral context is NULL!");
244 		return QDF_STATUS_E_FAILURE;
245 	}
246 
247 	return sc->sptrlc_register_spectral_wmi_ops(psoc, wmi_ops);
248 }
249 
250 qdf_export_symbol(wlan_register_spectral_wmi_ops);
251 
252 QDF_STATUS
253 wlan_register_spectral_tgt_ops(struct wlan_objmgr_psoc *psoc,
254 			       struct spectral_tgt_ops *tgt_ops)
255 {
256 	struct spectral_context *sc;
257 
258 	if (!psoc) {
259 		spectral_err("psoc is NULL!");
260 		return QDF_STATUS_E_INVAL;
261 	}
262 
263 	sc = spectral_get_spectral_ctx_from_psoc(psoc);
264 	if (!sc) {
265 		spectral_err("spectral context is NULL!");
266 		return QDF_STATUS_E_FAILURE;
267 	}
268 
269 	return sc->sptrlc_register_spectral_tgt_ops(psoc, tgt_ops);
270 }
271 
272 qdf_export_symbol(wlan_register_spectral_tgt_ops);
273 
274 /**
275  * wlan_spectral_psoc_target_attach() - Spectral psoc target attach
276  * @psoc:  pointer to psoc object
277  *
278  * API to initialize Spectral psoc target object
279  *
280  * Return: QDF_STATUS_SUCCESS upon successful registration,
281  *         QDF_STATUS_E_FAILURE upon failure
282  */
283 static QDF_STATUS
284 wlan_spectral_psoc_target_attach(struct wlan_objmgr_psoc *psoc)
285 {
286 	struct spectral_context *sc = NULL;
287 
288 	if (!psoc) {
289 		spectral_err("psoc is null");
290 		return QDF_STATUS_E_FAILURE;
291 	}
292 
293 	sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
294 						   WLAN_UMAC_COMP_SPECTRAL);
295 	if (!sc) {
296 		spectral_err("Spectral context is null");
297 		return QDF_STATUS_E_NOMEM;
298 	}
299 
300 	if (sc->sptrlc_psoc_spectral_init) {
301 		void *target_handle;
302 
303 		target_handle = sc->sptrlc_psoc_spectral_init(psoc);
304 		if (!target_handle) {
305 			spectral_err("Spectral psoc lmac object is NULL!");
306 			return QDF_STATUS_E_FAILURE;
307 		}
308 		sc->psoc_target_handle = target_handle;
309 	}
310 
311 	return QDF_STATUS_SUCCESS;
312 }
313 
314 /**
315  * wlan_spectral_psoc_target_detach() - Spectral psoc target detach
316  * @psoc:  pointer to psoc object
317  *
318  * API to destroy Spectral psoc target object
319  *
320  * Return: QDF_STATUS_SUCCESS upon successful registration,
321  *         QDF_STATUS_E_FAILURE upon failure
322  */
323 static QDF_STATUS
324 wlan_spectral_psoc_target_detach(struct wlan_objmgr_psoc *psoc)
325 {
326 	struct spectral_context *sc = NULL;
327 
328 	if (!psoc) {
329 		spectral_err("psoc is null");
330 		return QDF_STATUS_E_FAILURE;
331 	}
332 
333 	sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
334 						   WLAN_UMAC_COMP_SPECTRAL);
335 	if (!sc) {
336 		spectral_err("Spectral context is null");
337 		return QDF_STATUS_E_INVAL;
338 	}
339 
340 	if (sc->sptrlc_psoc_spectral_deinit)
341 		sc->sptrlc_psoc_spectral_deinit(psoc);
342 	sc->psoc_target_handle = NULL;
343 
344 	return QDF_STATUS_SUCCESS;
345 }
346 
347 #ifdef DIRECT_BUF_RX_ENABLE
348 bool spectral_dbr_event_handler(struct wlan_objmgr_pdev *pdev,
349 				struct direct_buf_rx_data *payload)
350 {
351 	struct spectral_context *sc;
352 
353 	if (!pdev) {
354 		spectral_err("PDEV is NULL!");
355 		return -EINVAL;
356 	}
357 	sc = spectral_get_spectral_ctx_from_pdev(pdev);
358 	if (!sc) {
359 		spectral_err("spectral context is NULL!");
360 		return -EINVAL;
361 	}
362 
363 	sc->sptrlc_process_spectral_report(pdev, payload);
364 
365 	return true;
366 }
367 #endif
368 
369 QDF_STATUS spectral_pdev_open(struct wlan_objmgr_pdev *pdev)
370 {
371 	struct wlan_objmgr_psoc *psoc;
372 	QDF_STATUS status;
373 
374 	psoc = wlan_pdev_get_psoc(pdev);
375 
376 	if (wlan_spectral_is_feature_disabled(psoc)) {
377 		spectral_info("Spectral is disabled");
378 		return QDF_STATUS_COMP_DISABLED;
379 	}
380 
381 	if (cfg_get(psoc, CFG_SPECTRAL_POISON_BUFS))
382 		tgt_set_spectral_dma_debug(pdev, SPECTRAL_DMA_BUFFER_DEBUG, 1);
383 
384 	status = tgt_spectral_register_to_dbr(pdev);
385 	return QDF_STATUS_SUCCESS;
386 }
387 
388 QDF_STATUS spectral_register_dbr(struct wlan_objmgr_pdev *pdev)
389 {
390 	return tgt_spectral_register_to_dbr(pdev);
391 }
392 
393 qdf_export_symbol(spectral_register_dbr);
394 
395 QDF_STATUS spectral_unregister_dbr(struct wlan_objmgr_pdev *pdev)
396 {
397 	QDF_STATUS status;
398 
399 	status = tgt_spectral_unregister_to_dbr(pdev);
400 
401 	return status;
402 }
403 
404 qdf_export_symbol(spectral_unregister_dbr);
405 
406 QDF_STATUS wlan_spectral_psoc_open(struct wlan_objmgr_psoc *psoc)
407 {
408 	if (!psoc) {
409 		spectral_err("psoc is null");
410 		return QDF_STATUS_E_INVAL;
411 	}
412 
413 	if (wlan_spectral_is_feature_disabled(psoc)) {
414 		spectral_info("Spectral is disabled");
415 		return QDF_STATUS_COMP_DISABLED;
416 	}
417 
418 	return wlan_spectral_psoc_target_attach(psoc);
419 }
420 
421 QDF_STATUS wlan_spectral_psoc_close(struct wlan_objmgr_psoc *psoc)
422 {
423 	if (!psoc) {
424 		spectral_err("psoc is null");
425 		return QDF_STATUS_E_INVAL;
426 	}
427 
428 	if (wlan_spectral_is_feature_disabled(psoc)) {
429 		spectral_info("Spectral is disabled");
430 		return QDF_STATUS_COMP_DISABLED;
431 	}
432 
433 	return wlan_spectral_psoc_target_detach(psoc);
434 }
435 
436 QDF_STATUS wlan_spectral_psoc_enable(struct wlan_objmgr_psoc *psoc)
437 {
438 	if (!psoc) {
439 		spectral_err("psoc is null");
440 		return QDF_STATUS_E_INVAL;
441 	}
442 
443 	if (wlan_spectral_is_feature_disabled(psoc)) {
444 		spectral_info("Spectral is disabled");
445 		return QDF_STATUS_COMP_DISABLED;
446 	}
447 
448 	return tgt_spectral_register_events(psoc);
449 }
450 
451 QDF_STATUS wlan_spectral_psoc_disable(struct wlan_objmgr_psoc *psoc)
452 {
453 	if (!psoc) {
454 		spectral_err("psoc is null");
455 		return QDF_STATUS_E_INVAL;
456 	}
457 
458 	if (wlan_spectral_is_feature_disabled(psoc)) {
459 		spectral_info("Spectral is disabled");
460 		return QDF_STATUS_COMP_DISABLED;
461 	}
462 
463 	return tgt_spectral_unregister_events(psoc);
464 }
465