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