1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * 6 * Permission to use, copy, modify, and/or distribute this software for 7 * any purpose with or without fee is hereby granted, provided that the 8 * above copyright notice and this permission notice appear in all 9 * copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 14 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 17 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 18 * PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 /** 22 * DOC: This file has the DFS dispatcher API implementation which is exposed 23 * to outside of DFS component. 24 */ 25 #include <wlan_objmgr_vdev_obj.h> 26 #include "wlan_dfs_utils_api.h" 27 #include "wlan_dfs_init_deinit_api.h" 28 #include "wlan_dfs_mlme_api.h" 29 #include "../../core/src/dfs.h" 30 #include "../../core/src/dfs_zero_cac.h" 31 #include <wlan_reg_services_api.h> 32 #include "../../core/src/dfs_random_chan_sel.h" 33 #ifdef QCA_DFS_USE_POLICY_MANAGER 34 #include "wlan_policy_mgr_api.h" 35 #endif 36 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 37 #include <pld_common.h> 38 #endif 39 #include <qdf_module.h> 40 #include "wlan_dfs_lmac_api.h" 41 #include "../../core/src/dfs_internal.h" 42 43 struct dfs_nol_info { 44 uint16_t num_chans; 45 struct dfsreq_nolelem dfs_nol[DFS_MAX_NOL_CHANNEL]; 46 }; 47 48 QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev) 49 { 50 struct wlan_dfs *dfs; 51 52 dfs = wlan_pdev_get_dfs_obj(pdev); 53 if (!dfs) 54 return QDF_STATUS_E_FAILURE; 55 56 dfs_reset(dfs); 57 dfs_nol_update(dfs); 58 dfs_reset_precaclists(dfs); 59 dfs_init_chan_state_array(pdev); 60 61 return QDF_STATUS_SUCCESS; 62 } 63 64 bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq) 65 { 66 struct wlan_dfs *dfs; 67 68 dfs = wlan_pdev_get_dfs_obj(pdev); 69 if (!dfs) 70 return false; 71 72 return dfs_is_freq_in_nol(dfs, freq); 73 } 74 75 #ifdef CONFIG_CHAN_FREQ_API 76 QDF_STATUS utils_dfs_cac_valid_reset_for_freq(struct wlan_objmgr_pdev *pdev, 77 uint16_t prevchan_freq, 78 uint32_t prevchan_flags) 79 { 80 struct wlan_dfs *dfs; 81 82 dfs = wlan_pdev_get_dfs_obj(pdev); 83 if (!dfs) 84 return QDF_STATUS_E_FAILURE; 85 86 dfs_cac_valid_reset_for_freq(dfs, prevchan_freq, prevchan_flags); 87 88 return QDF_STATUS_SUCCESS; 89 } 90 91 qdf_export_symbol(utils_dfs_cac_valid_reset_for_freq); 92 #endif 93 94 QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) 95 { 96 struct wlan_dfs *dfs; 97 98 dfs = wlan_pdev_get_dfs_obj(pdev); 99 if (!dfs) 100 return QDF_STATUS_E_FAILURE; 101 102 dfs_reset_precaclists(dfs); 103 104 return QDF_STATUS_SUCCESS; 105 } 106 qdf_export_symbol(utils_dfs_reset_precaclists); 107 108 #ifdef CONFIG_CHAN_FREQ_API 109 void utils_dfs_unmark_precac_nol_for_freq(struct wlan_objmgr_pdev *pdev, 110 uint16_t chan_freq) 111 { 112 struct wlan_dfs *dfs; 113 114 dfs = wlan_pdev_get_dfs_obj(pdev); 115 if (!dfs) 116 return; 117 118 dfs_unmark_precac_nol_for_freq(dfs, chan_freq); 119 } 120 121 qdf_export_symbol(utils_dfs_unmark_precac_nol_for_freq); 122 #endif 123 124 QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev) 125 { 126 struct wlan_dfs *dfs; 127 128 dfs = wlan_pdev_get_dfs_obj(pdev); 129 if (!dfs) 130 return QDF_STATUS_E_FAILURE; 131 132 dfs_cancel_precac_timer(dfs); 133 134 return QDF_STATUS_SUCCESS; 135 } 136 qdf_export_symbol(utils_dfs_cancel_precac_timer); 137 138 #ifdef CONFIG_CHAN_FREQ_API 139 QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev) 140 { 141 struct wlan_dfs *dfs; 142 143 dfs = wlan_pdev_get_dfs_obj(pdev); 144 if (!dfs) { 145 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs"); 146 return QDF_STATUS_E_FAILURE; 147 } 148 149 if (!dfs->dfs_precac_secondary_freq_mhz) 150 return QDF_STATUS_E_FAILURE; 151 152 dfs_start_precac_timer_for_freq(dfs, 153 dfs->dfs_precac_secondary_freq_mhz); 154 return QDF_STATUS_SUCCESS; 155 } 156 #else 157 #endif 158 159 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT 160 #ifdef CONFIG_CHAN_FREQ_API 161 bool 162 utils_dfs_precac_decide_pref_chan_for_freq(struct wlan_objmgr_pdev *pdev, 163 uint16_t *chan_freq, 164 enum wlan_phymode mode) 165 { 166 struct wlan_dfs *dfs; 167 168 dfs = wlan_pdev_get_dfs_obj(pdev); 169 if (!dfs) { 170 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs"); 171 return false; 172 } 173 return dfs_decide_precac_preferred_chan_for_freq(dfs, chan_freq, mode); 174 } 175 #endif 176 #endif 177 QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev) 178 { 179 struct wlan_dfs *dfs; 180 181 dfs = wlan_pdev_get_dfs_obj(pdev); 182 if (!dfs) 183 return QDF_STATUS_E_FAILURE; 184 185 dfs_cancel_cac_timer(dfs); 186 187 return QDF_STATUS_SUCCESS; 188 } 189 qdf_export_symbol(utils_dfs_cancel_cac_timer); 190 191 QDF_STATUS utils_dfs_start_cac_timer(struct wlan_objmgr_pdev *pdev) 192 { 193 struct wlan_dfs *dfs; 194 195 dfs = wlan_pdev_get_dfs_obj(pdev); 196 if (!dfs) 197 return QDF_STATUS_E_FAILURE; 198 199 dfs_start_cac_timer(dfs); 200 201 return QDF_STATUS_SUCCESS; 202 } 203 qdf_export_symbol(utils_dfs_start_cac_timer); 204 205 QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev) 206 { 207 struct wlan_dfs *dfs; 208 209 dfs = wlan_pdev_get_dfs_obj(pdev); 210 if (!dfs) 211 return QDF_STATUS_E_FAILURE; 212 213 dfs_cac_stop(dfs); 214 return QDF_STATUS_SUCCESS; 215 } 216 qdf_export_symbol(utils_dfs_cac_stop); 217 218 /** dfs_fill_chan_info() - Fill the dfs channel structure with wlan 219 * channel. 220 * @chan: Pointer to DFS channel structure. 221 * @wlan_chan: Pointer to WLAN Channel structure. 222 * 223 * Return: void 224 */ 225 #ifdef CONFIG_CHAN_FREQ_API 226 static void dfs_fill_chan_info(struct dfs_channel *chan, 227 struct wlan_channel *wlan_chan) 228 { 229 chan->dfs_ch_freq = wlan_chan->ch_freq; 230 chan->dfs_ch_flags = wlan_chan->ch_flags; 231 chan->dfs_ch_flagext = wlan_chan->ch_flagext; 232 chan->dfs_ch_ieee = wlan_chan->ch_ieee; 233 chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1; 234 chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2; 235 chan->dfs_ch_mhz_freq_seg1 = wlan_chan->ch_cfreq1; 236 chan->dfs_ch_mhz_freq_seg2 = wlan_chan->ch_cfreq2; 237 } 238 #endif 239 240 bool utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev, 241 struct wlan_channel *wlan_chan) 242 { 243 struct wlan_dfs *dfs; 244 struct dfs_channel chan; 245 246 dfs = wlan_pdev_get_dfs_obj(pdev); 247 if (!dfs) 248 return false; 249 250 dfs_fill_chan_info(&chan, wlan_chan); 251 252 return dfs_is_precac_done(dfs, &chan); 253 } 254 255 bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev, 256 struct wlan_channel *cur_chan, 257 struct wlan_channel *prev_chan, 258 bool *continue_current_cac) 259 { 260 struct wlan_dfs *dfs; 261 struct dfs_channel cur_channel; 262 struct dfs_channel prev_channel; 263 264 dfs = wlan_pdev_get_dfs_obj(pdev); 265 if (!dfs) 266 return false; 267 268 dfs_fill_chan_info(&cur_channel, cur_chan); 269 dfs_fill_chan_info(&prev_channel, prev_chan); 270 271 return dfs_is_cac_required(dfs, 272 &cur_channel, 273 &prev_channel, 274 continue_current_cac, true); 275 } 276 277 bool 278 utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev *pdev, 279 bool *continue_current_cac, 280 bool is_vap_restart) 281 { 282 struct wlan_dfs *dfs; 283 284 dfs = wlan_pdev_get_dfs_obj(pdev); 285 if (!dfs) 286 return false; 287 288 return dfs_is_cac_required(dfs, 289 dfs->dfs_curchan, 290 dfs->dfs_prevchan, 291 continue_current_cac, 292 is_vap_restart); 293 } 294 295 QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev) 296 { 297 struct wlan_dfs *dfs; 298 299 dfs = wlan_pdev_get_dfs_obj(pdev); 300 if (!dfs) 301 return QDF_STATUS_E_FAILURE; 302 303 dfs_stacac_stop(dfs); 304 305 return QDF_STATUS_SUCCESS; 306 } 307 qdf_export_symbol(utils_dfs_stacac_stop); 308 309 QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol) 310 { 311 struct wlan_dfs *dfs; 312 313 dfs = wlan_pdev_get_dfs_obj(pdev); 314 if (!dfs) 315 return QDF_STATUS_E_FAILURE; 316 317 *usenol = dfs_get_use_nol(dfs); 318 319 return QDF_STATUS_SUCCESS; 320 } 321 qdf_export_symbol(utils_dfs_get_usenol); 322 323 bool utils_dfs_is_spruce_spur_war_applicable(struct wlan_objmgr_pdev *pdev) 324 { 325 struct wlan_dfs *dfs; 326 struct wlan_objmgr_psoc *psoc; 327 struct wlan_lmac_if_tx_ops *tx_ops; 328 uint32_t target_type; 329 struct wlan_lmac_if_target_tx_ops *tgt_tx_ops; 330 qdf_freq_t cur_freq; 331 332 dfs = wlan_pdev_get_dfs_obj(pdev); 333 if (!dfs) 334 return false; 335 336 psoc = dfs->dfs_soc_obj->psoc; 337 338 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 339 if (!tx_ops) { 340 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "tx_ops is NULL"); 341 return false; 342 } 343 344 tgt_tx_ops = &tx_ops->target_tx_ops; 345 target_type = lmac_get_target_type(dfs->dfs_pdev_obj); 346 347 /* Is the target Spruce? */ 348 if (!tgt_tx_ops->tgt_is_tgt_type_qcn6122) 349 return false; 350 351 if (!tgt_tx_ops->tgt_is_tgt_type_qcn6122(target_type)) 352 return false; 353 354 cur_freq = dfs->dfs_curchan->dfs_ch_freq; 355 356 /* Is the current channel width 80MHz? */ 357 if (WLAN_IS_CHAN_MODE_80(dfs->dfs_curchan) || 358 WLAN_IS_CHAN_MODE_40(dfs->dfs_curchan) || 359 WLAN_IS_CHAN_MODE_20(dfs->dfs_curchan)) { 360 /* is the primary channel 52/56/60/64? */ 361 bool is_chan_spur_80mhzfreq = 362 DFS_IS_CHAN_SPRUCE_SPUR_FREQ_80MHZ(cur_freq); 363 if (is_chan_spur_80mhzfreq) 364 return true; 365 return false; 366 } 367 368 /* If the current channel width is not 80, is it 160MHz? */ 369 if (WLAN_IS_CHAN_MODE_160(dfs->dfs_curchan)) { 370 /* is the primary channel 36/44/48/52/56/60/64? */ 371 bool is_chan_spur_160mhz_freq = 372 DFS_IS_CHAN_SPRUCE_SPUR_FREQ_160MHZ(cur_freq); 373 if (is_chan_spur_160mhz_freq) 374 return true; 375 return false; 376 } 377 378 return false; 379 } 380 381 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev) 382 { 383 struct wlan_dfs *dfs; 384 385 dfs = wlan_pdev_get_dfs_obj(pdev); 386 if (!dfs) 387 return QDF_STATUS_E_FAILURE; 388 389 dfs_radar_disable(dfs); 390 391 return QDF_STATUS_SUCCESS; 392 } 393 qdf_export_symbol(utils_dfs_radar_disable); 394 395 QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev, 396 bool val) 397 { 398 struct wlan_dfs *dfs; 399 400 dfs = wlan_pdev_get_dfs_obj(pdev); 401 if (!dfs) 402 return QDF_STATUS_E_FAILURE; 403 404 dfs_set_update_nol_flag(dfs, val); 405 406 return QDF_STATUS_SUCCESS; 407 } 408 qdf_export_symbol(utils_dfs_set_update_nol_flag); 409 410 QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev, 411 bool *nol_flag) 412 { 413 struct wlan_dfs *dfs; 414 415 dfs = wlan_pdev_get_dfs_obj(pdev); 416 if (!dfs) 417 return QDF_STATUS_E_FAILURE; 418 419 *nol_flag = dfs_get_update_nol_flag(dfs); 420 421 return QDF_STATUS_SUCCESS; 422 } 423 qdf_export_symbol(utils_dfs_get_update_nol_flag); 424 425 QDF_STATUS utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev *pdev, 426 int *dfs_use_nol) 427 { 428 struct wlan_dfs *dfs; 429 430 dfs = wlan_pdev_get_dfs_obj(pdev); 431 if (!dfs) 432 return QDF_STATUS_E_FAILURE; 433 434 *dfs_use_nol = dfs_get_use_nol(dfs); 435 436 return QDF_STATUS_SUCCESS; 437 } 438 qdf_export_symbol(utils_dfs_get_dfs_use_nol); 439 440 QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev, 441 int *dfs_nol_timeout) 442 { 443 struct wlan_dfs *dfs; 444 445 dfs = wlan_pdev_get_dfs_obj(pdev); 446 if (!dfs) 447 return QDF_STATUS_E_FAILURE; 448 449 *dfs_nol_timeout = dfs_get_nol_timeout(dfs); 450 451 return QDF_STATUS_SUCCESS; 452 } 453 qdf_export_symbol(utils_dfs_get_nol_timeout); 454 455 QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev, 456 uint16_t freq, 457 uint32_t dfs_nol_timeout) 458 { 459 struct wlan_dfs *dfs; 460 461 dfs = wlan_pdev_get_dfs_obj(pdev); 462 if (!dfs) 463 return QDF_STATUS_E_FAILURE; 464 465 DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, dfs_nol_timeout); 466 467 return QDF_STATUS_SUCCESS; 468 } 469 qdf_export_symbol(utils_dfs_nol_addchan); 470 471 QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev) 472 { 473 struct wlan_dfs *dfs; 474 475 dfs = wlan_pdev_get_dfs_obj(pdev); 476 if (!dfs) 477 return QDF_STATUS_E_FAILURE; 478 479 dfs_nol_update(dfs); 480 481 return QDF_STATUS_SUCCESS; 482 } 483 qdf_export_symbol(utils_dfs_nol_update); 484 485 QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev) 486 { 487 struct wlan_dfs *dfs; 488 489 dfs = wlan_pdev_get_dfs_obj(pdev); 490 if (!dfs) 491 return QDF_STATUS_E_FAILURE; 492 493 dfs_second_segment_radar_disable(dfs); 494 495 return QDF_STATUS_SUCCESS; 496 } 497 498 QDF_STATUS utils_dfs_bw_reduce(struct wlan_objmgr_pdev *pdev, bool bw_reduce) 499 { 500 struct wlan_dfs *dfs; 501 502 dfs = wlan_pdev_get_dfs_obj(pdev); 503 if (!dfs) 504 return QDF_STATUS_E_FAILURE; 505 506 dfs->dfs_bw_reduced = bw_reduce; 507 508 return QDF_STATUS_SUCCESS; 509 } 510 511 qdf_export_symbol(utils_dfs_bw_reduce); 512 513 QDF_STATUS utils_dfs_is_bw_reduce(struct wlan_objmgr_pdev *pdev, 514 bool *bw_reduce) 515 { 516 struct wlan_dfs *dfs; 517 518 dfs = wlan_pdev_get_dfs_obj(pdev); 519 if (!dfs) 520 return QDF_STATUS_E_FAILURE; 521 522 *bw_reduce = dfs->dfs_bw_reduced; 523 524 return QDF_STATUS_SUCCESS; 525 } 526 527 QDF_STATUS utils_dfs_fetch_nol_ie_info(struct wlan_objmgr_pdev *pdev, 528 uint8_t *nol_ie_bandwidth, 529 uint16_t *nol_ie_startfreq, 530 uint8_t *nol_ie_bitmap) 531 { 532 struct wlan_dfs *dfs; 533 534 dfs = wlan_pdev_get_dfs_obj(pdev); 535 if (!dfs) 536 return QDF_STATUS_E_FAILURE; 537 538 dfs_fetch_nol_ie_info(dfs, nol_ie_bandwidth, nol_ie_startfreq, 539 nol_ie_bitmap); 540 541 return QDF_STATUS_SUCCESS; 542 } 543 544 QDF_STATUS utils_dfs_set_rcsa_flags(struct wlan_objmgr_pdev *pdev, 545 bool is_rcsa_ie_sent, 546 bool is_nol_ie_sent) 547 { 548 struct wlan_dfs *dfs; 549 550 dfs = wlan_pdev_get_dfs_obj(pdev); 551 if (!dfs) 552 return QDF_STATUS_E_FAILURE; 553 554 dfs_set_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent); 555 556 return QDF_STATUS_SUCCESS; 557 } 558 559 QDF_STATUS utils_dfs_get_rcsa_flags(struct wlan_objmgr_pdev *pdev, 560 bool *is_rcsa_ie_sent, 561 bool *is_nol_ie_sent) 562 { 563 struct wlan_dfs *dfs; 564 565 dfs = wlan_pdev_get_dfs_obj(pdev); 566 if (!dfs) 567 return QDF_STATUS_E_FAILURE; 568 dfs_get_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent); 569 570 return QDF_STATUS_SUCCESS; 571 } 572 573 bool utils_dfs_process_nol_ie_bitmap(struct wlan_objmgr_pdev *pdev, 574 uint8_t nol_ie_bandwidth, 575 uint16_t nol_ie_startfreq, 576 uint8_t nol_ie_bitmap) 577 { 578 struct wlan_dfs *dfs; 579 580 dfs = wlan_pdev_get_dfs_obj(pdev); 581 if (!dfs) 582 return false; 583 return dfs_process_nol_ie_bitmap(dfs, nol_ie_bandwidth, 584 nol_ie_startfreq, 585 nol_ie_bitmap); 586 } 587 588 QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev, 589 int val) 590 { 591 struct wlan_dfs *dfs; 592 593 dfs = wlan_pdev_get_dfs_obj(pdev); 594 if (!dfs) 595 return QDF_STATUS_E_FAILURE; 596 597 dfs->dfs_cac_timer_running = val; 598 599 return QDF_STATUS_SUCCESS; 600 } 601 qdf_export_symbol(utils_dfs_set_cac_timer_running); 602 603 QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev, 604 void *nollist, 605 uint32_t *nol_chfreq, 606 uint32_t *nol_chwidth, 607 int index) 608 { 609 struct wlan_dfs *dfs; 610 611 dfs = wlan_pdev_get_dfs_obj(pdev); 612 if (!dfs) 613 return QDF_STATUS_E_FAILURE; 614 615 dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index); 616 617 return QDF_STATUS_SUCCESS; 618 } 619 qdf_export_symbol(utils_dfs_get_nol_chfreq_and_chwidth); 620 621 QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev, 622 uint64_t flags, 623 uint16_t flagext) 624 { 625 struct wlan_dfs *dfs; 626 627 dfs = wlan_pdev_get_dfs_obj(pdev); 628 if (!dfs) 629 return QDF_STATUS_E_FAILURE; 630 631 dfs_update_cur_chan_flags(dfs, flags, flagext); 632 633 return QDF_STATUS_SUCCESS; 634 } 635 636 static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev, 637 uint32_t *phy_mode) 638 { 639 return; 640 } 641 642 static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev, 643 uint8_t *ch_width) 644 { 645 return; 646 } 647 648 #ifndef QCA_DFS_USE_POLICY_MANAGER 649 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, 650 void *clist, uint32_t *num_chan) 651 { 652 uint32_t i = 0, j = 0; 653 enum channel_state state; 654 struct regulatory_channel *cur_chan_list; 655 struct wlan_dfs *dfs; 656 struct dfs_channel *chan_list = (struct dfs_channel *)clist; 657 658 dfs = wlan_pdev_get_dfs_obj(pdev); 659 if (!dfs) { 660 *num_chan = 0; 661 return; 662 } 663 664 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * 665 sizeof(struct regulatory_channel)); 666 if (!cur_chan_list) { 667 *num_chan = 0; 668 return; 669 } 670 671 if (wlan_reg_get_current_chan_list( 672 pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { 673 *num_chan = 0; 674 dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, 675 "failed to get curr channel list"); 676 return; 677 } 678 679 for (i = 0; i < NUM_CHANNELS; i++) { 680 state = cur_chan_list[i].state; 681 if (state == CHANNEL_STATE_DFS || 682 state == CHANNEL_STATE_ENABLE) { 683 chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num; 684 chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq; 685 if (state == CHANNEL_STATE_DFS) 686 chan_list[j].dfs_ch_flagext = 687 WLAN_CHAN_DFS; 688 689 if (cur_chan_list[i].nol_history) 690 chan_list[j].dfs_ch_flagext |= 691 WLAN_CHAN_HISTORY_RADAR; 692 j++; 693 } 694 } 695 *num_chan = j; 696 qdf_mem_free(cur_chan_list); 697 698 return; 699 } 700 701 /** 702 * utils_dfs_get_channel_list() - Get channel list from regdb component, based 703 * on current channel list. 704 * @pdev: Pointer to pdev structure. 705 * @vdev: vdev of request 706 * @chan: Pointer to channel list. 707 * @num_chan: number of channels. 708 * 709 * Get regdb channel list based on dfs current channel. 710 * Ex: When AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels 711 * so that the random channel function does not select either 2.4GHz or 4.9GHz 712 * channel. 713 */ 714 #ifdef CONFIG_CHAN_FREQ_API 715 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, 716 struct wlan_objmgr_vdev *vdev, 717 struct dfs_channel *chan_list, 718 uint32_t *num_chan) 719 { 720 struct dfs_channel *tmp_chan_list = NULL; 721 struct wlan_dfs *dfs; 722 bool is_curchan_5g; 723 bool is_curchan_24g; 724 bool is_curchan_49g; 725 bool is_inter_band_switch_allowed; 726 uint8_t chan_num; 727 uint16_t center_freq; 728 uint16_t flagext; 729 uint32_t i, j = 0; 730 731 dfs = wlan_pdev_get_dfs_obj(pdev); 732 if (!dfs) { 733 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 734 return; 735 } 736 737 tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list)); 738 if (!tmp_chan_list) 739 return; 740 741 utils_dfs_get_chan_list(pdev, (void *)tmp_chan_list, num_chan); 742 743 chan_num = dfs->dfs_curchan->dfs_ch_ieee; 744 center_freq = dfs->dfs_curchan->dfs_ch_freq; 745 is_curchan_5g = WLAN_REG_IS_5GHZ_CH_FREQ(center_freq); 746 is_curchan_24g = WLAN_REG_IS_24GHZ_CH_FREQ(center_freq); 747 is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq); 748 is_inter_band_switch_allowed = 749 dfs_mlme_is_inter_band_chan_switch_allowed(dfs->dfs_pdev_obj); 750 751 for (i = 0; i < *num_chan; i++) { 752 chan_num = tmp_chan_list[i].dfs_ch_ieee; 753 center_freq = tmp_chan_list[i].dfs_ch_freq; 754 flagext = tmp_chan_list[i].dfs_ch_flagext; 755 /* No change in prototype needed. Hence retaining same func */ 756 if (!dfs_mlme_check_allowed_prim_chanlist(pdev, center_freq)) 757 continue; 758 759 if (is_curchan_5g) { 760 /* 761 * Always add 5G channels. 762 * If inter band is allowed, add 6G also. 763 */ 764 if (WLAN_REG_IS_5GHZ_CH_FREQ(center_freq) || 765 (is_inter_band_switch_allowed && 766 WLAN_REG_IS_6GHZ_CHAN_FREQ(center_freq))) { 767 chan_list[j].dfs_ch_ieee = chan_num; 768 chan_list[j].dfs_ch_freq = center_freq; 769 chan_list[j].dfs_ch_flagext = flagext; 770 j++; 771 } 772 } else if ((is_curchan_24g) && 773 WLAN_REG_IS_24GHZ_CH_FREQ(center_freq)) { 774 chan_list[j].dfs_ch_ieee = chan_num; 775 chan_list[j].dfs_ch_freq = center_freq; 776 j++; 777 } else if ((is_curchan_49g) && 778 WLAN_REG_IS_49GHZ_FREQ(center_freq)) { 779 chan_list[j].dfs_ch_ieee = chan_num; 780 chan_list[j].dfs_ch_freq = center_freq; 781 j++; 782 } 783 } 784 785 *num_chan = j; 786 787 qdf_mem_free(tmp_chan_list); 788 } 789 #endif 790 #else 791 void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, 792 void *clist, uint32_t *num_chan) 793 { 794 utils_dfs_get_chan_list(pdev, clist, num_chan); 795 } 796 797 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, 798 struct wlan_objmgr_vdev *vdev, 799 struct dfs_channel *chan_list, 800 uint32_t *num_chan) 801 { 802 uint32_t pcl_ch[NUM_CHANNELS] = {0}; 803 uint8_t weight_list[NUM_CHANNELS] = {0}; 804 uint32_t len; 805 uint32_t weight_len; 806 uint32_t i; 807 struct wlan_objmgr_psoc *psoc; 808 uint32_t conn_count = 0; 809 enum policy_mgr_con_mode mode; 810 811 psoc = wlan_pdev_get_psoc(pdev); 812 if (!psoc) { 813 *num_chan = 0; 814 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 815 return; 816 } 817 818 len = QDF_ARRAY_SIZE(pcl_ch); 819 weight_len = QDF_ARRAY_SIZE(weight_list); 820 821 if (vdev) 822 mode = policy_mgr_convert_device_mode_to_qdf_type( 823 wlan_vdev_mlme_get_opmode(vdev)); 824 else 825 mode = PM_SAP_MODE; 826 conn_count = policy_mgr_mode_specific_connection_count( 827 psoc, mode, NULL); 828 if (0 == conn_count) 829 policy_mgr_get_pcl(psoc, mode, pcl_ch, 830 &len, weight_list, weight_len); 831 else 832 policy_mgr_get_pcl_for_existing_conn( 833 psoc, mode, pcl_ch, &len, weight_list, 834 weight_len, true); 835 836 if (*num_chan < len) { 837 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 838 "Invalid len src=%d, dst=%d", 839 *num_chan, len); 840 *num_chan = 0; 841 return; 842 } 843 844 for (i = 0; i < len; i++) { 845 chan_list[i].dfs_ch_ieee = 846 wlan_reg_freq_to_chan(pdev, pcl_ch[i]); 847 chan_list[i].dfs_ch_freq = pcl_ch[i]; 848 if (wlan_reg_is_dfs_for_freq(pdev, pcl_ch[i])) 849 chan_list[i].dfs_ch_flagext |= WLAN_CHAN_DFS; 850 } 851 *num_chan = i; 852 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i); 853 } 854 855 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, 856 void *clist, uint32_t *num_chan) 857 { 858 utils_dfs_get_channel_list(pdev, NULL, (struct dfs_channel *)clist, 859 num_chan); 860 } 861 862 bool utils_dfs_can_ignore_radar_event(struct wlan_objmgr_pdev *pdev) 863 { 864 return policy_mgr_get_can_skip_radar_event( 865 wlan_pdev_get_psoc(pdev), INVALID_VDEV_ID); 866 } 867 #endif 868 869 #ifdef CONFIG_CHAN_FREQ_API 870 QDF_STATUS utils_dfs_get_vdev_random_channel_for_freq( 871 struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, 872 uint16_t flags, struct ch_params *chan_params, uint32_t *hw_mode, 873 uint16_t *target_chan_freq, struct dfs_acs_info *acs_info) 874 { 875 uint32_t dfs_reg; 876 uint32_t num_chan = NUM_CHANNELS; 877 struct wlan_dfs *dfs = NULL; 878 struct wlan_objmgr_psoc *psoc; 879 struct dfs_channel *chan_list = NULL; 880 QDF_STATUS status = QDF_STATUS_E_FAILURE; 881 882 *target_chan_freq = 0; 883 psoc = wlan_pdev_get_psoc(pdev); 884 if (!psoc) { 885 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 886 goto random_chan_error; 887 } 888 889 dfs = wlan_pdev_get_dfs_obj(pdev); 890 if (!dfs) { 891 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 892 goto random_chan_error; 893 } 894 895 wlan_reg_get_dfs_region(pdev, &dfs_reg); 896 chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list)); 897 if (!chan_list) 898 goto random_chan_error; 899 900 utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan); 901 if (!num_chan) { 902 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels"); 903 goto random_chan_error; 904 } 905 906 if (!chan_params->ch_width) 907 utils_dfs_get_max_sup_width(pdev, 908 (uint8_t *)&chan_params->ch_width); 909 910 *target_chan_freq = dfs_prepare_random_channel_for_freq( 911 dfs, chan_list, num_chan, flags, chan_params, 912 (uint8_t)dfs_reg, acs_info); 913 914 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 915 "input width=%d", chan_params->ch_width); 916 917 if (*target_chan_freq) { 918 wlan_reg_set_channel_params_for_pwrmode( 919 pdev, *target_chan_freq, 0, 920 chan_params, 921 REG_CURRENT_PWR_MODE); 922 utils_dfs_get_max_phy_mode(pdev, hw_mode); 923 status = QDF_STATUS_SUCCESS; 924 } 925 926 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 927 "ch=%d, seg0=%d, seg1=%d, width=%d", 928 *target_chan_freq, chan_params->center_freq_seg0, 929 chan_params->center_freq_seg1, chan_params->ch_width); 930 931 random_chan_error: 932 qdf_mem_free(chan_list); 933 934 return status; 935 } 936 937 qdf_export_symbol(utils_dfs_get_vdev_random_channel_for_freq); 938 #endif 939 940 #ifdef CONFIG_CHAN_FREQ_API 941 QDF_STATUS utils_dfs_get_random_channel_for_freq( 942 struct wlan_objmgr_pdev *pdev, 943 uint16_t flags, 944 struct ch_params *ch_params, 945 uint32_t *hw_mode, 946 uint16_t *target_chan_freq, 947 struct dfs_acs_info *acs_info) 948 { 949 return utils_dfs_get_vdev_random_channel_for_freq(pdev, NULL, flags, 950 ch_params, hw_mode, 951 target_chan_freq, 952 acs_info); 953 } 954 955 qdf_export_symbol(utils_dfs_get_random_channel_for_freq); 956 #endif 957 958 #ifdef CONFIG_CHAN_FREQ_API 959 QDF_STATUS utils_dfs_bw_reduced_channel_for_freq( 960 struct wlan_objmgr_pdev *pdev, 961 struct ch_params *chan_params, 962 uint32_t *hw_mode, 963 uint16_t *target_chan_freq) 964 { 965 struct wlan_dfs *dfs = NULL; 966 struct wlan_objmgr_psoc *psoc; 967 enum channel_state ch_state; 968 QDF_STATUS status = QDF_STATUS_E_FAILURE; 969 struct dfs_channel *dfs_curchan; 970 971 *target_chan_freq = 0; 972 psoc = wlan_pdev_get_psoc(pdev); 973 if (!psoc) { 974 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 975 return status; 976 } 977 978 dfs = wlan_pdev_get_dfs_obj(pdev); 979 if (!dfs) { 980 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 981 return status; 982 } 983 dfs_curchan = dfs->dfs_curchan; 984 ch_state = 985 wlan_reg_get_channel_state_for_pwrmode(pdev, 986 dfs_curchan->dfs_ch_freq, 987 REG_CURRENT_PWR_MODE); 988 989 if (ch_state == CHANNEL_STATE_DFS || 990 ch_state == CHANNEL_STATE_ENABLE) { 991 /* If the current channel is 80P80MHz and radar is detected on 992 * the channel, the next highest bandwidth that maybe available 993 * is 80MHz. Since the current regulatory algorithm reduces the 994 * bandwidth from 80P80MHz to 160MHz, provide the channel 995 * width as 80MHz if current channel is 80P80MHz. 996 */ 997 if (chan_params->ch_width == CH_WIDTH_80P80MHZ) 998 chan_params->ch_width = CH_WIDTH_80MHZ; 999 1000 chan_params->mhz_freq_seg0 = 1001 dfs_curchan->dfs_ch_mhz_freq_seg1; 1002 chan_params->mhz_freq_seg1 = 1003 dfs_curchan->dfs_ch_mhz_freq_seg2; 1004 wlan_reg_set_channel_params_for_pwrmode(pdev, dfs_curchan-> 1005 dfs_ch_freq, 1006 0, chan_params, 1007 REG_CURRENT_PWR_MODE); 1008 1009 *target_chan_freq = dfs_curchan->dfs_ch_freq; 1010 utils_dfs_get_max_phy_mode(pdev, hw_mode); 1011 1012 return QDF_STATUS_SUCCESS; 1013 } 1014 1015 return status; 1016 } 1017 1018 qdf_export_symbol(utils_dfs_bw_reduced_channel_for_freq); 1019 #endif 1020 1021 1022 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 1023 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev) 1024 { 1025 struct wlan_dfs *dfs; 1026 struct wlan_objmgr_psoc *psoc; 1027 qdf_device_t qdf_dev; 1028 struct dfs_nol_info *dfs_nolinfo; 1029 int len; 1030 1031 dfs = wlan_pdev_get_dfs_obj(pdev); 1032 psoc = wlan_pdev_get_psoc(pdev); 1033 if (!dfs || !psoc) { 1034 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 1035 "dfs %pK, psoc %pK", dfs, psoc); 1036 return; 1037 } 1038 1039 qdf_dev = psoc->soc_objmgr.qdf_dev; 1040 if (!qdf_dev->dev) { 1041 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null device"); 1042 return; 1043 } 1044 1045 dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo)); 1046 if (!dfs_nolinfo) 1047 return; 1048 1049 qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo)); 1050 len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo, 1051 (uint16_t)sizeof(*dfs_nolinfo)); 1052 if (len > 0) { 1053 dfs_set_nol(dfs, dfs_nolinfo->dfs_nol, dfs_nolinfo->num_chans); 1054 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld"); 1055 DFS_PRINT_NOL_LOCKED(dfs); 1056 } else { 1057 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "no nol in pld"); 1058 } 1059 qdf_mem_free(dfs_nolinfo); 1060 } 1061 #endif 1062 qdf_export_symbol(utils_dfs_init_nol); 1063 1064 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 1065 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev) 1066 { 1067 } 1068 #else 1069 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev) 1070 { 1071 struct dfs_nol_info *dfs_nolinfo; 1072 struct wlan_dfs *dfs = NULL; 1073 struct wlan_objmgr_psoc *psoc; 1074 qdf_device_t qdf_dev; 1075 int num_chans = 0; 1076 1077 dfs = wlan_pdev_get_dfs_obj(pdev); 1078 if (!dfs) { 1079 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1080 return; 1081 } 1082 1083 psoc = wlan_pdev_get_psoc(pdev); 1084 if (!psoc) { 1085 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 1086 return; 1087 } 1088 1089 qdf_dev = psoc->soc_objmgr.qdf_dev; 1090 if (!qdf_dev->dev) { 1091 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null device"); 1092 return; 1093 } 1094 1095 dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo)); 1096 if (!dfs_nolinfo) 1097 return; 1098 1099 qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo)); 1100 DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo->dfs_nol, &num_chans); 1101 1102 if (num_chans > DFS_MAX_NOL_CHANNEL) 1103 dfs_nolinfo->num_chans = DFS_MAX_NOL_CHANNEL; 1104 else 1105 dfs_nolinfo->num_chans = num_chans; 1106 1107 pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo, 1108 (uint16_t)sizeof(*dfs_nolinfo)); 1109 qdf_mem_free(dfs_nolinfo); 1110 } 1111 #endif 1112 qdf_export_symbol(utils_dfs_save_nol); 1113 1114 void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev) 1115 { 1116 struct wlan_dfs *dfs = NULL; 1117 1118 dfs = wlan_pdev_get_dfs_obj(pdev); 1119 if (!dfs) { 1120 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1121 return; 1122 } 1123 1124 DFS_PRINT_NOL_LOCKED(dfs); 1125 } 1126 qdf_export_symbol(utils_dfs_print_nol_channels); 1127 1128 void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev) 1129 { 1130 struct wlan_dfs *dfs = NULL; 1131 1132 dfs = wlan_pdev_get_dfs_obj(pdev); 1133 if (!dfs) { 1134 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1135 return; 1136 } 1137 1138 /* First print list */ 1139 DFS_PRINT_NOL_LOCKED(dfs); 1140 1141 /* clear local cache first */ 1142 dfs_nol_timer_cleanup(dfs); 1143 dfs_nol_update(dfs); 1144 1145 /* 1146 * update platform driver nol list with local cache which is zero, 1147 * cleared in above step, so this will clear list in platform driver. 1148 */ 1149 utils_dfs_save_nol(pdev); 1150 } 1151 qdf_export_symbol(utils_dfs_clear_nol_channels); 1152 1153 #ifdef CONFIG_CHAN_FREQ_API 1154 void utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev *pdev, 1155 uint16_t *freq_list, 1156 uint8_t num_chan, 1157 bool nol_chan) 1158 { 1159 wlan_reg_update_nol_ch_for_freq(pdev, freq_list, num_chan, nol_chan); 1160 } 1161 1162 qdf_export_symbol(utils_dfs_reg_update_nol_chan_for_freq); 1163 #endif 1164 1165 #ifdef CONFIG_CHAN_FREQ_API 1166 void 1167 utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev *pdev, 1168 uint16_t *freq_list, 1169 uint8_t num_chan, 1170 bool nol_history_chan) 1171 { 1172 wlan_reg_update_nol_history_ch_for_freq(pdev, freq_list, num_chan, 1173 nol_history_chan); 1174 } 1175 #endif 1176 1177 uint8_t utils_dfs_freq_to_chan(uint32_t freq) 1178 { 1179 uint8_t chan; 1180 1181 if (freq == 0) 1182 return 0; 1183 1184 if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ) 1185 chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ); 1186 else if (freq == DFS_CHAN_14_FREQ) 1187 chan = DFS_24_GHZ_CHANNEL_14; 1188 else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ)) 1189 chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) + 1190 DFS_24_GHZ_CHANNEL_15); 1191 else 1192 chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ; 1193 1194 return chan; 1195 } 1196 qdf_export_symbol(utils_dfs_freq_to_chan); 1197 1198 uint32_t utils_dfs_chan_to_freq(uint8_t chan) 1199 { 1200 if (chan == 0) 1201 return 0; 1202 1203 if (chan < DFS_24_GHZ_CHANNEL_14) 1204 return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ); 1205 else if (chan == DFS_24_GHZ_CHANNEL_14) 1206 return DFS_CHAN_14_FREQ; 1207 else if (chan < DFS_24_GHZ_CHANNEL_27) 1208 return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) * 1209 DFS_CHAN_SPACING_20MHZ); 1210 else if (chan == DFS_5_GHZ_CHANNEL_170) 1211 return DFS_CHAN_170_FREQ; 1212 else 1213 return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ); 1214 } 1215 qdf_export_symbol(utils_dfs_chan_to_freq); 1216 1217 #ifdef MOBILE_DFS_SUPPORT 1218 1219 #ifdef CONFIG_CHAN_FREQ_API 1220 QDF_STATUS utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev *pdev, 1221 enum phy_ch_width ch_width, 1222 uint8_t temp_chan_lst_sz, 1223 uint16_t *temp_freq_lst) 1224 { 1225 struct wlan_dfs *dfs = NULL; 1226 1227 dfs = wlan_pdev_get_dfs_obj(pdev); 1228 if (!dfs) { 1229 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1230 return QDF_STATUS_E_FAILURE; 1231 } 1232 1233 return dfs_mark_leaking_chan_for_freq(dfs, ch_width, temp_chan_lst_sz, 1234 temp_freq_lst); 1235 } 1236 qdf_export_symbol(utils_dfs_mark_leaking_chan_for_freq); 1237 #endif 1238 #endif 1239 1240 int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev) 1241 { 1242 enum dfs_reg dfsdomain; 1243 1244 wlan_reg_get_dfs_region(pdev, &dfsdomain); 1245 1246 return dfsdomain; 1247 } 1248 1249 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 1250 QDF_STATUS utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev *pdev, 1251 bool *is_spoof_check_failed) 1252 { 1253 struct wlan_dfs *dfs; 1254 1255 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) 1256 return QDF_STATUS_SUCCESS; 1257 1258 dfs = wlan_pdev_get_dfs_obj(pdev); 1259 if (!dfs) { 1260 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); 1261 return QDF_STATUS_E_FAILURE; 1262 } 1263 1264 *is_spoof_check_failed = dfs->dfs_spoof_check_failed; 1265 1266 return QDF_STATUS_SUCCESS; 1267 } 1268 1269 qdf_export_symbol(utils_dfs_is_spoof_check_failed); 1270 1271 bool utils_dfs_is_spoof_done(struct wlan_objmgr_pdev *pdev) 1272 { 1273 struct wlan_dfs *dfs; 1274 1275 dfs = wlan_pdev_get_dfs_obj(pdev); 1276 if (!dfs) 1277 return false; 1278 1279 if (lmac_is_host_dfs_check_support_enabled(dfs->dfs_pdev_obj) && 1280 utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_FCC_DOMAIN) 1281 return !!dfs->dfs_spoof_test_done; 1282 return true; 1283 } 1284 #endif 1285 1286 int dfs_get_num_chans(void) 1287 { 1288 return NUM_CHANNELS; 1289 } 1290 1291 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 1292 QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev, 1293 bool *disable_radar_marking) 1294 { 1295 struct wlan_dfs *dfs; 1296 1297 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) 1298 return QDF_STATUS_SUCCESS; 1299 1300 dfs = wlan_pdev_get_dfs_obj(pdev); 1301 if (!dfs) { 1302 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); 1303 return QDF_STATUS_E_FAILURE; 1304 } 1305 1306 *disable_radar_marking = dfs_get_disable_radar_marking(dfs); 1307 1308 return QDF_STATUS_SUCCESS; 1309 } 1310 1311 qdf_export_symbol(utils_dfs_get_disable_radar_marking); 1312 #endif 1313 1314 bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev) 1315 { 1316 struct wlan_dfs *dfs; 1317 1318 dfs = wlan_pdev_get_dfs_obj(pdev); 1319 if (!dfs) 1320 return false; 1321 1322 return WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan); 1323 } 1324 1325 qdf_export_symbol(utils_is_dfs_cfreq2_ch); 1326 1327 void utils_dfs_deliver_event(struct wlan_objmgr_pdev *pdev, uint16_t freq, 1328 enum WLAN_DFS_EVENTS event) 1329 { 1330 if (global_dfs_to_mlme.mlme_dfs_deliver_event) 1331 global_dfs_to_mlme.mlme_dfs_deliver_event(pdev, freq, event); 1332 } 1333 1334 void utils_dfs_reset_dfs_prevchan(struct wlan_objmgr_pdev *pdev) 1335 { 1336 struct wlan_dfs *dfs; 1337 1338 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) 1339 return; 1340 1341 dfs = wlan_pdev_get_dfs_obj(pdev); 1342 if (!dfs) { 1343 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); 1344 return; 1345 } 1346 1347 dfs_reset_dfs_prevchan(dfs); 1348 } 1349 1350 #ifdef QCA_SUPPORT_AGILE_DFS 1351 1352 void utils_dfs_agile_sm_deliver_evt(struct wlan_objmgr_pdev *pdev, 1353 enum dfs_agile_sm_evt event) 1354 { 1355 struct wlan_dfs *dfs; 1356 void *event_data; 1357 struct dfs_soc_priv_obj *dfs_soc_obj; 1358 1359 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) 1360 return; 1361 1362 dfs = wlan_pdev_get_dfs_obj(pdev); 1363 if (!dfs) { 1364 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); 1365 return; 1366 } 1367 1368 if (!dfs_is_agile_cac_enabled(dfs)) 1369 return; 1370 1371 dfs_soc_obj = dfs->dfs_soc_obj; 1372 dfs_soc_obj->dfs_priv[dfs->dfs_psoc_idx].agile_precac_active = true; 1373 event_data = (void *)dfs; 1374 1375 dfs_agile_sm_deliver_evt(dfs->dfs_soc_obj, 1376 event, 1377 0, 1378 event_data); 1379 } 1380 #endif 1381 1382 #ifdef QCA_SUPPORT_ADFS_RCAC 1383 QDF_STATUS utils_dfs_get_rcac_channel(struct wlan_objmgr_pdev *pdev, 1384 struct ch_params *chan_params, 1385 qdf_freq_t *target_chan_freq) 1386 { 1387 struct wlan_dfs *dfs = NULL; 1388 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1389 1390 if (!target_chan_freq) 1391 return status; 1392 1393 *target_chan_freq = 0; 1394 1395 dfs = wlan_pdev_get_dfs_obj(pdev); 1396 if (!dfs) { 1397 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1398 return status; 1399 } 1400 1401 if (!dfs_is_agile_rcac_enabled(dfs)) 1402 return status; 1403 1404 *target_chan_freq = dfs->dfs_rcac_param.rcac_pri_freq; 1405 1406 /* Do not modify the input ch_params if no RCAC channel is present. */ 1407 if (!*target_chan_freq) 1408 return status; 1409 1410 *chan_params = dfs->dfs_rcac_param.rcac_ch_params; 1411 1412 return QDF_STATUS_SUCCESS; 1413 } 1414 #endif 1415 1416 #ifdef ATH_SUPPORT_ZERO_CAC_DFS 1417 enum precac_status_for_chan 1418 utils_dfs_precac_status_for_channel(struct wlan_objmgr_pdev *pdev, 1419 struct wlan_channel *deschan) 1420 { 1421 struct wlan_dfs *dfs; 1422 struct dfs_channel chan; 1423 1424 dfs = wlan_pdev_get_dfs_obj(pdev); 1425 if (!dfs) 1426 return false; 1427 1428 dfs_fill_chan_info(&chan, deschan); 1429 1430 return dfs_precac_status_for_channel(dfs, &chan); 1431 } 1432 #endif 1433 1434 #if defined(WLAN_DISP_CHAN_INFO) 1435 #define FIRST_DFS_CHAN_NUM 52 1436 #define CHAN_NUM_SPACING 4 1437 #define INVALID_INDEX (-1) 1438 #define IS_CHAN_DFS(_flags) ((_flags) & REGULATORY_CHAN_RADAR) 1439 /** 1440 * utils_dfs_convert_freq_to_index() - Converts a DFS channel frequency 1441 * to the DFS channel state array index. The input frequency should be a DFS 1442 * channel frequency and this check should be done in the caller. 1443 * @freq: Input DFS channel frequency. 1444 * @index: Output DFS channel state array index. 1445 * 1446 * Return: QDF_STATUS. 1447 */ 1448 static void utils_dfs_convert_freq_to_index(qdf_freq_t freq, int8_t *index) 1449 { 1450 uint16_t chan_num; 1451 int8_t tmp_index; 1452 1453 chan_num = (freq - WLAN_5_GHZ_BASE_FREQ) / WLAN_CHAN_SPACING_5MHZ; 1454 tmp_index = (chan_num - FIRST_DFS_CHAN_NUM) / CHAN_NUM_SPACING; 1455 *index = ((tmp_index >= 0) && (tmp_index < NUM_DFS_CHANS)) ? 1456 tmp_index : INVALID_INDEX; 1457 } 1458 1459 /** 1460 * utils_dfs_update_chan_state_array_element() - Update the per dfs channel 1461 * state array element indexed by the frequency with the new state. 1462 * 1463 * @freq: Input DFS Channel frequency which will converted to channel state 1464 * array index. 1465 * @state: Input DFS state with which the value indexed by frequency will be 1466 * updated with. 1467 * 1468 * Return: void. 1469 */ 1470 static QDF_STATUS 1471 utils_dfs_update_chan_state_array_element(struct wlan_dfs *dfs, 1472 qdf_freq_t freq, 1473 enum channel_dfs_state state) 1474 { 1475 int8_t index; 1476 1477 if (state == CH_DFS_S_INVALID) 1478 return QDF_STATUS_E_INVAL; 1479 1480 utils_dfs_convert_freq_to_index(freq, &index); 1481 1482 if (index == INVALID_INDEX) 1483 return QDF_STATUS_E_INVAL; 1484 1485 dfs->dfs_channel_state_array[index] = state; 1486 1487 return QDF_STATUS_SUCCESS; 1488 } 1489 1490 QDF_STATUS dfs_init_chan_state_array(struct wlan_objmgr_pdev *pdev) 1491 { 1492 struct regulatory_channel *cur_chan_list; 1493 struct wlan_dfs *dfs; 1494 int i; 1495 1496 dfs = wlan_pdev_get_dfs_obj(pdev); 1497 1498 if (!dfs) 1499 return QDF_STATUS_E_FAILURE; 1500 1501 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * 1502 sizeof(struct regulatory_channel)); 1503 1504 if (!cur_chan_list) 1505 return QDF_STATUS_E_NOMEM; 1506 1507 if (wlan_reg_get_current_chan_list( 1508 pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { 1509 dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, 1510 "failed to get curr channel list"); 1511 return QDF_STATUS_E_FAILURE; 1512 } 1513 1514 for (i = 0; i < NUM_CHANNELS; i++) { 1515 qdf_freq_t freq = cur_chan_list[i].center_freq; 1516 1517 if (!IS_CHAN_DFS(cur_chan_list[i].chan_flags)) 1518 continue; 1519 1520 utils_dfs_update_chan_state_array_element(dfs, 1521 freq, 1522 CH_DFS_S_CAC_REQ); 1523 } 1524 1525 qdf_mem_free(cur_chan_list); 1526 qdf_err("channel state array initialized"); 1527 return QDF_STATUS_SUCCESS; 1528 } 1529 1530 QDF_STATUS utils_dfs_get_chan_dfs_state(struct wlan_objmgr_pdev *pdev, 1531 enum channel_dfs_state *dfs_ch_s) 1532 { 1533 struct wlan_dfs *dfs; 1534 1535 dfs = wlan_pdev_get_dfs_obj(pdev); 1536 1537 if (!dfs) 1538 return QDF_STATUS_E_FAILURE; 1539 1540 qdf_mem_copy(dfs_ch_s, 1541 dfs->dfs_channel_state_array, 1542 sizeof(dfs->dfs_channel_state_array)); 1543 1544 return QDF_STATUS_SUCCESS; 1545 } 1546 1547 qdf_export_symbol(utils_dfs_get_chan_dfs_state); 1548 1549 /** 1550 * convert_event_to_state() - Coverts the dfs events WLAN_DFS_EVENTS to dfs 1551 * states channel_dfs_state. 1552 * @event: Input DFS event. 1553 * @state: Output DFS state. 1554 * 1555 * Return: void. 1556 */ 1557 static 1558 void convert_event_to_state(enum WLAN_DFS_EVENTS event, 1559 enum channel_dfs_state *state) 1560 { 1561 static const 1562 enum channel_dfs_state ev_to_state[WLAN_EV_PCAC_COMPLETED + 1] = { 1563 [WLAN_EV_RADAR_DETECTED] = CH_DFS_S_INVALID, 1564 [WLAN_EV_CAC_RESET] = CH_DFS_S_CAC_REQ, 1565 [WLAN_EV_CAC_STARTED] = CH_DFS_S_CAC_STARTED, 1566 [WLAN_EV_CAC_COMPLETED] = CH_DFS_S_CAC_COMPLETED, 1567 [WLAN_EV_NOL_STARTED] = CH_DFS_S_NOL, 1568 [WLAN_EV_NOL_FINISHED] = CH_DFS_S_CAC_REQ, 1569 [WLAN_EV_PCAC_STARTED] = CH_DFS_S_PRECAC_STARTED, 1570 [WLAN_EV_PCAC_COMPLETED] = CH_DFS_S_PRECAC_COMPLETED, 1571 }; 1572 1573 *state = ev_to_state[event]; 1574 } 1575 1576 QDF_STATUS utils_dfs_update_chan_state_array(struct wlan_objmgr_pdev *pdev, 1577 qdf_freq_t freq, 1578 enum WLAN_DFS_EVENTS event) 1579 { 1580 enum channel_dfs_state state; 1581 struct wlan_dfs *dfs; 1582 1583 dfs = wlan_pdev_get_dfs_obj(pdev); 1584 if (!dfs) 1585 return QDF_STATUS_E_FAILURE; 1586 1587 convert_event_to_state(event, &state); 1588 return utils_dfs_update_chan_state_array_element(dfs, freq, state); 1589 } 1590 #endif /* WLAN_DISP_CHAN_INFO */ 1591 1592 QDF_STATUS utils_dfs_radar_enable(struct wlan_objmgr_pdev *pdev) 1593 { 1594 return tgt_dfs_radar_enable(pdev, 0, 0, true); 1595 } 1596