1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 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 !tgt_tx_ops->tgt_is_tgt_type_qcn9160) 350 return false; 351 352 if (!tgt_tx_ops->tgt_is_tgt_type_qcn6122(target_type) || 353 !tgt_tx_ops->tgt_is_tgt_type_qcn9160(target_type)) 354 return false; 355 356 cur_freq = dfs->dfs_curchan->dfs_ch_freq; 357 358 /* Is the current channel width 80MHz? */ 359 if (WLAN_IS_CHAN_MODE_80(dfs->dfs_curchan) || 360 WLAN_IS_CHAN_MODE_40(dfs->dfs_curchan) || 361 WLAN_IS_CHAN_MODE_20(dfs->dfs_curchan)) { 362 /* is the primary channel 52/56/60/64? */ 363 bool is_chan_spur_80mhzfreq = 364 DFS_IS_CHAN_SPRUCE_SPUR_FREQ_80MHZ(cur_freq); 365 if (is_chan_spur_80mhzfreq) 366 return true; 367 return false; 368 } 369 370 /* If the current channel width is not 80, is it 160MHz? */ 371 if (WLAN_IS_CHAN_MODE_160(dfs->dfs_curchan)) { 372 /* is the primary channel 36/44/48/52/56/60/64? */ 373 bool is_chan_spur_160mhz_freq = 374 DFS_IS_CHAN_SPRUCE_SPUR_FREQ_160MHZ(cur_freq); 375 if (is_chan_spur_160mhz_freq) 376 return true; 377 return false; 378 } 379 380 return false; 381 } 382 383 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev) 384 { 385 struct wlan_dfs *dfs; 386 387 dfs = wlan_pdev_get_dfs_obj(pdev); 388 if (!dfs) 389 return QDF_STATUS_E_FAILURE; 390 391 dfs_radar_disable(dfs); 392 393 return QDF_STATUS_SUCCESS; 394 } 395 qdf_export_symbol(utils_dfs_radar_disable); 396 397 QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev, 398 bool val) 399 { 400 struct wlan_dfs *dfs; 401 402 dfs = wlan_pdev_get_dfs_obj(pdev); 403 if (!dfs) 404 return QDF_STATUS_E_FAILURE; 405 406 dfs_set_update_nol_flag(dfs, val); 407 408 return QDF_STATUS_SUCCESS; 409 } 410 qdf_export_symbol(utils_dfs_set_update_nol_flag); 411 412 QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev, 413 bool *nol_flag) 414 { 415 struct wlan_dfs *dfs; 416 417 dfs = wlan_pdev_get_dfs_obj(pdev); 418 if (!dfs) 419 return QDF_STATUS_E_FAILURE; 420 421 *nol_flag = dfs_get_update_nol_flag(dfs); 422 423 return QDF_STATUS_SUCCESS; 424 } 425 qdf_export_symbol(utils_dfs_get_update_nol_flag); 426 427 QDF_STATUS utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev *pdev, 428 int *dfs_use_nol) 429 { 430 struct wlan_dfs *dfs; 431 432 dfs = wlan_pdev_get_dfs_obj(pdev); 433 if (!dfs) 434 return QDF_STATUS_E_FAILURE; 435 436 *dfs_use_nol = dfs_get_use_nol(dfs); 437 438 return QDF_STATUS_SUCCESS; 439 } 440 qdf_export_symbol(utils_dfs_get_dfs_use_nol); 441 442 QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev, 443 int *dfs_nol_timeout) 444 { 445 struct wlan_dfs *dfs; 446 447 dfs = wlan_pdev_get_dfs_obj(pdev); 448 if (!dfs) 449 return QDF_STATUS_E_FAILURE; 450 451 *dfs_nol_timeout = dfs_get_nol_timeout(dfs); 452 453 return QDF_STATUS_SUCCESS; 454 } 455 qdf_export_symbol(utils_dfs_get_nol_timeout); 456 457 QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev, 458 uint16_t freq, 459 uint32_t dfs_nol_timeout) 460 { 461 struct wlan_dfs *dfs; 462 463 dfs = wlan_pdev_get_dfs_obj(pdev); 464 if (!dfs) 465 return QDF_STATUS_E_FAILURE; 466 467 DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, dfs_nol_timeout); 468 469 return QDF_STATUS_SUCCESS; 470 } 471 qdf_export_symbol(utils_dfs_nol_addchan); 472 473 QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev) 474 { 475 struct wlan_dfs *dfs; 476 477 dfs = wlan_pdev_get_dfs_obj(pdev); 478 if (!dfs) 479 return QDF_STATUS_E_FAILURE; 480 481 dfs_nol_update(dfs); 482 483 return QDF_STATUS_SUCCESS; 484 } 485 qdf_export_symbol(utils_dfs_nol_update); 486 487 QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev) 488 { 489 struct wlan_dfs *dfs; 490 491 dfs = wlan_pdev_get_dfs_obj(pdev); 492 if (!dfs) 493 return QDF_STATUS_E_FAILURE; 494 495 dfs_second_segment_radar_disable(dfs); 496 497 return QDF_STATUS_SUCCESS; 498 } 499 500 QDF_STATUS utils_dfs_bw_reduce(struct wlan_objmgr_pdev *pdev, bool bw_reduce) 501 { 502 struct wlan_dfs *dfs; 503 504 dfs = wlan_pdev_get_dfs_obj(pdev); 505 if (!dfs) 506 return QDF_STATUS_E_FAILURE; 507 508 dfs->dfs_bw_reduced = bw_reduce; 509 510 return QDF_STATUS_SUCCESS; 511 } 512 513 qdf_export_symbol(utils_dfs_bw_reduce); 514 515 QDF_STATUS utils_dfs_is_bw_reduce(struct wlan_objmgr_pdev *pdev, 516 bool *bw_reduce) 517 { 518 struct wlan_dfs *dfs; 519 520 dfs = wlan_pdev_get_dfs_obj(pdev); 521 if (!dfs) 522 return QDF_STATUS_E_FAILURE; 523 524 *bw_reduce = dfs->dfs_bw_reduced; 525 526 return QDF_STATUS_SUCCESS; 527 } 528 529 QDF_STATUS utils_dfs_fetch_nol_ie_info(struct wlan_objmgr_pdev *pdev, 530 uint8_t *nol_ie_bandwidth, 531 uint16_t *nol_ie_startfreq, 532 uint8_t *nol_ie_bitmap) 533 { 534 struct wlan_dfs *dfs; 535 536 dfs = wlan_pdev_get_dfs_obj(pdev); 537 if (!dfs) 538 return QDF_STATUS_E_FAILURE; 539 540 dfs_fetch_nol_ie_info(dfs, nol_ie_bandwidth, nol_ie_startfreq, 541 nol_ie_bitmap); 542 543 return QDF_STATUS_SUCCESS; 544 } 545 546 QDF_STATUS utils_dfs_set_rcsa_flags(struct wlan_objmgr_pdev *pdev, 547 bool is_rcsa_ie_sent, 548 bool is_nol_ie_sent) 549 { 550 struct wlan_dfs *dfs; 551 552 dfs = wlan_pdev_get_dfs_obj(pdev); 553 if (!dfs) 554 return QDF_STATUS_E_FAILURE; 555 556 dfs_set_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent); 557 558 return QDF_STATUS_SUCCESS; 559 } 560 561 QDF_STATUS utils_dfs_get_rcsa_flags(struct wlan_objmgr_pdev *pdev, 562 bool *is_rcsa_ie_sent, 563 bool *is_nol_ie_sent) 564 { 565 struct wlan_dfs *dfs; 566 567 dfs = wlan_pdev_get_dfs_obj(pdev); 568 if (!dfs) 569 return QDF_STATUS_E_FAILURE; 570 dfs_get_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent); 571 572 return QDF_STATUS_SUCCESS; 573 } 574 575 bool utils_dfs_process_nol_ie_bitmap(struct wlan_objmgr_pdev *pdev, 576 uint8_t nol_ie_bandwidth, 577 uint16_t nol_ie_startfreq, 578 uint8_t nol_ie_bitmap) 579 { 580 struct wlan_dfs *dfs; 581 582 dfs = wlan_pdev_get_dfs_obj(pdev); 583 if (!dfs) 584 return false; 585 return dfs_process_nol_ie_bitmap(dfs, nol_ie_bandwidth, 586 nol_ie_startfreq, 587 nol_ie_bitmap); 588 } 589 590 QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev, 591 int val) 592 { 593 struct wlan_dfs *dfs; 594 595 dfs = wlan_pdev_get_dfs_obj(pdev); 596 if (!dfs) 597 return QDF_STATUS_E_FAILURE; 598 599 dfs->dfs_cac_timer_running = val; 600 601 return QDF_STATUS_SUCCESS; 602 } 603 qdf_export_symbol(utils_dfs_set_cac_timer_running); 604 605 QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev, 606 void *nollist, 607 uint32_t *nol_chfreq, 608 uint32_t *nol_chwidth, 609 int index) 610 { 611 struct wlan_dfs *dfs; 612 613 dfs = wlan_pdev_get_dfs_obj(pdev); 614 if (!dfs) 615 return QDF_STATUS_E_FAILURE; 616 617 dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index); 618 619 return QDF_STATUS_SUCCESS; 620 } 621 qdf_export_symbol(utils_dfs_get_nol_chfreq_and_chwidth); 622 623 QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev, 624 uint64_t flags, 625 uint16_t flagext) 626 { 627 struct wlan_dfs *dfs; 628 629 dfs = wlan_pdev_get_dfs_obj(pdev); 630 if (!dfs) 631 return QDF_STATUS_E_FAILURE; 632 633 dfs_update_cur_chan_flags(dfs, flags, flagext); 634 635 return QDF_STATUS_SUCCESS; 636 } 637 638 static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev, 639 uint32_t *phy_mode) 640 { 641 return; 642 } 643 644 static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev, 645 uint8_t *ch_width) 646 { 647 return; 648 } 649 650 #ifndef QCA_DFS_USE_POLICY_MANAGER 651 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, 652 void *clist, uint32_t *num_chan) 653 { 654 uint32_t i = 0, j = 0; 655 enum channel_state state; 656 struct regulatory_channel *cur_chan_list; 657 struct wlan_dfs *dfs; 658 struct dfs_channel *chan_list = (struct dfs_channel *)clist; 659 660 dfs = wlan_pdev_get_dfs_obj(pdev); 661 if (!dfs) { 662 *num_chan = 0; 663 return; 664 } 665 666 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * 667 sizeof(struct regulatory_channel)); 668 if (!cur_chan_list) { 669 *num_chan = 0; 670 return; 671 } 672 673 if (wlan_reg_get_current_chan_list( 674 pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { 675 *num_chan = 0; 676 dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, 677 "failed to get curr channel list"); 678 return; 679 } 680 681 for (i = 0; i < NUM_CHANNELS; i++) { 682 state = cur_chan_list[i].state; 683 if (state == CHANNEL_STATE_DFS || 684 state == CHANNEL_STATE_ENABLE) { 685 chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num; 686 chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq; 687 if (state == CHANNEL_STATE_DFS) 688 chan_list[j].dfs_ch_flagext = 689 WLAN_CHAN_DFS; 690 691 if (cur_chan_list[i].nol_history) 692 chan_list[j].dfs_ch_flagext |= 693 WLAN_CHAN_HISTORY_RADAR; 694 j++; 695 } 696 } 697 *num_chan = j; 698 qdf_mem_free(cur_chan_list); 699 700 return; 701 } 702 703 /** 704 * utils_dfs_get_channel_list() - Get channel list from regdb component, based 705 * on current channel list. 706 * @pdev: Pointer to pdev structure. 707 * @vdev: vdev of request 708 * @chan_list: Pointer to channel list. 709 * @num_chan: number of channels. 710 * 711 * Get regdb channel list based on dfs current channel. 712 * Ex: When AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels 713 * so that the random channel function does not select either 2.4GHz or 4.9GHz 714 * channel. 715 */ 716 #ifdef CONFIG_CHAN_FREQ_API 717 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, 718 struct wlan_objmgr_vdev *vdev, 719 struct dfs_channel *chan_list, 720 uint32_t *num_chan) 721 { 722 struct dfs_channel *tmp_chan_list = NULL; 723 struct wlan_dfs *dfs; 724 bool is_curchan_5g; 725 bool is_curchan_24g; 726 bool is_curchan_49g; 727 bool is_inter_band_switch_allowed; 728 uint8_t chan_num; 729 uint16_t center_freq; 730 uint16_t flagext; 731 uint32_t i, j = 0; 732 733 dfs = wlan_pdev_get_dfs_obj(pdev); 734 if (!dfs) { 735 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 736 return; 737 } 738 739 tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list)); 740 if (!tmp_chan_list) 741 return; 742 743 utils_dfs_get_chan_list(pdev, (void *)tmp_chan_list, num_chan); 744 745 chan_num = dfs->dfs_curchan->dfs_ch_ieee; 746 center_freq = dfs->dfs_curchan->dfs_ch_freq; 747 is_curchan_5g = WLAN_REG_IS_5GHZ_CH_FREQ(center_freq); 748 is_curchan_24g = WLAN_REG_IS_24GHZ_CH_FREQ(center_freq); 749 is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq); 750 is_inter_band_switch_allowed = 751 dfs_mlme_is_inter_band_chan_switch_allowed(dfs->dfs_pdev_obj); 752 753 for (i = 0; i < *num_chan; i++) { 754 chan_num = tmp_chan_list[i].dfs_ch_ieee; 755 center_freq = tmp_chan_list[i].dfs_ch_freq; 756 flagext = tmp_chan_list[i].dfs_ch_flagext; 757 /* No change in prototype needed. Hence retaining same func */ 758 if (!dfs_mlme_check_allowed_prim_chanlist(pdev, center_freq)) 759 continue; 760 761 if (is_curchan_5g) { 762 /* 763 * Always add 5G channels. 764 * If inter band is allowed, add 6G also. 765 */ 766 if (WLAN_REG_IS_5GHZ_CH_FREQ(center_freq) || 767 (is_inter_band_switch_allowed && 768 WLAN_REG_IS_6GHZ_CHAN_FREQ(center_freq))) { 769 chan_list[j].dfs_ch_ieee = chan_num; 770 chan_list[j].dfs_ch_freq = center_freq; 771 chan_list[j].dfs_ch_flagext = flagext; 772 j++; 773 } 774 } else if ((is_curchan_24g) && 775 WLAN_REG_IS_24GHZ_CH_FREQ(center_freq)) { 776 chan_list[j].dfs_ch_ieee = chan_num; 777 chan_list[j].dfs_ch_freq = center_freq; 778 j++; 779 } else if ((is_curchan_49g) && 780 WLAN_REG_IS_49GHZ_FREQ(center_freq)) { 781 chan_list[j].dfs_ch_ieee = chan_num; 782 chan_list[j].dfs_ch_freq = center_freq; 783 j++; 784 } 785 } 786 787 *num_chan = j; 788 789 qdf_mem_free(tmp_chan_list); 790 } 791 #endif 792 #else 793 void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, 794 void *clist, uint32_t *num_chan) 795 { 796 utils_dfs_get_chan_list(pdev, clist, num_chan); 797 } 798 799 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, 800 struct wlan_objmgr_vdev *vdev, 801 struct dfs_channel *chan_list, 802 uint32_t *num_chan) 803 { 804 uint32_t pcl_ch[NUM_CHANNELS] = {0}; 805 uint8_t weight_list[NUM_CHANNELS] = {0}; 806 uint32_t len; 807 uint32_t weight_len; 808 uint32_t i; 809 struct wlan_objmgr_psoc *psoc; 810 uint32_t conn_count = 0; 811 enum policy_mgr_con_mode mode; 812 813 psoc = wlan_pdev_get_psoc(pdev); 814 if (!psoc) { 815 *num_chan = 0; 816 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 817 return; 818 } 819 820 len = QDF_ARRAY_SIZE(pcl_ch); 821 weight_len = QDF_ARRAY_SIZE(weight_list); 822 823 if (vdev) 824 mode = policy_mgr_convert_device_mode_to_qdf_type( 825 wlan_vdev_mlme_get_opmode(vdev)); 826 else 827 mode = PM_SAP_MODE; 828 conn_count = policy_mgr_mode_specific_connection_count( 829 psoc, mode, NULL); 830 if (0 == conn_count) 831 policy_mgr_get_pcl(psoc, mode, pcl_ch, 832 &len, weight_list, weight_len); 833 else 834 policy_mgr_get_pcl_for_existing_conn( 835 psoc, mode, pcl_ch, &len, weight_list, 836 weight_len, true); 837 838 if (*num_chan < len) { 839 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 840 "Invalid len src=%d, dst=%d", 841 *num_chan, len); 842 *num_chan = 0; 843 return; 844 } 845 846 for (i = 0; i < len; i++) { 847 chan_list[i].dfs_ch_ieee = 848 wlan_reg_freq_to_chan(pdev, pcl_ch[i]); 849 chan_list[i].dfs_ch_freq = pcl_ch[i]; 850 if (wlan_reg_is_dfs_for_freq(pdev, pcl_ch[i])) 851 chan_list[i].dfs_ch_flagext |= WLAN_CHAN_DFS; 852 } 853 *num_chan = i; 854 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i); 855 } 856 857 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, 858 void *clist, uint32_t *num_chan) 859 { 860 utils_dfs_get_channel_list(pdev, NULL, (struct dfs_channel *)clist, 861 num_chan); 862 } 863 864 bool utils_dfs_can_ignore_radar_event(struct wlan_objmgr_pdev *pdev) 865 { 866 return policy_mgr_get_can_skip_radar_event( 867 wlan_pdev_get_psoc(pdev), INVALID_VDEV_ID); 868 } 869 #endif 870 871 #ifdef CONFIG_CHAN_FREQ_API 872 QDF_STATUS utils_dfs_get_vdev_random_channel_for_freq( 873 struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, 874 uint16_t flags, struct ch_params *chan_params, uint32_t *hw_mode, 875 uint16_t *target_chan_freq, struct dfs_acs_info *acs_info) 876 { 877 uint32_t dfs_reg; 878 uint32_t num_chan = NUM_CHANNELS; 879 struct wlan_dfs *dfs = NULL; 880 struct wlan_objmgr_psoc *psoc; 881 struct dfs_channel *chan_list = NULL; 882 QDF_STATUS status = QDF_STATUS_E_FAILURE; 883 884 *target_chan_freq = 0; 885 psoc = wlan_pdev_get_psoc(pdev); 886 if (!psoc) { 887 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 888 goto random_chan_error; 889 } 890 891 dfs = wlan_pdev_get_dfs_obj(pdev); 892 if (!dfs) { 893 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 894 goto random_chan_error; 895 } 896 897 wlan_reg_get_dfs_region(pdev, &dfs_reg); 898 chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list)); 899 if (!chan_list) 900 goto random_chan_error; 901 902 utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan); 903 if (!num_chan) { 904 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels"); 905 goto random_chan_error; 906 } 907 908 if (!chan_params->ch_width) 909 utils_dfs_get_max_sup_width(pdev, 910 (uint8_t *)&chan_params->ch_width); 911 912 *target_chan_freq = dfs_prepare_random_channel_for_freq( 913 dfs, chan_list, num_chan, flags, chan_params, 914 (uint8_t)dfs_reg, acs_info); 915 916 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 917 "input width=%d", chan_params->ch_width); 918 919 if (*target_chan_freq) { 920 wlan_reg_set_channel_params_for_pwrmode( 921 pdev, *target_chan_freq, 0, 922 chan_params, 923 REG_CURRENT_PWR_MODE); 924 utils_dfs_get_max_phy_mode(pdev, hw_mode); 925 status = QDF_STATUS_SUCCESS; 926 } 927 928 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 929 "ch=%d, seg0=%d, seg1=%d, width=%d", 930 *target_chan_freq, chan_params->center_freq_seg0, 931 chan_params->center_freq_seg1, chan_params->ch_width); 932 933 random_chan_error: 934 qdf_mem_free(chan_list); 935 936 return status; 937 } 938 939 qdf_export_symbol(utils_dfs_get_vdev_random_channel_for_freq); 940 #endif 941 942 #ifdef CONFIG_CHAN_FREQ_API 943 QDF_STATUS utils_dfs_get_random_channel_for_freq( 944 struct wlan_objmgr_pdev *pdev, 945 uint16_t flags, 946 struct ch_params *ch_params, 947 uint32_t *hw_mode, 948 uint16_t *target_chan_freq, 949 struct dfs_acs_info *acs_info) 950 { 951 return utils_dfs_get_vdev_random_channel_for_freq(pdev, NULL, flags, 952 ch_params, hw_mode, 953 target_chan_freq, 954 acs_info); 955 } 956 957 qdf_export_symbol(utils_dfs_get_random_channel_for_freq); 958 #endif 959 960 #ifdef CONFIG_CHAN_FREQ_API 961 QDF_STATUS utils_dfs_bw_reduced_channel_for_freq( 962 struct wlan_objmgr_pdev *pdev, 963 struct ch_params *chan_params, 964 uint32_t *hw_mode, 965 uint16_t *target_chan_freq) 966 { 967 struct wlan_dfs *dfs = NULL; 968 struct wlan_objmgr_psoc *psoc; 969 enum channel_state ch_state; 970 QDF_STATUS status = QDF_STATUS_E_FAILURE; 971 struct dfs_channel *dfs_curchan; 972 973 *target_chan_freq = 0; 974 psoc = wlan_pdev_get_psoc(pdev); 975 if (!psoc) { 976 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 977 return status; 978 } 979 980 dfs = wlan_pdev_get_dfs_obj(pdev); 981 if (!dfs) { 982 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 983 return status; 984 } 985 dfs_curchan = dfs->dfs_curchan; 986 ch_state = 987 wlan_reg_get_channel_state_for_pwrmode(pdev, 988 dfs_curchan->dfs_ch_freq, 989 REG_CURRENT_PWR_MODE); 990 991 if (ch_state == CHANNEL_STATE_DFS || 992 ch_state == CHANNEL_STATE_ENABLE) { 993 /* If the current channel is 80P80MHz and radar is detected on 994 * the channel, the next highest bandwidth that maybe available 995 * is 80MHz. Since the current regulatory algorithm reduces the 996 * bandwidth from 80P80MHz to 160MHz, provide the channel 997 * width as 80MHz if current channel is 80P80MHz. 998 */ 999 if (chan_params->ch_width == CH_WIDTH_80P80MHZ) 1000 chan_params->ch_width = CH_WIDTH_80MHZ; 1001 1002 chan_params->mhz_freq_seg0 = 1003 dfs_curchan->dfs_ch_mhz_freq_seg1; 1004 chan_params->mhz_freq_seg1 = 1005 dfs_curchan->dfs_ch_mhz_freq_seg2; 1006 wlan_reg_set_channel_params_for_pwrmode(pdev, dfs_curchan-> 1007 dfs_ch_freq, 1008 0, chan_params, 1009 REG_CURRENT_PWR_MODE); 1010 1011 *target_chan_freq = dfs_curchan->dfs_ch_freq; 1012 utils_dfs_get_max_phy_mode(pdev, hw_mode); 1013 1014 return QDF_STATUS_SUCCESS; 1015 } 1016 1017 return status; 1018 } 1019 1020 qdf_export_symbol(utils_dfs_bw_reduced_channel_for_freq); 1021 #endif 1022 1023 1024 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 1025 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev) 1026 { 1027 struct wlan_dfs *dfs; 1028 struct wlan_objmgr_psoc *psoc; 1029 qdf_device_t qdf_dev; 1030 struct dfs_nol_info *dfs_nolinfo; 1031 int len; 1032 1033 dfs = wlan_pdev_get_dfs_obj(pdev); 1034 psoc = wlan_pdev_get_psoc(pdev); 1035 if (!dfs || !psoc) { 1036 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 1037 "dfs %pK, psoc %pK", dfs, psoc); 1038 return; 1039 } 1040 1041 qdf_dev = psoc->soc_objmgr.qdf_dev; 1042 if (!qdf_dev->dev) { 1043 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null device"); 1044 return; 1045 } 1046 1047 dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo)); 1048 if (!dfs_nolinfo) 1049 return; 1050 1051 qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo)); 1052 len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo, 1053 (uint16_t)sizeof(*dfs_nolinfo)); 1054 if (len > 0) { 1055 dfs_set_nol(dfs, dfs_nolinfo->dfs_nol, dfs_nolinfo->num_chans); 1056 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld"); 1057 DFS_PRINT_NOL_LOCKED(dfs); 1058 } else { 1059 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "no nol in pld"); 1060 } 1061 qdf_mem_free(dfs_nolinfo); 1062 } 1063 qdf_export_symbol(utils_dfs_init_nol); 1064 #endif 1065 1066 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 1067 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev) 1068 { 1069 } 1070 #else 1071 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev) 1072 { 1073 struct dfs_nol_info *dfs_nolinfo; 1074 struct wlan_dfs *dfs = NULL; 1075 struct wlan_objmgr_psoc *psoc; 1076 qdf_device_t qdf_dev; 1077 int num_chans = 0; 1078 1079 dfs = wlan_pdev_get_dfs_obj(pdev); 1080 if (!dfs) { 1081 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1082 return; 1083 } 1084 1085 psoc = wlan_pdev_get_psoc(pdev); 1086 if (!psoc) { 1087 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 1088 return; 1089 } 1090 1091 qdf_dev = psoc->soc_objmgr.qdf_dev; 1092 if (!qdf_dev->dev) { 1093 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null device"); 1094 return; 1095 } 1096 1097 dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo)); 1098 if (!dfs_nolinfo) 1099 return; 1100 1101 qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo)); 1102 DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo->dfs_nol, &num_chans); 1103 1104 if (num_chans > DFS_MAX_NOL_CHANNEL) 1105 dfs_nolinfo->num_chans = DFS_MAX_NOL_CHANNEL; 1106 else 1107 dfs_nolinfo->num_chans = num_chans; 1108 1109 pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo, 1110 (uint16_t)sizeof(*dfs_nolinfo)); 1111 qdf_mem_free(dfs_nolinfo); 1112 } 1113 #endif 1114 qdf_export_symbol(utils_dfs_save_nol); 1115 1116 void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev) 1117 { 1118 struct wlan_dfs *dfs = NULL; 1119 1120 dfs = wlan_pdev_get_dfs_obj(pdev); 1121 if (!dfs) { 1122 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1123 return; 1124 } 1125 1126 DFS_PRINT_NOL_LOCKED(dfs); 1127 } 1128 qdf_export_symbol(utils_dfs_print_nol_channels); 1129 1130 void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev) 1131 { 1132 struct wlan_dfs *dfs = NULL; 1133 1134 dfs = wlan_pdev_get_dfs_obj(pdev); 1135 if (!dfs) { 1136 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1137 return; 1138 } 1139 1140 /* First print list */ 1141 DFS_PRINT_NOL_LOCKED(dfs); 1142 1143 /* clear local cache first */ 1144 dfs_nol_timer_cleanup(dfs); 1145 dfs_nol_update(dfs); 1146 1147 /* 1148 * update platform driver nol list with local cache which is zero, 1149 * cleared in above step, so this will clear list in platform driver. 1150 */ 1151 utils_dfs_save_nol(pdev); 1152 } 1153 qdf_export_symbol(utils_dfs_clear_nol_channels); 1154 1155 #ifdef CONFIG_CHAN_FREQ_API 1156 void utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev *pdev, 1157 uint16_t *freq_list, 1158 uint8_t num_chan, 1159 bool nol_chan) 1160 { 1161 wlan_reg_update_nol_ch_for_freq(pdev, freq_list, num_chan, nol_chan); 1162 } 1163 1164 qdf_export_symbol(utils_dfs_reg_update_nol_chan_for_freq); 1165 #endif 1166 1167 #ifdef CONFIG_CHAN_FREQ_API 1168 void 1169 utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev *pdev, 1170 uint16_t *freq_list, 1171 uint8_t num_chan, 1172 bool nol_history_chan) 1173 { 1174 wlan_reg_update_nol_history_ch_for_freq(pdev, freq_list, num_chan, 1175 nol_history_chan); 1176 } 1177 #endif 1178 1179 uint8_t utils_dfs_freq_to_chan(uint32_t freq) 1180 { 1181 uint8_t chan; 1182 1183 if (freq == 0) 1184 return 0; 1185 1186 if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ) 1187 chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ); 1188 else if (freq == DFS_CHAN_14_FREQ) 1189 chan = DFS_24_GHZ_CHANNEL_14; 1190 else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ)) 1191 chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) + 1192 DFS_24_GHZ_CHANNEL_15); 1193 else 1194 chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ; 1195 1196 return chan; 1197 } 1198 qdf_export_symbol(utils_dfs_freq_to_chan); 1199 1200 uint32_t utils_dfs_chan_to_freq(uint8_t chan) 1201 { 1202 if (chan == 0) 1203 return 0; 1204 1205 if (chan < DFS_24_GHZ_CHANNEL_14) 1206 return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ); 1207 else if (chan == DFS_24_GHZ_CHANNEL_14) 1208 return DFS_CHAN_14_FREQ; 1209 else if (chan < DFS_24_GHZ_CHANNEL_27) 1210 return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) * 1211 DFS_CHAN_SPACING_20MHZ); 1212 else if (chan == DFS_5_GHZ_CHANNEL_170) 1213 return DFS_CHAN_170_FREQ; 1214 else 1215 return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ); 1216 } 1217 qdf_export_symbol(utils_dfs_chan_to_freq); 1218 1219 #ifdef MOBILE_DFS_SUPPORT 1220 1221 #ifdef CONFIG_CHAN_FREQ_API 1222 QDF_STATUS utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev *pdev, 1223 enum phy_ch_width ch_width, 1224 uint8_t temp_chan_lst_sz, 1225 uint16_t *temp_freq_lst) 1226 { 1227 struct wlan_dfs *dfs = NULL; 1228 1229 dfs = wlan_pdev_get_dfs_obj(pdev); 1230 if (!dfs) { 1231 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1232 return QDF_STATUS_E_FAILURE; 1233 } 1234 1235 return dfs_mark_leaking_chan_for_freq(dfs, ch_width, temp_chan_lst_sz, 1236 temp_freq_lst); 1237 } 1238 qdf_export_symbol(utils_dfs_mark_leaking_chan_for_freq); 1239 #endif 1240 #endif 1241 1242 int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev) 1243 { 1244 enum dfs_reg dfsdomain; 1245 1246 wlan_reg_get_dfs_region(pdev, &dfsdomain); 1247 1248 return dfsdomain; 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 * @dfs: DFS context 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() - Converts 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