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