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