1  /*
2   * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
4   *
5   *
6   * Permission to use, copy, modify, and/or distribute this software for
7   * any purpose with or without fee is hereby granted, provided that the
8   * above copyright notice and this permission notice appear in all
9   * copies.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18   * PERFORMANCE OF THIS SOFTWARE.
19   */
20  
21  #include <wlan_spectral_utils_api.h>
22  #include <qdf_module.h>
23  #include "../../core/spectral_cmn_api_i.h"
24  #include <wlan_spectral_tgt_api.h>
25  #include <cfg_ucfg_api.h>
26  
wlan_spectral_is_mode_disabled_pdev(struct wlan_objmgr_pdev * pdev,enum spectral_scan_mode smode)27  bool wlan_spectral_is_mode_disabled_pdev(struct wlan_objmgr_pdev *pdev,
28  					 enum spectral_scan_mode smode)
29  {
30  	bool spectral_mode_disable;
31  
32  	if (!pdev) {
33  		spectral_err("pdev is NULL!");
34  		return true;
35  	}
36  
37  	switch (smode) {
38  	case SPECTRAL_SCAN_MODE_NORMAL:
39  		spectral_mode_disable = wlan_pdev_nif_feat_ext_cap_get(
40  			pdev, WLAN_PDEV_FEXT_NORMAL_SPECTRAL_SCAN_DIS);
41  		break;
42  
43  	case SPECTRAL_SCAN_MODE_AGILE:
44  		spectral_mode_disable = wlan_pdev_nif_feat_ext_cap_get(
45  			pdev, WLAN_PDEV_FEXT_AGILE_SPECTRAL_SCAN_DIS) &&
46  					wlan_pdev_nif_feat_ext_cap_get(
47  			pdev, WLAN_PDEV_FEXT_AGILE_SPECTRAL_SCAN_160_DIS) &&
48  					wlan_pdev_nif_feat_ext_cap_get(
49  			pdev, WLAN_PDEV_FEXT_AGILE_SPECTRAL_SCAN_80P80_DIS) &&
50  					wlan_pdev_nif_feat_ext_cap_get(
51  			pdev, WLAN_PDEV_FEXT_AGILE_SPECTRAL_SCAN_320_DIS);
52  		break;
53  
54  	default:
55  		spectral_err("Invalid Spectral scan mode %d", smode);
56  		spectral_mode_disable = true;
57  		break;
58  	}
59  
60  	return spectral_mode_disable;
61  }
62  
63  bool
wlan_spectral_is_feature_disabled_ini(struct wlan_objmgr_psoc * psoc)64  wlan_spectral_is_feature_disabled_ini(struct wlan_objmgr_psoc *psoc)
65  {
66  	if (!psoc) {
67  		spectral_err("PSOC is NULL!");
68  		return true;
69  	}
70  
71  	return wlan_psoc_nif_feat_cap_get(psoc,
72  					  WLAN_SOC_F_SPECTRAL_INI_DISABLE);
73  }
74  
75  bool
wlan_spectral_is_feature_disabled_psoc(struct wlan_objmgr_psoc * psoc)76  wlan_spectral_is_feature_disabled_psoc(struct wlan_objmgr_psoc *psoc)
77  {
78  	if (!psoc) {
79  		spectral_err("psoc is NULL!");
80  		return true;
81  	}
82  
83  	return wlan_spectral_is_feature_disabled_ini(psoc);
84  }
85  
86  bool
wlan_spectral_is_feature_disabled_pdev(struct wlan_objmgr_pdev * pdev)87  wlan_spectral_is_feature_disabled_pdev(struct wlan_objmgr_pdev *pdev)
88  {
89  	enum spectral_scan_mode smode;
90  
91  	if (!pdev) {
92  		spectral_err("pdev is NULL!");
93  		return true;
94  	}
95  
96  	smode = SPECTRAL_SCAN_MODE_NORMAL;
97  	for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++)
98  		if (!wlan_spectral_is_mode_disabled_pdev(pdev, smode))
99  			return false;
100  
101  	return true;
102  }
103  
104  QDF_STATUS
wlan_spectral_init_pdev_feature_caps(struct wlan_objmgr_pdev * pdev)105  wlan_spectral_init_pdev_feature_caps(struct wlan_objmgr_pdev *pdev)
106  {
107  	return tgt_spectral_init_pdev_feature_caps(pdev);
108  }
109  
110  QDF_STATUS
wlan_spectral_init_psoc_feature_cap(struct wlan_objmgr_psoc * psoc)111  wlan_spectral_init_psoc_feature_cap(struct wlan_objmgr_psoc *psoc)
112  {
113  	if (!psoc) {
114  		spectral_err("PSOC is NULL!");
115  		return QDF_STATUS_E_INVAL;
116  	}
117  
118  	if (cfg_get(psoc, CFG_SPECTRAL_DISABLE))
119  		wlan_psoc_nif_feat_cap_set(psoc,
120  					   WLAN_SOC_F_SPECTRAL_INI_DISABLE);
121  	else
122  		wlan_psoc_nif_feat_cap_clear(psoc,
123  					     WLAN_SOC_F_SPECTRAL_INI_DISABLE);
124  
125  	return QDF_STATUS_SUCCESS;
126  }
127  
128  QDF_STATUS
wlan_spectral_init(void)129  wlan_spectral_init(void)
130  {
131  	if (wlan_objmgr_register_psoc_create_handler(
132  		WLAN_UMAC_COMP_SPECTRAL,
133  		wlan_spectral_psoc_obj_create_handler,
134  		NULL) !=
135  	    QDF_STATUS_SUCCESS) {
136  		return QDF_STATUS_E_FAILURE;
137  	}
138  	if (wlan_objmgr_register_psoc_destroy_handler(
139  		WLAN_UMAC_COMP_SPECTRAL,
140  		wlan_spectral_psoc_obj_destroy_handler,
141  		NULL) !=
142  	    QDF_STATUS_SUCCESS) {
143  		return QDF_STATUS_E_FAILURE;
144  	}
145  	if (wlan_objmgr_register_pdev_create_handler(
146  		WLAN_UMAC_COMP_SPECTRAL,
147  		wlan_spectral_pdev_obj_create_handler,
148  		NULL) !=
149  	    QDF_STATUS_SUCCESS) {
150  		return QDF_STATUS_E_FAILURE;
151  	}
152  	if (wlan_objmgr_register_pdev_destroy_handler(
153  		WLAN_UMAC_COMP_SPECTRAL,
154  		wlan_spectral_pdev_obj_destroy_handler,
155  		NULL) !=
156  	    QDF_STATUS_SUCCESS) {
157  		return QDF_STATUS_E_FAILURE;
158  	}
159  
160  	return QDF_STATUS_SUCCESS;
161  }
162  
163  QDF_STATUS
wlan_spectral_deinit(void)164  wlan_spectral_deinit(void)
165  {
166  	if (wlan_objmgr_unregister_psoc_create_handler(
167  		WLAN_UMAC_COMP_SPECTRAL,
168  		wlan_spectral_psoc_obj_create_handler,
169  		NULL) !=
170  	    QDF_STATUS_SUCCESS) {
171  		return QDF_STATUS_E_FAILURE;
172  	}
173  	if (wlan_objmgr_unregister_psoc_destroy_handler(
174  		WLAN_UMAC_COMP_SPECTRAL,
175  		wlan_spectral_psoc_obj_destroy_handler,
176  		NULL) !=
177  	    QDF_STATUS_SUCCESS) {
178  		return QDF_STATUS_E_FAILURE;
179  	}
180  	if (wlan_objmgr_unregister_pdev_create_handler(
181  		WLAN_UMAC_COMP_SPECTRAL,
182  		wlan_spectral_pdev_obj_create_handler,
183  		NULL) !=
184  	    QDF_STATUS_SUCCESS) {
185  		return QDF_STATUS_E_FAILURE;
186  	}
187  	if (wlan_objmgr_unregister_pdev_destroy_handler(
188  		WLAN_UMAC_COMP_SPECTRAL,
189  		wlan_spectral_pdev_obj_destroy_handler,
190  		NULL) !=
191  	    QDF_STATUS_SUCCESS) {
192  		return QDF_STATUS_E_FAILURE;
193  	}
194  	return QDF_STATUS_SUCCESS;
195  }
196  
197  QDF_STATUS
spectral_register_legacy_cb(struct wlan_objmgr_psoc * psoc,struct spectral_legacy_cbacks * legacy_cbacks)198  spectral_register_legacy_cb(struct wlan_objmgr_psoc *psoc,
199  			    struct spectral_legacy_cbacks *legacy_cbacks)
200  {
201  	struct spectral_context *sc;
202  
203  	if (!psoc) {
204  		spectral_err("psoc is null");
205  		return QDF_STATUS_E_INVAL;
206  	}
207  
208  	if (wlan_spectral_is_feature_disabled_psoc(psoc)) {
209  		spectral_info("Spectral feature is disabled");
210  		return QDF_STATUS_COMP_DISABLED;
211  	}
212  
213  	sc = spectral_get_spectral_ctx_from_psoc(psoc);
214  	if (!sc) {
215  		spectral_err("Invalid Context");
216  		return QDF_STATUS_E_FAILURE;
217  	}
218  
219  	sc->legacy_cbacks.vdev_get_chan_freq =
220  	    legacy_cbacks->vdev_get_chan_freq;
221  	sc->legacy_cbacks.vdev_get_chan_freq_seg2 =
222  	    legacy_cbacks->vdev_get_chan_freq_seg2;
223  	sc->legacy_cbacks.vdev_get_ch_width = legacy_cbacks->vdev_get_ch_width;
224  	sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz =
225  	    legacy_cbacks->vdev_get_sec20chan_freq_mhz;
226  
227  	return QDF_STATUS_SUCCESS;
228  }
229  qdf_export_symbol(spectral_register_legacy_cb);
230  
231  int16_t
spectral_vdev_get_chan_freq(struct wlan_objmgr_vdev * vdev)232  spectral_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev)
233  {
234  	struct spectral_context *sc;
235  
236  	sc = spectral_get_spectral_ctx_from_vdev(vdev);
237  	if (!sc) {
238  		spectral_err("spectral context is Null");
239  		return -EINVAL;
240  	}
241  
242  	if (!sc->legacy_cbacks.vdev_get_chan_freq) {
243  		spectral_err("vdev_get_chan_freq is not supported");
244  		return -ENOTSUPP;
245  	}
246  
247  	return sc->legacy_cbacks.vdev_get_chan_freq(vdev);
248  }
249  
250  int16_t
spectral_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev * vdev)251  spectral_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev)
252  {
253  	struct spectral_context *sc;
254  	struct wlan_channel *des_chan;
255  
256  	sc = spectral_get_spectral_ctx_from_vdev(vdev);
257  	if (!sc) {
258  		spectral_err("spectral context is null");
259  		return -EINVAL;
260  	}
261  
262  	if (!sc->legacy_cbacks.vdev_get_chan_freq_seg2) {
263  		des_chan = wlan_vdev_mlme_get_des_chan(vdev);
264  		if (des_chan->ch_width == CH_WIDTH_80P80MHZ)
265  			return des_chan->ch_freq_seg2;
266  		else
267  			return 0;
268  	}
269  
270  	return sc->legacy_cbacks.vdev_get_chan_freq_seg2(vdev);
271  }
272  
273  enum phy_ch_width
spectral_vdev_get_ch_width(struct wlan_objmgr_vdev * vdev)274  spectral_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev)
275  {
276  	struct spectral_context *sc;
277  
278  	sc = spectral_get_spectral_ctx_from_vdev(vdev);
279  	if (!sc) {
280  		spectral_err("spectral context is Null");
281  		return CH_WIDTH_INVALID;
282  	}
283  
284  	if (!sc->legacy_cbacks.vdev_get_ch_width) {
285  		spectral_err("vdev_get_ch_width is not supported");
286  		return -ENOTSUPP;
287  	}
288  
289  	return sc->legacy_cbacks.vdev_get_ch_width(vdev);
290  }
291  
292  int
spectral_vdev_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev * vdev,uint16_t * sec20chan_freq)293  spectral_vdev_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
294  				     uint16_t *sec20chan_freq)
295  {
296  	struct spectral_context *sc;
297  
298  	sc = spectral_get_spectral_ctx_from_vdev(vdev);
299  	if (!sc) {
300  		spectral_err("spectral context is Null");
301  		return -EINVAL;
302  	}
303  
304  	if (!sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz) {
305  		spectral_err("vdev_get_sec20chan_freq_mhz is not supported");
306  		return -ENOTSUPP;
307  	}
308  
309  	return sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz(vdev,
310  							     sec20chan_freq);
311  }
312  
313  void
wlan_lmac_if_sptrl_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)314  wlan_lmac_if_sptrl_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
315  {
316  	struct wlan_lmac_if_sptrl_rx_ops *sptrl_rx_ops = &rx_ops->sptrl_rx_ops;
317  
318  	/* Spectral rx ops */
319  	sptrl_rx_ops->sptrlro_get_pdev_target_handle =
320  					tgt_get_pdev_target_handle;
321  	sptrl_rx_ops->sptrlro_get_psoc_target_handle =
322  					tgt_get_psoc_target_handle;
323  	sptrl_rx_ops->sptrlro_vdev_get_chan_freq = spectral_vdev_get_chan_freq;
324  	sptrl_rx_ops->sptrlro_vdev_get_chan_freq_seg2 =
325  					spectral_vdev_get_chan_freq_seg2;
326  	sptrl_rx_ops->sptrlro_vdev_get_ch_width = spectral_vdev_get_ch_width;
327  	sptrl_rx_ops->sptrlro_vdev_get_sec20chan_freq_mhz =
328  	    spectral_vdev_get_sec20chan_freq_mhz;
329  	sptrl_rx_ops->sptrlro_spectral_is_feature_disabled_pdev =
330  		wlan_spectral_is_feature_disabled_pdev;
331  	sptrl_rx_ops->sptrlro_spectral_is_feature_disabled_psoc =
332  		wlan_spectral_is_feature_disabled_psoc;
333  }
334  
335  QDF_STATUS
wlan_register_spectral_wmi_ops(struct wlan_objmgr_psoc * psoc,struct spectral_wmi_ops * wmi_ops)336  wlan_register_spectral_wmi_ops(struct wlan_objmgr_psoc *psoc,
337  			       struct spectral_wmi_ops *wmi_ops)
338  {
339  	struct spectral_context *sc;
340  
341  	if (!psoc) {
342  		spectral_err("psoc is NULL!");
343  		return QDF_STATUS_E_INVAL;
344  	}
345  
346  	if (wlan_spectral_is_feature_disabled_psoc(psoc)) {
347  		spectral_info("Spectral feature is disabled");
348  		return QDF_STATUS_COMP_DISABLED;
349  	}
350  
351  	sc = spectral_get_spectral_ctx_from_psoc(psoc);
352  	if (!sc) {
353  		spectral_err("spectral context is NULL!");
354  		return QDF_STATUS_E_FAILURE;
355  	}
356  
357  	return sc->sptrlc_register_spectral_wmi_ops(psoc, wmi_ops);
358  }
359  
360  qdf_export_symbol(wlan_register_spectral_wmi_ops);
361  
362  QDF_STATUS
wlan_register_spectral_tgt_ops(struct wlan_objmgr_psoc * psoc,struct spectral_tgt_ops * tgt_ops)363  wlan_register_spectral_tgt_ops(struct wlan_objmgr_psoc *psoc,
364  			       struct spectral_tgt_ops *tgt_ops)
365  {
366  	struct spectral_context *sc;
367  
368  	if (!psoc) {
369  		spectral_err("psoc is NULL!");
370  		return QDF_STATUS_E_INVAL;
371  	}
372  
373  	if (wlan_spectral_is_feature_disabled_psoc(psoc)) {
374  		spectral_info("Spectral feature is disabled");
375  		return QDF_STATUS_COMP_DISABLED;
376  	}
377  
378  	sc = spectral_get_spectral_ctx_from_psoc(psoc);
379  	if (!sc) {
380  		spectral_err("spectral context is NULL!");
381  		return QDF_STATUS_E_FAILURE;
382  	}
383  
384  	return sc->sptrlc_register_spectral_tgt_ops(psoc, tgt_ops);
385  }
386  
387  qdf_export_symbol(wlan_register_spectral_tgt_ops);
388  
389  /**
390   * wlan_spectral_psoc_target_attach() - Spectral psoc target attach
391   * @psoc:  pointer to psoc object
392   *
393   * API to initialize Spectral psoc target object
394   *
395   * Return: QDF_STATUS_SUCCESS upon successful registration,
396   *         QDF_STATUS_E_FAILURE upon failure
397   */
398  static QDF_STATUS
wlan_spectral_psoc_target_attach(struct wlan_objmgr_psoc * psoc)399  wlan_spectral_psoc_target_attach(struct wlan_objmgr_psoc *psoc)
400  {
401  	struct spectral_context *sc = NULL;
402  
403  	if (!psoc) {
404  		spectral_err("psoc is null");
405  		return QDF_STATUS_E_FAILURE;
406  	}
407  
408  	sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
409  						   WLAN_UMAC_COMP_SPECTRAL);
410  	if (!sc) {
411  		spectral_err("Spectral context is null");
412  		return QDF_STATUS_E_NOMEM;
413  	}
414  
415  	if (sc->sptrlc_psoc_spectral_init) {
416  		void *target_handle;
417  
418  		target_handle = sc->sptrlc_psoc_spectral_init(psoc);
419  		if (!target_handle) {
420  			spectral_err("Spectral psoc lmac object is NULL!");
421  			return QDF_STATUS_E_FAILURE;
422  		}
423  		sc->psoc_target_handle = target_handle;
424  	}
425  
426  	return QDF_STATUS_SUCCESS;
427  }
428  
429  /**
430   * wlan_spectral_psoc_target_detach() - Spectral psoc target detach
431   * @psoc:  pointer to psoc object
432   *
433   * API to destroy Spectral psoc target object
434   *
435   * Return: QDF_STATUS_SUCCESS upon successful registration,
436   *         QDF_STATUS_E_FAILURE upon failure
437   */
438  static QDF_STATUS
wlan_spectral_psoc_target_detach(struct wlan_objmgr_psoc * psoc)439  wlan_spectral_psoc_target_detach(struct wlan_objmgr_psoc *psoc)
440  {
441  	struct spectral_context *sc = NULL;
442  
443  	if (!psoc) {
444  		spectral_err("psoc is null");
445  		return QDF_STATUS_E_FAILURE;
446  	}
447  
448  	sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
449  						   WLAN_UMAC_COMP_SPECTRAL);
450  	if (!sc) {
451  		spectral_err("Spectral context is null");
452  		return QDF_STATUS_E_INVAL;
453  	}
454  
455  	if (sc->sptrlc_psoc_spectral_deinit)
456  		sc->sptrlc_psoc_spectral_deinit(psoc);
457  	sc->psoc_target_handle = NULL;
458  
459  	return QDF_STATUS_SUCCESS;
460  }
461  
462  #ifdef DIRECT_BUF_RX_ENABLE
spectral_dbr_event_handler(struct wlan_objmgr_pdev * pdev,struct direct_buf_rx_data * payload)463  bool spectral_dbr_event_handler(struct wlan_objmgr_pdev *pdev,
464  				struct direct_buf_rx_data *payload)
465  {
466  	struct spectral_context *sc;
467  
468  	if (!pdev) {
469  		spectral_err("PDEV is NULL!");
470  		return -EINVAL;
471  	}
472  	sc = spectral_get_spectral_ctx_from_pdev(pdev);
473  	if (!sc) {
474  		spectral_err("spectral context is NULL!");
475  		return -EINVAL;
476  	}
477  
478  	sc->sptrlc_process_spectral_report(pdev, payload);
479  
480  	return true;
481  }
482  #endif
483  
spectral_pdev_open(struct wlan_objmgr_pdev * pdev)484  QDF_STATUS spectral_pdev_open(struct wlan_objmgr_pdev *pdev)
485  {
486  	struct wlan_objmgr_psoc *psoc;
487  	QDF_STATUS status;
488  
489  	psoc = wlan_pdev_get_psoc(pdev);
490  
491  	if (wlan_spectral_is_feature_disabled_pdev(pdev)) {
492  		spectral_info("Spectral feature is disabled");
493  		return QDF_STATUS_COMP_DISABLED;
494  	}
495  
496  	if (cfg_get(psoc, CFG_SPECTRAL_POISON_BUFS))
497  		tgt_set_spectral_dma_debug(pdev, SPECTRAL_DMA_BUFFER_DEBUG, 1);
498  
499  	status = spectral_register_dbr(pdev);
500  	return status;
501  }
502  
spectral_register_dbr(struct wlan_objmgr_pdev * pdev)503  QDF_STATUS spectral_register_dbr(struct wlan_objmgr_pdev *pdev)
504  {
505  	if (wlan_spectral_is_feature_disabled_pdev(pdev)) {
506  		spectral_info("spectral feature is disabled");
507  		return QDF_STATUS_COMP_DISABLED;
508  	}
509  
510  	return tgt_spectral_register_to_dbr(pdev);
511  }
512  
513  qdf_export_symbol(spectral_register_dbr);
514  
spectral_unregister_dbr(struct wlan_objmgr_pdev * pdev)515  QDF_STATUS spectral_unregister_dbr(struct wlan_objmgr_pdev *pdev)
516  {
517  	QDF_STATUS status;
518  
519  	if (wlan_spectral_is_feature_disabled_pdev(pdev)) {
520  		spectral_info("spectral feature is disabled");
521  		return QDF_STATUS_COMP_DISABLED;
522  	}
523  	status = tgt_spectral_unregister_to_dbr(pdev);
524  
525  	return status;
526  }
527  
528  qdf_export_symbol(spectral_unregister_dbr);
529  
wlan_spectral_psoc_open(struct wlan_objmgr_psoc * psoc)530  QDF_STATUS wlan_spectral_psoc_open(struct wlan_objmgr_psoc *psoc)
531  {
532  	if (!psoc) {
533  		spectral_err("psoc is null");
534  		return QDF_STATUS_E_INVAL;
535  	}
536  
537  	if (wlan_spectral_is_feature_disabled_psoc(psoc)) {
538  		spectral_info("Spectral feature is disabled");
539  		return QDF_STATUS_COMP_DISABLED;
540  	}
541  
542  	return wlan_spectral_psoc_target_attach(psoc);
543  }
544  
wlan_spectral_psoc_close(struct wlan_objmgr_psoc * psoc)545  QDF_STATUS wlan_spectral_psoc_close(struct wlan_objmgr_psoc *psoc)
546  {
547  	if (!psoc) {
548  		spectral_err("psoc is null");
549  		return QDF_STATUS_E_INVAL;
550  	}
551  
552  	if (wlan_spectral_is_feature_disabled_psoc(psoc)) {
553  		spectral_info("Spectral feature is disabled");
554  		return QDF_STATUS_COMP_DISABLED;
555  	}
556  
557  	return wlan_spectral_psoc_target_detach(psoc);
558  }
559  
wlan_spectral_psoc_enable(struct wlan_objmgr_psoc * psoc)560  QDF_STATUS wlan_spectral_psoc_enable(struct wlan_objmgr_psoc *psoc)
561  {
562  	if (!psoc) {
563  		spectral_err("psoc is null");
564  		return QDF_STATUS_E_INVAL;
565  	}
566  
567  	if (wlan_spectral_is_feature_disabled_psoc(psoc)) {
568  		spectral_info("Spectral feature is disabled");
569  		return QDF_STATUS_COMP_DISABLED;
570  	}
571  
572  	return tgt_spectral_register_events(psoc);
573  }
574  
wlan_spectral_psoc_disable(struct wlan_objmgr_psoc * psoc)575  QDF_STATUS wlan_spectral_psoc_disable(struct wlan_objmgr_psoc *psoc)
576  {
577  	if (!psoc) {
578  		spectral_err("psoc is null");
579  		return QDF_STATUS_E_INVAL;
580  	}
581  
582  	if (wlan_spectral_is_feature_disabled_psoc(psoc)) {
583  		spectral_info("Spectral feature is disabled");
584  		return QDF_STATUS_COMP_DISABLED;
585  	}
586  
587  	return tgt_spectral_unregister_events(psoc);
588  }
589  
590  struct wlan_lmac_if_sptrl_tx_ops *
wlan_spectral_pdev_get_lmac_if_txops(struct wlan_objmgr_pdev * pdev)591  wlan_spectral_pdev_get_lmac_if_txops(struct wlan_objmgr_pdev *pdev)
592  {
593  	struct wlan_objmgr_psoc *psoc;
594  	struct wlan_lmac_if_tx_ops *tx_ops;
595  
596  	if (!pdev) {
597  		spectral_err("pdev is NULL!");
598  		return NULL;
599  	}
600  
601  	psoc = wlan_pdev_get_psoc(pdev);
602  	if (!psoc) {
603  		spectral_err("psoc is NULL!");
604  		return NULL;
605  	}
606  
607  	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
608  	if (!tx_ops) {
609  		spectral_err("tx_ops is NULL");
610  		return NULL;
611  	}
612  
613  	return &tx_ops->sptrl_tx_ops;
614  }
615