1 /* 2 * Copyright (c) 2016-2020 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_reinit_precac_lists() - Reinit DFS preCAC lists. 828 * @src_dfs: Source DFS from which the preCAC list is copied. 829 * @dest_dfs: Destination DFS to which the preCAC list is copied. 830 * @low_5g_freq: Low 5G frequency value of the destination DFS. 831 * @high_5g_freq: High 5G frequency value of the destination DFS. 832 * 833 * Copy all the preCAC list entries from the source DFS to the destination DFS 834 * which fall within the frequency range of low_5g_freq and high_5g_freq. 835 * 836 * Return: None (void). 837 */ 838 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) 839 void dfs_reinit_precac_lists(struct wlan_dfs *src_dfs, 840 struct wlan_dfs *dest_dfs, 841 uint16_t low_5g_freq, 842 uint16_t high_5g_freq); 843 #else 844 static inline void dfs_reinit_precac_lists(struct wlan_dfs *src_dfs, 845 struct wlan_dfs *dest_dfs, 846 uint16_t low_5g_freq, 847 uint16_t high_5g_freq) 848 { 849 } 850 #endif 851 852 /** 853 * dfs_is_precac_done_on_ht20_40_80_chan() - Is precac done on a 854 * VHT20/40/80 channel. 855 *@dfs: Pointer to wlan_dfs structure. 856 *@chan: Channel IEEE value. 857 * 858 * Return: 859 * * True: If CAC is done on channel. 860 * * False: If CAC is not done on channel. 861 */ 862 #ifdef CONFIG_CHAN_NUM_API 863 bool dfs_is_precac_done_on_ht20_40_80_chan(struct wlan_dfs *dfs, 864 uint8_t chan); 865 #endif 866 867 /** 868 * dfs_is_precac_done_on_ht20_40_80_chan_for_freq() - Is precac done on a 869 * VHT20/40/80 channel. 870 *@dfs: Pointer to wlan_dfs structure. 871 *@chan: Channel frequency 872 * 873 * Return: 874 * * True: If CAC is done on channel. 875 * * False: If CAC is not done on channel. 876 */ 877 #ifdef CONFIG_CHAN_FREQ_API 878 bool dfs_is_precac_done_on_ht20_40_80_chan_for_freq(struct wlan_dfs *dfs, 879 uint16_t chan_freq); 880 #endif 881 882 /** 883 * dfs_is_precac_done_on_ht8080_ht160_chan() - Is precac done on 884 * VHT80+80 or VHT160 885 * channel. 886 * @dfs: Pointer to wlan_dfs structure. 887 * @chan: Pointer to dfs_channel for which preCAC done is checked. 888 * 889 * Return: 890 * * True: If CAC is done on channel. 891 * * False: If CAC is not done on channel. 892 */ 893 bool dfs_is_precac_done_on_ht8080_ht160_chan(struct wlan_dfs *dfs, 894 struct dfs_channel *chan); 895 896 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) 897 /** 898 * dfs_find_chwidth_and_center_chan() - Find the channel width enum and 899 * primary and secondary center channel 900 * value of the current channel. 901 * @dfs: Pointer to wlan_dfs structure. 902 * @chwidth: Channel width enum of current channel. 903 * @primary_chan_ieee: Primary IEEE channel. 904 * @secondary_chan_ieee: Secondary IEEE channel (in HT80_80 mode). 905 */ 906 #ifdef CONFIG_CHAN_NUM_API 907 void dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs, 908 enum phy_ch_width *chwidth, 909 uint8_t *primary_chan_ieee, 910 uint8_t *secondary_chan_ieee); 911 912 #endif 913 914 #ifdef CONFIG_CHAN_FREQ_API 915 /** 916 * dfs_find_chwidth_and_center_chan_for_freq() - Find the channel width enum and 917 * primary and secondary center channel 918 * value of the current channel. 919 * @dfs: Pointer to wlan_dfs structure. 920 * @chwidth: Channel width enum of current channel. 921 * @primary_chan_freq: Primary IEEE channel freq. 922 * @secondary_chan_freq: Secondary IEEE channel freq (in HT80_80 mode). 923 */ 924 void dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs, 925 enum phy_ch_width *chwidth, 926 uint16_t *primary_chan_freq, 927 uint16_t *secondary_chan_freq); 928 #endif 929 930 /** 931 * dfs_mark_precac_done() - Mark the channel as preCAC done. 932 * @dfs: Pointer to wlan_dfs structure. 933 * @pri_ch_ieee: Primary channel IEEE. 934 * @sec_ch_ieee: Secondary channel IEEE (only in HT80_80 mode). 935 * @ch_width: Channel width enum. 936 */ 937 #ifdef CONFIG_CHAN_NUM_API 938 void dfs_mark_precac_done(struct wlan_dfs *dfs, 939 uint8_t pri_ch_ieee, 940 uint8_t sec_ch_ieee, 941 enum phy_ch_width ch_width); 942 #endif 943 944 #ifdef CONFIG_CHAN_FREQ_API 945 /** 946 * dfs_mark_precac_done_for_freq() - Mark the channel as preCAC done. 947 * @dfs: Pointer to wlan_dfs structure. 948 * @pri_chan_freq: Primary channel IEEE freq. 949 * @sec_chan_freq: Secondary channel IEEE freq(only in HT80_80 mode). 950 * @chan_width: Channel width enum. 951 */ 952 void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs, 953 uint16_t pri_chan_freq, 954 uint16_t sec_chan_freq, 955 enum phy_ch_width chan_width); 956 #endif 957 958 /** 959 * dfs_mark_precac_nol() - Mark the precac channel as radar. 960 * @dfs: Pointer to wlan_dfs structure. 961 * @is_radar_found_on_secondary_seg: Radar found on secondary seg for Cascade. 962 * @detector_id: detector id which found RADAR in HW. 963 * @channels: Array of radar found subchannels. 964 * @num_channels: Number of radar found subchannels. 965 */ 966 #ifdef CONFIG_CHAN_NUM_API 967 void dfs_mark_precac_nol(struct wlan_dfs *dfs, 968 uint8_t is_radar_found_on_secondary_seg, 969 uint8_t detector_id, 970 uint8_t *channels, 971 uint8_t num_channels); 972 #endif 973 974 /** 975 * dfs_mark_precac_nol_for_freq() - Mark the precac channel as radar. 976 * @dfs: Pointer to wlan_dfs structure. 977 * @is_radar_found_on_secondary_seg: Radar found on secondary seg for Cascade. 978 * @detector_id: detector id which found RADAR in HW. 979 * @freq_list: Array of radar found frequencies. 980 * @num_channels: Number of radar found subchannels. 981 */ 982 #ifdef CONFIG_CHAN_FREQ_API 983 void dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs, 984 uint8_t is_radar_found_on_secondary_seg, 985 uint8_t detector_id, 986 uint16_t *freq_list, 987 uint8_t num_channels); 988 #endif 989 990 /** 991 * dfs_unmark_precac_nol() - Unmark the precac channel as radar. 992 * @dfs: Pointer to wlan_dfs structure. 993 * @channel: channel marked as radar. 994 */ 995 #ifdef CONFIG_CHAN_NUM_API 996 void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel); 997 #endif 998 999 /** 1000 * dfs_unmark_precac_nol_for_freq() - Unmark the precac channel as radar. 1001 * @dfs: Pointer to wlan_dfs structure. 1002 * @channel: channel freq marked as radar. 1003 */ 1004 #ifdef CONFIG_CHAN_FREQ_API 1005 void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs, uint16_t chan_freq); 1006 #endif 1007 1008 #else 1009 #ifdef CONFIG_CHAN_NUM_API 1010 static inline void 1011 dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs, 1012 enum phy_ch_width *chwidth, 1013 uint8_t *primary_chan_ieee, 1014 uint8_t *secondary_chan_ieee) 1015 { 1016 } 1017 #endif 1018 1019 #ifdef CONFIG_CHAN_FREQ_API 1020 static inline void 1021 dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs, 1022 enum phy_ch_width *chwidth, 1023 uint16_t *primary_chan_freq, 1024 uint16_t *secondary_chan_freq) 1025 { 1026 } 1027 #endif 1028 1029 #ifdef CONFIG_CHAN_NUM_API 1030 static inline void dfs_mark_precac_done(struct wlan_dfs *dfs, 1031 uint8_t pri_ch_ieee, 1032 uint8_t sec_ch_ieee, 1033 enum phy_ch_width ch_width) 1034 { 1035 } 1036 #endif 1037 1038 #ifdef CONFIG_CHAN_FREQ_API 1039 static inline void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs, 1040 uint16_t pri_chan_freq, 1041 uint16_t sec_chan_freq, 1042 enum phy_ch_width chan_width) 1043 { 1044 } 1045 #endif 1046 1047 #ifdef CONFIG_CHAN_NUM_API 1048 static inline void dfs_mark_precac_nol(struct wlan_dfs *dfs, 1049 uint8_t is_radar_found_on_secondary_seg, 1050 uint8_t detector_id, 1051 uint8_t *channels, 1052 uint8_t num_channels) 1053 { 1054 } 1055 #endif 1056 1057 #ifdef CONFIG_CHAN_FREQ_API 1058 static inline void 1059 dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs, 1060 uint8_t is_radar_found_on_secondary_seg, 1061 uint8_t detector_id, 1062 uint16_t *freq, 1063 uint8_t num_channels) 1064 { 1065 } 1066 #endif 1067 1068 #ifdef CONFIG_CHAN_NUM_API 1069 static inline void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel) 1070 { 1071 } 1072 #endif 1073 1074 #ifdef CONFIG_CHAN_FREQ_API 1075 static inline void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs, 1076 uint16_t chan_freq) 1077 { 1078 } 1079 #endif 1080 #endif 1081 1082 /** 1083 * dfs_is_precac_timer_running() - Check whether precac timer is running. 1084 * @dfs: Pointer to wlan_dfs structure. 1085 */ 1086 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) 1087 bool dfs_is_precac_timer_running(struct wlan_dfs *dfs); 1088 #else 1089 static inline bool dfs_is_precac_timer_running(struct wlan_dfs *dfs) 1090 { 1091 return false; 1092 } 1093 #endif 1094 1095 #ifdef CONFIG_CHAN_FREQ_API 1096 #define VHT160_FREQ_DIFF 80 1097 1098 #define INITIAL_20_CHAN_FREQ_OFFSET -30 1099 #define INITIAL_40_CHAN_FREQ_OFFSET -20 1100 #define INITIAL_80_CHAN_FREQ_OFFSET 0 1101 1102 #define NEXT_20_CHAN_FREQ_OFFSET 20 1103 #define NEXT_40_CHAN_FREQ_OFFSET 40 1104 #define NEXT_80_CHAN_FREQ_OFFSET 80 1105 1106 #define WEATHER_CHAN_START_FREQ 5600 1107 #define WEATHER_CHAN_END_FREQ 5640 1108 1109 #endif 1110 1111 #endif /* _DFS_ZERO_CAC_H_ */ 1112