xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  *
6  * Permission to use, copy, modify, and/or distribute this software for
7  * any purpose with or without fee is hereby granted, provided that the
8  * above copyright notice and this permission notice appear in all
9  * copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18  * PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 /**
22  * DOC: This file has the DFS dispatcher API implementation which is exposed
23  * to outside of DFS component.
24  */
25 #include <wlan_objmgr_vdev_obj.h>
26 #include "wlan_dfs_utils_api.h"
27 #include "wlan_dfs_init_deinit_api.h"
28 #include "wlan_dfs_mlme_api.h"
29 #include "../../core/src/dfs.h"
30 #include "../../core/src/dfs_zero_cac.h"
31 #include <wlan_reg_services_api.h>
32 #include "../../core/src/dfs_random_chan_sel.h"
33 #ifdef QCA_DFS_USE_POLICY_MANAGER
34 #include "wlan_policy_mgr_api.h"
35 #endif
36 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
37 #include <pld_common.h>
38 #endif
39 #include <qdf_module.h>
40 #include "wlan_dfs_lmac_api.h"
41 #include "../../core/src/dfs_internal.h"
42 
43 struct dfs_nol_info {
44 	uint16_t num_chans;
45 	struct dfsreq_nolelem dfs_nol[DFS_MAX_NOL_CHANNEL];
46 };
47 
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 	    !tgt_tx_ops->tgt_is_tgt_type_qcn9160)
350 		return false;
351 
352 	if (!tgt_tx_ops->tgt_is_tgt_type_qcn6122(target_type) ||
353 	    !tgt_tx_ops->tgt_is_tgt_type_qcn9160(target_type))
354 		return false;
355 
356 	cur_freq = dfs->dfs_curchan->dfs_ch_freq;
357 
358 	/* Is the current channel width 80MHz? */
359 	if (WLAN_IS_CHAN_MODE_80(dfs->dfs_curchan) ||
360 	    WLAN_IS_CHAN_MODE_40(dfs->dfs_curchan) ||
361 	    WLAN_IS_CHAN_MODE_20(dfs->dfs_curchan)) {
362 		/* is the primary channel 52/56/60/64? */
363 		bool is_chan_spur_80mhzfreq =
364 		    DFS_IS_CHAN_SPRUCE_SPUR_FREQ_80MHZ(cur_freq);
365 		if (is_chan_spur_80mhzfreq)
366 			return true;
367 		return false;
368 	}
369 
370 	/* If the current channel width is not 80, is it 160MHz? */
371 	if (WLAN_IS_CHAN_MODE_160(dfs->dfs_curchan)) {
372 		/* is the primary channel 36/44/48/52/56/60/64? */
373 		bool is_chan_spur_160mhz_freq =
374 		    DFS_IS_CHAN_SPRUCE_SPUR_FREQ_160MHZ(cur_freq);
375 		if (is_chan_spur_160mhz_freq)
376 			return true;
377 		return false;
378 	}
379 
380 	return false;
381 }
382 
383 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev)
384 {
385 	struct wlan_dfs *dfs;
386 
387 	dfs = wlan_pdev_get_dfs_obj(pdev);
388 	if (!dfs)
389 		return  QDF_STATUS_E_FAILURE;
390 
391 	dfs_radar_disable(dfs);
392 
393 	return QDF_STATUS_SUCCESS;
394 }
395 qdf_export_symbol(utils_dfs_radar_disable);
396 
397 QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev,
398 		bool val)
399 {
400 	struct wlan_dfs *dfs;
401 
402 	dfs = wlan_pdev_get_dfs_obj(pdev);
403 	if (!dfs)
404 		return  QDF_STATUS_E_FAILURE;
405 
406 	dfs_set_update_nol_flag(dfs, val);
407 
408 	return QDF_STATUS_SUCCESS;
409 }
410 qdf_export_symbol(utils_dfs_set_update_nol_flag);
411 
412 QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev,
413 		bool *nol_flag)
414 {
415 	struct wlan_dfs *dfs;
416 
417 	dfs = wlan_pdev_get_dfs_obj(pdev);
418 	if (!dfs)
419 		return  QDF_STATUS_E_FAILURE;
420 
421 	*nol_flag = dfs_get_update_nol_flag(dfs);
422 
423 	return QDF_STATUS_SUCCESS;
424 }
425 qdf_export_symbol(utils_dfs_get_update_nol_flag);
426 
427 QDF_STATUS utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev *pdev,
428 		int *dfs_use_nol)
429 {
430 	struct wlan_dfs *dfs;
431 
432 	dfs = wlan_pdev_get_dfs_obj(pdev);
433 	if (!dfs)
434 		return  QDF_STATUS_E_FAILURE;
435 
436 	*dfs_use_nol = dfs_get_use_nol(dfs);
437 
438 	return QDF_STATUS_SUCCESS;
439 }
440 qdf_export_symbol(utils_dfs_get_dfs_use_nol);
441 
442 QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev,
443 		int *dfs_nol_timeout)
444 {
445 	struct wlan_dfs *dfs;
446 
447 	dfs = wlan_pdev_get_dfs_obj(pdev);
448 	if (!dfs)
449 		return  QDF_STATUS_E_FAILURE;
450 
451 	*dfs_nol_timeout = dfs_get_nol_timeout(dfs);
452 
453 	return QDF_STATUS_SUCCESS;
454 }
455 qdf_export_symbol(utils_dfs_get_nol_timeout);
456 
457 QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev,
458 		uint16_t freq,
459 		uint32_t dfs_nol_timeout)
460 {
461 	struct wlan_dfs *dfs;
462 
463 	dfs = wlan_pdev_get_dfs_obj(pdev);
464 	if (!dfs)
465 		return  QDF_STATUS_E_FAILURE;
466 
467 	DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, dfs_nol_timeout);
468 
469 	return QDF_STATUS_SUCCESS;
470 }
471 qdf_export_symbol(utils_dfs_nol_addchan);
472 
473 QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev)
474 {
475 	struct wlan_dfs *dfs;
476 
477 	dfs = wlan_pdev_get_dfs_obj(pdev);
478 	if (!dfs)
479 		return  QDF_STATUS_E_FAILURE;
480 
481 	dfs_nol_update(dfs);
482 
483 	return QDF_STATUS_SUCCESS;
484 }
485 qdf_export_symbol(utils_dfs_nol_update);
486 
487 QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev)
488 {
489 	struct wlan_dfs *dfs;
490 
491 	dfs = wlan_pdev_get_dfs_obj(pdev);
492 	if (!dfs)
493 		return  QDF_STATUS_E_FAILURE;
494 
495 	dfs_second_segment_radar_disable(dfs);
496 
497 	return QDF_STATUS_SUCCESS;
498 }
499 
500 QDF_STATUS utils_dfs_bw_reduce(struct wlan_objmgr_pdev *pdev, bool bw_reduce)
501 {
502 	struct wlan_dfs *dfs;
503 
504 	dfs = wlan_pdev_get_dfs_obj(pdev);
505 	if (!dfs)
506 		return  QDF_STATUS_E_FAILURE;
507 
508 	dfs->dfs_bw_reduced = bw_reduce;
509 
510 	return QDF_STATUS_SUCCESS;
511 }
512 
513 qdf_export_symbol(utils_dfs_bw_reduce);
514 
515 QDF_STATUS utils_dfs_is_bw_reduce(struct wlan_objmgr_pdev *pdev,
516 				  bool *bw_reduce)
517 {
518 	struct wlan_dfs *dfs;
519 
520 	dfs = wlan_pdev_get_dfs_obj(pdev);
521 	if (!dfs)
522 		return  QDF_STATUS_E_FAILURE;
523 
524 	*bw_reduce = dfs->dfs_bw_reduced;
525 
526 	return QDF_STATUS_SUCCESS;
527 }
528 
529 QDF_STATUS utils_dfs_fetch_nol_ie_info(struct wlan_objmgr_pdev *pdev,
530 				       uint8_t *nol_ie_bandwidth,
531 				       uint16_t *nol_ie_startfreq,
532 				       uint8_t *nol_ie_bitmap)
533 {
534 	struct wlan_dfs *dfs;
535 
536 	dfs = wlan_pdev_get_dfs_obj(pdev);
537 	if (!dfs)
538 		return  QDF_STATUS_E_FAILURE;
539 
540 	dfs_fetch_nol_ie_info(dfs, nol_ie_bandwidth, nol_ie_startfreq,
541 			      nol_ie_bitmap);
542 
543 	return QDF_STATUS_SUCCESS;
544 }
545 
546 QDF_STATUS utils_dfs_set_rcsa_flags(struct wlan_objmgr_pdev *pdev,
547 				    bool is_rcsa_ie_sent,
548 				    bool is_nol_ie_sent)
549 {
550 	struct wlan_dfs *dfs;
551 
552 	dfs = wlan_pdev_get_dfs_obj(pdev);
553 	if (!dfs)
554 		return  QDF_STATUS_E_FAILURE;
555 
556 	dfs_set_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent);
557 
558 	return QDF_STATUS_SUCCESS;
559 }
560 
561 QDF_STATUS utils_dfs_get_rcsa_flags(struct wlan_objmgr_pdev *pdev,
562 				    bool *is_rcsa_ie_sent,
563 				    bool *is_nol_ie_sent)
564 {
565 	struct wlan_dfs *dfs;
566 
567 	dfs = wlan_pdev_get_dfs_obj(pdev);
568 	if (!dfs)
569 		return  QDF_STATUS_E_FAILURE;
570 	dfs_get_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent);
571 
572 	return QDF_STATUS_SUCCESS;
573 }
574 
575 bool utils_dfs_process_nol_ie_bitmap(struct wlan_objmgr_pdev *pdev,
576 				     uint8_t nol_ie_bandwidth,
577 				     uint16_t nol_ie_startfreq,
578 				     uint8_t nol_ie_bitmap)
579 {
580 	struct wlan_dfs *dfs;
581 
582 	dfs = wlan_pdev_get_dfs_obj(pdev);
583 	if (!dfs)
584 		return  false;
585 	return dfs_process_nol_ie_bitmap(dfs, nol_ie_bandwidth,
586 					 nol_ie_startfreq,
587 					 nol_ie_bitmap);
588 }
589 
590 QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev,
591 		int val)
592 {
593 	struct wlan_dfs *dfs;
594 
595 	dfs = wlan_pdev_get_dfs_obj(pdev);
596 	if (!dfs)
597 		return  QDF_STATUS_E_FAILURE;
598 
599 	dfs->dfs_cac_timer_running = val;
600 
601 	return QDF_STATUS_SUCCESS;
602 }
603 qdf_export_symbol(utils_dfs_set_cac_timer_running);
604 
605 QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev,
606 		void *nollist,
607 		uint32_t *nol_chfreq,
608 		uint32_t *nol_chwidth,
609 		int index)
610 {
611 	struct wlan_dfs *dfs;
612 
613 	dfs = wlan_pdev_get_dfs_obj(pdev);
614 	if (!dfs)
615 		return  QDF_STATUS_E_FAILURE;
616 
617 	dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index);
618 
619 	return QDF_STATUS_SUCCESS;
620 }
621 qdf_export_symbol(utils_dfs_get_nol_chfreq_and_chwidth);
622 
623 QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev,
624 		uint64_t flags,
625 		uint16_t flagext)
626 {
627 	struct wlan_dfs *dfs;
628 
629 	dfs = wlan_pdev_get_dfs_obj(pdev);
630 	if (!dfs)
631 		return  QDF_STATUS_E_FAILURE;
632 
633 	dfs_update_cur_chan_flags(dfs, flags, flagext);
634 
635 	return QDF_STATUS_SUCCESS;
636 }
637 
638 static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev,
639 		uint32_t *phy_mode)
640 {
641 	return;
642 }
643 
644 static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev,
645 		uint8_t *ch_width)
646 {
647 	return;
648 }
649 
650 #ifndef QCA_DFS_USE_POLICY_MANAGER
651 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
652 			     void *clist, uint32_t *num_chan)
653 {
654 	uint32_t i = 0, j = 0;
655 	enum channel_state state;
656 	struct regulatory_channel *cur_chan_list;
657 	struct wlan_dfs *dfs;
658 	struct dfs_channel *chan_list = (struct dfs_channel *)clist;
659 
660 	dfs = wlan_pdev_get_dfs_obj(pdev);
661 	if (!dfs) {
662 		*num_chan = 0;
663 		return;
664 	}
665 
666 	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
667 			sizeof(struct regulatory_channel));
668 	if (!cur_chan_list) {
669 		*num_chan = 0;
670 		return;
671 	}
672 
673 	if (wlan_reg_get_current_chan_list(
674 			pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
675 		*num_chan = 0;
676 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
677 				"failed to get curr channel list");
678 		return;
679 	}
680 
681 	for (i = 0; i < NUM_CHANNELS; i++) {
682 		state = cur_chan_list[i].state;
683 		if (state == CHANNEL_STATE_DFS ||
684 				state == CHANNEL_STATE_ENABLE) {
685 			chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num;
686 			chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq;
687 			if (state == CHANNEL_STATE_DFS)
688 				chan_list[j].dfs_ch_flagext =
689 					WLAN_CHAN_DFS;
690 
691 			if (cur_chan_list[i].nol_history)
692 				chan_list[j].dfs_ch_flagext |=
693 					WLAN_CHAN_HISTORY_RADAR;
694 			j++;
695 		}
696 	}
697 	*num_chan = j;
698 	qdf_mem_free(cur_chan_list);
699 
700 	return;
701 }
702 
703 /**
704  * utils_dfs_get_channel_list() - Get channel list from regdb component, based
705  * on current channel list.
706  * @pdev: Pointer to pdev structure.
707  * @vdev: vdev of request
708  * @chan_list: Pointer to channel list.
709  * @num_chan: number of channels.
710  *
711  * Get regdb channel list based on dfs current channel.
712  * Ex: When  AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels
713  * so that the random channel function does not select either 2.4GHz or 4.9GHz
714  * channel.
715  */
716 #ifdef CONFIG_CHAN_FREQ_API
717 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
718 				       struct wlan_objmgr_vdev *vdev,
719 				       struct dfs_channel *chan_list,
720 				       uint32_t *num_chan)
721 {
722 	struct dfs_channel *tmp_chan_list = NULL;
723 	struct wlan_dfs *dfs;
724 	bool is_curchan_5g;
725 	bool is_curchan_24g;
726 	bool is_curchan_49g;
727 	bool is_inter_band_switch_allowed;
728 	uint8_t chan_num;
729 	uint16_t center_freq;
730 	uint16_t flagext;
731 	uint32_t i, j = 0;
732 
733 	dfs = wlan_pdev_get_dfs_obj(pdev);
734 	if (!dfs) {
735 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
736 		return;
737 	}
738 
739 	tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list));
740 	if (!tmp_chan_list)
741 		return;
742 
743 	utils_dfs_get_chan_list(pdev, (void *)tmp_chan_list, num_chan);
744 
745 	chan_num = dfs->dfs_curchan->dfs_ch_ieee;
746 	center_freq = dfs->dfs_curchan->dfs_ch_freq;
747 	is_curchan_5g = WLAN_REG_IS_5GHZ_CH_FREQ(center_freq);
748 	is_curchan_24g = WLAN_REG_IS_24GHZ_CH_FREQ(center_freq);
749 	is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq);
750 	is_inter_band_switch_allowed =
751 		dfs_mlme_is_inter_band_chan_switch_allowed(dfs->dfs_pdev_obj);
752 
753 	for (i = 0; i < *num_chan; i++) {
754 		chan_num = tmp_chan_list[i].dfs_ch_ieee;
755 		center_freq = tmp_chan_list[i].dfs_ch_freq;
756 		flagext = tmp_chan_list[i].dfs_ch_flagext;
757 		/* No change in prototype needed. Hence retaining same func */
758 		if (!dfs_mlme_check_allowed_prim_chanlist(pdev, center_freq))
759 			continue;
760 
761 		if (is_curchan_5g) {
762 			/*
763 			 * Always add 5G channels.
764 			 * If inter band is allowed, add 6G also.
765 			 */
766 			if (WLAN_REG_IS_5GHZ_CH_FREQ(center_freq) ||
767 			    (is_inter_band_switch_allowed &&
768 			     WLAN_REG_IS_6GHZ_CHAN_FREQ(center_freq))) {
769 				chan_list[j].dfs_ch_ieee = chan_num;
770 				chan_list[j].dfs_ch_freq = center_freq;
771 				chan_list[j].dfs_ch_flagext = flagext;
772 				j++;
773 			}
774 		} else if ((is_curchan_24g) &&
775 				WLAN_REG_IS_24GHZ_CH_FREQ(center_freq)) {
776 			chan_list[j].dfs_ch_ieee = chan_num;
777 			chan_list[j].dfs_ch_freq = center_freq;
778 			j++;
779 		} else if ((is_curchan_49g) &&
780 				WLAN_REG_IS_49GHZ_FREQ(center_freq)) {
781 			chan_list[j].dfs_ch_ieee = chan_num;
782 			chan_list[j].dfs_ch_freq = center_freq;
783 			j++;
784 		}
785 	}
786 
787 	*num_chan = j;
788 
789 	qdf_mem_free(tmp_chan_list);
790 }
791 #endif
792 #else
793 void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev,
794 					 void *clist, uint32_t *num_chan)
795 {
796 	utils_dfs_get_chan_list(pdev, clist, num_chan);
797 }
798 
799 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
800 				       struct wlan_objmgr_vdev *vdev,
801 				       struct dfs_channel *chan_list,
802 				       uint32_t *num_chan)
803 {
804 	uint32_t pcl_ch[NUM_CHANNELS] = {0};
805 	uint8_t weight_list[NUM_CHANNELS] = {0};
806 	uint32_t len;
807 	uint32_t weight_len;
808 	uint32_t i;
809 	struct wlan_objmgr_psoc *psoc;
810 	uint32_t conn_count = 0;
811 	enum policy_mgr_con_mode mode;
812 
813 	psoc = wlan_pdev_get_psoc(pdev);
814 	if (!psoc) {
815 		*num_chan = 0;
816 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
817 		return;
818 	}
819 
820 	len = QDF_ARRAY_SIZE(pcl_ch);
821 	weight_len = QDF_ARRAY_SIZE(weight_list);
822 
823 	if (vdev)
824 		mode = policy_mgr_convert_device_mode_to_qdf_type(
825 				wlan_vdev_mlme_get_opmode(vdev));
826 	else
827 		mode = PM_SAP_MODE;
828 	conn_count = policy_mgr_mode_specific_connection_count(
829 			psoc, mode, NULL);
830 	if (0 == conn_count)
831 		policy_mgr_get_pcl(psoc, mode, pcl_ch,
832 				   &len, weight_list, weight_len);
833 	else
834 		policy_mgr_get_pcl_for_existing_conn(
835 			psoc, mode, pcl_ch, &len, weight_list,
836 			weight_len, true);
837 
838 	if (*num_chan < len) {
839 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
840 				"Invalid len src=%d, dst=%d",
841 				*num_chan, len);
842 		*num_chan = 0;
843 		return;
844 	}
845 
846 	for (i = 0; i < len; i++) {
847 		chan_list[i].dfs_ch_ieee  =
848 			wlan_reg_freq_to_chan(pdev, pcl_ch[i]);
849 		chan_list[i].dfs_ch_freq  = pcl_ch[i];
850 		if (wlan_reg_is_dfs_for_freq(pdev, pcl_ch[i]))
851 			chan_list[i].dfs_ch_flagext |= WLAN_CHAN_DFS;
852 	}
853 	*num_chan = i;
854 	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i);
855 }
856 
857 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
858 			     void *clist, uint32_t *num_chan)
859 {
860 	utils_dfs_get_channel_list(pdev, NULL, (struct dfs_channel *)clist,
861 				   num_chan);
862 }
863 
864 bool utils_dfs_can_ignore_radar_event(struct wlan_objmgr_pdev *pdev)
865 {
866 	return policy_mgr_get_can_skip_radar_event(
867 		wlan_pdev_get_psoc(pdev), INVALID_VDEV_ID);
868 }
869 #endif
870 
871 #ifdef CONFIG_CHAN_FREQ_API
872 QDF_STATUS utils_dfs_get_vdev_random_channel_for_freq(
873 	struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev,
874 	uint16_t flags, struct ch_params *chan_params, uint32_t *hw_mode,
875 	uint16_t *target_chan_freq, struct dfs_acs_info *acs_info)
876 {
877 	uint32_t dfs_reg;
878 	uint32_t num_chan = NUM_CHANNELS;
879 	struct wlan_dfs *dfs = NULL;
880 	struct wlan_objmgr_psoc *psoc;
881 	struct dfs_channel *chan_list = NULL;
882 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
883 
884 	*target_chan_freq = 0;
885 	psoc = wlan_pdev_get_psoc(pdev);
886 	if (!psoc) {
887 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
888 		goto random_chan_error;
889 	}
890 
891 	dfs = wlan_pdev_get_dfs_obj(pdev);
892 	if (!dfs) {
893 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
894 		goto random_chan_error;
895 	}
896 
897 	wlan_reg_get_dfs_region(pdev, &dfs_reg);
898 	chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list));
899 	if (!chan_list)
900 		goto random_chan_error;
901 
902 	utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan);
903 	if (!num_chan) {
904 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "zero channels");
905 		goto random_chan_error;
906 	}
907 
908 	if (!chan_params->ch_width)
909 		utils_dfs_get_max_sup_width(pdev,
910 					    (uint8_t *)&chan_params->ch_width);
911 
912 	*target_chan_freq = dfs_prepare_random_channel_for_freq(
913 			dfs, chan_list, num_chan, flags, chan_params,
914 			(uint8_t)dfs_reg, acs_info);
915 
916 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
917 		 "input width=%d", chan_params->ch_width);
918 
919 	if (*target_chan_freq) {
920 		wlan_reg_set_channel_params_for_pwrmode(
921 						     pdev, *target_chan_freq, 0,
922 						     chan_params,
923 						     REG_CURRENT_PWR_MODE);
924 		utils_dfs_get_max_phy_mode(pdev, hw_mode);
925 		status = QDF_STATUS_SUCCESS;
926 	}
927 
928 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
929 		 "ch=%d, seg0=%d, seg1=%d, width=%d",
930 		 *target_chan_freq, chan_params->center_freq_seg0,
931 		 chan_params->center_freq_seg1, chan_params->ch_width);
932 
933 random_chan_error:
934 	qdf_mem_free(chan_list);
935 
936 	return status;
937 }
938 
939 qdf_export_symbol(utils_dfs_get_vdev_random_channel_for_freq);
940 #endif
941 
942 #ifdef CONFIG_CHAN_FREQ_API
943 QDF_STATUS utils_dfs_get_random_channel_for_freq(
944 	struct wlan_objmgr_pdev *pdev,
945 	uint16_t flags,
946 	struct ch_params *ch_params,
947 	uint32_t *hw_mode,
948 	uint16_t *target_chan_freq,
949 	struct dfs_acs_info *acs_info)
950 {
951 	return utils_dfs_get_vdev_random_channel_for_freq(pdev, NULL, flags,
952 							  ch_params, hw_mode,
953 							  target_chan_freq,
954 							  acs_info);
955 }
956 
957 qdf_export_symbol(utils_dfs_get_random_channel_for_freq);
958 #endif
959 
960 #ifdef CONFIG_CHAN_FREQ_API
961 QDF_STATUS utils_dfs_bw_reduced_channel_for_freq(
962 						 struct wlan_objmgr_pdev *pdev,
963 						 struct ch_params *chan_params,
964 						 uint32_t *hw_mode,
965 						 uint16_t *target_chan_freq)
966 {
967 	struct wlan_dfs *dfs = NULL;
968 	struct wlan_objmgr_psoc *psoc;
969 	enum channel_state ch_state;
970 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
971 	struct dfs_channel *dfs_curchan;
972 
973 	*target_chan_freq = 0;
974 	psoc = wlan_pdev_get_psoc(pdev);
975 	if (!psoc) {
976 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
977 		return status;
978 	}
979 
980 	dfs = wlan_pdev_get_dfs_obj(pdev);
981 	if (!dfs) {
982 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
983 		return status;
984 	}
985 	dfs_curchan = dfs->dfs_curchan;
986 	ch_state =
987 		wlan_reg_get_channel_state_for_pwrmode(pdev,
988 						       dfs_curchan->dfs_ch_freq,
989 						       REG_CURRENT_PWR_MODE);
990 
991 	if (ch_state == CHANNEL_STATE_DFS ||
992 	    ch_state == CHANNEL_STATE_ENABLE) {
993 		/* If the current channel is 80P80MHz and radar is detected on
994 		 * the channel, the next highest bandwidth that maybe available
995 		 * is 80MHz. Since the current regulatory algorithm reduces the
996 		 * bandwidth from 80P80MHz to 160MHz, provide the channel
997 		 * width as 80MHz if current channel is 80P80MHz.
998 		 */
999 		if (chan_params->ch_width == CH_WIDTH_80P80MHZ)
1000 			chan_params->ch_width = CH_WIDTH_80MHZ;
1001 
1002 		chan_params->mhz_freq_seg0 =
1003 			dfs_curchan->dfs_ch_mhz_freq_seg1;
1004 		chan_params->mhz_freq_seg1 =
1005 			dfs_curchan->dfs_ch_mhz_freq_seg2;
1006 		wlan_reg_set_channel_params_for_pwrmode(pdev, dfs_curchan->
1007 							dfs_ch_freq,
1008 							0, chan_params,
1009 							REG_CURRENT_PWR_MODE);
1010 
1011 		*target_chan_freq = dfs_curchan->dfs_ch_freq;
1012 		utils_dfs_get_max_phy_mode(pdev, hw_mode);
1013 
1014 		return QDF_STATUS_SUCCESS;
1015 	}
1016 
1017 	return status;
1018 }
1019 
1020 qdf_export_symbol(utils_dfs_bw_reduced_channel_for_freq);
1021 #endif
1022 
1023 
1024 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
1025 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev)
1026 {
1027 	struct wlan_dfs *dfs;
1028 	struct wlan_objmgr_psoc *psoc;
1029 	qdf_device_t qdf_dev;
1030 	struct dfs_nol_info *dfs_nolinfo;
1031 	int len;
1032 
1033 	dfs = wlan_pdev_get_dfs_obj(pdev);
1034 	psoc = wlan_pdev_get_psoc(pdev);
1035 	if (!dfs || !psoc) {
1036 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
1037 				"dfs %pK, psoc %pK", dfs, psoc);
1038 		return;
1039 	}
1040 
1041 	qdf_dev = psoc->soc_objmgr.qdf_dev;
1042 	if (!qdf_dev->dev) {
1043 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
1044 		return;
1045 	}
1046 
1047 	dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo));
1048 	if (!dfs_nolinfo)
1049 		return;
1050 
1051 	qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo));
1052 	len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo,
1053 				   (uint16_t)sizeof(*dfs_nolinfo));
1054 	if (len > 0) {
1055 		dfs_set_nol(dfs, dfs_nolinfo->dfs_nol, dfs_nolinfo->num_chans);
1056 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld");
1057 		DFS_PRINT_NOL_LOCKED(dfs);
1058 	} else {
1059 		dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,  "no nol in pld");
1060 	}
1061 	qdf_mem_free(dfs_nolinfo);
1062 }
1063 qdf_export_symbol(utils_dfs_init_nol);
1064 #endif
1065 
1066 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
1067 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
1068 {
1069 }
1070 #else
1071 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
1072 {
1073 	struct dfs_nol_info *dfs_nolinfo;
1074 	struct wlan_dfs *dfs = NULL;
1075 	struct wlan_objmgr_psoc *psoc;
1076 	qdf_device_t qdf_dev;
1077 	int num_chans = 0;
1078 
1079 	dfs = wlan_pdev_get_dfs_obj(pdev);
1080 	if (!dfs) {
1081 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1082 		return;
1083 	}
1084 
1085 	psoc = wlan_pdev_get_psoc(pdev);
1086 	if (!psoc) {
1087 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
1088 		return;
1089 	}
1090 
1091 	qdf_dev = psoc->soc_objmgr.qdf_dev;
1092 	if (!qdf_dev->dev) {
1093 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
1094 		return;
1095 	}
1096 
1097 	dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo));
1098 	if (!dfs_nolinfo)
1099 		return;
1100 
1101 	qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo));
1102 	DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo->dfs_nol, &num_chans);
1103 
1104 	if (num_chans > DFS_MAX_NOL_CHANNEL)
1105 		dfs_nolinfo->num_chans = DFS_MAX_NOL_CHANNEL;
1106 	else
1107 		dfs_nolinfo->num_chans = num_chans;
1108 
1109 	pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo,
1110 			     (uint16_t)sizeof(*dfs_nolinfo));
1111 	qdf_mem_free(dfs_nolinfo);
1112 }
1113 #endif
1114 qdf_export_symbol(utils_dfs_save_nol);
1115 
1116 void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev)
1117 {
1118 	struct wlan_dfs *dfs = NULL;
1119 
1120 	dfs = wlan_pdev_get_dfs_obj(pdev);
1121 	if (!dfs) {
1122 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1123 		return;
1124 	}
1125 
1126 	DFS_PRINT_NOL_LOCKED(dfs);
1127 }
1128 qdf_export_symbol(utils_dfs_print_nol_channels);
1129 
1130 void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev)
1131 {
1132 	struct wlan_dfs *dfs = NULL;
1133 
1134 	dfs = wlan_pdev_get_dfs_obj(pdev);
1135 	if (!dfs) {
1136 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1137 		return;
1138 	}
1139 
1140 	/* First print list */
1141 	DFS_PRINT_NOL_LOCKED(dfs);
1142 
1143 	/* clear local cache first */
1144 	dfs_nol_timer_cleanup(dfs);
1145 	dfs_nol_update(dfs);
1146 
1147 	/*
1148 	 * update platform driver nol list with local cache which is zero,
1149 	 * cleared in above step, so this will clear list in platform driver.
1150 	 */
1151 	utils_dfs_save_nol(pdev);
1152 }
1153 qdf_export_symbol(utils_dfs_clear_nol_channels);
1154 
1155 #ifdef CONFIG_CHAN_FREQ_API
1156 void utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev *pdev,
1157 					  uint16_t *freq_list,
1158 					  uint8_t num_chan,
1159 					  bool nol_chan)
1160 {
1161 	wlan_reg_update_nol_ch_for_freq(pdev, freq_list, num_chan, nol_chan);
1162 }
1163 
1164 qdf_export_symbol(utils_dfs_reg_update_nol_chan_for_freq);
1165 #endif
1166 
1167 #ifdef CONFIG_CHAN_FREQ_API
1168 void
1169 utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev *pdev,
1170 					       uint16_t *freq_list,
1171 					       uint8_t num_chan,
1172 					       bool nol_history_chan)
1173 {
1174 	wlan_reg_update_nol_history_ch_for_freq(pdev, freq_list, num_chan,
1175 						nol_history_chan);
1176 }
1177 #endif
1178 
1179 uint8_t utils_dfs_freq_to_chan(uint32_t freq)
1180 {
1181 	uint8_t chan;
1182 
1183 	if (freq == 0)
1184 		return 0;
1185 
1186 	if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ)
1187 		chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ);
1188 	else if (freq == DFS_CHAN_14_FREQ)
1189 		chan = DFS_24_GHZ_CHANNEL_14;
1190 	else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ))
1191 		chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) +
1192 			DFS_24_GHZ_CHANNEL_15);
1193 	else
1194 		chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ;
1195 
1196 	return chan;
1197 }
1198 qdf_export_symbol(utils_dfs_freq_to_chan);
1199 
1200 uint32_t utils_dfs_chan_to_freq(uint8_t chan)
1201 {
1202 	if (chan == 0)
1203 		return 0;
1204 
1205 	if (chan < DFS_24_GHZ_CHANNEL_14)
1206 		return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
1207 	else if (chan == DFS_24_GHZ_CHANNEL_14)
1208 		return DFS_CHAN_14_FREQ;
1209 	else if (chan < DFS_24_GHZ_CHANNEL_27)
1210 		return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) *
1211 				DFS_CHAN_SPACING_20MHZ);
1212 	else if (chan == DFS_5_GHZ_CHANNEL_170)
1213 		return DFS_CHAN_170_FREQ;
1214 	else
1215 		return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
1216 }
1217 qdf_export_symbol(utils_dfs_chan_to_freq);
1218 
1219 #ifdef MOBILE_DFS_SUPPORT
1220 
1221 #ifdef CONFIG_CHAN_FREQ_API
1222 QDF_STATUS utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev *pdev,
1223 	enum phy_ch_width ch_width,
1224 	uint8_t temp_chan_lst_sz,
1225 	uint16_t *temp_freq_lst)
1226 {
1227 	struct wlan_dfs *dfs = NULL;
1228 
1229 	dfs = wlan_pdev_get_dfs_obj(pdev);
1230 	if (!dfs) {
1231 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
1232 		return  QDF_STATUS_E_FAILURE;
1233 	}
1234 
1235 	return dfs_mark_leaking_chan_for_freq(dfs, ch_width, temp_chan_lst_sz,
1236 					    temp_freq_lst);
1237 }
1238 qdf_export_symbol(utils_dfs_mark_leaking_chan_for_freq);
1239 #endif
1240 #endif
1241 
1242 int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev)
1243 {
1244 	enum dfs_reg dfsdomain;
1245 
1246 	wlan_reg_get_dfs_region(pdev, &dfsdomain);
1247 
1248 	return dfsdomain;
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  * @dfs: DFS context
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() - Converts 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