1 /* 2 * Copyright (c) 2016-2017 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 "../../core/src/dfs.h" 26 #include "../../core/src/dfs_zero_cac.h" 27 #include "../../core/src/dfs_random_chan_sel.h" 28 #ifdef QCA_DFS_USE_POLICY_MANAGER 29 #include "wlan_policy_mgr_api.h" 30 #endif 31 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 32 #include <pld_common.h> 33 #endif 34 35 struct dfs_nol_info { 36 uint16_t num_chans; 37 struct dfsreq_nolelem dfs_nol[DFS_MAX_NOL_CHANNEL]; 38 }; 39 40 QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev) 41 { 42 struct wlan_dfs *dfs; 43 44 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 45 if (dfs == NULL) 46 return QDF_STATUS_E_FAILURE; 47 48 dfs_reset(dfs); 49 dfs_nol_update(dfs); 50 dfs_init_precac_list(dfs); 51 52 return QDF_STATUS_SUCCESS; 53 } 54 55 QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev, 56 uint8_t prevchan_ieee, 57 uint32_t prevchan_flags) 58 { 59 struct wlan_dfs *dfs; 60 61 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 62 if (dfs == NULL) 63 return QDF_STATUS_E_FAILURE; 64 65 dfs_cac_valid_reset(dfs, prevchan_ieee, prevchan_flags); 66 67 return QDF_STATUS_SUCCESS; 68 } 69 EXPORT_SYMBOL(utils_dfs_cac_valid_reset); 70 71 QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) 72 { 73 struct wlan_dfs *dfs; 74 75 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 76 if (dfs == NULL) 77 return QDF_STATUS_E_FAILURE; 78 79 dfs_reset_precaclists(dfs); 80 81 return QDF_STATUS_SUCCESS; 82 } 83 EXPORT_SYMBOL(utils_dfs_reset_precaclists); 84 85 QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev) 86 { 87 struct wlan_dfs *dfs; 88 89 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 90 if (dfs == NULL) 91 return QDF_STATUS_E_FAILURE; 92 93 dfs_cancel_precac_timer(dfs); 94 95 return QDF_STATUS_SUCCESS; 96 } 97 EXPORT_SYMBOL(utils_dfs_cancel_precac_timer); 98 99 QDF_STATUS utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev, 100 bool *is_precac_done) 101 { 102 struct wlan_dfs *dfs; 103 104 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 105 if (dfs == NULL) 106 return QDF_STATUS_E_FAILURE; 107 108 *is_precac_done = dfs_is_precac_done(dfs); 109 110 return QDF_STATUS_SUCCESS; 111 } 112 EXPORT_SYMBOL(utils_dfs_is_precac_done); 113 114 QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev) 115 { 116 struct wlan_dfs *dfs; 117 118 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 119 if (dfs == NULL) 120 return QDF_STATUS_E_FAILURE; 121 122 dfs_cancel_cac_timer(dfs); 123 124 return QDF_STATUS_SUCCESS; 125 } 126 EXPORT_SYMBOL(utils_dfs_cancel_cac_timer); 127 128 QDF_STATUS utils_dfs_start_cac_timer(struct wlan_objmgr_pdev *pdev) 129 { 130 struct wlan_dfs *dfs; 131 132 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 133 if (dfs == NULL) 134 return QDF_STATUS_E_FAILURE; 135 136 dfs_start_cac_timer(dfs); 137 138 return QDF_STATUS_SUCCESS; 139 } 140 EXPORT_SYMBOL(utils_dfs_start_cac_timer); 141 142 QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev) 143 { 144 struct wlan_dfs *dfs; 145 146 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 147 if (dfs == NULL) 148 return QDF_STATUS_E_FAILURE; 149 150 dfs_cac_stop(dfs); 151 return QDF_STATUS_SUCCESS; 152 } 153 EXPORT_SYMBOL(utils_dfs_cac_stop); 154 155 QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev) 156 { 157 struct wlan_dfs *dfs; 158 159 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 160 if (dfs == NULL) 161 return QDF_STATUS_E_FAILURE; 162 163 dfs_stacac_stop(dfs); 164 165 return QDF_STATUS_SUCCESS; 166 } 167 EXPORT_SYMBOL(utils_dfs_stacac_stop); 168 169 QDF_STATUS utils_dfs_random_channel(struct wlan_objmgr_pdev *pdev, 170 uint8_t is_select_nondfs, 171 uint8_t skip_curchan, 172 int *target_channel) 173 { 174 struct wlan_dfs *dfs; 175 176 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 177 if (dfs == NULL) 178 return QDF_STATUS_E_FAILURE; 179 180 *target_channel = dfs_random_channel(dfs, 181 is_select_nondfs, 182 skip_curchan); 183 184 return QDF_STATUS_SUCCESS; 185 } 186 EXPORT_SYMBOL(utils_dfs_random_channel); 187 188 QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol) 189 { 190 struct wlan_dfs *dfs; 191 192 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 193 if (dfs == NULL) 194 return QDF_STATUS_E_FAILURE; 195 196 *usenol = dfs_get_usenol(dfs); 197 198 return QDF_STATUS_SUCCESS; 199 } 200 EXPORT_SYMBOL(utils_dfs_get_usenol); 201 202 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev) 203 { 204 struct wlan_dfs *dfs; 205 206 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 207 if (dfs == NULL) 208 return QDF_STATUS_E_FAILURE; 209 210 dfs_radar_disable(dfs); 211 212 return QDF_STATUS_SUCCESS; 213 } 214 EXPORT_SYMBOL(utils_dfs_radar_disable); 215 216 QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev, 217 bool val) 218 { 219 struct wlan_dfs *dfs; 220 221 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 222 if (dfs == NULL) 223 return QDF_STATUS_E_FAILURE; 224 225 dfs_set_update_nol_flag(dfs, val); 226 227 return QDF_STATUS_SUCCESS; 228 } 229 EXPORT_SYMBOL(utils_dfs_set_update_nol_flag); 230 231 QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev, 232 bool *nol_flag) 233 { 234 struct wlan_dfs *dfs; 235 236 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 237 if (dfs == NULL) 238 return QDF_STATUS_E_FAILURE; 239 240 *nol_flag = dfs_get_update_nol_flag(dfs); 241 242 return QDF_STATUS_SUCCESS; 243 } 244 EXPORT_SYMBOL(utils_dfs_get_update_nol_flag); 245 246 QDF_STATUS utils_dfs_get_rn_use_nol(struct wlan_objmgr_pdev *pdev, 247 int *rn_use_nol) 248 { 249 struct wlan_dfs *dfs; 250 251 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 252 if (dfs == NULL) 253 return QDF_STATUS_E_FAILURE; 254 255 *rn_use_nol = dfs_get_rn_use_nol(dfs); 256 257 return QDF_STATUS_SUCCESS; 258 } 259 EXPORT_SYMBOL(utils_dfs_get_rn_use_nol); 260 261 QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev, 262 int *dfs_nol_timeout) 263 { 264 struct wlan_dfs *dfs; 265 266 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 267 if (dfs == NULL) 268 return QDF_STATUS_E_FAILURE; 269 270 *dfs_nol_timeout = dfs_get_nol_timeout(dfs); 271 272 return QDF_STATUS_SUCCESS; 273 } 274 EXPORT_SYMBOL(utils_dfs_get_nol_timeout); 275 276 QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev, 277 uint16_t freq, 278 uint32_t dfs_nol_timeout) 279 { 280 struct wlan_dfs *dfs; 281 282 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 283 if (dfs == NULL) 284 return QDF_STATUS_E_FAILURE; 285 286 dfs_nol_addchan(dfs, freq, dfs_nol_timeout); 287 288 return QDF_STATUS_SUCCESS; 289 } 290 EXPORT_SYMBOL(utils_dfs_nol_addchan); 291 292 QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev) 293 { 294 struct wlan_dfs *dfs; 295 296 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 297 if (dfs == NULL) 298 return QDF_STATUS_E_FAILURE; 299 300 dfs_nol_update(dfs); 301 302 return QDF_STATUS_SUCCESS; 303 } 304 EXPORT_SYMBOL(utils_dfs_nol_update); 305 306 QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev) 307 { 308 struct wlan_dfs *dfs; 309 310 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 311 if (dfs == NULL) 312 return QDF_STATUS_E_FAILURE; 313 314 dfs_second_segment_radar_disable(dfs); 315 316 return QDF_STATUS_SUCCESS; 317 } 318 319 QDF_STATUS utils_dfs_is_ignore_dfs(struct wlan_objmgr_pdev *pdev, 320 bool *ignore_dfs) 321 { 322 struct wlan_dfs *dfs; 323 324 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 325 if (dfs == NULL) 326 return QDF_STATUS_E_FAILURE; 327 328 *ignore_dfs = dfs->dfs_ignore_dfs; 329 330 return QDF_STATUS_SUCCESS; 331 } 332 EXPORT_SYMBOL(utils_dfs_is_ignore_dfs); 333 334 QDF_STATUS utils_dfs_is_cac_valid(struct wlan_objmgr_pdev *pdev, 335 bool *is_cac_valid) 336 { 337 struct wlan_dfs *dfs; 338 339 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 340 if (dfs == NULL) 341 return QDF_STATUS_E_FAILURE; 342 343 *is_cac_valid = dfs->dfs_cac_valid; 344 345 return QDF_STATUS_SUCCESS; 346 } 347 EXPORT_SYMBOL(utils_dfs_is_cac_valid); 348 349 QDF_STATUS utils_dfs_is_ignore_cac(struct wlan_objmgr_pdev *pdev, 350 bool *ignore_cac) 351 { 352 struct wlan_dfs *dfs; 353 354 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 355 if (dfs == NULL) 356 return QDF_STATUS_E_FAILURE; 357 358 *ignore_cac = dfs->dfs_ignore_cac; 359 360 return QDF_STATUS_SUCCESS; 361 } 362 EXPORT_SYMBOL(utils_dfs_is_ignore_cac); 363 364 QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev, 365 int val) 366 { 367 struct wlan_dfs *dfs; 368 369 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 370 if (dfs == NULL) 371 return QDF_STATUS_E_FAILURE; 372 373 dfs->dfs_cac_timer_running = val; 374 375 return QDF_STATUS_SUCCESS; 376 } 377 EXPORT_SYMBOL(utils_dfs_set_cac_timer_running); 378 379 QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev, 380 void *nollist, 381 uint32_t *nol_chfreq, 382 uint32_t *nol_chwidth, 383 int index) 384 { 385 struct wlan_dfs *dfs; 386 387 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 388 if (dfs == NULL) 389 return QDF_STATUS_E_FAILURE; 390 391 dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index); 392 393 return QDF_STATUS_SUCCESS; 394 } 395 EXPORT_SYMBOL(utils_dfs_get_nol_chfreq_and_chwidth); 396 397 QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev, 398 uint64_t flags, 399 uint16_t flagext) 400 { 401 struct wlan_dfs *dfs; 402 403 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 404 if (dfs == NULL) 405 return QDF_STATUS_E_FAILURE; 406 407 dfs_update_cur_chan_flags(dfs, flags, flagext); 408 409 return QDF_STATUS_SUCCESS; 410 } 411 412 static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev, 413 uint32_t *phy_mode) 414 { 415 return; 416 } 417 418 static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev, 419 uint8_t *ch_width) 420 { 421 return; 422 } 423 424 #ifndef QCA_DFS_USE_POLICY_MANAGER 425 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, 426 struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan) 427 { 428 return; 429 } 430 #else 431 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, 432 struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan) 433 { 434 uint8_t pcl_ch[NUM_CHANNELS]; 435 uint8_t weight_list[NUM_CHANNELS]; 436 uint32_t len; 437 uint32_t weight_len; 438 int i; 439 struct wlan_objmgr_psoc *psoc; 440 uint32_t conn_count = 0; 441 442 psoc = wlan_pdev_get_psoc(pdev); 443 if (!psoc) { 444 *num_chan = 0; 445 DFS_PRINTK("%s: null psoc\n", __func__); 446 return; 447 } 448 449 len = QDF_ARRAY_SIZE(pcl_ch); 450 weight_len = QDF_ARRAY_SIZE(weight_list); 451 conn_count = policy_mgr_mode_specific_connection_count( 452 psoc, PM_SAP_MODE, NULL); 453 if (0 == conn_count) 454 policy_mgr_get_pcl(psoc, PM_SAP_MODE, pcl_ch, 455 &len, weight_list, weight_len); 456 else 457 policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, pcl_ch, 458 &len, weight_list, weight_len, true); 459 460 if (*num_chan < len) { 461 DFS_PRINTK("%s: Invalid len src=%d, dst=%d\n", 462 __func__, *num_chan, len); 463 *num_chan = 0; 464 return; 465 } 466 467 for (i = 0; i < len; i++) { 468 chan_list[i].dfs_ch_ieee = pcl_ch[i]; 469 chan_list[i].dfs_ch_freq = 470 wlan_reg_chan_to_freq(pdev, pcl_ch[i]); 471 } 472 *num_chan = i; 473 DFS_PRINTK("%s: num channels %d\n", __func__, i); 474 } 475 #endif 476 477 QDF_STATUS dfs_get_random_channel( 478 struct wlan_objmgr_pdev *pdev, 479 uint16_t flags, 480 struct ch_params *ch_params, 481 uint32_t *hw_mode, 482 int *target_chan, 483 struct dfs_acs_info *acs_info) 484 { 485 uint32_t dfs_reg; 486 uint32_t num_chan = NUM_CHANNELS; 487 struct wlan_dfs *dfs = NULL; 488 struct wlan_objmgr_psoc *psoc; 489 struct dfs_ieee80211_channel *chan_list = NULL; 490 struct dfs_ieee80211_channel cur_chan; 491 QDF_STATUS status = QDF_STATUS_E_FAILURE; 492 493 *target_chan = 0; 494 psoc = wlan_pdev_get_psoc(pdev); 495 if (!psoc) { 496 DFS_PRINTK("%s: null psoc\n", __func__); 497 goto random_chan_error; 498 } 499 500 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 501 if (!dfs) { 502 DFS_PRINTK("%s: null dfs\n", __func__); 503 goto random_chan_error; 504 } 505 506 wlan_reg_get_dfs_region(pdev, &dfs_reg); 507 chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list)); 508 if (!chan_list) { 509 DFS_PRINTK("%s: mem alloc failed\n", __func__); 510 goto random_chan_error; 511 } 512 513 utils_dfs_get_chan_list(pdev, chan_list, &num_chan); 514 if (!num_chan) { 515 DFS_PRINTK("%s: zero channels\n", __func__); 516 goto random_chan_error; 517 } 518 519 cur_chan.dfs_ch_vhtop_ch_freq_seg1 = ch_params->center_freq_seg0; 520 cur_chan.dfs_ch_vhtop_ch_freq_seg2 = ch_params->center_freq_seg1; 521 522 if (!ch_params->ch_width) 523 utils_dfs_get_max_sup_width(pdev, 524 (uint8_t *)&ch_params->ch_width); 525 526 *target_chan = dfs_prepare_random_channel(dfs, chan_list, 527 num_chan, flags, (uint8_t *)&ch_params->ch_width, 528 &cur_chan, (uint8_t)dfs_reg, acs_info); 529 530 ch_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1; 531 ch_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2; 532 DFS_PRINTK("%s: input width=%d\n", __func__, ch_params->ch_width); 533 534 if (*target_chan) { 535 wlan_reg_set_channel_params(pdev, 536 (uint8_t)*target_chan, 0, ch_params); 537 utils_dfs_get_max_phy_mode(pdev, hw_mode); 538 status = QDF_STATUS_SUCCESS; 539 } 540 541 DFS_PRINTK("%s: ch=%d, seg0=%d, seg1=%d, width=%d\n", 542 __func__, *target_chan, ch_params->center_freq_seg0, 543 ch_params->center_freq_seg1, ch_params->ch_width); 544 random_chan_error: 545 qdf_mem_free(chan_list); 546 547 return status; 548 } 549 EXPORT_SYMBOL(dfs_get_random_channel); 550 551 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 552 void dfs_init_nol(struct wlan_objmgr_pdev *pdev) 553 { 554 } 555 #else 556 void dfs_init_nol(struct wlan_objmgr_pdev *pdev) 557 { 558 struct wlan_dfs *dfs; 559 struct wlan_objmgr_psoc *psoc; 560 qdf_device_t qdf_dev; 561 struct dfs_nol_info dfs_nolinfo; 562 int len; 563 564 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 565 psoc = wlan_pdev_get_psoc(pdev); 566 if (!dfs || !psoc) { 567 DFS_PRINTK("%s: dfs %p, psoc %p\n", __func__, dfs, psoc); 568 return; 569 } 570 571 qdf_dev = psoc->soc_objmgr.qdf_dev; 572 if (!qdf_dev->dev) { 573 DFS_PRINTK("%s: null device\n", __func__); 574 return; 575 } 576 577 qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo)); 578 len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo, 579 (uint16_t)sizeof(dfs_nolinfo)); 580 if (len > 0) { 581 dfs_set_nol(dfs, dfs_nolinfo.dfs_nol, dfs_nolinfo.num_chans); 582 DFS_PRINTK("%s: nol channels in pld\n", __func__); 583 dfs_print_nol(dfs); 584 } else { 585 DFS_PRINTK("%s: no nol in pld\n", __func__); 586 } 587 } 588 #endif 589 EXPORT_SYMBOL(dfs_init_nol); 590 591 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT 592 void dfs_save_nol(struct wlan_objmgr_pdev *pdev) 593 { 594 } 595 #else 596 void dfs_save_nol(struct wlan_objmgr_pdev *pdev) 597 { 598 struct dfs_nol_info dfs_nolinfo; 599 struct wlan_dfs *dfs = NULL; 600 struct wlan_objmgr_psoc *psoc; 601 qdf_device_t qdf_dev; 602 int num_chans = 0; 603 604 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 605 if (!dfs) { 606 DFS_PRINTK("%s: null dfs\n", __func__); 607 return; 608 } 609 610 psoc = wlan_pdev_get_psoc(pdev); 611 if (!psoc) { 612 DFS_PRINTK("%s: null psoc\n", __func__); 613 return; 614 } 615 616 qdf_dev = psoc->soc_objmgr.qdf_dev; 617 if (!qdf_dev->dev) { 618 DFS_PRINTK("%s: null device\n", __func__); 619 return; 620 } 621 622 qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo)); 623 dfs_get_nol(dfs, dfs_nolinfo.dfs_nol, &num_chans); 624 if (num_chans > 0) { 625 626 if (num_chans > DFS_MAX_NOL_CHANNEL) 627 dfs_nolinfo.num_chans = DFS_MAX_NOL_CHANNEL; 628 else 629 dfs_nolinfo.num_chans = num_chans; 630 631 pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo, 632 (uint16_t)sizeof(dfs_nolinfo)); 633 } 634 } 635 #endif 636 EXPORT_SYMBOL(dfs_save_nol); 637 638 void dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev) 639 { 640 struct wlan_dfs *dfs = NULL; 641 642 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 643 if (!dfs) { 644 DFS_PRINTK("%s: null dfs\n", __func__); 645 return; 646 } 647 648 dfs_print_nol(dfs); 649 } 650 EXPORT_SYMBOL(dfs_print_nol_channels); 651 652 void dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev) 653 { 654 struct wlan_dfs *dfs = NULL; 655 656 dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); 657 if (!dfs) { 658 DFS_PRINTK("%s: null dfs\n", __func__); 659 return; 660 } 661 662 /* First print list */ 663 dfs_print_nol(dfs); 664 665 /* clear local cache first */ 666 dfs_nol_timer_cleanup(dfs); 667 dfs_nol_update(dfs); 668 669 /* 670 * update platform driver nol list with local cache which is zero, 671 * cleared in above step, so this will clear list in platform driver. 672 */ 673 dfs_save_nol(pdev); 674 } 675 EXPORT_SYMBOL(dfs_clear_nol_channels); 676 677 bool utils_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan) 678 { 679 return wlan_reg_is_dfs_ch(pdev, chan); 680 } 681 EXPORT_SYMBOL(utils_is_dfs_ch); 682 683 void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, 684 uint8_t *ch_list, 685 uint8_t num_ch, 686 bool nol_ch) 687 { 688 wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch); 689 } 690 EXPORT_SYMBOL(utils_dfs_reg_update_nol_ch); 691 692 uint8_t utils_dfs_freq_to_chan(uint32_t freq) 693 { 694 uint8_t chan; 695 696 if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ) 697 chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ); 698 else if (freq == DFS_CHAN_14_FREQ) 699 chan = DFS_24_GHZ_CHANNEL_14; 700 else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ)) 701 chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) + 702 DFS_24_GHZ_CHANNEL_15); 703 else 704 chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ; 705 706 return chan; 707 } 708 EXPORT_SYMBOL(utils_dfs_freq_to_chan); 709 710 uint32_t utils_dfs_chan_to_freq(uint8_t chan) 711 { 712 if (chan < DFS_24_GHZ_CHANNEL_14) 713 return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ); 714 else if (chan == DFS_24_GHZ_CHANNEL_14) 715 return DFS_CHAN_14_FREQ; 716 else if (chan < DFS_24_GHZ_CHANNEL_27) 717 return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) * 718 DFS_CHAN_SPACING_20MHZ); 719 else if (chan == DFS_5_GHZ_CHANNEL_170) 720 return DFS_CHAN_170_FREQ; 721 else 722 return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ); 723 } 724 EXPORT_SYMBOL(utils_dfs_chan_to_freq); 725