1 /* 2 * Copyright (c) 2016-2019 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 "../../core/src/dfs_etsi_precac.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 41 struct dfs_nol_info { 42 uint16_t num_chans; 43 struct dfsreq_nolelem dfs_nol[DFS_MAX_NOL_CHANNEL]; 44 }; 45 46 QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev) 47 { 48 struct wlan_dfs *dfs; 49 50 dfs = wlan_pdev_get_dfs_obj(pdev); 51 if (!dfs) 52 return QDF_STATUS_E_FAILURE; 53 54 dfs_reset(dfs); 55 dfs_nol_update(dfs); 56 dfs_reset_precaclists(dfs); 57 dfs_reset_etsiprecaclists(dfs); 58 59 return QDF_STATUS_SUCCESS; 60 } 61 62 bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq) 63 { 64 struct wlan_dfs *dfs; 65 66 dfs = wlan_pdev_get_dfs_obj(pdev); 67 if (!dfs) 68 return false; 69 70 return dfs_is_freq_in_nol(dfs, freq); 71 } 72 73 QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev, 74 uint8_t prevchan_ieee, 75 uint32_t prevchan_flags) 76 { 77 struct wlan_dfs *dfs; 78 79 dfs = wlan_pdev_get_dfs_obj(pdev); 80 if (!dfs) 81 return QDF_STATUS_E_FAILURE; 82 83 dfs_cac_valid_reset(dfs, prevchan_ieee, prevchan_flags); 84 85 return QDF_STATUS_SUCCESS; 86 } 87 qdf_export_symbol(utils_dfs_cac_valid_reset); 88 89 QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) 90 { 91 struct wlan_dfs *dfs; 92 93 dfs = wlan_pdev_get_dfs_obj(pdev); 94 if (!dfs) 95 return QDF_STATUS_E_FAILURE; 96 97 dfs_reset_precaclists(dfs); 98 99 return QDF_STATUS_SUCCESS; 100 } 101 qdf_export_symbol(utils_dfs_reset_precaclists); 102 103 #ifdef QCA_SUPPORT_ETSI_PRECAC_DFS 104 QDF_STATUS utils_dfs_reset_etsi_precaclists(struct wlan_objmgr_pdev *pdev) 105 { 106 struct wlan_dfs *dfs; 107 108 dfs = wlan_pdev_get_dfs_obj(pdev); 109 if (!dfs) 110 return QDF_STATUS_E_FAILURE; 111 112 dfs_reset_etsiprecaclists(dfs); 113 114 return QDF_STATUS_SUCCESS; 115 } 116 117 qdf_export_symbol(utils_dfs_reset_etsi_precaclists); 118 119 void utils_dfs_add_to_etsi_precac_required_list(struct wlan_objmgr_pdev *pdev, 120 uint8_t *chan) 121 { 122 struct wlan_dfs *dfs; 123 124 dfs = wlan_pdev_get_dfs_obj(pdev); 125 if (!dfs) 126 return; 127 128 dfs_add_to_etsi_precac_required_list(dfs, chan); 129 } 130 131 qdf_export_symbol(utils_dfs_add_to_etsi_precac_required_list); 132 #endif 133 134 QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev) 135 { 136 struct wlan_dfs *dfs; 137 138 dfs = wlan_pdev_get_dfs_obj(pdev); 139 if (!dfs) 140 return QDF_STATUS_E_FAILURE; 141 142 dfs_cancel_precac_timer(dfs); 143 144 return QDF_STATUS_SUCCESS; 145 } 146 qdf_export_symbol(utils_dfs_cancel_precac_timer); 147 148 QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev) 149 { 150 struct wlan_dfs *dfs; 151 152 dfs = wlan_pdev_get_dfs_obj(pdev); 153 if (!dfs) { 154 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs"); 155 return QDF_STATUS_E_FAILURE; 156 } 157 158 if (!dfs->dfs_precac_secondary_freq) 159 return QDF_STATUS_E_FAILURE; 160 dfs_start_precac_timer(dfs, 161 dfs->dfs_precac_secondary_freq); 162 return QDF_STATUS_SUCCESS; 163 } 164 165 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT 166 bool 167 utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev, 168 uint8_t *ch_ieee, 169 enum wlan_phymode mode) 170 { 171 struct wlan_dfs *dfs; 172 173 dfs = wlan_pdev_get_dfs_obj(pdev); 174 if (!dfs) { 175 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs"); 176 return false; 177 } 178 return dfs_decide_precac_preferred_chan(dfs, ch_ieee, mode); 179 } 180 #endif 181 182 QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev) 183 { 184 struct wlan_dfs *dfs; 185 186 dfs = wlan_pdev_get_dfs_obj(pdev); 187 if (!dfs) 188 return QDF_STATUS_E_FAILURE; 189 190 dfs_cancel_cac_timer(dfs); 191 192 return QDF_STATUS_SUCCESS; 193 } 194 qdf_export_symbol(utils_dfs_cancel_cac_timer); 195 196 QDF_STATUS utils_dfs_start_cac_timer(struct wlan_objmgr_pdev *pdev) 197 { 198 struct wlan_dfs *dfs; 199 200 dfs = wlan_pdev_get_dfs_obj(pdev); 201 if (!dfs) 202 return QDF_STATUS_E_FAILURE; 203 204 dfs_start_cac_timer(dfs); 205 206 return QDF_STATUS_SUCCESS; 207 } 208 qdf_export_symbol(utils_dfs_start_cac_timer); 209 210 QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev) 211 { 212 struct wlan_dfs *dfs; 213 214 dfs = wlan_pdev_get_dfs_obj(pdev); 215 if (!dfs) 216 return QDF_STATUS_E_FAILURE; 217 218 dfs_cac_stop(dfs); 219 return QDF_STATUS_SUCCESS; 220 } 221 qdf_export_symbol(utils_dfs_cac_stop); 222 223 void utils_dfs_clear_cac_started_chan(struct wlan_objmgr_pdev *pdev) 224 { 225 struct wlan_dfs *dfs; 226 227 dfs = wlan_pdev_get_dfs_obj(pdev); 228 if (!dfs) 229 return; 230 231 dfs_clear_cac_started_chan(dfs); 232 } 233 234 /** dfs_fill_chan_info() - Fill the dfs channel structure with wlan 235 * channel. 236 * @chan: Pointer to DFS channel structure. 237 * @wlan_chan: Pointer to WLAN Channel structure. 238 * 239 * Return: void 240 */ 241 static void dfs_fill_chan_info(struct dfs_channel *chan, 242 struct wlan_channel *wlan_chan) 243 { 244 chan->dfs_ch_freq = wlan_chan->ch_freq; 245 chan->dfs_ch_flags = wlan_chan->ch_flags; 246 chan->dfs_ch_flagext = wlan_chan->ch_flagext; 247 chan->dfs_ch_ieee = wlan_chan->ch_ieee; 248 chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1; 249 chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2; 250 } 251 252 bool utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev, 253 struct wlan_channel *wlan_chan) 254 { 255 struct wlan_dfs *dfs; 256 struct dfs_channel chan; 257 258 dfs = wlan_pdev_get_dfs_obj(pdev); 259 if (!dfs) 260 return false; 261 262 dfs_fill_chan_info(&chan, wlan_chan); 263 264 return dfs_is_precac_done(dfs, &chan); 265 } 266 267 bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev, 268 bool *continue_current_cac) 269 { 270 struct wlan_dfs *dfs; 271 272 dfs = wlan_pdev_get_dfs_obj(pdev); 273 if (!dfs) 274 return false; 275 276 return dfs_check_for_cac_start(dfs, continue_current_cac); 277 } 278 279 QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev) 280 { 281 struct wlan_dfs *dfs; 282 283 dfs = wlan_pdev_get_dfs_obj(pdev); 284 if (!dfs) 285 return QDF_STATUS_E_FAILURE; 286 287 dfs_stacac_stop(dfs); 288 289 return QDF_STATUS_SUCCESS; 290 } 291 qdf_export_symbol(utils_dfs_stacac_stop); 292 293 QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol) 294 { 295 struct wlan_dfs *dfs; 296 297 dfs = wlan_pdev_get_dfs_obj(pdev); 298 if (!dfs) 299 return QDF_STATUS_E_FAILURE; 300 301 *usenol = dfs_get_use_nol(dfs); 302 303 return QDF_STATUS_SUCCESS; 304 } 305 qdf_export_symbol(utils_dfs_get_usenol); 306 307 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev) 308 { 309 struct wlan_dfs *dfs; 310 311 dfs = wlan_pdev_get_dfs_obj(pdev); 312 if (!dfs) 313 return QDF_STATUS_E_FAILURE; 314 315 dfs_radar_disable(dfs); 316 317 return QDF_STATUS_SUCCESS; 318 } 319 qdf_export_symbol(utils_dfs_radar_disable); 320 321 QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev, 322 bool val) 323 { 324 struct wlan_dfs *dfs; 325 326 dfs = wlan_pdev_get_dfs_obj(pdev); 327 if (!dfs) 328 return QDF_STATUS_E_FAILURE; 329 330 dfs_set_update_nol_flag(dfs, val); 331 332 return QDF_STATUS_SUCCESS; 333 } 334 qdf_export_symbol(utils_dfs_set_update_nol_flag); 335 336 QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev, 337 bool *nol_flag) 338 { 339 struct wlan_dfs *dfs; 340 341 dfs = wlan_pdev_get_dfs_obj(pdev); 342 if (!dfs) 343 return QDF_STATUS_E_FAILURE; 344 345 *nol_flag = dfs_get_update_nol_flag(dfs); 346 347 return QDF_STATUS_SUCCESS; 348 } 349 qdf_export_symbol(utils_dfs_get_update_nol_flag); 350 351 QDF_STATUS utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev *pdev, 352 int *dfs_use_nol) 353 { 354 struct wlan_dfs *dfs; 355 356 dfs = wlan_pdev_get_dfs_obj(pdev); 357 if (!dfs) 358 return QDF_STATUS_E_FAILURE; 359 360 *dfs_use_nol = dfs_get_use_nol(dfs); 361 362 return QDF_STATUS_SUCCESS; 363 } 364 qdf_export_symbol(utils_dfs_get_dfs_use_nol); 365 366 QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev, 367 int *dfs_nol_timeout) 368 { 369 struct wlan_dfs *dfs; 370 371 dfs = wlan_pdev_get_dfs_obj(pdev); 372 if (!dfs) 373 return QDF_STATUS_E_FAILURE; 374 375 *dfs_nol_timeout = dfs_get_nol_timeout(dfs); 376 377 return QDF_STATUS_SUCCESS; 378 } 379 qdf_export_symbol(utils_dfs_get_nol_timeout); 380 381 QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev, 382 uint16_t freq, 383 uint32_t dfs_nol_timeout) 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_NOL_ADD_CHAN_LOCKED(dfs, freq, dfs_nol_timeout); 392 393 return QDF_STATUS_SUCCESS; 394 } 395 qdf_export_symbol(utils_dfs_nol_addchan); 396 397 QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev) 398 { 399 struct wlan_dfs *dfs; 400 401 dfs = wlan_pdev_get_dfs_obj(pdev); 402 if (!dfs) 403 return QDF_STATUS_E_FAILURE; 404 405 dfs_nol_update(dfs); 406 407 return QDF_STATUS_SUCCESS; 408 } 409 qdf_export_symbol(utils_dfs_nol_update); 410 411 QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev) 412 { 413 struct wlan_dfs *dfs; 414 415 dfs = wlan_pdev_get_dfs_obj(pdev); 416 if (!dfs) 417 return QDF_STATUS_E_FAILURE; 418 419 dfs_second_segment_radar_disable(dfs); 420 421 return QDF_STATUS_SUCCESS; 422 } 423 424 QDF_STATUS utils_dfs_bw_reduce(struct wlan_objmgr_pdev *pdev, bool bw_reduce) 425 { 426 struct wlan_dfs *dfs; 427 428 dfs = wlan_pdev_get_dfs_obj(pdev); 429 if (!dfs) 430 return QDF_STATUS_E_FAILURE; 431 432 dfs->dfs_bw_reduced = bw_reduce; 433 434 return QDF_STATUS_SUCCESS; 435 } 436 437 qdf_export_symbol(utils_dfs_bw_reduce); 438 439 QDF_STATUS utils_dfs_is_bw_reduce(struct wlan_objmgr_pdev *pdev, 440 bool *bw_reduce) 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 *bw_reduce = dfs->dfs_bw_reduced; 449 450 return QDF_STATUS_SUCCESS; 451 } 452 453 QDF_STATUS utils_dfs_fetch_nol_ie_info(struct wlan_objmgr_pdev *pdev, 454 uint8_t *nol_ie_bandwidth, 455 uint16_t *nol_ie_startfreq, 456 uint8_t *nol_ie_bitmap) 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_fetch_nol_ie_info(dfs, nol_ie_bandwidth, nol_ie_startfreq, 465 nol_ie_bitmap); 466 467 return QDF_STATUS_SUCCESS; 468 } 469 470 QDF_STATUS utils_dfs_set_rcsa_flags(struct wlan_objmgr_pdev *pdev, 471 bool is_rcsa_ie_sent, 472 bool is_nol_ie_sent) 473 { 474 struct wlan_dfs *dfs; 475 476 dfs = wlan_pdev_get_dfs_obj(pdev); 477 if (!dfs) 478 return QDF_STATUS_E_FAILURE; 479 480 dfs_set_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent); 481 482 return QDF_STATUS_SUCCESS; 483 } 484 485 QDF_STATUS utils_dfs_get_rcsa_flags(struct wlan_objmgr_pdev *pdev, 486 bool *is_rcsa_ie_sent, 487 bool *is_nol_ie_sent) 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 dfs_get_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent); 495 496 return QDF_STATUS_SUCCESS; 497 } 498 499 bool utils_dfs_process_nol_ie_bitmap(struct wlan_objmgr_pdev *pdev, 500 uint8_t nol_ie_bandwidth, 501 uint16_t nol_ie_startfreq, 502 uint8_t nol_ie_bitmap) 503 { 504 struct wlan_dfs *dfs; 505 506 dfs = wlan_pdev_get_dfs_obj(pdev); 507 if (!dfs) 508 return false; 509 return dfs_process_nol_ie_bitmap(dfs, nol_ie_bandwidth, 510 nol_ie_startfreq, 511 nol_ie_bitmap); 512 } 513 514 QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev, 515 int val) 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_cac_timer_running = val; 524 525 return QDF_STATUS_SUCCESS; 526 } 527 qdf_export_symbol(utils_dfs_set_cac_timer_running); 528 529 QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev, 530 void *nollist, 531 uint32_t *nol_chfreq, 532 uint32_t *nol_chwidth, 533 int index) 534 { 535 struct wlan_dfs *dfs; 536 537 dfs = wlan_pdev_get_dfs_obj(pdev); 538 if (!dfs) 539 return QDF_STATUS_E_FAILURE; 540 541 dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index); 542 543 return QDF_STATUS_SUCCESS; 544 } 545 qdf_export_symbol(utils_dfs_get_nol_chfreq_and_chwidth); 546 547 QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev, 548 uint64_t flags, 549 uint16_t flagext) 550 { 551 struct wlan_dfs *dfs; 552 553 dfs = wlan_pdev_get_dfs_obj(pdev); 554 if (!dfs) 555 return QDF_STATUS_E_FAILURE; 556 557 dfs_update_cur_chan_flags(dfs, flags, flagext); 558 559 return QDF_STATUS_SUCCESS; 560 } 561 562 static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev, 563 uint32_t *phy_mode) 564 { 565 return; 566 } 567 568 static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev, 569 uint8_t *ch_width) 570 { 571 return; 572 } 573 574 #ifndef QCA_DFS_USE_POLICY_MANAGER 575 void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, 576 void *clist, uint32_t *num_chan) 577 { 578 int i, j = 0; 579 struct regulatory_channel *cur_chan_list; 580 struct wlan_dfs *dfs; 581 struct dfs_channel *chan_list = (struct dfs_channel *)clist; 582 583 *num_chan = 0; 584 585 dfs = wlan_pdev_get_dfs_obj(pdev); 586 if (!dfs) 587 return; 588 589 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(*cur_chan_list)); 590 if (!cur_chan_list) 591 return; 592 593 if (wlan_reg_get_current_chan_list( 594 pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { 595 dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, 596 "failed to get cur_chan list"); 597 qdf_mem_free(cur_chan_list); 598 return; 599 } 600 601 for (i = 0; i < NUM_CHANNELS; i++) { 602 if (cur_chan_list[i].nol_history) { 603 chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq; 604 j++; 605 } 606 } 607 608 *num_chan = j; 609 qdf_mem_free(cur_chan_list); 610 } 611 612 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, 613 void *clist, uint32_t *num_chan) 614 { 615 int i = 0, j = 0; 616 enum channel_state state; 617 struct regulatory_channel *cur_chan_list; 618 struct wlan_dfs *dfs; 619 struct dfs_channel *chan_list = (struct dfs_channel *)clist; 620 621 dfs = wlan_pdev_get_dfs_obj(pdev); 622 if (!dfs) 623 return; 624 625 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * 626 sizeof(struct regulatory_channel)); 627 if (!cur_chan_list) { 628 *num_chan = 0; 629 return; 630 } 631 632 if (wlan_reg_get_current_chan_list( 633 pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { 634 *num_chan = 0; 635 dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, 636 "failed to get curr channel list"); 637 return; 638 } 639 640 for (i = 0; i < NUM_CHANNELS; i++) { 641 state = cur_chan_list[i].state; 642 if (state == CHANNEL_STATE_DFS || 643 state == CHANNEL_STATE_ENABLE) { 644 chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num; 645 chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq; 646 if (state == CHANNEL_STATE_DFS) 647 chan_list[j].dfs_ch_flagext = 648 WLAN_CHAN_DFS; 649 650 if (cur_chan_list[i].nol_history) 651 chan_list[j].dfs_ch_flagext |= 652 WLAN_CHAN_HISTORY_RADAR; 653 j++; 654 } 655 } 656 *num_chan = j; 657 qdf_mem_free(cur_chan_list); 658 659 return; 660 } 661 662 /** 663 * utils_dfs_get_channel_list() - Get channel list from regdb component, based 664 * on current channel list. 665 * @pdev: Pointer to pdev structure. 666 * @chan: Pointer to channel list. 667 * @num_chan: number of channels. 668 * 669 * Get regdb channel list based on dfs current channel. 670 * Ex: When AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels 671 * so that the random channel function does not select either 2.4GHz or 4.9GHz 672 * channel. 673 */ 674 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, 675 struct dfs_channel *chan_list, 676 uint32_t *num_chan) 677 { 678 struct dfs_channel *tmp_chan_list = NULL; 679 struct wlan_dfs *dfs; 680 bool is_curchan_5g; 681 bool is_curchan_24g; 682 bool is_curchan_49g; 683 uint32_t chan_num; 684 uint32_t center_freq; 685 uint16_t flagext; 686 int i, j = 0; 687 688 dfs = wlan_pdev_get_dfs_obj(pdev); 689 if (!dfs) { 690 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 691 return; 692 } 693 694 tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list)); 695 if (!tmp_chan_list) 696 return; 697 698 utils_dfs_get_chan_list(pdev, (void *)tmp_chan_list, num_chan); 699 700 chan_num = dfs->dfs_curchan->dfs_ch_ieee; 701 center_freq = dfs->dfs_curchan->dfs_ch_freq; 702 is_curchan_5g = WLAN_REG_IS_5GHZ_CH(chan_num); 703 is_curchan_24g = WLAN_REG_IS_24GHZ_CH(chan_num); 704 is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq); 705 706 for (i = 0; i < *num_chan; i++) { 707 chan_num = tmp_chan_list[i].dfs_ch_ieee; 708 center_freq = tmp_chan_list[i].dfs_ch_freq; 709 flagext = tmp_chan_list[i].dfs_ch_flagext; 710 711 if (!dfs_mlme_check_allowed_prim_chanlist(pdev, chan_num)) 712 continue; 713 714 if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH(chan_num)) { 715 chan_list[j].dfs_ch_ieee = chan_num; 716 chan_list[j].dfs_ch_freq = center_freq; 717 chan_list[j].dfs_ch_flagext = flagext; 718 j++; 719 } else if ((is_curchan_24g) && 720 WLAN_REG_IS_24GHZ_CH(chan_num)) { 721 chan_list[j].dfs_ch_ieee = chan_num; 722 chan_list[j].dfs_ch_freq = center_freq; 723 j++; 724 } else if ((is_curchan_49g) && 725 WLAN_REG_IS_49GHZ_FREQ(center_freq)) { 726 chan_list[j].dfs_ch_ieee = chan_num; 727 chan_list[j].dfs_ch_freq = center_freq; 728 j++; 729 } 730 } 731 732 *num_chan = j; 733 734 qdf_mem_free(tmp_chan_list); 735 } 736 737 #else 738 739 void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, 740 void *clist, uint32_t *num_chan) 741 { 742 utils_dfs_get_chan_list(pdev, clist, num_chan); 743 } 744 745 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, 746 void *clist, uint32_t *num_chan) 747 { 748 uint8_t pcl_ch[QDF_MAX_NUM_CHAN] = {0}; 749 uint8_t weight_list[QDF_MAX_NUM_CHAN] = {0}; 750 uint32_t len; 751 uint32_t weight_len; 752 int i; 753 struct wlan_objmgr_psoc *psoc; 754 uint32_t conn_count = 0; 755 struct dfs_channel *chan_list = (struct dfs_channel *)clist; 756 757 psoc = wlan_pdev_get_psoc(pdev); 758 if (!psoc) { 759 *num_chan = 0; 760 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 761 return; 762 } 763 764 len = QDF_ARRAY_SIZE(pcl_ch); 765 weight_len = QDF_ARRAY_SIZE(weight_list); 766 conn_count = policy_mgr_mode_specific_connection_count( 767 psoc, PM_SAP_MODE, NULL); 768 if (0 == conn_count) 769 policy_mgr_get_pcl(psoc, PM_SAP_MODE, pcl_ch, 770 &len, weight_list, weight_len); 771 else 772 policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, pcl_ch, 773 &len, weight_list, weight_len, true); 774 775 if (*num_chan < len) { 776 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 777 "Invalid len src=%d, dst=%d", 778 *num_chan, len); 779 *num_chan = 0; 780 return; 781 } 782 783 for (i = 0; i < len; i++) { 784 chan_list[i].dfs_ch_ieee = pcl_ch[i]; 785 chan_list[i].dfs_ch_freq = 786 wlan_reg_chan_to_freq(pdev, pcl_ch[i]); 787 } 788 *num_chan = i; 789 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i); 790 } 791 792 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, 793 struct dfs_channel *chan_list, 794 uint32_t *num_chan) 795 { 796 utils_dfs_get_chan_list(pdev, (void *)chan_list, num_chan); 797 } 798 #endif 799 800 QDF_STATUS utils_dfs_get_random_channel( 801 struct wlan_objmgr_pdev *pdev, 802 uint16_t flags, 803 struct ch_params *ch_params, 804 uint32_t *hw_mode, 805 uint8_t *target_chan, 806 struct dfs_acs_info *acs_info) 807 { 808 uint32_t dfs_reg; 809 uint32_t num_chan = NUM_CHANNELS; 810 struct wlan_dfs *dfs = NULL; 811 struct wlan_objmgr_psoc *psoc; 812 struct dfs_channel *chan_list = NULL; 813 struct dfs_channel cur_chan; 814 QDF_STATUS status = QDF_STATUS_E_FAILURE; 815 816 *target_chan = 0; 817 psoc = wlan_pdev_get_psoc(pdev); 818 if (!psoc) { 819 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 820 goto random_chan_error; 821 } 822 823 dfs = wlan_pdev_get_dfs_obj(pdev); 824 if (!dfs) { 825 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 826 goto random_chan_error; 827 } 828 829 wlan_reg_get_dfs_region(pdev, &dfs_reg); 830 chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list)); 831 if (!chan_list) 832 goto random_chan_error; 833 834 utils_dfs_get_channel_list(pdev, chan_list, &num_chan); 835 if (!num_chan) { 836 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels"); 837 goto random_chan_error; 838 } 839 840 cur_chan.dfs_ch_vhtop_ch_freq_seg1 = ch_params->center_freq_seg0; 841 cur_chan.dfs_ch_vhtop_ch_freq_seg2 = ch_params->center_freq_seg1; 842 843 if (!ch_params->ch_width) 844 utils_dfs_get_max_sup_width(pdev, 845 (uint8_t *)&ch_params->ch_width); 846 847 *target_chan = dfs_prepare_random_channel(dfs, chan_list, 848 num_chan, flags, (uint8_t *)&ch_params->ch_width, 849 &cur_chan, (uint8_t)dfs_reg, acs_info); 850 851 ch_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1; 852 ch_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2; 853 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 854 "input width=%d", ch_params->ch_width); 855 856 if (*target_chan) { 857 wlan_reg_set_channel_params(pdev, 858 *target_chan, 0, ch_params); 859 utils_dfs_get_max_phy_mode(pdev, hw_mode); 860 status = QDF_STATUS_SUCCESS; 861 } 862 863 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 864 "ch=%d, seg0=%d, seg1=%d, width=%d", 865 *target_chan, ch_params->center_freq_seg0, 866 ch_params->center_freq_seg1, ch_params->ch_width); 867 868 random_chan_error: 869 qdf_mem_free(chan_list); 870 871 return status; 872 } 873 qdf_export_symbol(utils_dfs_get_random_channel); 874 875 QDF_STATUS utils_dfs_bw_reduced_channel( 876 struct wlan_objmgr_pdev *pdev, 877 struct ch_params *ch_params, 878 uint32_t *hw_mode, 879 uint8_t *target_chan) 880 { 881 struct wlan_dfs *dfs = NULL; 882 struct wlan_objmgr_psoc *psoc; 883 enum channel_state ch_state; 884 QDF_STATUS status = QDF_STATUS_E_FAILURE; 885 886 *target_chan = 0; 887 psoc = wlan_pdev_get_psoc(pdev); 888 if (!psoc) { 889 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 890 return status; 891 } 892 893 dfs = wlan_pdev_get_dfs_obj(pdev); 894 if (!dfs) { 895 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 896 return status; 897 } 898 899 ch_state = wlan_reg_get_channel_state(pdev, 900 dfs->dfs_curchan->dfs_ch_ieee); 901 902 if (ch_state == CHANNEL_STATE_DFS || 903 ch_state == CHANNEL_STATE_ENABLE) { 904 ch_params->center_freq_seg0 = 905 dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1; 906 ch_params->center_freq_seg1 = 907 dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2; 908 wlan_reg_set_channel_params(pdev, 909 dfs->dfs_curchan->dfs_ch_ieee, 910 0, ch_params); 911 912 *target_chan = dfs->dfs_curchan->dfs_ch_ieee; 913 utils_dfs_get_max_phy_mode(pdev, hw_mode); 914 915 return QDF_STATUS_SUCCESS; 916 } 917 918 return status; 919 } 920 921 qdf_export_symbol(utils_dfs_bw_reduced_channel); 922 923 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 924 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev) 925 { 926 struct wlan_dfs *dfs; 927 struct wlan_objmgr_psoc *psoc; 928 qdf_device_t qdf_dev; 929 struct dfs_nol_info *dfs_nolinfo; 930 int len; 931 932 dfs = wlan_pdev_get_dfs_obj(pdev); 933 psoc = wlan_pdev_get_psoc(pdev); 934 if (!dfs || !psoc) { 935 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 936 "dfs %pK, psoc %pK", dfs, psoc); 937 return; 938 } 939 940 qdf_dev = psoc->soc_objmgr.qdf_dev; 941 if (!qdf_dev->dev) { 942 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null device"); 943 return; 944 } 945 946 dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo)); 947 if (!dfs_nolinfo) 948 return; 949 950 qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo)); 951 len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo, 952 (uint16_t)sizeof(*dfs_nolinfo)); 953 if (len > 0) { 954 dfs_set_nol(dfs, dfs_nolinfo->dfs_nol, dfs_nolinfo->num_chans); 955 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld"); 956 DFS_PRINT_NOL_LOCKED(dfs); 957 } else { 958 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "no nol in pld"); 959 } 960 qdf_mem_free(dfs_nolinfo); 961 } 962 #endif 963 qdf_export_symbol(utils_dfs_init_nol); 964 965 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 966 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev) 967 { 968 } 969 #else 970 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev) 971 { 972 struct dfs_nol_info *dfs_nolinfo; 973 struct wlan_dfs *dfs = NULL; 974 struct wlan_objmgr_psoc *psoc; 975 qdf_device_t qdf_dev; 976 int num_chans = 0; 977 978 dfs = wlan_pdev_get_dfs_obj(pdev); 979 if (!dfs) { 980 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 981 return; 982 } 983 984 psoc = wlan_pdev_get_psoc(pdev); 985 if (!psoc) { 986 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 987 return; 988 } 989 990 qdf_dev = psoc->soc_objmgr.qdf_dev; 991 if (!qdf_dev->dev) { 992 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null device"); 993 return; 994 } 995 996 dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo)); 997 if (!dfs_nolinfo) 998 return; 999 1000 qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo)); 1001 DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo->dfs_nol, &num_chans); 1002 if (num_chans > 0) { 1003 1004 if (num_chans > DFS_MAX_NOL_CHANNEL) 1005 dfs_nolinfo->num_chans = DFS_MAX_NOL_CHANNEL; 1006 else 1007 dfs_nolinfo->num_chans = num_chans; 1008 1009 pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo, 1010 (uint16_t)sizeof(*dfs_nolinfo)); 1011 } 1012 qdf_mem_free(dfs_nolinfo); 1013 } 1014 #endif 1015 qdf_export_symbol(utils_dfs_save_nol); 1016 1017 void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev) 1018 { 1019 struct wlan_dfs *dfs = NULL; 1020 1021 dfs = wlan_pdev_get_dfs_obj(pdev); 1022 if (!dfs) { 1023 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1024 return; 1025 } 1026 1027 DFS_PRINT_NOL_LOCKED(dfs); 1028 } 1029 qdf_export_symbol(utils_dfs_print_nol_channels); 1030 1031 void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev) 1032 { 1033 struct wlan_dfs *dfs = NULL; 1034 1035 dfs = wlan_pdev_get_dfs_obj(pdev); 1036 if (!dfs) { 1037 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1038 return; 1039 } 1040 1041 /* First print list */ 1042 DFS_PRINT_NOL_LOCKED(dfs); 1043 1044 /* clear local cache first */ 1045 dfs_nol_timer_cleanup(dfs); 1046 dfs_nol_update(dfs); 1047 1048 /* 1049 * update platform driver nol list with local cache which is zero, 1050 * cleared in above step, so this will clear list in platform driver. 1051 */ 1052 utils_dfs_save_nol(pdev); 1053 } 1054 qdf_export_symbol(utils_dfs_clear_nol_channels); 1055 1056 void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, 1057 uint8_t *ch_list, 1058 uint8_t num_ch, 1059 bool nol_ch) 1060 { 1061 /* TODO : Need locking?*/ 1062 wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch); 1063 } 1064 qdf_export_symbol(utils_dfs_reg_update_nol_ch); 1065 1066 void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, 1067 uint8_t *ch_list, 1068 uint8_t num_ch, 1069 bool nol_history_ch) 1070 { 1071 wlan_reg_update_nol_history_ch(pdev, ch_list, num_ch, nol_history_ch); 1072 } 1073 1074 uint8_t utils_dfs_freq_to_chan(uint32_t freq) 1075 { 1076 uint8_t chan; 1077 1078 if (freq == 0) 1079 return 0; 1080 1081 if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ) 1082 chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ); 1083 else if (freq == DFS_CHAN_14_FREQ) 1084 chan = DFS_24_GHZ_CHANNEL_14; 1085 else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ)) 1086 chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) + 1087 DFS_24_GHZ_CHANNEL_15); 1088 else 1089 chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ; 1090 1091 return chan; 1092 } 1093 qdf_export_symbol(utils_dfs_freq_to_chan); 1094 1095 uint32_t utils_dfs_chan_to_freq(uint8_t chan) 1096 { 1097 if (chan == 0) 1098 return 0; 1099 1100 if (chan < DFS_24_GHZ_CHANNEL_14) 1101 return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ); 1102 else if (chan == DFS_24_GHZ_CHANNEL_14) 1103 return DFS_CHAN_14_FREQ; 1104 else if (chan < DFS_24_GHZ_CHANNEL_27) 1105 return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) * 1106 DFS_CHAN_SPACING_20MHZ); 1107 else if (chan == DFS_5_GHZ_CHANNEL_170) 1108 return DFS_CHAN_170_FREQ; 1109 else 1110 return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ); 1111 } 1112 qdf_export_symbol(utils_dfs_chan_to_freq); 1113 1114 #ifdef QCA_MCL_DFS_SUPPORT 1115 QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev, 1116 enum phy_ch_width ch_width, 1117 uint8_t temp_ch_lst_sz, 1118 uint8_t *temp_ch_lst) 1119 { 1120 struct wlan_dfs *dfs = NULL; 1121 1122 dfs = wlan_pdev_get_dfs_obj(pdev); 1123 if (!dfs) { 1124 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 1125 return QDF_STATUS_E_FAILURE; 1126 } 1127 1128 return dfs_mark_leaking_ch(dfs, ch_width, temp_ch_lst_sz, temp_ch_lst); 1129 } 1130 qdf_export_symbol(utils_dfs_mark_leaking_ch); 1131 #endif 1132 1133 int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev) 1134 { 1135 enum dfs_reg dfsdomain; 1136 1137 wlan_reg_get_dfs_region(pdev, &dfsdomain); 1138 1139 return dfsdomain; 1140 } 1141 1142 uint16_t utils_dfs_get_cur_rd(struct wlan_objmgr_pdev *pdev) 1143 { 1144 struct cur_regdmn_info cur_regdmn; 1145 1146 wlan_reg_get_curr_regdomain(pdev, &cur_regdmn); 1147 1148 return cur_regdmn.regdmn_pair_id; 1149 } 1150 1151 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 1152 QDF_STATUS utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev *pdev, 1153 bool *is_spoof_check_failed) 1154 { 1155 struct wlan_dfs *dfs; 1156 1157 if (!tgt_dfs_is_pdev_5ghz(pdev)) 1158 return QDF_STATUS_SUCCESS; 1159 1160 dfs = wlan_pdev_get_dfs_obj(pdev); 1161 if (!dfs) { 1162 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); 1163 return QDF_STATUS_E_FAILURE; 1164 } 1165 1166 *is_spoof_check_failed = dfs->dfs_spoof_check_failed; 1167 1168 return QDF_STATUS_SUCCESS; 1169 } 1170 1171 qdf_export_symbol(utils_dfs_is_spoof_check_failed); 1172 #endif 1173 1174 int dfs_get_num_chans(void) 1175 { 1176 return NUM_CHANNELS; 1177 } 1178 1179 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 1180 QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev, 1181 bool *disable_radar_marking) 1182 { 1183 struct wlan_dfs *dfs; 1184 1185 if (!tgt_dfs_is_pdev_5ghz(pdev)) 1186 return QDF_STATUS_SUCCESS; 1187 1188 dfs = wlan_pdev_get_dfs_obj(pdev); 1189 if (!dfs) { 1190 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); 1191 return QDF_STATUS_E_FAILURE; 1192 } 1193 1194 *disable_radar_marking = dfs_get_disable_radar_marking(dfs); 1195 1196 return QDF_STATUS_SUCCESS; 1197 } 1198 1199 qdf_export_symbol(utils_dfs_get_disable_radar_marking); 1200 1201 bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev) 1202 { 1203 struct wlan_dfs *dfs; 1204 1205 dfs = wlan_pdev_get_dfs_obj(pdev); 1206 if (!dfs) 1207 return false; 1208 1209 return WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan); 1210 } 1211 1212 qdf_export_symbol(utils_is_dfs_cfreq2_ch); 1213 #endif 1214 1215 void utils_dfs_deliver_event(struct wlan_objmgr_pdev *pdev, uint16_t freq, 1216 enum WLAN_DFS_EVENTS event) 1217 { 1218 if (global_dfs_to_mlme.mlme_dfs_deliver_event) 1219 global_dfs_to_mlme.mlme_dfs_deliver_event(pdev, freq, event); 1220 } 1221