1  /*
2   * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2021-2023 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  /**
22   * DOC: This file has the DFS dispatcher API implementation which is exposed
23   * to outside of DFS component.
24   */
25  #include <wlan_objmgr_vdev_obj.h>
26  #include "wlan_dfs_utils_api.h"
27  #include "wlan_dfs_init_deinit_api.h"
28  #include "wlan_dfs_mlme_api.h"
29  #include "../../core/src/dfs.h"
30  #include "../../core/src/dfs_zero_cac.h"
31  #include <wlan_reg_services_api.h>
32  #include "../../core/src/dfs_random_chan_sel.h"
33  #ifdef QCA_DFS_USE_POLICY_MANAGER
34  #include "wlan_policy_mgr_api.h"
35  #endif
36  #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
37  #include <pld_common.h>
38  #endif
39  #include <qdf_module.h>
40  #include "wlan_dfs_lmac_api.h"
41  #include "../../core/src/dfs_internal.h"
42  
43  struct dfs_nol_info {
44  	uint16_t num_chans;
45  	struct dfsreq_nolelem dfs_nol[DFS_MAX_NOL_CHANNEL];
46  };
47  
utils_dfs_reset(struct wlan_objmgr_pdev * pdev)48  QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev)
49  {
50  	struct wlan_dfs *dfs;
51  
52  	dfs = wlan_pdev_get_dfs_obj(pdev);
53  	if (!dfs)
54  		return  QDF_STATUS_E_FAILURE;
55  
56  	dfs_reset(dfs);
57  	dfs_nol_update(dfs);
58  	dfs_reset_precaclists(dfs);
59  	dfs_init_chan_state_array(pdev);
60  
61  	if (dfs->dfs_use_puncture && !dfs->dfs_is_stadfs_enabled)
62  		dfs_punc_sm_stop_all(dfs);
63  
64  	return QDF_STATUS_SUCCESS;
65  }
66  
utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev * pdev,uint32_t freq)67  bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq)
68  {
69  	struct wlan_dfs *dfs;
70  
71  	dfs = wlan_pdev_get_dfs_obj(pdev);
72  	if (!dfs)
73  		return false;
74  
75  	return dfs_is_freq_in_nol(dfs, freq);
76  }
77  
78  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_cac_valid_reset_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t prevchan_freq,uint32_t prevchan_flags)79  QDF_STATUS utils_dfs_cac_valid_reset_for_freq(struct wlan_objmgr_pdev *pdev,
80  					      uint16_t prevchan_freq,
81  					      uint32_t prevchan_flags)
82  {
83  	struct wlan_dfs *dfs;
84  
85  	dfs = wlan_pdev_get_dfs_obj(pdev);
86  	if (!dfs)
87  		return  QDF_STATUS_E_FAILURE;
88  
89  	dfs_cac_valid_reset_for_freq(dfs, prevchan_freq, prevchan_flags);
90  
91  	return QDF_STATUS_SUCCESS;
92  }
93  
94  qdf_export_symbol(utils_dfs_cac_valid_reset_for_freq);
95  #endif
96  
utils_dfs_reset_precaclists(struct wlan_objmgr_pdev * pdev)97  QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev)
98  {
99  	struct wlan_dfs *dfs;
100  
101  	dfs = wlan_pdev_get_dfs_obj(pdev);
102  	if (!dfs)
103  		return  QDF_STATUS_E_FAILURE;
104  
105  	dfs_reset_precaclists(dfs);
106  
107  	return QDF_STATUS_SUCCESS;
108  }
109  qdf_export_symbol(utils_dfs_reset_precaclists);
110  
111  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_unmark_precac_nol_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t chan_freq)112  void utils_dfs_unmark_precac_nol_for_freq(struct wlan_objmgr_pdev *pdev,
113  					  uint16_t chan_freq)
114  {
115  	struct wlan_dfs *dfs;
116  
117  	dfs = wlan_pdev_get_dfs_obj(pdev);
118  	if (!dfs)
119  		return;
120  
121  	dfs_unmark_precac_nol_for_freq(dfs, chan_freq);
122  }
123  
124  qdf_export_symbol(utils_dfs_unmark_precac_nol_for_freq);
125  #endif
126  
utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev * pdev)127  QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev)
128  {
129  	struct wlan_dfs *dfs;
130  
131  	dfs = wlan_pdev_get_dfs_obj(pdev);
132  	if (!dfs)
133  		return  QDF_STATUS_E_FAILURE;
134  
135  	dfs_cancel_precac_timer(dfs);
136  
137  	return QDF_STATUS_SUCCESS;
138  }
139  qdf_export_symbol(utils_dfs_cancel_precac_timer);
140  
141  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_start_precac_timer(struct wlan_objmgr_pdev * pdev)142  QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev)
143  {
144  	struct wlan_dfs *dfs;
145  
146  	dfs = wlan_pdev_get_dfs_obj(pdev);
147  	if (!dfs) {
148  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs");
149  		return  QDF_STATUS_E_FAILURE;
150  	}
151  
152  	if (!dfs->dfs_precac_secondary_freq_mhz)
153  		return QDF_STATUS_E_FAILURE;
154  
155  	dfs_start_precac_timer_for_freq(dfs,
156  					dfs->dfs_precac_secondary_freq_mhz);
157  	return QDF_STATUS_SUCCESS;
158  }
159  #else
160  #endif
161  
162  #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
163  #ifdef CONFIG_CHAN_FREQ_API
164  bool
utils_dfs_precac_decide_pref_chan_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t * chan_freq,enum wlan_phymode mode)165  utils_dfs_precac_decide_pref_chan_for_freq(struct wlan_objmgr_pdev *pdev,
166  					   uint16_t *chan_freq,
167  					   enum wlan_phymode mode)
168  {
169  	struct wlan_dfs *dfs;
170  
171  	dfs = wlan_pdev_get_dfs_obj(pdev);
172  	if (!dfs) {
173  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs");
174  		return false;
175  	}
176  	return dfs_decide_precac_preferred_chan_for_freq(dfs, chan_freq, mode);
177  }
178  #endif
179  #endif
utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev * pdev)180  QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev)
181  {
182  	struct wlan_dfs *dfs;
183  
184  	dfs = wlan_pdev_get_dfs_obj(pdev);
185  	if (!dfs)
186  		return  QDF_STATUS_E_FAILURE;
187  
188  	dfs_cancel_cac_timer(dfs);
189  
190  	return QDF_STATUS_SUCCESS;
191  }
192  qdf_export_symbol(utils_dfs_cancel_cac_timer);
193  
utils_dfs_start_cac_timer(struct wlan_objmgr_pdev * pdev)194  QDF_STATUS utils_dfs_start_cac_timer(struct wlan_objmgr_pdev *pdev)
195  {
196  	struct wlan_dfs *dfs;
197  
198  	dfs = wlan_pdev_get_dfs_obj(pdev);
199  	if (!dfs)
200  		return  QDF_STATUS_E_FAILURE;
201  
202  	dfs_start_cac_timer(dfs);
203  
204  	return QDF_STATUS_SUCCESS;
205  }
206  qdf_export_symbol(utils_dfs_start_cac_timer);
207  
utils_dfs_cac_stop(struct wlan_objmgr_pdev * pdev)208  QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev)
209  {
210  	struct wlan_dfs *dfs;
211  
212  	dfs = wlan_pdev_get_dfs_obj(pdev);
213  	if (!dfs)
214  		return  QDF_STATUS_E_FAILURE;
215  
216  	dfs_cac_stop(dfs);
217  	return  QDF_STATUS_SUCCESS;
218  }
219  qdf_export_symbol(utils_dfs_cac_stop);
220  
221  /** dfs_fill_chan_info() - Fill the dfs channel structure with wlan
222   * channel.
223   * @chan: Pointer to DFS channel structure.
224   * @wlan_chan: Pointer to WLAN Channel structure.
225   *
226   * Return: void
227   */
228  #ifdef CONFIG_CHAN_FREQ_API
dfs_fill_chan_info(struct dfs_channel * chan,struct wlan_channel * wlan_chan)229  static void dfs_fill_chan_info(struct dfs_channel *chan,
230  			       struct wlan_channel *wlan_chan)
231  {
232  	chan->dfs_ch_freq = wlan_chan->ch_freq;
233  	chan->dfs_ch_flags = wlan_chan->ch_flags;
234  	chan->dfs_ch_flagext = wlan_chan->ch_flagext;
235  	chan->dfs_ch_ieee = wlan_chan->ch_ieee;
236  	chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1;
237  	chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2;
238  	chan->dfs_ch_mhz_freq_seg1 = wlan_chan->ch_cfreq1;
239  	chan->dfs_ch_mhz_freq_seg2 = wlan_chan->ch_cfreq2;
240  }
241  #endif
242  
utils_dfs_is_precac_done(struct wlan_objmgr_pdev * pdev,struct wlan_channel * wlan_chan)243  bool utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev,
244  			      struct wlan_channel *wlan_chan)
245  {
246  	struct wlan_dfs *dfs;
247  	struct dfs_channel chan;
248  
249  	dfs = wlan_pdev_get_dfs_obj(pdev);
250  	if (!dfs)
251  		return false;
252  
253  	dfs_fill_chan_info(&chan, wlan_chan);
254  
255  	return dfs_is_precac_done(dfs, &chan);
256  }
257  
utils_dfs_is_cac_required(struct wlan_objmgr_pdev * pdev,struct wlan_channel * cur_chan,struct wlan_channel * prev_chan,bool * continue_current_cac)258  bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev,
259  			       struct wlan_channel *cur_chan,
260  			       struct wlan_channel *prev_chan,
261  			       bool *continue_current_cac)
262  {
263  	struct wlan_dfs *dfs;
264  	struct dfs_channel cur_channel;
265  	struct dfs_channel prev_channel;
266  
267  	dfs = wlan_pdev_get_dfs_obj(pdev);
268  	if (!dfs)
269  		return false;
270  
271  	dfs_fill_chan_info(&cur_channel, cur_chan);
272  	dfs_fill_chan_info(&prev_channel, prev_chan);
273  
274  	return dfs_is_cac_required(dfs,
275  				   &cur_channel,
276  				   &prev_channel,
277  				   continue_current_cac, true);
278  }
279  
280  bool
utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev * pdev,bool * continue_current_cac,bool is_vap_restart)281  utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev *pdev,
282  					 bool *continue_current_cac,
283  					 bool is_vap_restart)
284  {
285  	struct wlan_dfs *dfs;
286  
287  	dfs = wlan_pdev_get_dfs_obj(pdev);
288  	if (!dfs)
289  		return false;
290  
291  	return dfs_is_cac_required(dfs,
292  				   dfs->dfs_curchan,
293  				   dfs->dfs_prevchan,
294  				   continue_current_cac,
295  				   is_vap_restart);
296  }
297  
utils_dfs_stacac_stop(struct wlan_objmgr_pdev * pdev)298  QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev)
299  {
300  	struct wlan_dfs *dfs;
301  
302  	dfs = wlan_pdev_get_dfs_obj(pdev);
303  	if (!dfs)
304  		return  QDF_STATUS_E_FAILURE;
305  
306  	dfs_stacac_stop(dfs);
307  
308  	return QDF_STATUS_SUCCESS;
309  }
310  qdf_export_symbol(utils_dfs_stacac_stop);
311  
utils_dfs_get_usenol(struct wlan_objmgr_pdev * pdev,uint16_t * usenol)312  QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol)
313  {
314  	struct wlan_dfs *dfs;
315  
316  	dfs = wlan_pdev_get_dfs_obj(pdev);
317  	if (!dfs)
318  		return  QDF_STATUS_E_FAILURE;
319  
320  	*usenol = dfs_get_use_nol(dfs);
321  
322  	return QDF_STATUS_SUCCESS;
323  }
324  qdf_export_symbol(utils_dfs_get_usenol);
325  
utils_dfs_is_spruce_spur_war_applicable(struct wlan_objmgr_pdev * pdev)326  bool utils_dfs_is_spruce_spur_war_applicable(struct wlan_objmgr_pdev *pdev)
327  {
328  	struct wlan_dfs *dfs;
329  	struct wlan_objmgr_psoc *psoc;
330  	struct wlan_lmac_if_tx_ops *tx_ops;
331  	uint32_t target_type;
332  	struct wlan_lmac_if_target_tx_ops *tgt_tx_ops;
333  	qdf_freq_t cur_freq;
334  
335  	dfs = wlan_pdev_get_dfs_obj(pdev);
336  	if (!dfs)
337  		return false;
338  
339  	psoc = dfs->dfs_soc_obj->psoc;
340  
341  	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
342  	if (!tx_ops) {
343  		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "tx_ops is NULL");
344  		return false;
345  	}
346  
347  	tgt_tx_ops = &tx_ops->target_tx_ops;
348  	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
349  
350  	/* Is the target Spruce? */
351  	if (!tgt_tx_ops->tgt_is_tgt_type_qcn6122 ||
352  	    !tgt_tx_ops->tgt_is_tgt_type_qcn9160)
353  		return false;
354  
355  	if (!tgt_tx_ops->tgt_is_tgt_type_qcn6122(target_type) ||
356  	    !tgt_tx_ops->tgt_is_tgt_type_qcn9160(target_type))
357  		return false;
358  
359  	cur_freq = dfs->dfs_curchan->dfs_ch_freq;
360  
361  	/* Is the current channel width 80MHz? */
362  	if (WLAN_IS_CHAN_MODE_80(dfs->dfs_curchan) ||
363  	    WLAN_IS_CHAN_MODE_40(dfs->dfs_curchan) ||
364  	    WLAN_IS_CHAN_MODE_20(dfs->dfs_curchan)) {
365  		/* is the primary channel 52/56/60/64? */
366  		bool is_chan_spur_80mhzfreq =
367  		    DFS_IS_CHAN_SPRUCE_SPUR_FREQ_80MHZ(cur_freq);
368  		if (is_chan_spur_80mhzfreq)
369  			return true;
370  		return false;
371  	}
372  
373  	/* If the current channel width is not 80, is it 160MHz? */
374  	if (WLAN_IS_CHAN_MODE_160(dfs->dfs_curchan)) {
375  		/* is the primary channel 36/44/48/52/56/60/64? */
376  		bool is_chan_spur_160mhz_freq =
377  		    DFS_IS_CHAN_SPRUCE_SPUR_FREQ_160MHZ(cur_freq);
378  		if (is_chan_spur_160mhz_freq)
379  			return true;
380  		return false;
381  	}
382  
383  	return false;
384  }
385  
utils_dfs_radar_disable(struct wlan_objmgr_pdev * pdev)386  QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev)
387  {
388  	struct wlan_dfs *dfs;
389  
390  	dfs = wlan_pdev_get_dfs_obj(pdev);
391  	if (!dfs)
392  		return  QDF_STATUS_E_FAILURE;
393  
394  	dfs_radar_disable(dfs);
395  
396  	return QDF_STATUS_SUCCESS;
397  }
398  qdf_export_symbol(utils_dfs_radar_disable);
399  
utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev * pdev,bool val)400  QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev,
401  		bool val)
402  {
403  	struct wlan_dfs *dfs;
404  
405  	dfs = wlan_pdev_get_dfs_obj(pdev);
406  	if (!dfs)
407  		return  QDF_STATUS_E_FAILURE;
408  
409  	dfs_set_update_nol_flag(dfs, val);
410  
411  	return QDF_STATUS_SUCCESS;
412  }
413  qdf_export_symbol(utils_dfs_set_update_nol_flag);
414  
utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev * pdev,bool * nol_flag)415  QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev,
416  		bool *nol_flag)
417  {
418  	struct wlan_dfs *dfs;
419  
420  	dfs = wlan_pdev_get_dfs_obj(pdev);
421  	if (!dfs)
422  		return  QDF_STATUS_E_FAILURE;
423  
424  	*nol_flag = dfs_get_update_nol_flag(dfs);
425  
426  	return QDF_STATUS_SUCCESS;
427  }
428  qdf_export_symbol(utils_dfs_get_update_nol_flag);
429  
utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev * pdev,int * dfs_use_nol)430  QDF_STATUS utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev *pdev,
431  		int *dfs_use_nol)
432  {
433  	struct wlan_dfs *dfs;
434  
435  	dfs = wlan_pdev_get_dfs_obj(pdev);
436  	if (!dfs)
437  		return  QDF_STATUS_E_FAILURE;
438  
439  	*dfs_use_nol = dfs_get_use_nol(dfs);
440  
441  	return QDF_STATUS_SUCCESS;
442  }
443  qdf_export_symbol(utils_dfs_get_dfs_use_nol);
444  
utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev * pdev,int * dfs_nol_timeout)445  QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev,
446  		int *dfs_nol_timeout)
447  {
448  	struct wlan_dfs *dfs;
449  
450  	dfs = wlan_pdev_get_dfs_obj(pdev);
451  	if (!dfs)
452  		return  QDF_STATUS_E_FAILURE;
453  
454  	*dfs_nol_timeout = dfs_get_nol_timeout(dfs);
455  
456  	return QDF_STATUS_SUCCESS;
457  }
458  qdf_export_symbol(utils_dfs_get_nol_timeout);
459  
utils_dfs_nol_addchan(struct wlan_objmgr_pdev * pdev,uint16_t freq,uint32_t dfs_nol_timeout)460  QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev,
461  		uint16_t freq,
462  		uint32_t dfs_nol_timeout)
463  {
464  	struct wlan_dfs *dfs;
465  
466  	dfs = wlan_pdev_get_dfs_obj(pdev);
467  	if (!dfs)
468  		return  QDF_STATUS_E_FAILURE;
469  
470  	DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, dfs_nol_timeout);
471  
472  	return QDF_STATUS_SUCCESS;
473  }
474  qdf_export_symbol(utils_dfs_nol_addchan);
475  
utils_dfs_nol_update(struct wlan_objmgr_pdev * pdev)476  QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev)
477  {
478  	struct wlan_dfs *dfs;
479  
480  	dfs = wlan_pdev_get_dfs_obj(pdev);
481  	if (!dfs)
482  		return  QDF_STATUS_E_FAILURE;
483  
484  	dfs_nol_update(dfs);
485  
486  	return QDF_STATUS_SUCCESS;
487  }
488  qdf_export_symbol(utils_dfs_nol_update);
489  
utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev * pdev)490  QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev)
491  {
492  	struct wlan_dfs *dfs;
493  
494  	dfs = wlan_pdev_get_dfs_obj(pdev);
495  	if (!dfs)
496  		return  QDF_STATUS_E_FAILURE;
497  
498  	dfs_second_segment_radar_disable(dfs);
499  
500  	return QDF_STATUS_SUCCESS;
501  }
502  
utils_dfs_bw_reduce(struct wlan_objmgr_pdev * pdev,bool bw_reduce)503  QDF_STATUS utils_dfs_bw_reduce(struct wlan_objmgr_pdev *pdev, bool bw_reduce)
504  {
505  	struct wlan_dfs *dfs;
506  
507  	dfs = wlan_pdev_get_dfs_obj(pdev);
508  	if (!dfs)
509  		return  QDF_STATUS_E_FAILURE;
510  
511  	dfs->dfs_bw_reduced = bw_reduce;
512  
513  	return QDF_STATUS_SUCCESS;
514  }
515  
516  qdf_export_symbol(utils_dfs_bw_reduce);
517  
utils_dfs_is_bw_reduce(struct wlan_objmgr_pdev * pdev,bool * bw_reduce)518  QDF_STATUS utils_dfs_is_bw_reduce(struct wlan_objmgr_pdev *pdev,
519  				  bool *bw_reduce)
520  {
521  	struct wlan_dfs *dfs;
522  
523  	dfs = wlan_pdev_get_dfs_obj(pdev);
524  	if (!dfs)
525  		return  QDF_STATUS_E_FAILURE;
526  
527  	*bw_reduce = dfs->dfs_bw_reduced;
528  
529  	return QDF_STATUS_SUCCESS;
530  }
531  
utils_dfs_fetch_nol_ie_info(struct wlan_objmgr_pdev * pdev,uint8_t * nol_ie_bandwidth,uint16_t * nol_ie_startfreq,uint8_t * nol_ie_bitmap)532  QDF_STATUS utils_dfs_fetch_nol_ie_info(struct wlan_objmgr_pdev *pdev,
533  				       uint8_t *nol_ie_bandwidth,
534  				       uint16_t *nol_ie_startfreq,
535  				       uint8_t *nol_ie_bitmap)
536  {
537  	struct wlan_dfs *dfs;
538  
539  	dfs = wlan_pdev_get_dfs_obj(pdev);
540  	if (!dfs)
541  		return  QDF_STATUS_E_FAILURE;
542  
543  	dfs_fetch_nol_ie_info(dfs, nol_ie_bandwidth, nol_ie_startfreq,
544  			      nol_ie_bitmap);
545  
546  	return QDF_STATUS_SUCCESS;
547  }
548  
utils_dfs_set_rcsa_flags(struct wlan_objmgr_pdev * pdev,bool is_rcsa_ie_sent,bool is_nol_ie_sent)549  QDF_STATUS utils_dfs_set_rcsa_flags(struct wlan_objmgr_pdev *pdev,
550  				    bool is_rcsa_ie_sent,
551  				    bool is_nol_ie_sent)
552  {
553  	struct wlan_dfs *dfs;
554  
555  	dfs = wlan_pdev_get_dfs_obj(pdev);
556  	if (!dfs)
557  		return  QDF_STATUS_E_FAILURE;
558  
559  	dfs_set_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent);
560  
561  	return QDF_STATUS_SUCCESS;
562  }
563  
utils_dfs_get_rcsa_flags(struct wlan_objmgr_pdev * pdev,bool * is_rcsa_ie_sent,bool * is_nol_ie_sent)564  QDF_STATUS utils_dfs_get_rcsa_flags(struct wlan_objmgr_pdev *pdev,
565  				    bool *is_rcsa_ie_sent,
566  				    bool *is_nol_ie_sent)
567  {
568  	struct wlan_dfs *dfs;
569  
570  	dfs = wlan_pdev_get_dfs_obj(pdev);
571  	if (!dfs)
572  		return  QDF_STATUS_E_FAILURE;
573  	dfs_get_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent);
574  
575  	return QDF_STATUS_SUCCESS;
576  }
577  
utils_dfs_process_nol_ie_bitmap(struct wlan_objmgr_pdev * pdev,uint8_t nol_ie_bandwidth,uint16_t nol_ie_startfreq,uint8_t nol_ie_bitmap)578  bool utils_dfs_process_nol_ie_bitmap(struct wlan_objmgr_pdev *pdev,
579  				     uint8_t nol_ie_bandwidth,
580  				     uint16_t nol_ie_startfreq,
581  				     uint8_t nol_ie_bitmap)
582  {
583  	struct wlan_dfs *dfs;
584  
585  	dfs = wlan_pdev_get_dfs_obj(pdev);
586  	if (!dfs)
587  		return  false;
588  	return dfs_process_nol_ie_bitmap(dfs, nol_ie_bandwidth,
589  					 nol_ie_startfreq,
590  					 nol_ie_bitmap);
591  }
592  
utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev * pdev,int val)593  QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev,
594  		int val)
595  {
596  	struct wlan_dfs *dfs;
597  
598  	dfs = wlan_pdev_get_dfs_obj(pdev);
599  	if (!dfs)
600  		return  QDF_STATUS_E_FAILURE;
601  
602  	dfs->dfs_cac_timer_running = val;
603  
604  	return QDF_STATUS_SUCCESS;
605  }
606  qdf_export_symbol(utils_dfs_set_cac_timer_running);
607  
utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev * pdev,void * nollist,uint32_t * nol_chfreq,uint32_t * nol_chwidth,int index)608  QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev,
609  		void *nollist,
610  		uint32_t *nol_chfreq,
611  		uint32_t *nol_chwidth,
612  		int index)
613  {
614  	struct wlan_dfs *dfs;
615  
616  	dfs = wlan_pdev_get_dfs_obj(pdev);
617  	if (!dfs)
618  		return  QDF_STATUS_E_FAILURE;
619  
620  	dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index);
621  
622  	return QDF_STATUS_SUCCESS;
623  }
624  qdf_export_symbol(utils_dfs_get_nol_chfreq_and_chwidth);
625  
utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev * pdev,uint64_t flags,uint16_t flagext)626  QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev,
627  		uint64_t flags,
628  		uint16_t flagext)
629  {
630  	struct wlan_dfs *dfs;
631  
632  	dfs = wlan_pdev_get_dfs_obj(pdev);
633  	if (!dfs)
634  		return  QDF_STATUS_E_FAILURE;
635  
636  	dfs_update_cur_chan_flags(dfs, flags, flagext);
637  
638  	return QDF_STATUS_SUCCESS;
639  }
640  
utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev * pdev,uint32_t * phy_mode)641  static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev,
642  		uint32_t *phy_mode)
643  {
644  	return;
645  }
646  
utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev * pdev,uint8_t * ch_width)647  static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev,
648  		uint8_t *ch_width)
649  {
650  	return;
651  }
652  
653  #ifndef QCA_DFS_USE_POLICY_MANAGER
utils_dfs_get_chan_list(struct wlan_objmgr_pdev * pdev,void * clist,uint32_t * num_chan)654  void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
655  			     void *clist, uint32_t *num_chan)
656  {
657  	uint32_t i = 0, j = 0;
658  	enum channel_state state;
659  	struct regulatory_channel *cur_chan_list;
660  	struct wlan_dfs *dfs;
661  	struct dfs_channel *chan_list = (struct dfs_channel *)clist;
662  
663  	dfs = wlan_pdev_get_dfs_obj(pdev);
664  	if (!dfs) {
665  		*num_chan = 0;
666  		return;
667  	}
668  
669  	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
670  			sizeof(struct regulatory_channel));
671  	if (!cur_chan_list) {
672  		*num_chan = 0;
673  		return;
674  	}
675  
676  	if (wlan_reg_get_current_chan_list(
677  			pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
678  		*num_chan = 0;
679  		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
680  				"failed to get curr channel list");
681  		return;
682  	}
683  
684  	for (i = 0; i < NUM_CHANNELS; i++) {
685  		state = cur_chan_list[i].state;
686  		if (state == CHANNEL_STATE_DFS ||
687  				state == CHANNEL_STATE_ENABLE) {
688  			chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num;
689  			chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq;
690  			if (state == CHANNEL_STATE_DFS)
691  				chan_list[j].dfs_ch_flagext =
692  					WLAN_CHAN_DFS;
693  
694  			if (cur_chan_list[i].nol_history)
695  				chan_list[j].dfs_ch_flagext |=
696  					WLAN_CHAN_HISTORY_RADAR;
697  			j++;
698  		}
699  	}
700  	*num_chan = j;
701  	qdf_mem_free(cur_chan_list);
702  
703  	return;
704  }
705  
706  /**
707   * utils_dfs_get_channel_list() - Get channel list from regdb component, based
708   * on current channel list.
709   * @pdev: Pointer to pdev structure.
710   * @vdev: vdev of request
711   * @chan_list: Pointer to channel list.
712   * @num_chan: number of channels.
713   *
714   * Get regdb channel list based on dfs current channel.
715   * Ex: When  AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels
716   * so that the random channel function does not select either 2.4GHz or 4.9GHz
717   * channel.
718   */
719  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_get_channel_list(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,struct dfs_channel * chan_list,uint32_t * num_chan)720  static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
721  				       struct wlan_objmgr_vdev *vdev,
722  				       struct dfs_channel *chan_list,
723  				       uint32_t *num_chan)
724  {
725  	struct dfs_channel *tmp_chan_list = NULL;
726  	struct wlan_dfs *dfs;
727  	bool is_curchan_5g;
728  	bool is_curchan_24g;
729  	bool is_curchan_49g;
730  	bool is_inter_band_switch_allowed;
731  	uint8_t chan_num;
732  	uint16_t center_freq;
733  	uint16_t flagext;
734  	uint32_t i, j = 0;
735  
736  	dfs = wlan_pdev_get_dfs_obj(pdev);
737  	if (!dfs) {
738  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
739  		return;
740  	}
741  
742  	tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list));
743  	if (!tmp_chan_list)
744  		return;
745  
746  	utils_dfs_get_chan_list(pdev, (void *)tmp_chan_list, num_chan);
747  
748  	chan_num = dfs->dfs_curchan->dfs_ch_ieee;
749  	center_freq = dfs->dfs_curchan->dfs_ch_freq;
750  	is_curchan_5g = WLAN_REG_IS_5GHZ_CH_FREQ(center_freq);
751  	is_curchan_24g = WLAN_REG_IS_24GHZ_CH_FREQ(center_freq);
752  	is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq);
753  	is_inter_band_switch_allowed =
754  		dfs_mlme_is_inter_band_chan_switch_allowed(dfs->dfs_pdev_obj);
755  
756  	for (i = 0; i < *num_chan; i++) {
757  		chan_num = tmp_chan_list[i].dfs_ch_ieee;
758  		center_freq = tmp_chan_list[i].dfs_ch_freq;
759  		flagext = tmp_chan_list[i].dfs_ch_flagext;
760  		/* No change in prototype needed. Hence retaining same func */
761  		if (!dfs_mlme_check_allowed_prim_chanlist(pdev, center_freq))
762  			continue;
763  
764  		if (is_curchan_5g) {
765  			/*
766  			 * Always add 5G channels.
767  			 * If inter band is allowed, add 6G also.
768  			 */
769  			if (WLAN_REG_IS_5GHZ_CH_FREQ(center_freq) ||
770  			    (is_inter_band_switch_allowed &&
771  			     WLAN_REG_IS_6GHZ_CHAN_FREQ(center_freq))) {
772  				chan_list[j].dfs_ch_ieee = chan_num;
773  				chan_list[j].dfs_ch_freq = center_freq;
774  				chan_list[j].dfs_ch_flagext = flagext;
775  				j++;
776  			}
777  		} else if ((is_curchan_24g) &&
778  				WLAN_REG_IS_24GHZ_CH_FREQ(center_freq)) {
779  			chan_list[j].dfs_ch_ieee = chan_num;
780  			chan_list[j].dfs_ch_freq = center_freq;
781  			j++;
782  		} else if ((is_curchan_49g) &&
783  				WLAN_REG_IS_49GHZ_FREQ(center_freq)) {
784  			chan_list[j].dfs_ch_ieee = chan_num;
785  			chan_list[j].dfs_ch_freq = center_freq;
786  			j++;
787  		}
788  	}
789  
790  	*num_chan = j;
791  
792  	qdf_mem_free(tmp_chan_list);
793  }
794  #endif
795  #else
utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev * pdev,void * clist,uint32_t * num_chan)796  void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev,
797  					 void *clist, uint32_t *num_chan)
798  {
799  	utils_dfs_get_chan_list(pdev, clist, num_chan);
800  }
801  
utils_dfs_get_channel_list(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,struct dfs_channel * chan_list,uint32_t * num_chan)802  static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
803  				       struct wlan_objmgr_vdev *vdev,
804  				       struct dfs_channel *chan_list,
805  				       uint32_t *num_chan)
806  {
807  	uint32_t pcl_ch[NUM_CHANNELS] = {0};
808  	uint8_t weight_list[NUM_CHANNELS] = {0};
809  	uint32_t len;
810  	uint32_t weight_len;
811  	uint32_t i;
812  	struct wlan_objmgr_psoc *psoc;
813  	uint32_t conn_count = 0;
814  	enum policy_mgr_con_mode mode;
815  	uint8_t vdev_id = WLAN_INVALID_VDEV_ID;
816  	enum QDF_OPMODE op_mode;
817  
818  	psoc = wlan_pdev_get_psoc(pdev);
819  	if (!psoc) {
820  		*num_chan = 0;
821  		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
822  		return;
823  	}
824  
825  	len = QDF_ARRAY_SIZE(pcl_ch);
826  	weight_len = QDF_ARRAY_SIZE(weight_list);
827  
828  	if (vdev) {
829  		vdev_id = wlan_vdev_get_id(vdev);
830  		op_mode = wlan_vdev_mlme_get_opmode(vdev);
831  		mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode,
832  							    vdev_id);
833  	} else {
834  		mode = PM_SAP_MODE;
835  	}
836  	conn_count = policy_mgr_mode_specific_connection_count(
837  			psoc, mode, NULL);
838  	if (0 == conn_count)
839  		policy_mgr_get_pcl(psoc, mode, pcl_ch,
840  				   &len, weight_list, weight_len, vdev_id);
841  	else
842  		policy_mgr_get_pcl_for_existing_conn(
843  			psoc, mode, pcl_ch, &len, weight_list,
844  			weight_len, true, vdev_id);
845  
846  	if (*num_chan < len) {
847  		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
848  				"Invalid len src=%d, dst=%d",
849  				*num_chan, len);
850  		*num_chan = 0;
851  		return;
852  	}
853  
854  	for (i = 0; i < len; i++) {
855  		chan_list[i].dfs_ch_ieee  =
856  			wlan_reg_freq_to_chan(pdev, pcl_ch[i]);
857  		chan_list[i].dfs_ch_freq  = pcl_ch[i];
858  		if (wlan_reg_is_dfs_for_freq(pdev, pcl_ch[i]))
859  			chan_list[i].dfs_ch_flagext |= WLAN_CHAN_DFS;
860  	}
861  	*num_chan = i;
862  	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i);
863  }
864  
utils_dfs_get_chan_list(struct wlan_objmgr_pdev * pdev,void * clist,uint32_t * num_chan)865  void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
866  			     void *clist, uint32_t *num_chan)
867  {
868  	utils_dfs_get_channel_list(pdev, NULL, (struct dfs_channel *)clist,
869  				   num_chan);
870  }
871  
utils_dfs_can_ignore_radar_event(struct wlan_objmgr_pdev * pdev)872  bool utils_dfs_can_ignore_radar_event(struct wlan_objmgr_pdev *pdev)
873  {
874  	return policy_mgr_get_can_skip_radar_event(
875  		wlan_pdev_get_psoc(pdev), INVALID_VDEV_ID);
876  }
877  #endif
878  
879  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_get_vdev_random_channel_for_freq(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,uint16_t flags,struct ch_params * chan_params,uint32_t * hw_mode,uint16_t * target_chan_freq,struct dfs_acs_info * acs_info)880  QDF_STATUS utils_dfs_get_vdev_random_channel_for_freq(
881  	struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev,
882  	uint16_t flags, struct ch_params *chan_params, uint32_t *hw_mode,
883  	uint16_t *target_chan_freq, struct dfs_acs_info *acs_info)
884  {
885  	uint32_t dfs_reg;
886  	uint32_t num_chan = NUM_CHANNELS;
887  	struct wlan_dfs *dfs = NULL;
888  	struct wlan_objmgr_psoc *psoc;
889  	struct dfs_channel *chan_list = NULL;
890  	QDF_STATUS status = QDF_STATUS_E_FAILURE;
891  
892  	*target_chan_freq = 0;
893  	psoc = wlan_pdev_get_psoc(pdev);
894  	if (!psoc) {
895  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
896  		goto random_chan_error;
897  	}
898  
899  	dfs = wlan_pdev_get_dfs_obj(pdev);
900  	if (!dfs) {
901  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
902  		goto random_chan_error;
903  	}
904  
905  	wlan_reg_get_dfs_region(pdev, &dfs_reg);
906  	chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list));
907  	if (!chan_list)
908  		goto random_chan_error;
909  
910  	utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan);
911  	if (!num_chan) {
912  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "zero channels");
913  		goto random_chan_error;
914  	}
915  
916  	if (!chan_params->ch_width)
917  		utils_dfs_get_max_sup_width(pdev,
918  					    (uint8_t *)&chan_params->ch_width);
919  
920  	*target_chan_freq = dfs_prepare_random_channel_for_freq(
921  			dfs, chan_list, num_chan, flags, chan_params,
922  			(uint8_t)dfs_reg, acs_info);
923  
924  	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
925  		 "input width=%d", chan_params->ch_width);
926  
927  	if (*target_chan_freq) {
928  		wlan_reg_set_channel_params_for_pwrmode(
929  						     pdev, *target_chan_freq, 0,
930  						     chan_params,
931  						     REG_CURRENT_PWR_MODE);
932  		utils_dfs_get_max_phy_mode(pdev, hw_mode);
933  		status = QDF_STATUS_SUCCESS;
934  	}
935  
936  	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
937  		 "ch=%d, seg0=%d, seg1=%d, width=%d",
938  		 *target_chan_freq, chan_params->center_freq_seg0,
939  		 chan_params->center_freq_seg1, chan_params->ch_width);
940  
941  random_chan_error:
942  	qdf_mem_free(chan_list);
943  
944  	return status;
945  }
946  
947  qdf_export_symbol(utils_dfs_get_vdev_random_channel_for_freq);
948  #endif
949  
950  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_get_random_channel_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t flags,struct ch_params * ch_params,uint32_t * hw_mode,uint16_t * target_chan_freq,struct dfs_acs_info * acs_info)951  QDF_STATUS utils_dfs_get_random_channel_for_freq(
952  	struct wlan_objmgr_pdev *pdev,
953  	uint16_t flags,
954  	struct ch_params *ch_params,
955  	uint32_t *hw_mode,
956  	uint16_t *target_chan_freq,
957  	struct dfs_acs_info *acs_info)
958  {
959  	return utils_dfs_get_vdev_random_channel_for_freq(pdev, NULL, flags,
960  							  ch_params, hw_mode,
961  							  target_chan_freq,
962  							  acs_info);
963  }
964  
965  qdf_export_symbol(utils_dfs_get_random_channel_for_freq);
966  #endif
967  
968  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_bw_reduced_channel_for_freq(struct wlan_objmgr_pdev * pdev,struct ch_params * chan_params,uint32_t * hw_mode,uint16_t * target_chan_freq)969  QDF_STATUS utils_dfs_bw_reduced_channel_for_freq(
970  						 struct wlan_objmgr_pdev *pdev,
971  						 struct ch_params *chan_params,
972  						 uint32_t *hw_mode,
973  						 uint16_t *target_chan_freq)
974  {
975  	struct wlan_dfs *dfs = NULL;
976  	struct wlan_objmgr_psoc *psoc;
977  	enum channel_state ch_state;
978  	QDF_STATUS status = QDF_STATUS_E_FAILURE;
979  	struct dfs_channel *dfs_curchan;
980  
981  	*target_chan_freq = 0;
982  	psoc = wlan_pdev_get_psoc(pdev);
983  	if (!psoc) {
984  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
985  		return status;
986  	}
987  
988  	dfs = wlan_pdev_get_dfs_obj(pdev);
989  	if (!dfs) {
990  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
991  		return status;
992  	}
993  	dfs_curchan = dfs->dfs_curchan;
994  	ch_state =
995  		wlan_reg_get_channel_state_for_pwrmode(pdev,
996  						       dfs_curchan->dfs_ch_freq,
997  						       REG_CURRENT_PWR_MODE);
998  
999  	if (ch_state == CHANNEL_STATE_DFS ||
1000  	    ch_state == CHANNEL_STATE_ENABLE) {
1001  		/* If the current channel is 80P80MHz and radar is detected on
1002  		 * the channel, the next highest bandwidth that maybe available
1003  		 * is 80MHz. Since the current regulatory algorithm reduces the
1004  		 * bandwidth from 80P80MHz to 160MHz, provide the channel
1005  		 * width as 80MHz if current channel is 80P80MHz.
1006  		 */
1007  		if (chan_params->ch_width == CH_WIDTH_80P80MHZ)
1008  			chan_params->ch_width = CH_WIDTH_80MHZ;
1009  
1010  		chan_params->mhz_freq_seg0 =
1011  			dfs_curchan->dfs_ch_mhz_freq_seg1;
1012  		chan_params->mhz_freq_seg1 =
1013  			dfs_curchan->dfs_ch_mhz_freq_seg2;
1014  		wlan_reg_set_channel_params_for_pwrmode(pdev, dfs_curchan->
1015  							dfs_ch_freq,
1016  							0, chan_params,
1017  							REG_CURRENT_PWR_MODE);
1018  
1019  		*target_chan_freq = dfs_curchan->dfs_ch_freq;
1020  		utils_dfs_get_max_phy_mode(pdev, hw_mode);
1021  
1022  		return QDF_STATUS_SUCCESS;
1023  	}
1024  
1025  	return status;
1026  }
1027  
1028  qdf_export_symbol(utils_dfs_bw_reduced_channel_for_freq);
1029  #endif
1030  
1031  
1032  #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
utils_dfs_init_nol(struct wlan_objmgr_pdev * pdev)1033  void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev)
1034  {
1035  	struct wlan_dfs *dfs;
1036  	struct wlan_objmgr_psoc *psoc;
1037  	qdf_device_t qdf_dev;
1038  	struct dfs_nol_info *dfs_nolinfo;
1039  	int len;
1040  
1041  	dfs = wlan_pdev_get_dfs_obj(pdev);
1042  	psoc = wlan_pdev_get_psoc(pdev);
1043  	if (!dfs || !psoc) {
1044  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
1045  				"dfs %pK, psoc %pK", dfs, psoc);
1046  		return;
1047  	}
1048  
1049  	qdf_dev = psoc->soc_objmgr.qdf_dev;
1050  	if (!qdf_dev->dev) {
1051  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
1052  		return;
1053  	}
1054  
1055  	dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo));
1056  	if (!dfs_nolinfo)
1057  		return;
1058  
1059  	qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo));
1060  	len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo,
1061  				   (uint16_t)sizeof(*dfs_nolinfo));
1062  	if (len > 0) {
1063  		dfs_set_nol(dfs, dfs_nolinfo->dfs_nol, dfs_nolinfo->num_chans);
1064  		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld");
1065  		DFS_PRINT_NOL_LOCKED(dfs);
1066  	} else {
1067  		dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,  "no nol in pld");
1068  	}
1069  	qdf_mem_free(dfs_nolinfo);
1070  }
1071  qdf_export_symbol(utils_dfs_init_nol);
1072  #endif
1073  
1074  #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
utils_dfs_save_nol(struct wlan_objmgr_pdev * pdev)1075  void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
1076  {
1077  }
1078  #else
utils_dfs_save_nol(struct wlan_objmgr_pdev * pdev)1079  void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
1080  {
1081  	struct dfs_nol_info *dfs_nolinfo;
1082  	struct wlan_dfs *dfs = NULL;
1083  	struct wlan_objmgr_psoc *psoc;
1084  	qdf_device_t qdf_dev;
1085  	int num_chans = 0;
1086  
1087  	dfs = wlan_pdev_get_dfs_obj(pdev);
1088  	if (!dfs) {
1089  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1090  		return;
1091  	}
1092  
1093  	psoc = wlan_pdev_get_psoc(pdev);
1094  	if (!psoc) {
1095  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
1096  		return;
1097  	}
1098  
1099  	qdf_dev = psoc->soc_objmgr.qdf_dev;
1100  	if (!qdf_dev->dev) {
1101  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
1102  		return;
1103  	}
1104  
1105  	dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo));
1106  	if (!dfs_nolinfo)
1107  		return;
1108  
1109  	qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo));
1110  	DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo->dfs_nol, &num_chans);
1111  
1112  	if (num_chans > DFS_MAX_NOL_CHANNEL)
1113  		dfs_nolinfo->num_chans = DFS_MAX_NOL_CHANNEL;
1114  	else
1115  		dfs_nolinfo->num_chans = num_chans;
1116  
1117  	pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo,
1118  			     (uint16_t)sizeof(*dfs_nolinfo));
1119  	qdf_mem_free(dfs_nolinfo);
1120  }
1121  #endif
1122  qdf_export_symbol(utils_dfs_save_nol);
1123  
utils_dfs_print_nol_channels(struct wlan_objmgr_pdev * pdev)1124  void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev)
1125  {
1126  	struct wlan_dfs *dfs = NULL;
1127  
1128  	dfs = wlan_pdev_get_dfs_obj(pdev);
1129  	if (!dfs) {
1130  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1131  		return;
1132  	}
1133  
1134  	DFS_PRINT_NOL_LOCKED(dfs);
1135  }
1136  qdf_export_symbol(utils_dfs_print_nol_channels);
1137  
utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev * pdev)1138  void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev)
1139  {
1140  	struct wlan_dfs *dfs = NULL;
1141  
1142  	dfs = wlan_pdev_get_dfs_obj(pdev);
1143  	if (!dfs) {
1144  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1145  		return;
1146  	}
1147  
1148  	/* First print list */
1149  	DFS_PRINT_NOL_LOCKED(dfs);
1150  
1151  	/* clear local cache first */
1152  	dfs_nol_timer_cleanup(dfs);
1153  	dfs_nol_update(dfs);
1154  
1155  	/*
1156  	 * update platform driver nol list with local cache which is zero,
1157  	 * cleared in above step, so this will clear list in platform driver.
1158  	 */
1159  	utils_dfs_save_nol(pdev);
1160  }
1161  qdf_export_symbol(utils_dfs_clear_nol_channels);
1162  
1163  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t * freq_list,uint8_t num_chan,bool nol_chan)1164  void utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev *pdev,
1165  					  uint16_t *freq_list,
1166  					  uint8_t num_chan,
1167  					  bool nol_chan)
1168  {
1169  	wlan_reg_update_nol_ch_for_freq(pdev, freq_list, num_chan, nol_chan);
1170  }
1171  
1172  qdf_export_symbol(utils_dfs_reg_update_nol_chan_for_freq);
1173  #endif
1174  
1175  #ifdef CONFIG_CHAN_FREQ_API
1176  void
utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t * freq_list,uint8_t num_chan,bool nol_history_chan)1177  utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev *pdev,
1178  					       uint16_t *freq_list,
1179  					       uint8_t num_chan,
1180  					       bool nol_history_chan)
1181  {
1182  	wlan_reg_update_nol_history_ch_for_freq(pdev, freq_list, num_chan,
1183  						nol_history_chan);
1184  }
1185  #endif
1186  
utils_dfs_freq_to_chan(uint32_t freq)1187  uint8_t utils_dfs_freq_to_chan(uint32_t freq)
1188  {
1189  	uint8_t chan;
1190  
1191  	if (freq == 0)
1192  		return 0;
1193  
1194  	if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ)
1195  		chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ);
1196  	else if (freq == DFS_CHAN_14_FREQ)
1197  		chan = DFS_24_GHZ_CHANNEL_14;
1198  	else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ))
1199  		chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) +
1200  			DFS_24_GHZ_CHANNEL_15);
1201  	else
1202  		chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ;
1203  
1204  	return chan;
1205  }
1206  qdf_export_symbol(utils_dfs_freq_to_chan);
1207  
utils_dfs_chan_to_freq(uint8_t chan)1208  uint32_t utils_dfs_chan_to_freq(uint8_t chan)
1209  {
1210  	if (chan == 0)
1211  		return 0;
1212  
1213  	if (chan < DFS_24_GHZ_CHANNEL_14)
1214  		return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
1215  	else if (chan == DFS_24_GHZ_CHANNEL_14)
1216  		return DFS_CHAN_14_FREQ;
1217  	else if (chan < DFS_24_GHZ_CHANNEL_27)
1218  		return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) *
1219  				DFS_CHAN_SPACING_20MHZ);
1220  	else if (chan == DFS_5_GHZ_CHANNEL_170)
1221  		return DFS_CHAN_170_FREQ;
1222  	else
1223  		return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
1224  }
1225  qdf_export_symbol(utils_dfs_chan_to_freq);
1226  
1227  #ifdef MOBILE_DFS_SUPPORT
1228  
1229  #ifdef CONFIG_CHAN_FREQ_API
utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev * pdev,enum phy_ch_width ch_width,uint8_t temp_chan_lst_sz,uint16_t * temp_freq_lst)1230  QDF_STATUS utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev *pdev,
1231  	enum phy_ch_width ch_width,
1232  	uint8_t temp_chan_lst_sz,
1233  	uint16_t *temp_freq_lst)
1234  {
1235  	struct wlan_dfs *dfs = NULL;
1236  
1237  	dfs = wlan_pdev_get_dfs_obj(pdev);
1238  	if (!dfs) {
1239  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1240  		return  QDF_STATUS_E_FAILURE;
1241  	}
1242  
1243  	return dfs_mark_leaking_chan_for_freq(dfs, ch_width, temp_chan_lst_sz,
1244  					    temp_freq_lst);
1245  }
1246  qdf_export_symbol(utils_dfs_mark_leaking_chan_for_freq);
1247  #endif
1248  #endif
1249  
utils_get_dfsdomain(struct wlan_objmgr_pdev * pdev)1250  int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev)
1251  {
1252  	enum dfs_reg dfsdomain;
1253  
1254  	wlan_reg_get_dfs_region(pdev, &dfsdomain);
1255  
1256  	return dfsdomain;
1257  }
1258  
1259  #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev * pdev,bool * is_spoof_check_failed)1260  QDF_STATUS utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev *pdev,
1261  					   bool *is_spoof_check_failed)
1262  {
1263  	struct wlan_dfs *dfs;
1264  
1265  	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
1266  		return QDF_STATUS_SUCCESS;
1267  
1268  	dfs = wlan_pdev_get_dfs_obj(pdev);
1269  	if (!dfs) {
1270  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is null");
1271  		return  QDF_STATUS_E_FAILURE;
1272  	}
1273  
1274  	*is_spoof_check_failed = dfs->dfs_spoof_check_failed;
1275  
1276  	return QDF_STATUS_SUCCESS;
1277  }
1278  
1279  qdf_export_symbol(utils_dfs_is_spoof_check_failed);
1280  
utils_dfs_is_spoof_done(struct wlan_objmgr_pdev * pdev)1281  bool utils_dfs_is_spoof_done(struct wlan_objmgr_pdev *pdev)
1282  {
1283  	struct wlan_dfs *dfs;
1284  
1285  	dfs = wlan_pdev_get_dfs_obj(pdev);
1286  	if (!dfs)
1287  		return false;
1288  
1289  	if (lmac_is_host_dfs_check_support_enabled(dfs->dfs_pdev_obj) &&
1290  	    utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_FCC_DOMAIN)
1291  		return !!dfs->dfs_spoof_test_done;
1292  	return true;
1293  }
1294  #endif
1295  
dfs_get_num_chans(void)1296  int dfs_get_num_chans(void)
1297  {
1298  	return NUM_CHANNELS;
1299  }
1300  
1301  #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev * pdev,bool * disable_radar_marking)1302  QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
1303  					       bool *disable_radar_marking)
1304  {
1305  	struct wlan_dfs *dfs;
1306  
1307  	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
1308  		return QDF_STATUS_SUCCESS;
1309  
1310  	dfs = wlan_pdev_get_dfs_obj(pdev);
1311  	if (!dfs) {
1312  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is null");
1313  		return  QDF_STATUS_E_FAILURE;
1314  	}
1315  
1316  	*disable_radar_marking = dfs_get_disable_radar_marking(dfs);
1317  
1318  	return QDF_STATUS_SUCCESS;
1319  }
1320  
1321  qdf_export_symbol(utils_dfs_get_disable_radar_marking);
1322  #endif
1323  
utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev * pdev)1324  bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev)
1325  {
1326  	struct wlan_dfs *dfs;
1327  
1328  	dfs = wlan_pdev_get_dfs_obj(pdev);
1329  	if (!dfs)
1330  		return false;
1331  
1332  	return WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan);
1333  }
1334  
1335  qdf_export_symbol(utils_is_dfs_cfreq2_ch);
1336  
utils_dfs_deliver_event(struct wlan_objmgr_pdev * pdev,uint16_t freq,enum WLAN_DFS_EVENTS event)1337  void utils_dfs_deliver_event(struct wlan_objmgr_pdev *pdev, uint16_t freq,
1338  			     enum WLAN_DFS_EVENTS event)
1339  {
1340  	if (global_dfs_to_mlme.mlme_dfs_deliver_event)
1341  		global_dfs_to_mlme.mlme_dfs_deliver_event(pdev, freq, event);
1342  }
1343  
utils_dfs_reset_dfs_prevchan(struct wlan_objmgr_pdev * pdev)1344  void utils_dfs_reset_dfs_prevchan(struct wlan_objmgr_pdev *pdev)
1345  {
1346  	struct wlan_dfs *dfs;
1347  
1348  	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
1349  		return;
1350  
1351  	dfs = wlan_pdev_get_dfs_obj(pdev);
1352  	if (!dfs) {
1353  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is null");
1354  		return;
1355  	}
1356  
1357  	dfs_reset_dfs_prevchan(dfs);
1358  }
1359  
1360  #ifdef QCA_SUPPORT_AGILE_DFS
1361  
utils_dfs_agile_sm_deliver_evt(struct wlan_objmgr_pdev * pdev,enum dfs_agile_sm_evt event)1362  void utils_dfs_agile_sm_deliver_evt(struct wlan_objmgr_pdev *pdev,
1363  				    enum dfs_agile_sm_evt event)
1364  {
1365  	struct wlan_dfs *dfs;
1366  	void *event_data;
1367  	struct dfs_soc_priv_obj *dfs_soc_obj;
1368  
1369  	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
1370  		return;
1371  
1372  	dfs = wlan_pdev_get_dfs_obj(pdev);
1373  	if (!dfs) {
1374  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is null");
1375  		return;
1376  	}
1377  
1378  	if (!dfs_is_agile_cac_enabled(dfs))
1379  		return;
1380  
1381  	dfs_soc_obj = dfs->dfs_soc_obj;
1382  	dfs_soc_obj->dfs_priv[dfs->dfs_psoc_idx].agile_precac_active = true;
1383  	event_data = (void *)dfs;
1384  
1385  	dfs_agile_sm_deliver_evt(dfs->dfs_soc_obj,
1386  				 event,
1387  				 0,
1388  				 event_data);
1389  }
1390  #endif
1391  
1392  #ifdef QCA_SUPPORT_ADFS_RCAC
utils_dfs_get_rcac_channel(struct wlan_objmgr_pdev * pdev,struct ch_params * chan_params,qdf_freq_t * target_chan_freq)1393  QDF_STATUS utils_dfs_get_rcac_channel(struct wlan_objmgr_pdev *pdev,
1394  				      struct ch_params *chan_params,
1395  				      qdf_freq_t *target_chan_freq)
1396  {
1397  	struct wlan_dfs *dfs = NULL;
1398  	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1399  
1400  	if (!target_chan_freq)
1401  		return status;
1402  
1403  	*target_chan_freq = 0;
1404  
1405  	dfs = wlan_pdev_get_dfs_obj(pdev);
1406  	if (!dfs) {
1407  		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1408  		return status;
1409  	}
1410  
1411  	if (!dfs_is_agile_rcac_enabled(dfs))
1412  		return status;
1413  
1414  	*target_chan_freq = dfs->dfs_rcac_param.rcac_pri_freq;
1415  
1416  	/* Do not modify the input ch_params if no RCAC channel is present. */
1417  	if (!*target_chan_freq)
1418  		return status;
1419  
1420  	*chan_params = dfs->dfs_rcac_param.rcac_ch_params;
1421  
1422  	return QDF_STATUS_SUCCESS;
1423  }
1424  #endif
1425  
1426  #ifdef ATH_SUPPORT_ZERO_CAC_DFS
1427  enum precac_status_for_chan
utils_dfs_precac_status_for_channel(struct wlan_objmgr_pdev * pdev,struct wlan_channel * deschan)1428  utils_dfs_precac_status_for_channel(struct wlan_objmgr_pdev *pdev,
1429  				    struct wlan_channel *deschan)
1430  {
1431  	struct wlan_dfs *dfs;
1432  	struct dfs_channel chan;
1433  
1434  	dfs = wlan_pdev_get_dfs_obj(pdev);
1435  	if (!dfs)
1436  		return false;
1437  
1438  	dfs_fill_chan_info(&chan, deschan);
1439  
1440  	return dfs_precac_status_for_channel(dfs, &chan);
1441  }
1442  #endif
1443  
1444  #if defined(WLAN_DISP_CHAN_INFO)
1445  #define FIRST_DFS_CHAN_NUM  52
1446  #define CHAN_NUM_SPACING     4
1447  #define INVALID_INDEX     (-1)
1448  
utils_dfs_convert_freq_to_index(qdf_freq_t freq,int8_t * index)1449  void utils_dfs_convert_freq_to_index(qdf_freq_t freq, int8_t *index)
1450  {
1451  	uint16_t chan_num;
1452  	int8_t tmp_index;
1453  
1454  	chan_num = (freq - WLAN_5_GHZ_BASE_FREQ) / WLAN_CHAN_SPACING_5MHZ;
1455  	tmp_index = (chan_num - FIRST_DFS_CHAN_NUM) / CHAN_NUM_SPACING;
1456  	*index = ((tmp_index >= 0) && (tmp_index < NUM_DFS_CHANS)) ?
1457  		  tmp_index : INVALID_INDEX;
1458  }
1459  
1460  /**
1461   * utils_dfs_update_chan_state_array_element() - Update the per dfs channel
1462   * state array element indexed by the frequency with the new state.
1463   * @dfs: DFS context
1464   * @freq: Input DFS Channel frequency which will converted to channel state
1465   * array index.
1466   * @state: Input DFS state with which the value indexed by frequency will be
1467   * updated with.
1468   *
1469   * Return: QDF_STATUS
1470   */
1471  static QDF_STATUS
utils_dfs_update_chan_state_array_element(struct wlan_dfs * dfs,qdf_freq_t freq,enum channel_dfs_state state)1472  utils_dfs_update_chan_state_array_element(struct wlan_dfs *dfs,
1473  					  qdf_freq_t freq,
1474  					  enum channel_dfs_state state)
1475  {
1476  	int8_t index;
1477  	enum channel_enum chan_enum;
1478  
1479  	if (state == CH_DFS_S_INVALID)
1480  		return QDF_STATUS_E_INVAL;
1481  
1482  	chan_enum = wlan_reg_get_chan_enum_for_freq(freq);
1483  	/* Do not send DFS events on invalid IEEE channels */
1484  	if (chan_enum == INVALID_CHANNEL)
1485  		return QDF_STATUS_E_INVAL;
1486  
1487  	utils_dfs_convert_freq_to_index(freq, &index);
1488  
1489  	if (index == INVALID_INDEX)
1490  		return QDF_STATUS_E_INVAL;
1491  
1492  	dfs->dfs_channel_state_array[index] = state;
1493  
1494  	return QDF_STATUS_SUCCESS;
1495  }
1496  
dfs_init_chan_state_array(struct wlan_objmgr_pdev * pdev)1497  QDF_STATUS dfs_init_chan_state_array(struct wlan_objmgr_pdev *pdev)
1498  {
1499  	struct regulatory_channel *cur_chan_list;
1500  	struct wlan_dfs *dfs;
1501  	int i;
1502  
1503  	dfs = wlan_pdev_get_dfs_obj(pdev);
1504  	if (!dfs)
1505  		return QDF_STATUS_E_FAILURE;
1506  
1507  	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
1508  			sizeof(struct regulatory_channel));
1509  	if (!cur_chan_list)
1510  		return QDF_STATUS_E_NOMEM;
1511  
1512  	if (wlan_reg_get_current_chan_list(
1513  				pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
1514  		qdf_mem_free(cur_chan_list);
1515  		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
1516  			  "failed to get curr channel list");
1517  		return QDF_STATUS_E_FAILURE;
1518  	}
1519  
1520  	for (i = 0; i < NUM_CHANNELS; i++) {
1521  		qdf_freq_t freq = cur_chan_list[i].center_freq;
1522  
1523  		if (!IS_CHAN_DFS(cur_chan_list[i].chan_flags))
1524  			continue;
1525  
1526  		utils_dfs_update_chan_state_array_element(dfs,
1527  							  freq,
1528  							  CH_DFS_S_CAC_REQ);
1529  	}
1530  
1531  	qdf_mem_free(cur_chan_list);
1532  	qdf_err("channel state array initialized");
1533  	return QDF_STATUS_SUCCESS;
1534  }
1535  
utils_dfs_get_chan_dfs_state(struct wlan_objmgr_pdev * pdev,enum channel_dfs_state * dfs_ch_s)1536  QDF_STATUS utils_dfs_get_chan_dfs_state(struct wlan_objmgr_pdev *pdev,
1537  					enum channel_dfs_state *dfs_ch_s)
1538  {
1539  	struct wlan_dfs *dfs;
1540  
1541  	dfs = wlan_pdev_get_dfs_obj(pdev);
1542  
1543  	if (!dfs)
1544  		return QDF_STATUS_E_FAILURE;
1545  
1546  	qdf_mem_copy(dfs_ch_s,
1547  		     dfs->dfs_channel_state_array,
1548  		     sizeof(dfs->dfs_channel_state_array));
1549  
1550  	return QDF_STATUS_SUCCESS;
1551  }
1552  
1553  qdf_export_symbol(utils_dfs_get_chan_dfs_state);
1554  
1555  /**
1556   * convert_event_to_state() - Converts the dfs events WLAN_DFS_EVENTS to dfs
1557   * states channel_dfs_state.
1558   * @event: Input DFS event.
1559   * @state: Output DFS state.
1560   *
1561   * Return: void.
1562   */
1563  static
convert_event_to_state(enum WLAN_DFS_EVENTS event,enum channel_dfs_state * state)1564  void convert_event_to_state(enum WLAN_DFS_EVENTS event,
1565  			    enum channel_dfs_state *state)
1566  {
1567  	static const
1568  	enum channel_dfs_state ev_to_state[WLAN_EV_PCAC_COMPLETED + 1] = {
1569  	[WLAN_EV_RADAR_DETECTED] = CH_DFS_S_INVALID,
1570  	[WLAN_EV_CAC_RESET]      = CH_DFS_S_CAC_REQ,
1571  	[WLAN_EV_CAC_STARTED]    = CH_DFS_S_CAC_STARTED,
1572  	[WLAN_EV_CAC_COMPLETED]  = CH_DFS_S_CAC_COMPLETED,
1573  	[WLAN_EV_NOL_STARTED]    = CH_DFS_S_NOL,
1574  	[WLAN_EV_NOL_FINISHED]   = CH_DFS_S_CAC_REQ,
1575  	[WLAN_EV_PCAC_STARTED]   = CH_DFS_S_PRECAC_STARTED,
1576  	[WLAN_EV_PCAC_COMPLETED] = CH_DFS_S_PRECAC_COMPLETED,
1577  	};
1578  
1579  	*state = ev_to_state[event];
1580  }
1581  
utils_dfs_update_chan_state_array(struct wlan_objmgr_pdev * pdev,qdf_freq_t freq,enum WLAN_DFS_EVENTS event)1582  QDF_STATUS utils_dfs_update_chan_state_array(struct wlan_objmgr_pdev *pdev,
1583  					     qdf_freq_t freq,
1584  					     enum WLAN_DFS_EVENTS event)
1585  {
1586  	enum channel_dfs_state state;
1587  	struct wlan_dfs *dfs;
1588  
1589  	dfs = wlan_pdev_get_dfs_obj(pdev);
1590  	if (!dfs)
1591  		return QDF_STATUS_E_FAILURE;
1592  
1593  	convert_event_to_state(event, &state);
1594  	return utils_dfs_update_chan_state_array_element(dfs, freq, state);
1595  }
1596  #endif /* WLAN_DISP_CHAN_INFO */
1597  
utils_dfs_radar_enable(struct wlan_objmgr_pdev * pdev)1598  QDF_STATUS utils_dfs_radar_enable(struct wlan_objmgr_pdev *pdev)
1599  {
1600  	return tgt_dfs_radar_enable(pdev, 0, 0, true);
1601  }
1602  
1603  #ifdef WLAN_FEATURE_11BE
1604  enum phy_ch_width
utils_dfs_convert_wlan_phymode_to_chwidth(enum wlan_phymode phymode)1605  utils_dfs_convert_wlan_phymode_to_chwidth(enum wlan_phymode phymode)
1606  {
1607  		switch (phymode) {
1608  		case WLAN_PHYMODE_11NA_HT20:
1609  		case WLAN_PHYMODE_11NG_HT20:
1610  		case WLAN_PHYMODE_11AC_VHT20:
1611  		case WLAN_PHYMODE_11AC_VHT20_2G:
1612  		case WLAN_PHYMODE_11AXA_HE20:
1613  		case WLAN_PHYMODE_11AXG_HE20:
1614  		case WLAN_PHYMODE_11BEG_EHT20:
1615  		case WLAN_PHYMODE_11BEA_EHT20:
1616  			return CH_WIDTH_20MHZ;
1617  		case WLAN_PHYMODE_11NA_HT40:
1618  		case WLAN_PHYMODE_11NG_HT40PLUS:
1619  		case WLAN_PHYMODE_11NG_HT40MINUS:
1620  		case WLAN_PHYMODE_11NG_HT40:
1621  		case WLAN_PHYMODE_11AC_VHT40:
1622  		case WLAN_PHYMODE_11AC_VHT40PLUS_2G:
1623  		case WLAN_PHYMODE_11AC_VHT40MINUS_2G:
1624  		case WLAN_PHYMODE_11AC_VHT40_2G:
1625  		case WLAN_PHYMODE_11AXG_HE40PLUS:
1626  		case WLAN_PHYMODE_11AXG_HE40MINUS:
1627  		case WLAN_PHYMODE_11AXG_HE40:
1628  		case WLAN_PHYMODE_11BEA_EHT40:
1629  		case WLAN_PHYMODE_11BEG_EHT40PLUS:
1630  		case WLAN_PHYMODE_11BEG_EHT40MINUS:
1631  		case WLAN_PHYMODE_11BEG_EHT40:
1632  			return CH_WIDTH_40MHZ;
1633  		case WLAN_PHYMODE_11AC_VHT80:
1634  		case WLAN_PHYMODE_11AC_VHT80_2G:
1635  		case WLAN_PHYMODE_11AXA_HE80:
1636  		case WLAN_PHYMODE_11AXG_HE80:
1637  		case WLAN_PHYMODE_11BEA_EHT80:
1638  			return CH_WIDTH_80MHZ;
1639  		case WLAN_PHYMODE_11AC_VHT160:
1640  		case WLAN_PHYMODE_11AXA_HE160:
1641  		case WLAN_PHYMODE_11BEA_EHT160:
1642  			return CH_WIDTH_160MHZ;
1643  		case WLAN_PHYMODE_11AC_VHT80_80:
1644  		case WLAN_PHYMODE_11AXA_HE80_80:
1645  			return CH_WIDTH_80P80MHZ;
1646  		case WLAN_PHYMODE_11BEA_EHT320:
1647  			return CH_WIDTH_320MHZ;
1648  		default:
1649  			return CH_WIDTH_INVALID;
1650  		}
1651  }
1652  #else
1653  enum phy_ch_width
utils_dfs_convert_wlan_phymode_to_chwidth(enum wlan_phymode phymode)1654  utils_dfs_convert_wlan_phymode_to_chwidth(enum wlan_phymode phymode)
1655  {
1656  		switch (phymode) {
1657  		case WLAN_PHYMODE_11NA_HT20:
1658  		case WLAN_PHYMODE_11NG_HT20:
1659  		case WLAN_PHYMODE_11AC_VHT20:
1660  		case WLAN_PHYMODE_11AC_VHT20_2G:
1661  		case WLAN_PHYMODE_11AXA_HE20:
1662  		case WLAN_PHYMODE_11AXG_HE20:
1663  			return CH_WIDTH_20MHZ;
1664  		case WLAN_PHYMODE_11NA_HT40:
1665  		case WLAN_PHYMODE_11NG_HT40PLUS:
1666  		case WLAN_PHYMODE_11NG_HT40MINUS:
1667  		case WLAN_PHYMODE_11NG_HT40:
1668  		case WLAN_PHYMODE_11AC_VHT40:
1669  		case WLAN_PHYMODE_11AC_VHT40PLUS_2G:
1670  		case WLAN_PHYMODE_11AC_VHT40MINUS_2G:
1671  		case WLAN_PHYMODE_11AC_VHT40_2G:
1672  		case WLAN_PHYMODE_11AXG_HE40PLUS:
1673  		case WLAN_PHYMODE_11AXG_HE40MINUS:
1674  		case WLAN_PHYMODE_11AXG_HE40:
1675  			return CH_WIDTH_40MHZ;
1676  		case WLAN_PHYMODE_11AC_VHT80:
1677  		case WLAN_PHYMODE_11AC_VHT80_2G:
1678  		case WLAN_PHYMODE_11AXA_HE80:
1679  		case WLAN_PHYMODE_11AXG_HE80:
1680  			return CH_WIDTH_80MHZ;
1681  		case WLAN_PHYMODE_11AC_VHT160:
1682  		case WLAN_PHYMODE_11AXA_HE160:
1683  			return CH_WIDTH_160MHZ;
1684  		case WLAN_PHYMODE_11AC_VHT80_80:
1685  		case WLAN_PHYMODE_11AXA_HE80_80:
1686  			return CH_WIDTH_80P80MHZ;
1687  		default:
1688  			return CH_WIDTH_INVALID;
1689  		}
1690  }
1691  #endif
1692  
1693  #if defined(WLAN_FEATURE_11BE) && defined(QCA_DFS_BW_EXPAND) && \
1694  	defined(QCA_DFS_RCSA_SUPPORT)
1695  uint16_t
utils_dfs_get_radar_bitmap_from_nolie(struct wlan_objmgr_pdev * pdev,enum wlan_phymode phy_mode,qdf_freq_t nol_ie_start_freq,uint8_t nol_ie_bitmap)1696  utils_dfs_get_radar_bitmap_from_nolie(struct wlan_objmgr_pdev *pdev,
1697  				      enum wlan_phymode phy_mode,
1698  				      qdf_freq_t nol_ie_start_freq,
1699  				      uint8_t nol_ie_bitmap)
1700  {
1701  	struct wlan_dfs *dfs;
1702  
1703  	dfs = wlan_pdev_get_dfs_obj(pdev);
1704  	if (!dfs)
1705  		return 0;
1706  
1707  	return dfs_get_radar_bitmap_from_nolie(dfs, phy_mode, nol_ie_start_freq,
1708  					       nol_ie_bitmap);
1709  }
1710  #endif
1711