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