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