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