1 /* 2 * Copyright (c) 2016-2020 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_pdev_obj.h> 25 #include "wlan_dfs_tgt_api.h" 26 #include "wlan_dfs_utils_api.h" 27 #include "wlan_dfs_init_deinit_api.h" 28 #include "wlan_lmac_if_def.h" 29 #include "wlan_lmac_if_api.h" 30 #include "wlan_dfs_mlme_api.h" 31 #include "../../core/src/dfs.h" 32 #include "../../core/src/dfs_zero_cac.h" 33 #include "../../core/src/dfs_process_radar_found_ind.h" 34 #include <qdf_module.h> 35 #include "../../core/src/dfs_partial_offload_radar.h" 36 #ifdef QCA_MCL_DFS_SUPPORT 37 #include "wlan_mlme_ucfg_api.h" 38 #endif 39 40 struct wlan_lmac_if_dfs_tx_ops * 41 wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc *psoc) 42 { 43 return &((psoc->soc_cb.tx_ops.dfs_tx_ops)); 44 } 45 46 bool tgt_dfs_is_pdev_5ghz(struct wlan_objmgr_pdev *pdev) 47 { 48 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 49 struct wlan_objmgr_psoc *psoc; 50 bool is_5ghz = false; 51 QDF_STATUS status; 52 53 psoc = wlan_pdev_get_psoc(pdev); 54 if (!psoc) { 55 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 56 return false; 57 } 58 59 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 60 if (!(dfs_tx_ops && dfs_tx_ops->dfs_is_pdev_5ghz)) { 61 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "dfs_tx_ops is null"); 62 return false; 63 } 64 65 status = dfs_tx_ops->dfs_is_pdev_5ghz(pdev, &is_5ghz); 66 if (QDF_IS_STATUS_ERROR(status)) { 67 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Failed to get is_5ghz value"); 68 return false; 69 } 70 71 return is_5ghz; 72 } 73 74 #ifdef CONFIG_CHAN_NUM_API 75 QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev, 76 uint16_t dfs_ch_freq, 77 uint64_t dfs_ch_flags, 78 uint16_t dfs_ch_flagext, 79 uint8_t dfs_ch_ieee, 80 uint8_t dfs_ch_vhtop_ch_freq_seg1, 81 uint8_t dfs_ch_vhtop_ch_freq_seg2) 82 { 83 struct wlan_dfs *dfs; 84 85 if (!tgt_dfs_is_pdev_5ghz(pdev)) 86 return QDF_STATUS_SUCCESS; 87 88 dfs = wlan_pdev_get_dfs_obj(pdev); 89 if (!dfs) { 90 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 91 return QDF_STATUS_E_FAILURE; 92 } 93 94 dfs_set_current_channel(dfs, 95 dfs_ch_freq, 96 dfs_ch_flags, 97 dfs_ch_flagext, 98 dfs_ch_ieee, 99 dfs_ch_vhtop_ch_freq_seg1, 100 dfs_ch_vhtop_ch_freq_seg2); 101 102 return QDF_STATUS_SUCCESS; 103 } 104 qdf_export_symbol(tgt_dfs_set_current_channel); 105 #endif 106 107 #ifdef CONFIG_CHAN_FREQ_API 108 QDF_STATUS 109 tgt_dfs_set_current_channel_for_freq(struct wlan_objmgr_pdev *pdev, 110 uint16_t dfs_chan_freq, 111 uint64_t dfs_chan_flags, 112 uint16_t dfs_chan_flagext, 113 uint8_t dfs_chan_ieee, 114 uint8_t dfs_chan_vhtop_freq_seg1, 115 uint8_t dfs_chan_vhtop_freq_seg2, 116 uint16_t dfs_chan_mhz_freq_seg1, 117 uint16_t dfs_chan_mhz_freq_seg2) 118 { 119 struct wlan_dfs *dfs; 120 121 if (!tgt_dfs_is_pdev_5ghz(pdev)) 122 return QDF_STATUS_SUCCESS; 123 124 dfs = wlan_pdev_get_dfs_obj(pdev); 125 if (!dfs) { 126 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 127 return QDF_STATUS_E_FAILURE; 128 } 129 130 dfs_set_current_channel_for_freq(dfs, 131 dfs_chan_freq, 132 dfs_chan_flags, 133 dfs_chan_flagext, 134 dfs_chan_ieee, 135 dfs_chan_vhtop_freq_seg1, 136 dfs_chan_vhtop_freq_seg2, 137 dfs_chan_mhz_freq_seg1, 138 dfs_chan_mhz_freq_seg2); 139 140 return QDF_STATUS_SUCCESS; 141 } 142 143 qdf_export_symbol(tgt_dfs_set_current_channel_for_freq); 144 #endif 145 146 QDF_STATUS tgt_dfs_radar_enable(struct wlan_objmgr_pdev *pdev, 147 int no_cac, uint32_t opmode, bool enable) 148 { 149 struct wlan_dfs *dfs; 150 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 151 struct wlan_objmgr_psoc *psoc; 152 QDF_STATUS status; 153 154 dfs = wlan_pdev_get_dfs_obj(pdev); 155 if (!dfs) { 156 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 157 return QDF_STATUS_E_FAILURE; 158 } 159 160 if (!dfs->dfs_is_offload_enabled) { 161 if (enable) { 162 dfs_radar_enable(dfs, no_cac, opmode); 163 return QDF_STATUS_SUCCESS; 164 } else { 165 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, 166 "Disabling dfs not allowed for non-offload chips"); 167 return QDF_STATUS_E_FAILURE; 168 } 169 } 170 171 psoc = wlan_pdev_get_psoc(pdev); 172 if (!psoc) { 173 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 174 return QDF_STATUS_E_FAILURE; 175 } 176 177 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 178 if (!dfs_tx_ops) { 179 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_tx_ops is null"); 180 return QDF_STATUS_E_FAILURE; 181 } 182 183 status = dfs_tx_ops->dfs_send_offload_enable_cmd(pdev, enable); 184 if (QDF_IS_STATUS_ERROR(status)) 185 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 186 "Failed to enable dfs offload, pdev_id: %d", 187 wlan_objmgr_pdev_get_pdev_id(pdev)); 188 189 return status; 190 } 191 qdf_export_symbol(tgt_dfs_radar_enable); 192 193 void tgt_dfs_is_radar_enabled(struct wlan_objmgr_pdev *pdev, int *ignore_dfs) 194 { 195 struct wlan_dfs *dfs; 196 197 dfs = wlan_pdev_get_dfs_obj(pdev); 198 if (!dfs) { 199 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 200 return; 201 } 202 203 dfs_is_radar_enabled(dfs, ignore_dfs); 204 } 205 206 qdf_export_symbol(tgt_dfs_is_radar_enabled); 207 208 QDF_STATUS tgt_dfs_process_phyerr(struct wlan_objmgr_pdev *pdev, 209 void *buf, 210 uint16_t datalen, 211 uint8_t r_rssi, 212 uint8_t r_ext_rssi, 213 uint32_t r_rs_tstamp, 214 uint64_t r_fulltsf) 215 { 216 struct wlan_dfs *dfs; 217 218 dfs = wlan_pdev_get_dfs_obj(pdev); 219 if (!dfs) { 220 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 221 return QDF_STATUS_E_FAILURE; 222 } 223 224 if (!dfs->dfs_is_offload_enabled) 225 dfs_process_phyerr(dfs, buf, datalen, r_rssi, 226 r_ext_rssi, r_rs_tstamp, r_fulltsf); 227 else 228 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 229 "Unexpect phyerror as DFS is offloaded, pdev_id: %d", 230 wlan_objmgr_pdev_get_pdev_id(pdev)); 231 232 return QDF_STATUS_SUCCESS; 233 } 234 qdf_export_symbol(tgt_dfs_process_phyerr); 235 236 #ifdef QCA_MCL_DFS_SUPPORT 237 QDF_STATUS tgt_dfs_process_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev, 238 struct radar_event_info 239 *wlan_radar_event) 240 { 241 struct wlan_dfs *dfs; 242 243 dfs = wlan_pdev_get_dfs_obj(pdev); 244 if (!dfs) { 245 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 246 return QDF_STATUS_E_FAILURE; 247 } 248 if (!dfs->dfs_is_offload_enabled) 249 dfs_process_phyerr_filter_offload(dfs, wlan_radar_event); 250 else 251 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 252 "Unexpect phyerror as DFS is offloaded, pdev_id: %d", 253 wlan_objmgr_pdev_get_pdev_id(pdev)); 254 255 return QDF_STATUS_SUCCESS; 256 } 257 qdf_export_symbol(tgt_dfs_process_phyerr_filter_offload); 258 259 QDF_STATUS tgt_dfs_is_phyerr_filter_offload(struct wlan_objmgr_psoc *psoc, 260 bool *is_phyerr_filter_offload) 261 { 262 struct dfs_soc_priv_obj *soc_obj; 263 264 if (!psoc) { 265 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 266 return QDF_STATUS_E_FAILURE; 267 } 268 269 soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 270 WLAN_UMAC_COMP_DFS); 271 if (!soc_obj) { 272 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 273 "Failed to get dfs psoc component"); 274 return QDF_STATUS_E_FAILURE; 275 } 276 277 *is_phyerr_filter_offload = soc_obj->dfs_is_phyerr_filter_offload; 278 279 return QDF_STATUS_SUCCESS; 280 } 281 qdf_export_symbol(tgt_dfs_is_phyerr_filter_offload); 282 #else 283 QDF_STATUS tgt_dfs_process_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev, 284 struct radar_event_info 285 *wlan_radar_event) 286 { 287 return QDF_STATUS_SUCCESS; 288 } 289 290 QDF_STATUS tgt_dfs_is_phyerr_filter_offload(struct wlan_objmgr_psoc *psoc, 291 bool *is_phyerr_filter_offload) 292 { 293 return QDF_STATUS_SUCCESS; 294 } 295 #endif 296 297 QDF_STATUS tgt_dfs_is_precac_timer_running(struct wlan_objmgr_pdev *pdev, 298 bool *is_precac_timer_running) 299 { 300 struct wlan_dfs *dfs; 301 302 if (!tgt_dfs_is_pdev_5ghz(pdev)) 303 return QDF_STATUS_SUCCESS; 304 305 dfs = wlan_pdev_get_dfs_obj(pdev); 306 if (!dfs) { 307 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 308 return QDF_STATUS_E_FAILURE; 309 } 310 311 *is_precac_timer_running = dfs_is_precac_timer_running(dfs); 312 313 return QDF_STATUS_SUCCESS; 314 } 315 qdf_export_symbol(tgt_dfs_is_precac_timer_running); 316 317 QDF_STATUS tgt_dfs_get_radars(struct wlan_objmgr_pdev *pdev) 318 { 319 struct wlan_dfs *dfs; 320 321 if (!tgt_dfs_is_pdev_5ghz(pdev)) 322 return QDF_STATUS_SUCCESS; 323 324 dfs = wlan_pdev_get_dfs_obj(pdev); 325 if (!dfs) { 326 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 327 return QDF_STATUS_E_FAILURE; 328 } 329 330 if (!dfs->dfs_is_offload_enabled) 331 dfs_get_radars(dfs); 332 333 return QDF_STATUS_SUCCESS; 334 } 335 qdf_export_symbol(tgt_dfs_get_radars); 336 337 QDF_STATUS tgt_dfs_destroy_object(struct wlan_objmgr_pdev *pdev) 338 { 339 struct wlan_dfs *dfs; 340 341 dfs = wlan_pdev_get_dfs_obj(pdev); 342 if (!dfs) { 343 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 344 return QDF_STATUS_E_FAILURE; 345 } 346 347 dfs_destroy_object(dfs); 348 349 return QDF_STATUS_SUCCESS; 350 } 351 qdf_export_symbol(tgt_dfs_destroy_object); 352 353 #ifdef QCA_MCL_DFS_SUPPORT 354 QDF_STATUS tgt_dfs_set_tx_leakage_threshold(struct wlan_objmgr_pdev *pdev) 355 { 356 struct wlan_dfs *dfs; 357 uint32_t tx_leakage_threshold = 0; 358 struct wlan_objmgr_psoc *psoc; 359 360 psoc = wlan_pdev_get_psoc(pdev); 361 if (!psoc) { 362 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 363 return QDF_STATUS_E_FAILURE; 364 } 365 366 dfs = wlan_pdev_get_dfs_obj(pdev); 367 if (!dfs) { 368 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 369 return QDF_STATUS_E_FAILURE; 370 } 371 ucfg_mlme_get_sap_tx_leakage_threshold(psoc, 372 &tx_leakage_threshold); 373 374 dfs->tx_leakage_threshold = tx_leakage_threshold; 375 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, 376 "dfs tx_leakage_threshold = %d", dfs->tx_leakage_threshold); 377 378 return QDF_STATUS_SUCCESS; 379 } 380 qdf_export_symbol(tgt_dfs_set_tx_leakage_threshold); 381 #endif 382 383 QDF_STATUS tgt_dfs_control(struct wlan_objmgr_pdev *pdev, 384 u_int id, 385 void *indata, 386 uint32_t insize, 387 void *outdata, 388 uint32_t *outsize, 389 int *error) 390 { 391 struct wlan_dfs *dfs; 392 393 dfs = wlan_pdev_get_dfs_obj(pdev); 394 if (!dfs) { 395 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 396 return QDF_STATUS_E_FAILURE; 397 } 398 399 *error = dfs_control(dfs, id, indata, insize, outdata, outsize); 400 401 return QDF_STATUS_SUCCESS; 402 } 403 qdf_export_symbol(tgt_dfs_control); 404 405 #ifdef QCA_SUPPORT_AGILE_DFS 406 QDF_STATUS tgt_dfs_agile_precac_start(struct wlan_objmgr_pdev *pdev) 407 { 408 struct wlan_dfs *dfs; 409 410 dfs = wlan_pdev_get_dfs_obj(pdev); 411 if (!dfs) { 412 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 413 return QDF_STATUS_E_FAILURE; 414 } 415 416 dfs_agile_precac_start(dfs); 417 418 return QDF_STATUS_SUCCESS; 419 } 420 #else 421 QDF_STATUS tgt_dfs_agile_precac_start(struct wlan_objmgr_pdev *pdev) 422 { 423 return QDF_STATUS_SUCCESS; 424 } 425 #endif 426 qdf_export_symbol(tgt_dfs_agile_precac_start); 427 428 #ifdef QCA_SUPPORT_AGILE_DFS 429 #ifdef CONFIG_CHAN_FREQ_API 430 QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, 431 int agile_precac_state) 432 { 433 struct wlan_dfs *dfs; 434 struct dfs_soc_priv_obj *dfs_soc; 435 bool is_precac_running_on_given_pdev = false; 436 int i; 437 438 if (!tgt_dfs_is_pdev_5ghz(pdev)) 439 return QDF_STATUS_SUCCESS; 440 441 dfs = wlan_pdev_get_dfs_obj(pdev); 442 if (!dfs) { 443 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 444 return QDF_STATUS_E_FAILURE; 445 } 446 447 dfs_soc = dfs->dfs_soc_obj; 448 for (i = 0; i < dfs_soc->num_dfs_privs; i++) { 449 if (dfs_soc->dfs_priv[i].dfs == dfs) { 450 /* Set the pdev state to given value. */ 451 dfs_soc->dfs_priv[i].agile_precac_active = 452 agile_precac_state; 453 /* If the pdev state is changed to inactive, 454 * reset the agile channel. 455 */ 456 if (!agile_precac_state) 457 dfs->dfs_agile_precac_freq_mhz = 0; 458 if (dfs_soc->cur_precac_dfs_index == i) 459 is_precac_running_on_given_pdev = true; 460 } 461 } 462 463 /* If preCAC is running on this pdev and the agile_precac_state 464 * is set to false, set the global state in dfs_soc_obj to false. 465 * If this global state is not set to false, then preCAC will not be 466 * started the next time this pdev becomes active. 467 */ 468 if (is_precac_running_on_given_pdev && !agile_precac_state) 469 dfs_soc->precac_state_started = PRECAC_NOT_STARTED; 470 471 return QDF_STATUS_SUCCESS; 472 } 473 #else 474 #ifdef CONFIG_CHAN_NUM_API 475 QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, 476 int agile_precac_state) 477 { 478 struct wlan_dfs *dfs; 479 struct dfs_soc_priv_obj *dfs_soc; 480 bool is_precac_running_on_given_pdev = false; 481 int i; 482 483 if (!tgt_dfs_is_pdev_5ghz(pdev)) 484 return QDF_STATUS_SUCCESS; 485 486 dfs = wlan_pdev_get_dfs_obj(pdev); 487 if (!dfs) { 488 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 489 return QDF_STATUS_E_FAILURE; 490 } 491 492 dfs_soc = dfs->dfs_soc_obj; 493 for (i = 0; i < dfs_soc->num_dfs_privs; i++) { 494 if (dfs_soc->dfs_priv[i].dfs == dfs) { 495 /* Set the pdev state to given value. */ 496 dfs_soc->dfs_priv[i].agile_precac_active = 497 agile_precac_state; 498 /* If the pdev state is changed to inactive, 499 * reset the agile channel. 500 */ 501 if (!agile_precac_state) 502 dfs->dfs_agile_precac_freq = 0; 503 if (dfs_soc->cur_precac_dfs_index == i) 504 is_precac_running_on_given_pdev = true; 505 } 506 } 507 508 /* If preCAC is running on this pdev and the agile_precac_state 509 * is set to false, set the global state in dfs_soc_obj to false. 510 * If this global state is not set to false, then preCAC will not be 511 * started the next time this pdev becomes active. 512 */ 513 if (is_precac_running_on_given_pdev && !agile_precac_state) 514 dfs_soc->precac_state_started = PRECAC_NOT_STARTED; 515 516 return QDF_STATUS_SUCCESS; 517 } 518 #endif 519 #endif 520 521 #else 522 QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, 523 int agile_precac_state) 524 { 525 return QDF_STATUS_SUCCESS; 526 } 527 #endif 528 qdf_export_symbol(tgt_dfs_set_agile_precac_state); 529 530 #ifdef QCA_SUPPORT_AGILE_DFS 531 QDF_STATUS tgt_dfs_ocac_complete(struct wlan_objmgr_pdev *pdev, 532 struct vdev_adfs_complete_status *adfs_status) 533 { 534 struct wlan_dfs *dfs; 535 QDF_STATUS status = QDF_STATUS_E_FAILURE; 536 537 if (!pdev) { 538 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 539 return status; 540 } 541 542 dfs = wlan_pdev_get_dfs_obj(pdev); 543 if (!dfs) { 544 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); 545 return status; 546 } 547 548 dfs_process_ocac_complete(pdev, adfs_status->ocac_status, 549 adfs_status->center_freq); 550 551 return QDF_STATUS_SUCCESS; 552 } 553 #else 554 QDF_STATUS tgt_dfs_ocac_complete(struct wlan_objmgr_pdev *pdev, 555 struct vdev_adfs_complete_status *adfs_status) 556 { 557 return QDF_STATUS_SUCCESS; 558 } 559 #endif 560 qdf_export_symbol(tgt_dfs_ocac_complete); 561 562 #ifdef CONFIG_CHAN_NUM_API 563 QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, 564 uint32_t chan_mode, 565 uint8_t ch_freq_seg1, 566 uint32_t *cfreq1, 567 uint32_t *cfreq2, 568 uint32_t *phy_mode, 569 bool *dfs_set_cfreq2, 570 bool *set_agile) 571 { 572 struct wlan_dfs *dfs; 573 574 dfs = wlan_pdev_get_dfs_obj(pdev); 575 if (!dfs) { 576 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 577 return QDF_STATUS_E_FAILURE; 578 } 579 580 dfs_find_vht80_chan_for_precac(dfs, 581 chan_mode, 582 ch_freq_seg1, 583 cfreq1, 584 cfreq2, 585 phy_mode, 586 dfs_set_cfreq2, 587 set_agile); 588 589 return QDF_STATUS_SUCCESS; 590 } 591 qdf_export_symbol(tgt_dfs_find_vht80_chan_for_precac); 592 #endif 593 594 #ifdef CONFIG_CHAN_FREQ_API 595 QDF_STATUS 596 tgt_dfs_find_vht80_precac_chan_freq(struct wlan_objmgr_pdev *pdev, 597 uint32_t chan_mode, 598 uint16_t chan_freq_seg1_mhz, 599 uint32_t *cfreq1, 600 uint32_t *cfreq2, 601 uint32_t *phy_mode, 602 bool *dfs_set_cfreq2, 603 bool *set_agile) 604 { 605 struct wlan_dfs *dfs; 606 607 dfs = wlan_pdev_get_dfs_obj(pdev); 608 if (!dfs) { 609 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 610 return QDF_STATUS_E_FAILURE; 611 } 612 613 dfs_find_vht80_chan_for_precac_for_freq(dfs, 614 chan_mode, 615 chan_freq_seg1_mhz, 616 cfreq1, 617 cfreq2, 618 phy_mode, 619 dfs_set_cfreq2, 620 set_agile); 621 622 return QDF_STATUS_SUCCESS; 623 } 624 625 qdf_export_symbol(tgt_dfs_find_vht80_precac_chan_freq); 626 #endif 627 628 QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev, 629 struct radar_found_info *radar_found) 630 { 631 struct wlan_dfs *dfs; 632 QDF_STATUS status = QDF_STATUS_E_FAILURE; 633 634 if (!pdev) { 635 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 636 return status; 637 } 638 639 dfs = wlan_pdev_get_dfs_obj(pdev); 640 if (!dfs) { 641 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); 642 return status; 643 } 644 645 dfs->dfs_radar_found_for_fo = 1; 646 status = dfs_process_radar_ind(dfs, radar_found); 647 dfs->dfs_radar_found_for_fo = 0; 648 649 return status; 650 } 651 qdf_export_symbol(tgt_dfs_process_radar_ind); 652 653 #ifndef QCA_MCL_DFS_SUPPORT 654 QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 655 { 656 return QDF_STATUS_SUCCESS; 657 } 658 #else 659 QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 660 { 661 dfs_mlme_proc_cac(pdev, vdev_id); 662 663 return QDF_STATUS_SUCCESS; 664 } 665 #endif 666 qdf_export_symbol(tgt_dfs_cac_complete); 667 668 QDF_STATUS tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc *psoc) 669 { 670 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 671 672 if (!psoc) { 673 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 674 return QDF_STATUS_E_FAILURE; 675 } 676 677 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 678 if (!dfs_tx_ops) { 679 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null dfs_tx_ops"); 680 return QDF_STATUS_E_FAILURE; 681 } 682 683 if (dfs_tx_ops->dfs_reg_ev_handler) 684 return dfs_tx_ops->dfs_reg_ev_handler(psoc); 685 686 return QDF_STATUS_E_FAILURE; 687 } 688 qdf_export_symbol(tgt_dfs_reg_ev_handler); 689 690 QDF_STATUS tgt_dfs_stop(struct wlan_objmgr_pdev *pdev) 691 { 692 struct wlan_dfs *dfs; 693 694 if (!tgt_dfs_is_pdev_5ghz(pdev)) 695 return QDF_STATUS_SUCCESS; 696 697 dfs = wlan_pdev_get_dfs_obj(pdev); 698 if (!dfs) { 699 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 700 return QDF_STATUS_E_FAILURE; 701 } 702 703 dfs_stop(dfs); 704 705 return QDF_STATUS_SUCCESS; 706 } 707 qdf_export_symbol(tgt_dfs_stop); 708 709 QDF_STATUS tgt_dfs_process_emulate_bang_radar_cmd(struct wlan_objmgr_pdev *pdev, 710 struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test) 711 { 712 struct wlan_objmgr_psoc *psoc; 713 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 714 715 psoc = wlan_pdev_get_psoc(pdev); 716 if (!psoc) { 717 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 718 return QDF_STATUS_E_FAILURE; 719 } 720 721 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 722 if (dfs_tx_ops && dfs_tx_ops->dfs_process_emulate_bang_radar_cmd) 723 return dfs_tx_ops->dfs_process_emulate_bang_radar_cmd(pdev, 724 dfs_unit_test); 725 else 726 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 727 "dfs_tx_ops=%pK", dfs_tx_ops); 728 729 return QDF_STATUS_E_FAILURE; 730 } 731 qdf_export_symbol(tgt_dfs_process_emulate_bang_radar_cmd); 732 733 #ifdef QCA_MCL_DFS_SUPPORT 734 QDF_STATUS tgt_dfs_set_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev) 735 { 736 struct wlan_objmgr_psoc *psoc; 737 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 738 struct dfs_soc_priv_obj *soc_obj; 739 740 psoc = wlan_pdev_get_psoc(pdev); 741 if (!psoc) { 742 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 743 return QDF_STATUS_E_FAILURE; 744 } 745 746 soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 747 WLAN_UMAC_COMP_DFS); 748 if (!soc_obj) { 749 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 750 "Failed to get dfs psoc component"); 751 return QDF_STATUS_E_FAILURE; 752 } 753 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 754 if (dfs_tx_ops && dfs_tx_ops->dfs_set_phyerr_filter_offload) 755 return dfs_tx_ops->dfs_set_phyerr_filter_offload(pdev, 756 soc_obj->dfs_is_phyerr_filter_offload); 757 else 758 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 759 "dfs_tx_ops=%pK", dfs_tx_ops); 760 761 return QDF_STATUS_E_FAILURE; 762 } 763 qdf_export_symbol(tgt_dfs_set_phyerr_filter_offload); 764 #endif 765 766 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 767 QDF_STATUS 768 tgt_dfs_send_avg_params_to_fw(struct wlan_objmgr_pdev *pdev, 769 struct dfs_radar_found_params *params) 770 { 771 struct wlan_objmgr_psoc *psoc; 772 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 773 struct wlan_dfs *dfs; 774 QDF_STATUS status = QDF_STATUS_E_FAILURE; 775 776 dfs = wlan_pdev_get_dfs_obj(pdev); 777 if (!dfs) { 778 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 779 return status; 780 } 781 782 psoc = wlan_pdev_get_psoc(pdev); 783 if (!psoc) { 784 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 785 return status; 786 } 787 788 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 789 if (dfs_tx_ops && dfs_tx_ops->dfs_send_avg_radar_params_to_fw) 790 status = dfs_tx_ops->dfs_send_avg_radar_params_to_fw(pdev, 791 params); 792 793 if (QDF_IS_STATUS_SUCCESS(status)) { 794 dfs->dfs_average_params_sent = 1; 795 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 796 "Average radar parameters sent %d", 797 dfs->dfs_average_params_sent); 798 } 799 800 return status; 801 } 802 803 qdf_export_symbol(tgt_dfs_send_avg_params_to_fw); 804 805 QDF_STATUS tgt_dfs_action_on_status_from_fw(struct wlan_objmgr_pdev *pdev, 806 uint32_t *status) 807 { 808 struct wlan_dfs *dfs; 809 810 dfs = wlan_pdev_get_dfs_obj(pdev); 811 if (!dfs) { 812 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 813 return QDF_STATUS_E_FAILURE; 814 } 815 816 dfs_action_on_fw_radar_status_check(dfs, status); 817 818 return QDF_STATUS_SUCCESS; 819 } 820 821 qdf_export_symbol(tgt_dfs_action_on_status_from_fw); 822 823 QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev) 824 { 825 struct wlan_dfs *dfs; 826 827 if (!tgt_dfs_is_pdev_5ghz(pdev)) 828 return QDF_STATUS_SUCCESS; 829 830 dfs = wlan_pdev_get_dfs_obj(pdev); 831 if (!dfs) { 832 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 833 return QDF_STATUS_E_FAILURE; 834 } 835 836 dfs_reset_spoof_test(dfs); 837 838 return QDF_STATUS_SUCCESS; 839 } 840 841 qdf_export_symbol(tgt_dfs_reset_spoof_test); 842 #endif 843 844 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 845 QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev, 846 bool usenol) 847 { 848 struct wlan_objmgr_psoc *psoc; 849 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 850 851 psoc = wlan_pdev_get_psoc(pdev); 852 if (!psoc) { 853 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 854 return QDF_STATUS_E_FAILURE; 855 } 856 857 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 858 if (dfs_tx_ops && dfs_tx_ops->dfs_send_usenol_pdev_param) 859 return dfs_tx_ops->dfs_send_usenol_pdev_param(pdev, usenol); 860 861 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 862 "dfs_tx_ops=%pK", dfs_tx_ops); 863 864 return QDF_STATUS_E_FAILURE; 865 } 866 867 qdf_export_symbol(tgt_dfs_send_usenol_pdev_param); 868 869 QDF_STATUS tgt_dfs_send_subchan_marking(struct wlan_objmgr_pdev *pdev, 870 bool subchanmark) 871 { 872 struct wlan_objmgr_psoc *psoc; 873 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 874 875 psoc = wlan_pdev_get_psoc(pdev); 876 if (!psoc) { 877 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 878 return QDF_STATUS_E_FAILURE; 879 } 880 881 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 882 if (!dfs_tx_ops) { 883 dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, 884 "dfs_tx_ops=%pK", dfs_tx_ops); 885 return QDF_STATUS_E_FAILURE; 886 } 887 888 if (dfs_tx_ops->dfs_send_subchan_marking_pdev_param) 889 return dfs_tx_ops->dfs_send_subchan_marking_pdev_param( 890 pdev, subchanmark); 891 892 dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, 893 "dfs_send_subchan_marking_pdev_param is null"); 894 895 return QDF_STATUS_E_FAILURE; 896 } 897 898 qdf_export_symbol(tgt_dfs_send_subchan_marking); 899 #endif 900 901 void tgt_dfs_enable_stadfs(struct wlan_objmgr_pdev *pdev, bool val) 902 { 903 struct wlan_dfs *dfs; 904 905 dfs = wlan_pdev_get_dfs_obj(pdev); 906 if (!dfs) { 907 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 908 return; 909 } 910 911 dfs->dfs_is_stadfs_enabled = val; 912 } 913 914 bool tgt_dfs_is_stadfs_enabled(struct wlan_objmgr_pdev *pdev) 915 { 916 struct wlan_dfs *dfs; 917 918 dfs = wlan_pdev_get_dfs_obj(pdev); 919 if (!dfs) { 920 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 921 return false; 922 } 923 924 return dfs->dfs_is_stadfs_enabled; 925 } 926 927 #ifdef QCA_SUPPORT_AGILE_DFS 928 void tgt_dfs_set_fw_adfs_support(struct wlan_objmgr_pdev *pdev, 929 bool fw_adfs_support_160, 930 bool fw_adfs_support_non_160) 931 { 932 struct wlan_dfs *dfs; 933 934 dfs = wlan_pdev_get_dfs_obj(pdev); 935 if (!dfs) { 936 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 937 return; 938 } 939 940 dfs_set_fw_adfs_support(dfs, 941 fw_adfs_support_160, 942 fw_adfs_support_non_160); 943 } 944 945 qdf_export_symbol(tgt_dfs_set_fw_adfs_support); 946 #endif 947 948 void tgt_dfs_init_tmp_psoc_nol(struct wlan_objmgr_pdev *pdev, 949 uint8_t num_radios) 950 { 951 struct wlan_dfs *dfs; 952 953 dfs = wlan_pdev_get_dfs_obj(pdev); 954 if (!dfs) { 955 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 956 return; 957 } 958 959 dfs_init_tmp_psoc_nol(dfs, num_radios); 960 } 961 962 qdf_export_symbol(tgt_dfs_init_tmp_psoc_nol); 963 964 void tgt_dfs_deinit_tmp_psoc_nol(struct wlan_objmgr_pdev *pdev) 965 { 966 struct wlan_dfs *dfs; 967 968 dfs = wlan_pdev_get_dfs_obj(pdev); 969 if (!dfs) { 970 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 971 return; 972 } 973 974 dfs_deinit_tmp_psoc_nol(dfs); 975 } 976 977 qdf_export_symbol(tgt_dfs_deinit_tmp_psoc_nol); 978 979 void tgt_dfs_save_dfs_nol_in_psoc(struct wlan_objmgr_pdev *pdev, 980 uint8_t pdev_id, 981 uint16_t low_5ghz_freq, 982 uint16_t high_5ghz_freq) 983 { 984 struct wlan_dfs *dfs; 985 986 dfs = wlan_pdev_get_dfs_obj(pdev); 987 if (!dfs) { 988 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 989 return; 990 } 991 992 dfs_save_dfs_nol_in_psoc(dfs, pdev_id, low_5ghz_freq, high_5ghz_freq); 993 } 994 995 qdf_export_symbol(tgt_dfs_save_dfs_nol_in_psoc); 996 997 void tgt_dfs_reinit_nol_from_psoc_copy(struct wlan_objmgr_pdev *pdev, 998 uint8_t pdev_id) 999 { 1000 struct wlan_dfs *dfs; 1001 1002 dfs = wlan_pdev_get_dfs_obj(pdev); 1003 if (!dfs) { 1004 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 1005 return; 1006 } 1007 1008 dfs_reinit_nol_from_psoc_copy(dfs, pdev_id); 1009 } 1010 1011 qdf_export_symbol(tgt_dfs_reinit_nol_from_psoc_copy); 1012 1013 void tgt_dfs_reinit_precac_lists(struct wlan_objmgr_pdev *src_pdev, 1014 struct wlan_objmgr_pdev *dest_pdev, 1015 uint16_t low_5g_freq, 1016 uint16_t high_5g_freq) 1017 { 1018 struct wlan_dfs *src_dfs, *dest_dfs; 1019 1020 src_dfs = wlan_pdev_get_dfs_obj(src_pdev); 1021 if (!src_dfs) { 1022 dfs_err(src_dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 1023 return; 1024 } 1025 dest_dfs = wlan_pdev_get_dfs_obj(dest_pdev); 1026 if (!dest_dfs) { 1027 dfs_err(dest_dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 1028 return; 1029 } 1030 1031 dfs_reinit_precac_lists(src_dfs, dest_dfs, low_5g_freq, high_5g_freq); 1032 } 1033 1034 void tgt_dfs_complete_deferred_tasks(struct wlan_objmgr_pdev *pdev) 1035 { 1036 struct wlan_dfs *dfs; 1037 1038 dfs = wlan_pdev_get_dfs_obj(pdev); 1039 if (!dfs) { 1040 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 1041 return; 1042 } 1043 1044 dfs_complete_deferred_tasks(dfs); 1045 } 1046