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