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