xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/dfs_zero_cac.h (revision 11f5a63a6cbdda84849a730de22f0a71e635d58c)
1 /*
2  * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /**
28  * DOC: This file has Zero CAC DFS APIs.
29  */
30 
31 #ifndef _DFS_ZERO_CAC_H_
32 #define _DFS_ZERO_CAC_H_
33 
34 #include "dfs.h"
35 #include <wlan_dfs_tgt_api.h>
36 
37 #ifdef CONFIG_CHAN_NUM_API
38 #define VHT160_IEEE_FREQ_DIFF 16
39 #endif
40 
41 #define OCAC_SUCCESS 0
42 #define OCAC_RESET 1
43 #define OCAC_CANCEL 2
44 
45 #define TREE_DEPTH                        3
46 #define N_SUBCHANS_FOR_80BW               4
47 
48 #define INITIAL_20_CHAN_OFFSET           -6
49 #define INITIAL_40_CHAN_OFFSET           -4
50 #define INITIAL_80_CHAN_OFFSET            0
51 
52 #define NEXT_20_CHAN_OFFSET               4
53 #define NEXT_40_CHAN_OFFSET               8
54 #define NEXT_80_CHAN_OFFSET              16
55 
56 #define DFS_CHWIDTH_20_VAL               20
57 #define DFS_CHWIDTH_40_VAL               40
58 #define DFS_CHWIDTH_80_VAL               80
59 #define DFS_CHWIDTH_160_VAL             160
60 
61 #define WEATHER_CHAN_START              120
62 #define WEATHER_CHAN_END                128
63 
64 /* PreCAC timeout durations in ms. */
65 #define MIN_PRECAC_DURATION                   (6 * 60 * 1000) /* 6 mins */
66 #define MIN_WEATHER_PRECAC_DURATION          (60 * 60 * 1000) /* 1 hour */
67 #define MAX_PRECAC_DURATION              (4 * 60 * 60 * 1000) /* 4 hours */
68 #define MAX_WEATHER_PRECAC_DURATION     (24 * 60 * 60 * 1000) /* 24 hours */
69 
70 #define PCAC_DFS_INDEX_ZERO               0
71 #define PCAC_TIMER_NOT_RUNNING            0
72 #define PRECAC_NOT_STARTED                0
73 /**
74  * struct precac_tree_node - Individual tree node structure for every node in
75  *                           the precac forest maintained.
76  * @left_child:        Pointer to the left child of the node.
77  * @right_child:       Pointer to the right child of the node.
78  * @ch_ieee:           Center channel ieee value.
79  * @ch_freq:           Center channel frequency value (BSTree node key value).
80  * @n_caced_subchs:    Number of CACed subchannels of the ch_ieee.
81  * @n_nol_subchs:      Number of subchannels of the ch_ieee in NOL.
82  * @n_valid_subchs:    Number of subchannels of the ch_ieee available (as per
83  *                     the country's channel list).
84  * @bandwidth:         Bandwidth of the ch_ieee (in the current node).
85  */
86 struct precac_tree_node {
87 	struct precac_tree_node *left_child;
88 	struct precac_tree_node *right_child;
89 	uint8_t ch_ieee;
90 	uint16_t ch_freq;
91 	uint8_t n_caced_subchs;
92 	uint8_t n_nol_subchs;
93 	uint8_t n_valid_subchs;
94 	uint8_t bandwidth;
95 };
96 
97 /**
98  * enum precac_chan_state - Enum for PreCAC state of a channel.
99  * @PRECAC_ERR:            Invalid preCAC state.
100  * @PRECAC_REQUIRED:       preCAC need to be done on the channel.
101  * @PRECAC_NOW:            preCAC is running on the channel.
102  * @PRECAC_DONE:           preCAC is done and channel is clear.
103  * @PRECAC_NOL:            preCAC is done and radar is detected.
104  */
105 enum precac_chan_state {
106 	PRECAC_ERR      = -1,
107 	PRECAC_REQUIRED,
108 	PRECAC_NOW,
109 	PRECAC_DONE,
110 	PRECAC_NOL,
111 };
112 
113 /**
114  * struct dfs_precac_entry - PreCAC entry.
115  * @pe_list:           PreCAC entry.
116  * @vht80_ch_ieee:     VHT80 centre channel IEEE value.
117  * @vht80_ch_freq:     VHT80 centre channel frequency value.
118  * @dfs:               Pointer to wlan_dfs structure.
119  * @tree_root:         Tree root node with 80MHz channel key.
120  */
121 struct dfs_precac_entry {
122 	TAILQ_ENTRY(dfs_precac_entry) pe_list;
123 	uint8_t             vht80_ch_ieee;
124 	uint16_t            vht80_ch_freq;
125 	struct wlan_dfs     *dfs;
126 	struct precac_tree_node *tree_root;
127 };
128 
129 /**
130  * dfs_zero_cac_timer_init() - Initialize zero-cac timers
131  * @dfs_soc_obj: Pointer to DFS SOC object structure.
132  */
133 #if !defined(QCA_MCL_DFS_SUPPORT)
134 void dfs_zero_cac_timer_init(struct dfs_soc_priv_obj *dfs_soc_obj);
135 #else
136 static inline void
137 dfs_zero_cac_timer_init(struct dfs_soc_priv_obj *dfs_soc_obj)
138 {
139 }
140 #endif
141 /**
142  * dfs_print_precaclists() - Print precac list.
143  * @dfs: Pointer to wlan_dfs structure.
144  */
145 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
146 void dfs_print_precaclists(struct wlan_dfs *dfs);
147 #else
148 static inline void dfs_print_precaclists(struct wlan_dfs *dfs)
149 {
150 }
151 #endif
152 
153 /**
154  * dfs_reset_precac_lists() - Resets the precac lists.
155  * @dfs: Pointer to wlan_dfs structure.
156  */
157 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
158 void dfs_reset_precac_lists(struct wlan_dfs *dfs);
159 #else
160 static inline void dfs_reset_precac_lists(struct wlan_dfs *dfs)
161 {
162 }
163 #endif
164 
165 /**
166  * dfs_reset_precaclists() - Clears and initializes precac_list.
167  * @dfs: Pointer to wlan_dfs structure.
168  */
169 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
170 void dfs_reset_precaclists(struct wlan_dfs *dfs);
171 #else
172 static inline void dfs_reset_precaclists(struct wlan_dfs *dfs)
173 {
174 }
175 #endif
176 
177 /**
178  * dfs_deinit_precac_list() - Clears the precac list.
179  * @dfs: Pointer to wlan_dfs dtructure.
180  */
181 void dfs_deinit_precac_list(struct wlan_dfs *dfs);
182 
183 /**
184  * dfs_zero_cac_detach() - Free zero_cac memory.
185  * @dfs: Pointer to wlan_dfs dtructure.
186  */
187 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
188 void dfs_zero_cac_detach(struct wlan_dfs *dfs);
189 #else
190 static inline void dfs_zero_cac_detach(struct wlan_dfs *dfs)
191 {
192 }
193 #endif
194 
195 /**
196  * dfs_init_precac_list() - Init precac list.
197  * @dfs: Pointer to wlan_dfs dtructure.
198  */
199 void dfs_init_precac_list(struct wlan_dfs *dfs);
200 
201 /**
202  * dfs_start_precac_timer() - Start precac timer.
203  * @dfs: Pointer to wlan_dfs structure.
204  * @precac_chan: Start thr precac timer in this channel.
205  */
206 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
207 #ifdef CONFIG_CHAN_NUM_API
208 void dfs_start_precac_timer(struct wlan_dfs *dfs,
209 			    uint8_t precac_chan);
210 #endif
211 
212 /**
213  * dfs_start_precac_timer() - Start precac timer.
214  * @dfs: Pointer to wlan_dfs structure.
215  * @precac_chan_freq: Frequency to start precac timer.
216  */
217 #ifdef CONFIG_CHAN_FREQ_API
218 void dfs_start_precac_timer_for_freq(struct wlan_dfs *dfs,
219 				     uint16_t precac_chan_freq);
220 #endif
221 #else
222 #ifdef CONFIG_CHAN_NUM_API
223 static inline void dfs_start_precac_timer(struct wlan_dfs *dfs,
224 					  uint8_t precac_chan)
225 {
226 }
227 #endif
228 #ifdef CONFIG_CHAN_FREQ_API
229 static inline
230 void dfs_start_precac_timer_for_freq(struct wlan_dfs *dfs,
231 				     uint16_t precac_chan_freq)
232 {
233 }
234 #endif
235 #endif
236 
237 /**
238  * dfs_cancel_precac_timer() - Cancel the precac timer.
239  * @dfs: Pointer to wlan_dfs structure.
240  */
241 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
242 void dfs_cancel_precac_timer(struct wlan_dfs *dfs);
243 #else
244 static inline void dfs_cancel_precac_timer(struct wlan_dfs *dfs)
245 {
246 }
247 #endif
248 
249 /**
250  * dfs_zero_cac_attach() - Initialize dfs zerocac variables.
251  * @dfs: Pointer to DFS structure.
252  */
253 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
254 void dfs_zero_cac_attach(struct wlan_dfs *dfs);
255 #else
256 static inline void dfs_zero_cac_attach(struct wlan_dfs *dfs)
257 {
258 }
259 #endif
260 
261 /**
262  * dfs_zero_cac_reset() - Reset Zero cac DFS variables.
263  * @dfs: Pointer to wlan_dfs structure.
264  */
265 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
266 void dfs_zero_cac_reset(struct wlan_dfs *dfs);
267 #else
268 static inline void dfs_zero_cac_reset(struct wlan_dfs *dfs)
269 {
270 }
271 #endif
272 
273 /**
274  * dfs_zero_cac_timer_detach() - Free Zero cac DFS variables.
275  * @dfs_soc_obj: Pointer to dfs_soc_priv_obj structure.
276  */
277 #if !defined(QCA_MCL_DFS_SUPPORT)
278 void dfs_zero_cac_timer_detach(struct dfs_soc_priv_obj *dfs_soc_obj);
279 #else
280 static inline void
281 dfs_zero_cac_timer_detach(struct dfs_soc_priv_obj *dfs_soc_obj)
282 {
283 }
284 #endif
285 
286 /**
287  * dfs_is_precac_done() - Is precac done.
288  * @dfs: Pointer to wlan_dfs structure.
289  * @chan: Pointer to dfs_channel for which preCAC done is checked.
290  *
291  * Return:
292  * * True:  If precac is done on channel.
293  * * False: If precac is not done on channel.
294  */
295 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
296 bool dfs_is_precac_done(struct wlan_dfs *dfs, struct dfs_channel *chan);
297 #else
298 static inline bool dfs_is_precac_done(struct wlan_dfs *dfs,
299 				      struct dfs_channel *chan)
300 {
301 	return false;
302 }
303 #endif
304 
305 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
306 /**
307  * dfs_decide_precac_preferred_chan() - Choose operating channel among
308  *                                      configured DFS channel and
309  *                                      intermediate channel based on
310  *                                      precac status of configured
311  *                                      DFS channel.
312  * @dfs: Pointer to wlan_dfs structure.
313  * @pref_chan: Configured DFS channel.
314  * @mode: Configured PHY mode.
315  *
316  * Return: True if intermediate channel needs to configure. False otherwise.
317  */
318 #ifdef CONFIG_CHAN_NUM_API
319 bool
320 dfs_decide_precac_preferred_chan(struct wlan_dfs *dfs,
321 				  uint8_t *pref_chan,
322 				  enum wlan_phymode mode);
323 #endif
324 
325 /**
326  * dfs_decide_precac_preferred_chan_for_freq() - Choose operating channel among
327  *                                      configured DFS channel and
328  *                                      intermediate channel based on
329  *                                      precac status of configured
330  *                                      DFS channel.
331  * @dfs: Pointer to wlan_dfs structure.
332  * @pref_chan: Configured DFS channel frequency
333  * @mode: Configured PHY mode.
334  *
335  * Return: True if intermediate channel needs to configure. False otherwise.
336  */
337 
338 #ifdef CONFIG_CHAN_FREQ_API
339 bool
340 dfs_decide_precac_preferred_chan_for_freq(struct wlan_dfs *dfs,
341 					  uint16_t *pref_chan_freq,
342 					  enum wlan_phymode mode);
343 #endif
344 #else
345 #ifdef CONFIG_CHAN_NUM_API
346 static inline void dfs_decide_precac_preferred_chan(struct wlan_dfs *dfs,
347 						    uint8_t *pref_chan,
348 						    enum wlan_phymode mode)
349 {
350 }
351 #endif
352 #ifdef CONFIG_CHAN_FREQ_API
353 static inline void
354 dfs_decide_precac_preferred_chan_for_freq(struct wlan_dfs *dfs,
355 					  uint8_t *pref_chan,
356 					  enum wlan_phymode mode)
357 {
358 }
359 #endif
360 #endif
361 
362 /**
363  * dfs_get_ieeechan_for_precac() - Get chan of required bandwidth from
364  *                                 precac_list.
365  * @dfs:                 Pointer to wlan_dfs structure.
366  * @exclude_pri_ch_ieee: Primary channel IEEE to be excluded for preCAC.
367  * @exclude_sec_ch_ieee: Secondary channel IEEE to be excluded for preCAC.
368  * @bandwidth:           Bandwidth of requested channel.
369  */
370 #ifdef CONFIG_CHAN_NUM_API
371 uint8_t dfs_get_ieeechan_for_precac(struct wlan_dfs *dfs,
372 				    uint8_t exclude_pri_ch_ieee,
373 				    uint8_t exclude_sec_ch_ieee,
374 				    uint8_t bandwidth);
375 #endif
376 
377 /**
378  * dfs_get_ieeechan_for_precac_for_freq() - Get chan of required bandwidth from
379  *                                 precac_list.
380  * @dfs:                 Pointer to wlan_dfs structure.
381  * @exclude_pri_chan_freq: Primary channel freq to be excluded for preCAC.
382  * @exclude_sec_chan_freq: Secondary channel freq to be excluded for preCAC.
383  * @bandwidth:           Bandwidth of requested channel.
384  */
385 #ifdef CONFIG_CHAN_FREQ_API
386 uint16_t dfs_get_ieeechan_for_precac_for_freq(struct wlan_dfs *dfs,
387 					      uint16_t exclude_pri_chan_freq,
388 					      uint16_t exclude_sec_chan_freq,
389 					      uint8_t bandwidth);
390 #endif
391 
392 /**
393  * dfs_override_precac_timeout() - Override the default precac timeout.
394  * @dfs: Pointer to wlan_dfs structure.
395  * @precac_timeout: Precac timeout value.
396  */
397 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
398 int dfs_override_precac_timeout(struct wlan_dfs *dfs,
399 		int precac_timeout);
400 #else
401 static inline int dfs_override_precac_timeout(struct wlan_dfs *dfs,
402 		int precac_timeout)
403 {
404 	return 0;
405 }
406 #endif
407 
408 /**
409  * dfs_get_override_precac_timeout() - Get precac timeout.
410  * @dfs: Pointer wlan_dfs structure.
411  * @precac_timeout: Get precac timeout value in this variable.
412  */
413 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
414 int dfs_get_override_precac_timeout(struct wlan_dfs *dfs,
415 		int *precac_timeout);
416 #else
417 static inline int dfs_get_override_precac_timeout(struct wlan_dfs *dfs,
418 		int *precac_timeout)
419 {
420 	return 0;
421 }
422 #endif
423 
424 /**
425  * dfs_find_vht80_chan_for_precac() - Find VHT80 channel for precac.
426  * @dfs: Pointer to wlan_dfs structure.
427  * @chan_mode: Channel mode.
428  * @ch_freq_seg1: Segment1 channel freq.
429  * @cfreq1: cfreq1.
430  * @cfreq2: cfreq2.
431  * @phy_mode: Precac phymode.
432  * @dfs_set_cfreq2: Precac cfreq2
433  * @set_agile: Agile mode flag.
434  *
435  * Zero-CAC-DFS algorithm:-
436  * Zero-CAC-DFS algorithm works in stealth mode.
437  * 1) When any channel change happens in VHT80 mode the algorithm
438  * changes the HW channel mode to VHT80_80/VHT160 mode and adds a
439  * new channel in the secondary VHT80 to perform precac and a
440  * precac timer is started. However the upper layer/UMAC is unaware
441  * of this change.
442  * 2) When the precac timer expires without being interrupted by
443  * any channel change the secondary VHT80 channel is moved from
444  * precac-required-list to precac-done-list.
445  * 3) If there is a radar detect at any time in any segment
446  * (segment-1 is preimary VHT80 and segment-2 is VHT80)then the
447  * channel is searched in both precac-reuired-list and precac-done-list
448  * and moved to precac-nol-list.
449  * 4) Whenever channel change happens if the new channel is a DFS
450  * channel then precac-done-list is searched and if the channel is
451  * found in the precac-done-list then the CAC is skipped.
452  * 5) The precac expiry timer makes a vedv_restart(channel change
453  * with current-upper-layer-channel-mode which is VHT80). In channel
454  * change the algorithm tries to pick a new channel from the
455  * precac-required list. If none found then channel mode remains same.
456  * Which means when all the channels in precac-required-list are
457  * exhausted the VHT80_80/VHT160 comes back to VHT80 mode.
458  */
459 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
460 #ifdef CONFIG_CHAN_NUM_API
461 void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
462 		uint32_t chan_mode,
463 		uint8_t ch_freq_seg1,
464 		uint32_t *cfreq1,
465 		uint32_t *cfreq2,
466 		uint32_t *phy_mode,
467 		bool *dfs_set_cfreq2,
468 		bool *set_agile);
469 #endif
470 
471 /*
472  * dfs_find_vht80_chan_for_precac() - Find VHT80 channel for precac.
473  * @dfs: Pointer to wlan_dfs structure.
474  * @chan_mode: Channel mode.
475  * @ch_freq_seg1: Segment1 channel freq in mhz.
476  * @cfreq1: cfreq1.
477  * @cfreq2: cfreq2.
478  * @phy_mode: Precac phymode.
479  * @dfs_set_cfreq2: Precac cfreq2
480  * @set_agile: Agile mode flag.
481  */
482 #ifdef CONFIG_CHAN_FREQ_API
483 void dfs_find_vht80_chan_for_precac_for_freq(struct wlan_dfs *dfs,
484 					     uint32_t chan_mode,
485 					     uint16_t ch_freq_seg1_mhz,
486 					     uint32_t *cfreq1,
487 					     uint32_t *cfreq2,
488 					     uint32_t *phy_mode,
489 					     bool *dfs_set_cfreq2,
490 					     bool *set_agile);
491 #endif
492 
493 #else
494 #ifdef CONFIG_CHAN_NUM_API
495 static inline void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
496 		uint32_t chan_mode,
497 		uint8_t ch_freq_seg1,
498 		uint32_t *cfreq1,
499 		uint32_t *cfreq2,
500 		uint32_t *phy_mode,
501 		bool *dfs_set_cfreq2,
502 		bool *set_agile)
503 {
504 }
505 #endif
506 
507 #ifdef CONFIG_CHAN_FREQ_API
508 static inline
509 void dfs_find_vht80_chan_for_precac_for_freq(struct wlan_dfs *dfs,
510 					     uint32_t chan_mode,
511 					     uint16_t ch_freq_seg1_mhz,
512 					     uint32_t *cfreq1,
513 					     uint32_t *cfreq2,
514 					     uint32_t *phy_mode,
515 					     bool *dfs_set_cfreq2,
516 					     bool *set_agile)
517 {
518 }
519 #endif
520 #endif
521 
522 #if defined(QCA_SUPPORT_AGILE_DFS)
523 /**
524  * dfs_find_pdev_for_agile_precac() - Find pdev to select channel for precac.
525  * @pdev: Pointer to wlan_objmgr_pdev structure.
526  * @cur_precac_dfs_index: current precac index
527  */
528 void dfs_find_pdev_for_agile_precac(struct wlan_objmgr_pdev *pdev,
529 				    uint8_t *cur_precac_dfs_index);
530 
531 /**
532  * dfs_prepare_agile_precac_chan() - Send Agile set request for given pdev.
533  * @dfs: Pointer to wlan_dfs structure.
534  */
535 void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs);
536 
537 /**
538  * dfs_process_ocac_complete() - Process Off-Channel CAC complete indication.
539  * @pdev :Pointer to wlan_objmgr_pdev structure.
540  * @ocac_status: Off channel CAC complete status
541  * @center_freq : Center Frequency of O-CAC done indication.
542  */
543 void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
544 			       uint32_t ocac_status,
545 			       uint32_t center_freq);
546 
547 /**
548  * dfs_get_ieeechan_for_agilecac() - Find an IEEE channel for agile CAC.
549  * @dfs:         Pointer to wlan_dfs structure.
550  * @ch_ieee:     Pointer to channel number for agile set request.
551  * @pri_ch_ieee: Current primary IEEE channel.
552  * @sec_ch_ieee: Current secondary IEEE channel (in HT80_80 mode).
553  *
554  * Find an IEEE channel for agileCAC which is not the current operating
555  * channels (indicated by pri_ch_ieee, sec_ch_ieee).
556  */
557 #ifdef CONFIG_CHAN_NUM_API
558 void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs,
559 				   uint8_t *ch_ieee,
560 				   uint8_t pri_ch_ieee,
561 				   uint8_t sec_ch_ieee);
562 #endif
563 
564 /**
565  * dfs_get_ieeechan_for_agilecac_for_freq() - Find chan freq for agile CAC.
566  * @dfs:         Pointer to wlan_dfs structure.
567  * @chan_freq:     Pointer to channel freq for agile set request.
568  * @pri_chan_freq: Current primary IEEE channel freq.
569  * @sec_chan_freq: Current secondary IEEE channel freq (in HT80_80 mode).
570  *
571  * Find an IEEE channel freq for agileCAC which is not the current operating
572  * channels (indicated by pri_chan_freq, sec_chan_freq).
573  */
574 #ifdef CONFIG_CHAN_FREQ_API
575 void dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs,
576 					    uint16_t *chan_freq,
577 					    uint16_t pri_chan_freq,
578 					    uint16_t sec_chan_freq);
579 #endif
580 
581 /**
582  * dfs_agile_precac_start() - Start agile precac.
583  * @dfs: Pointer to wlan_dfs structure.
584  */
585 void dfs_agile_precac_start(struct wlan_dfs *dfs);
586 
587 /**
588  * dfs_start_agile_precac_timer() - Start precac timer for the given channel.
589  * @dfs:         Pointer to wlan_dfs structure.
590  * @ocac_status: Status of the off channel CAC.
591  * @adfs_param:  Agile DFS CAC parameters.
592  *
593  * Start the precac timer with proper timeout values based on the channel to
594  * be preCACed. The preCAC channel number and chwidth information is present
595  * in the adfs_param argument. Once the timer is started, update the timeout
596  * fields in adfs_param.
597  */
598 void dfs_start_agile_precac_timer(struct wlan_dfs *dfs,
599 				  uint8_t ocac_status,
600 				  struct dfs_agile_cac_params *adfs_param);
601 
602 /**
603  * dfs_set_fw_adfs_support() - Set FW aDFS support in dfs object.
604  * @dfs: Pointer to wlan_dfs structure.
605  * @fw_adfs_support_160: aDFS enabled when pdev is on 160/80P80MHz.
606  * @fw_adfs_support_non_160: aDFS enabled when pdev is on 20/40/80MHz.
607  *
608  * Return: void.
609  */
610 void dfs_set_fw_adfs_support(struct wlan_dfs *dfs,
611 			     bool fw_adfs_support_160,
612 			     bool fw_adfs_support_non_160);
613 #else
614 static inline void dfs_find_pdev_for_agile_precac(struct wlan_objmgr_pdev *pdev,
615 						  uint8_t *cur_precac_dfs_index)
616 {
617 }
618 
619 static inline void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs)
620 {
621 }
622 
623 static inline void
624 dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
625 			  uint32_t ocac_status,
626 			  uint32_t center_freq)
627 {
628 }
629 
630 #ifdef CONFIG_CHAN_NUM_API
631 static inline void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs,
632 						 uint8_t *ch_ieee,
633 						 uint8_t pri_ch_ieee,
634 						 uint8_t sec_ch_ieee)
635 {
636 }
637 #endif
638 
639 #ifdef CONFIG_CHAN_FREQ_API
640 static inline void
641 dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs,
642 				       uint16_t *chan_freq,
643 				       uint16_t pri_chan_freq,
644 				       uint16_t sec_chan_freq)
645 {
646 }
647 #endif
648 
649 static inline void dfs_agile_precac_start(struct wlan_dfs *dfs)
650 {
651 }
652 
653 static inline void
654 dfs_start_agile_precac_timer(struct wlan_dfs *dfs,
655 			     uint8_t ocac_status,
656 			     struct dfs_agile_cac_params *adfs_param)
657 {
658 }
659 
660 static inline void
661 dfs_set_fw_adfs_support(struct wlan_dfs *dfs,
662 			bool fw_adfs_support_160,
663 			bool fw_adfs_support_non_160)
664 {
665 }
666 #endif
667 
668 #if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS)
669 /**
670  * dfs_agile_soc_obj_init() - Initialize soc obj for agile precac.
671  * @dfs: Pointer to wlan_dfs structure.
672  * @precac_chan: Start thr precac timer in this channel.
673  * @ocac_status: Status of the off channel CAC.
674  */
675 void dfs_agile_soc_obj_init(struct wlan_dfs *dfs,
676 			    struct wlan_objmgr_psoc *psoc);
677 #else
678 static inline void dfs_agile_soc_obj_init(struct wlan_dfs *dfs,
679 					  struct wlan_objmgr_psoc *psoc)
680 {
681 }
682 #endif
683 
684 /**
685  * dfs_set_precac_enable() - Set precac enable flag.
686  * @dfs: Pointer to wlan_dfs structure.
687  * @value: input value for dfs_legacy_precac_ucfg flag.
688  */
689 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
690 void dfs_set_precac_enable(struct wlan_dfs *dfs,
691 		uint32_t value);
692 #else
693 static inline void dfs_set_precac_enable(struct wlan_dfs *dfs,
694 		uint32_t value)
695 {
696 }
697 #endif
698 
699 /**
700  * dfs_is_legacy_precac_enabled() - Check if legacy preCAC is enabled for the
701  * DFS onject.
702  * @dfs: Pointer to the wlan_dfs object.
703  *
704  * Return: True if legacy preCAC is enabled, else false.
705  */
706 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
707 bool dfs_is_legacy_precac_enabled(struct wlan_dfs *dfs);
708 #else
709 static inline bool dfs_is_legacy_precac_enabled(struct wlan_dfs *dfs)
710 {
711 	return 0;
712 }
713 #endif
714 
715 /**
716  * dfs_is_agile_precac_enabled() - Check if agile preCAC is enabled for the DFS.
717  * @dfs: Pointer to the wlan_dfs object.
718  *
719  * Return: True if agile DFS is enabled, else false.
720  *
721  * For agile preCAC to be enabled,
722  * 1. User configuration should be set.
723  * 2. Target should support aDFS.
724  */
725 #ifdef QCA_SUPPORT_AGILE_DFS
726 bool dfs_is_agile_precac_enabled(struct wlan_dfs *dfs);
727 #else
728 static inline bool dfs_is_agile_precac_enabled(struct wlan_dfs *dfs)
729 {
730 	return false;
731 }
732 #endif
733 
734 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
735 /**
736  * dfs_set_precac_intermediate_chan() - Set intermediate chan to be used while
737  *                                      doing precac.
738  * @dfs: Pointer to wlan_dfs structure.
739  * @value: input value for dfs_legacy_precac_ucfg flag.
740  *
741  * Return:
742  * * 0       - Successfully set intermediate channel.
743  * * -EINVAL - Invalid channel.
744  */
745 int32_t dfs_set_precac_intermediate_chan(struct wlan_dfs *dfs,
746 					 uint32_t value);
747 #else
748 static inline int32_t dfs_set_precac_intermediate_chan(struct wlan_dfs *dfs,
749 						       uint32_t value)
750 {
751 	return 0;
752 }
753 #endif
754 
755 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
756 /**
757  * dfs_get_precac_intermediate_chan() - Get configured precac
758  *					intermediate channel.
759  * @dfs: Pointer to wlan_dfs structure.
760  *
761  * Return: Configured intermediate channel number.
762  */
763 uint32_t dfs_get_precac_intermediate_chan(struct wlan_dfs *dfs);
764 #else
765 static inline uint32_t dfs_get_intermediate_chan(struct wlan_dfs *dfs)
766 {
767 	return 0;
768 }
769 #endif
770 
771 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
772 /**
773  * dfs_get_precac_chan_state() - Get precac status of a given channel.
774  * @dfs:         Pointer to wlan_dfs structure.
775  * @precac_chan: Channel number for which precac state need to be checked.
776  *
777  * Return:
778  * * PRECAC_REQUIRED: Precac has not done on precac_chan.
779  * * PRECAC_NOW     : Precac is running on precac_chan.
780  * * PRECAC_DONE    : precac_chan is in CAC done state in precac list.
781  * * PRECAC_NOL     : precac_chan is in NOL state in precac list.
782  * * PRECAC_ERR     : Invalid precac state.
783  */
784 enum precac_chan_state
785 dfs_get_precac_chan_state(struct wlan_dfs *dfs, uint8_t precac_chan);
786 
787 /**
788  * dfs_get_precac_chan_state_for_freq() - Get precac status of a given channel.
789  * @dfs:         Pointer to wlan_dfs structure.
790  * @precac_chan: Channel freq for which precac state need to be checked.
791  */
792 
793 #ifdef CONFIG_CHAN_FREQ_API
794 enum precac_chan_state
795 dfs_get_precac_chan_state_for_freq(struct wlan_dfs *dfs,
796 				   uint16_t precac_chan_freq);
797 #endif
798 
799 #else
800 
801 #ifdef CONFIG_CHAN_NUM_API
802 static inline enum precac_chan_state
803 dfs_get_precac_chan_state(struct wlan_dfs *dfs,
804 			  uint8_t precac_chan)
805 {
806 	return PRECAC_REQUIRED;
807 }
808 #endif
809 
810 #ifdef CONFIG_CHAN_FREQ_API
811 static inline enum precac_chan_state
812 dfs_get_precac_chan_state_for_freq(struct wlan_dfs *dfs,
813 				   uint16_t precac_chan_freq)
814 {
815 	return PRECAC_REQUIRED;
816 }
817 #endif
818 #endif
819 
820 /**
821  * dfs_zero_cac_reset() - Reset Zero cac DFS variables.
822  * @dfs: Pointer to wlan_dfs structure.
823  */
824 void dfs_zero_cac_reset(struct wlan_dfs *dfs);
825 
826 /**
827  * dfs_is_precac_done_on_ht20_40_80_chan() - Is precac done on a
828  *                                           VHT20/40/80 channel.
829  *@dfs: Pointer to wlan_dfs structure.
830  *@chan: Channel IEEE value.
831  *
832  * Return:
833  * * True:  If CAC is done on channel.
834  * * False: If CAC is not done on channel.
835  */
836 #ifdef CONFIG_CHAN_NUM_API
837 bool dfs_is_precac_done_on_ht20_40_80_chan(struct wlan_dfs *dfs,
838 					   uint8_t chan);
839 #endif
840 
841 /**
842  * dfs_is_precac_done_on_ht20_40_80_chan_for_freq() - Is precac done on a
843  *                                                    VHT20/40/80 channel.
844  *@dfs: Pointer to wlan_dfs structure.
845  *@chan: Channel frequency
846  *
847  * Return:
848  * * True:  If CAC is done on channel.
849  * * False: If CAC is not done on channel.
850  */
851 #ifdef CONFIG_CHAN_FREQ_API
852 bool dfs_is_precac_done_on_ht20_40_80_chan_for_freq(struct wlan_dfs *dfs,
853 						    uint16_t chan_freq);
854 #endif
855 
856 /**
857  * dfs_is_precac_done_on_ht8080_ht160_chan() - Is precac done on
858  *                                             VHT80+80 or VHT160
859  *                                             channel.
860  * @dfs: Pointer to wlan_dfs structure.
861  * @chan: Pointer to dfs_channel for which preCAC done is checked.
862  *
863  * Return:
864  * * True:  If CAC is done on channel.
865  * * False: If CAC is not done on channel.
866  */
867 bool dfs_is_precac_done_on_ht8080_ht160_chan(struct wlan_dfs *dfs,
868 					     struct dfs_channel *chan);
869 
870 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
871 /**
872  * dfs_find_chwidth_and_center_chan() - Find the channel width enum and
873  *                                      primary and secondary center channel
874  *                                      value of the current channel.
875  * @dfs:                  Pointer to wlan_dfs structure.
876  * @chwidth:              Channel width enum of current channel.
877  * @primary_chan_ieee:    Primary IEEE channel.
878  * @secondary_chan_ieee:  Secondary IEEE channel (in HT80_80 mode).
879  */
880 #ifdef CONFIG_CHAN_NUM_API
881 void dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs,
882 				      enum phy_ch_width *chwidth,
883 				      uint8_t *primary_chan_ieee,
884 				      uint8_t *secondary_chan_ieee);
885 
886 #endif
887 
888 #ifdef CONFIG_CHAN_FREQ_API
889 /**
890  * dfs_find_chwidth_and_center_chan_for_freq() - Find the channel width enum and
891  *                                      primary and secondary center channel
892  *                                      value of the current channel.
893  * @dfs:                  Pointer to wlan_dfs structure.
894  * @chwidth:              Channel width enum of current channel.
895  * @primary_chan_freq:    Primary IEEE channel freq.
896  * @secondary_chan_freq:  Secondary IEEE channel freq (in HT80_80 mode).
897  */
898 void dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs,
899 					       enum phy_ch_width *chwidth,
900 					       uint16_t *primary_chan_freq,
901 					       uint16_t *secondary_chan_freq);
902 #endif
903 
904 /**
905  * dfs_mark_precac_done() - Mark the channel as preCAC done.
906  * @dfs:           Pointer to wlan_dfs structure.
907  * @pri_ch_ieee:   Primary channel IEEE.
908  * @sec_ch_ieee:   Secondary channel IEEE (only in HT80_80 mode).
909  * @ch_width:      Channel width enum.
910  */
911 #ifdef CONFIG_CHAN_NUM_API
912 void dfs_mark_precac_done(struct wlan_dfs *dfs,
913 			  uint8_t pri_ch_ieee,
914 			  uint8_t sec_ch_ieee,
915 			  enum phy_ch_width ch_width);
916 #endif
917 
918 #ifdef CONFIG_CHAN_FREQ_API
919 /**
920  * dfs_mark_precac_done_for_freq() - Mark the channel as preCAC done.
921  * @dfs:             Pointer to wlan_dfs structure.
922  * @pri_chan_freq:   Primary channel IEEE freq.
923  * @sec_chan_freq:   Secondary channel IEEE freq(only in HT80_80 mode).
924  * @chan_width:      Channel width enum.
925  */
926 void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs,
927 				   uint16_t pri_chan_freq,
928 				   uint16_t sec_chan_freq,
929 				   enum phy_ch_width chan_width);
930 #endif
931 
932 /**
933  * dfs_mark_precac_nol() - Mark the precac channel as radar.
934  * @dfs:                              Pointer to wlan_dfs structure.
935  * @is_radar_found_on_secondary_seg:  Radar found on secondary seg for Cascade.
936  * @detector_id:                      detector id which found RADAR in HW.
937  * @channels:                         Array of radar found subchannels.
938  * @num_channels:                     Number of radar found subchannels.
939  */
940 #ifdef CONFIG_CHAN_NUM_API
941 void dfs_mark_precac_nol(struct wlan_dfs *dfs,
942 			 uint8_t is_radar_found_on_secondary_seg,
943 			 uint8_t detector_id,
944 			 uint8_t *channels,
945 			 uint8_t num_channels);
946 #endif
947 
948 /**
949  * dfs_mark_precac_nol_for_freq() - Mark the precac channel as radar.
950  * @dfs:                              Pointer to wlan_dfs structure.
951  * @is_radar_found_on_secondary_seg:  Radar found on secondary seg for Cascade.
952  * @detector_id:                      detector id which found RADAR in HW.
953  * @freq_list:                         Array of radar found frequencies.
954  * @num_channels:                     Number of radar found subchannels.
955  */
956 #ifdef CONFIG_CHAN_FREQ_API
957 void dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs,
958 				  uint8_t is_radar_found_on_secondary_seg,
959 				  uint8_t detector_id,
960 				  uint16_t *freq_list,
961 				  uint8_t num_channels);
962 #endif
963 
964 /**
965  * dfs_unmark_precac_nol() - Unmark the precac channel as radar.
966  * @dfs:      Pointer to wlan_dfs structure.
967  * @channel:  channel marked as radar.
968  */
969 #ifdef CONFIG_CHAN_NUM_API
970 void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel);
971 #endif
972 
973 /**
974  * dfs_unmark_precac_nol_for_freq() - Unmark the precac channel as radar.
975  * @dfs:      Pointer to wlan_dfs structure.
976  * @channel:  channel freq marked as radar.
977  */
978 #ifdef CONFIG_CHAN_FREQ_API
979 void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs, uint16_t chan_freq);
980 #endif
981 
982 #else
983 #ifdef CONFIG_CHAN_NUM_API
984 static inline void
985 dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs,
986 				 enum phy_ch_width *chwidth,
987 				 uint8_t *primary_chan_ieee,
988 				 uint8_t *secondary_chan_ieee)
989 {
990 }
991 #endif
992 
993 #ifdef CONFIG_CHAN_FREQ_API
994 static inline void
995 dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs,
996 					  enum phy_ch_width *chwidth,
997 					  uint16_t *primary_chan_freq,
998 					  uint16_t *secondary_chan_freq)
999 {
1000 }
1001 #endif
1002 
1003 #ifdef CONFIG_CHAN_NUM_API
1004 static inline void dfs_mark_precac_done(struct wlan_dfs *dfs,
1005 					uint8_t pri_ch_ieee,
1006 					uint8_t sec_ch_ieee,
1007 					enum phy_ch_width ch_width)
1008 {
1009 }
1010 #endif
1011 
1012 #ifdef CONFIG_CHAN_FREQ_API
1013 static inline void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs,
1014 						 uint16_t pri_chan_freq,
1015 						 uint16_t sec_chan_freq,
1016 						 enum phy_ch_width chan_width)
1017 {
1018 }
1019 #endif
1020 
1021 #ifdef CONFIG_CHAN_NUM_API
1022 static inline void dfs_mark_precac_nol(struct wlan_dfs *dfs,
1023 				       uint8_t is_radar_found_on_secondary_seg,
1024 				       uint8_t detector_id,
1025 				       uint8_t *channels,
1026 				       uint8_t num_channels)
1027 {
1028 }
1029 #endif
1030 
1031 #ifdef CONFIG_CHAN_FREQ_API
1032 static inline void
1033 dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs,
1034 			     uint8_t is_radar_found_on_secondary_seg,
1035 			     uint8_t detector_id,
1036 			     uint16_t *freq,
1037 			     uint8_t num_channels)
1038 {
1039 }
1040 #endif
1041 
1042 #ifdef CONFIG_CHAN_NUM_API
1043 static inline void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel)
1044 {
1045 }
1046 #endif
1047 
1048 #ifdef CONFIG_CHAN_FREQ_API
1049 static inline void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs,
1050 						  uint16_t chan_freq)
1051 {
1052 }
1053 #endif
1054 #endif
1055 
1056 /**
1057  * dfs_is_precac_timer_running() - Check whether precac timer is running.
1058  * @dfs: Pointer to wlan_dfs structure.
1059  */
1060 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT)
1061 bool dfs_is_precac_timer_running(struct wlan_dfs *dfs);
1062 #else
1063 static inline bool dfs_is_precac_timer_running(struct wlan_dfs *dfs)
1064 {
1065 	return false;
1066 }
1067 #endif
1068 
1069 #ifdef CONFIG_CHAN_FREQ_API
1070 #define VHT160_FREQ_DIFF 80
1071 
1072 #define INITIAL_20_CHAN_FREQ_OFFSET           -30
1073 #define INITIAL_40_CHAN_FREQ_OFFSET           -20
1074 #define INITIAL_80_CHAN_FREQ_OFFSET            0
1075 
1076 #define NEXT_20_CHAN_FREQ_OFFSET               20
1077 #define NEXT_40_CHAN_FREQ_OFFSET               40
1078 #define NEXT_80_CHAN_FREQ_OFFSET               80
1079 
1080 #define WEATHER_CHAN_START_FREQ              5600
1081 #define WEATHER_CHAN_END_FREQ                5640
1082 
1083 #endif
1084 
1085 #endif /* _DFS_ZERO_CAC_H_ */
1086