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