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