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