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