xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/dfs_zero_cac.h (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
1 /*
2  * Copyright (c) 2016-2018 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 
36 #define VHT160_IEEE_FREQ_DIFF 16
37 
38 /**
39  * struct dfs_precac_entry - PreCAC entry.
40  * @pe_list:           PreCAC entry.
41  * @vht80_freq:        VHT80 freq.
42  * @precac_nol_timer:  Per element precac NOL timer.
43  * @dfs:               Pointer to wlan_dfs structure.
44  */
45 struct dfs_precac_entry {
46 	TAILQ_ENTRY(dfs_precac_entry) pe_list;
47 	uint8_t             vht80_freq;
48 	os_timer_t          precac_nol_timer;
49 	struct wlan_dfs      *dfs;
50 };
51 
52 /**
53  * dfs_zero_cac_timer_init() - Initialize zero-cac timers
54  * @dfs: Pointer to DFS structure.
55  */
56 void dfs_zero_cac_timer_init(struct wlan_dfs *dfs);
57 
58 /**
59  * dfs_print_precaclists() - Print precac list.
60  * @dfs: Pointer to wlan_dfs structure.
61  */
62 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
63 void dfs_print_precaclists(struct wlan_dfs *dfs);
64 #else
65 static inline void dfs_print_precaclists(struct wlan_dfs *dfs)
66 {
67 }
68 #endif
69 
70 /**
71  * dfs_reset_precac_lists() - Resets the precac lists.
72  * @dfs: Pointer to wlan_dfs structure.
73  */
74 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
75 void dfs_reset_precac_lists(struct wlan_dfs *dfs);
76 #else
77 static inline void dfs_reset_precac_lists(struct wlan_dfs *dfs)
78 {
79 }
80 #endif
81 
82 /**
83  * dfs_reset_precaclists() - Clears and initiakizes precac_required_list,
84  *                           precac_done_list and precac_nol_list.
85  *
86  * @dfs: Pointer to wlan_dfs structure.
87  */
88 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
89 void dfs_reset_precaclists(struct wlan_dfs *dfs);
90 #else
91 static inline void dfs_reset_precaclists(struct wlan_dfs *dfs)
92 {
93 }
94 #endif
95 
96 /**
97  * dfs_deinit_precac_list() - Clears the precac list.
98  * @dfs: Pointer to wlan_dfs dtructure.
99  */
100 void dfs_deinit_precac_list(struct wlan_dfs *dfs);
101 
102 /**
103  * dfs_zero_cac_detach() - Free zero_cac memory.
104  * @dfs: Pointer to wlan_dfs dtructure.
105  */
106 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
107 void dfs_zero_cac_detach(struct wlan_dfs *dfs);
108 #else
109 static inline void dfs_zero_cac_detach(struct wlan_dfs *dfs)
110 {
111 }
112 #endif
113 
114 /**
115  * dfs_init_precac_list() - Init precac list.
116  * @dfs: Pointer to wlan_dfs dtructure.
117  */
118 void dfs_init_precac_list(struct wlan_dfs *dfs);
119 
120 /**
121  * dfs_start_precac_timer() - Start precac timer.
122  * @dfs: Pointer to wlan_dfs structure.
123  * @precac_chan: Start thr precac timer in this channel.
124  */
125 void dfs_start_precac_timer(struct wlan_dfs *dfs,
126 		uint8_t precac_chan);
127 
128 /**
129  * dfs_cancel_precac_timer() - Cancel the precac timer.
130  * @dfs: Pointer to wlan_dfs structure.
131  */
132 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
133 void dfs_cancel_precac_timer(struct wlan_dfs *dfs);
134 #else
135 static inline void dfs_cancel_precac_timer(struct wlan_dfs *dfs)
136 {
137 }
138 #endif
139 
140 /**
141  * dfs_zero_cac_attach() - Initialize dfs zerocac variables.
142  * @dfs: Pointer to DFS structure.
143  */
144 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
145 void dfs_zero_cac_attach(struct wlan_dfs *dfs);
146 #else
147 static inline void dfs_zero_cac_attach(struct wlan_dfs *dfs)
148 {
149 }
150 #endif
151 
152 /**
153  * dfs_zero_cac_reset() - Reset Zero cac DFS variables.
154  * @dfs: Pointer to wlan_dfs structure.
155  */
156 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
157 void dfs_zero_cac_reset(struct wlan_dfs *dfs);
158 #else
159 static inline void dfs_zero_cac_reset(struct wlan_dfs *dfs)
160 {
161 }
162 #endif
163 
164 /**
165  * dfs_is_precac_done() - Is precac done.
166  * @dfs: Pointer to wlan_dfs structure.
167  */
168 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
169 bool dfs_is_precac_done(struct wlan_dfs *dfs);
170 #else
171 static inline bool dfs_is_precac_done(struct wlan_dfs *dfs)
172 {
173 	return false;
174 }
175 #endif
176 
177 /**
178  * dfs_get_freq_from_precac_required_list() - Get VHT80 freq from
179  *                                            precac_required_list.
180  * @dfs: Pointer to wlan_dfs structure.
181  * @exclude_ieee_freq: Find a VHT80 freqency that is not equal to
182  *                     exclude_ieee_freq.
183  */
184 uint8_t dfs_get_freq_from_precac_required_list(struct wlan_dfs *dfs,
185 		uint8_t exclude_ieee_freq);
186 
187 /**
188  * dfs_override_precac_timeout() - Override the default precac timeout.
189  * @dfs: Pointer to wlan_dfs structure.
190  * @precac_timeout: Precac timeout value.
191  */
192 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
193 int dfs_override_precac_timeout(struct wlan_dfs *dfs,
194 		int precac_timeout);
195 #else
196 static inline int dfs_override_precac_timeout(struct wlan_dfs *dfs,
197 		int precac_timeout)
198 {
199 	return 0;
200 }
201 #endif
202 
203 /**
204  * dfs_get_override_precac_timeout() - Get precac timeout.
205  * @dfs: Pointer wlan_dfs structure.
206  * @precac_timeout: Get precac timeout value in this variable.
207  */
208 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
209 int dfs_get_override_precac_timeout(struct wlan_dfs *dfs,
210 		int *precac_timeout);
211 #else
212 static inline int dfs_get_override_precac_timeout(struct wlan_dfs *dfs,
213 		int *precac_timeout)
214 {
215 	return 0;
216 }
217 #endif
218 
219 /**
220  * dfs_find_vht80_chan_for_precac() - Find VHT80 channel for precac.
221  * @dfs: Pointer to wlan_dfs structure.
222  * @chan_mode: Channel mode.
223  * @ch_freq_seg1: Segment1 channel freq.
224  * @cfreq1: cfreq1.
225  * @cfreq2: cfreq2.
226  * @phy_mode: Precac phymode.
227  * @dfs_set_cfreq2: Precac cfreq2
228  * @set_agile: Agile mode flag.
229  *
230  * Zero-CAC-DFS algorithm:-
231  * Zero-CAC-DFS algorithm works in stealth mode.
232  * 1) When any channel change happens in VHT80 mode the algorithm
233  * changes the HW channel mode to VHT80_80/VHT160 mode and adds a
234  * new channel in the secondary VHT80 to perform precac and a
235  * precac timer is started. However the upper layer/UMAC is unaware
236  * of this change.
237  * 2) When the precac timer expires without being interrupted by
238  * any channel change the secondary VHT80 channel is moved from
239  * precac-required-list to precac-done-list.
240  * 3) If there is a radar detect at any time in any segment
241  * (segment-1 is preimary VHT80 and segment-2 is VHT80)then the
242  * channel is searched in both precac-reuired-list and precac-done-list
243  * and moved to precac-nol-list.
244  * 4) Whenever channel change happens if the new channel is a DFS
245  * channel then precac-done-list is searched and if the channel is
246  * found in the precac-done-list then the CAC is skipped.
247  * 5) The precac expiry timer makes a vedv_restart(channel change
248  * with current-upper-layer-channel-mode which is VHT80). In channel
249  * change the algorithm tries to pick a new channel from the
250  * precac-required list. If none found then channel mode remains same.
251  * Which means when all the channels in precac-required-list are
252  * exhausted the VHT80_80/VHT160 comes back to VHT80 mode.
253  */
254 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
255 void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
256 		uint32_t chan_mode,
257 		uint8_t ch_freq_seg1,
258 		uint32_t *cfreq1,
259 		uint32_t *cfreq2,
260 		uint32_t *phy_mode,
261 		bool *dfs_set_cfreq2,
262 		bool *set_agile);
263 #else
264 static inline void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
265 		uint32_t chan_mode,
266 		uint8_t ch_freq_seg1,
267 		uint32_t *cfreq1,
268 		uint32_t *cfreq2,
269 		uint32_t *phy_mode,
270 		bool *dfs_set_cfreq2,
271 		bool *set_agile)
272 {
273 }
274 #endif
275 
276 /**
277  * dfs_set_precac_enable() - Set precac enable flag.
278  * @dfs: Pointer to wlan_dfs structure.
279  * @value: input value for dfs_precac_enable flag.
280  */
281 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
282 void dfs_set_precac_enable(struct wlan_dfs *dfs,
283 		uint32_t value);
284 #else
285 static inline void dfs_set_precac_enable(struct wlan_dfs *dfs,
286 		uint32_t value)
287 {
288 }
289 #endif
290 
291 /**
292  * dfs_get_precac_enable() - Get precac enable flag.
293  * @dfs: Pointer to wlan_dfs structure.
294  */
295 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
296 uint32_t dfs_get_precac_enable(struct wlan_dfs *dfs);
297 #else
298 static inline uint32_t dfs_get_precac_enable(struct wlan_dfs *dfs)
299 {
300 	return 0;
301 }
302 #endif
303 
304 /**
305  * dfs_zero_cac_reset() - Reset Zero cac DFS variables.
306  * @dfs: Pointer to wlan_dfs structure.
307  */
308 void dfs_zero_cac_reset(struct wlan_dfs *dfs);
309 
310 /**
311  * dfs_is_ht20_40_80_chan_in_precac_done_list() - Is precac done on a
312  *                                                VHT20/40/80 channel.
313  *@dfs: Pointer to wlan_dfs structure.
314  */
315 bool dfs_is_ht20_40_80_chan_in_precac_done_list(struct wlan_dfs *dfs);
316 
317 /**
318  * dfs_is_ht80_80_chan_in_precac_done_list() - Is precac done on a VHT80+80
319  *                                             channel.
320  *@dfs: Pointer to wlan_dfs structure.
321  */
322 bool dfs_is_ht80_80_chan_in_precac_done_list(struct wlan_dfs *dfs);
323 
324 /**
325  * dfs_mark_precac_dfs() - Mark the precac channel as radar.
326  * @dfs: Pointer to wlan_dfs structure.
327  */
328 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
329 void dfs_mark_precac_dfs(struct wlan_dfs *dfs,
330 		uint8_t is_radar_found_on_secondary_seg);
331 #else
332 static inline void dfs_mark_precac_dfs(struct wlan_dfs *dfs,
333 		uint8_t is_radar_found_on_secondary_seg)
334 {
335 }
336 #endif
337 
338 /**
339  * dfs_is_precac_timer_running() - Check whether precac timer is running.
340  * @dfs: Pointer to wlan_dfs structure.
341  */
342 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
343 bool dfs_is_precac_timer_running(struct wlan_dfs *dfs);
344 #else
345 static inline bool dfs_is_precac_timer_running(struct wlan_dfs *dfs)
346 {
347 	return false;
348 }
349 #endif
350 #endif /* _DFS_ZERO_CAC_H_ */
351