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_agile_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_agile_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_translate_radar_params(dfs, radar_found); 658 status = dfs_process_radar_ind(dfs, radar_found); 659 660 return status; 661 } 662 qdf_export_symbol(tgt_dfs_process_radar_ind); 663 664 #ifndef QCA_MCL_DFS_SUPPORT 665 QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 666 { 667 return QDF_STATUS_SUCCESS; 668 } 669 #else 670 QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 671 { 672 dfs_mlme_proc_cac(pdev, vdev_id); 673 674 return QDF_STATUS_SUCCESS; 675 } 676 #endif 677 qdf_export_symbol(tgt_dfs_cac_complete); 678 679 QDF_STATUS tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc *psoc) 680 { 681 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 682 683 if (!psoc) { 684 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 685 return QDF_STATUS_E_FAILURE; 686 } 687 688 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 689 if (!dfs_tx_ops) { 690 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null dfs_tx_ops"); 691 return QDF_STATUS_E_FAILURE; 692 } 693 694 if (dfs_tx_ops->dfs_reg_ev_handler) 695 return dfs_tx_ops->dfs_reg_ev_handler(psoc); 696 697 return QDF_STATUS_E_FAILURE; 698 } 699 qdf_export_symbol(tgt_dfs_reg_ev_handler); 700 701 QDF_STATUS tgt_dfs_stop(struct wlan_objmgr_pdev *pdev) 702 { 703 struct wlan_dfs *dfs; 704 705 if (!tgt_dfs_is_pdev_5ghz(pdev)) 706 return QDF_STATUS_SUCCESS; 707 708 dfs = wlan_pdev_get_dfs_obj(pdev); 709 if (!dfs) { 710 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 711 return QDF_STATUS_E_FAILURE; 712 } 713 714 dfs_stop(dfs); 715 716 return QDF_STATUS_SUCCESS; 717 } 718 qdf_export_symbol(tgt_dfs_stop); 719 720 QDF_STATUS tgt_dfs_process_emulate_bang_radar_cmd(struct wlan_objmgr_pdev *pdev, 721 struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test) 722 { 723 struct wlan_objmgr_psoc *psoc; 724 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 725 726 psoc = wlan_pdev_get_psoc(pdev); 727 if (!psoc) { 728 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 729 return QDF_STATUS_E_FAILURE; 730 } 731 732 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 733 if (dfs_tx_ops && dfs_tx_ops->dfs_process_emulate_bang_radar_cmd) 734 return dfs_tx_ops->dfs_process_emulate_bang_radar_cmd(pdev, 735 dfs_unit_test); 736 else 737 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 738 "dfs_tx_ops=%pK", dfs_tx_ops); 739 740 return QDF_STATUS_E_FAILURE; 741 } 742 qdf_export_symbol(tgt_dfs_process_emulate_bang_radar_cmd); 743 744 #ifdef QCA_MCL_DFS_SUPPORT 745 QDF_STATUS tgt_dfs_set_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev) 746 { 747 struct wlan_objmgr_psoc *psoc; 748 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 749 struct dfs_soc_priv_obj *soc_obj; 750 751 psoc = wlan_pdev_get_psoc(pdev); 752 if (!psoc) { 753 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 754 return QDF_STATUS_E_FAILURE; 755 } 756 757 soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 758 WLAN_UMAC_COMP_DFS); 759 if (!soc_obj) { 760 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 761 "Failed to get dfs psoc component"); 762 return QDF_STATUS_E_FAILURE; 763 } 764 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 765 if (dfs_tx_ops && dfs_tx_ops->dfs_set_phyerr_filter_offload) 766 return dfs_tx_ops->dfs_set_phyerr_filter_offload(pdev, 767 soc_obj->dfs_is_phyerr_filter_offload); 768 else 769 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 770 "dfs_tx_ops=%pK", dfs_tx_ops); 771 772 return QDF_STATUS_E_FAILURE; 773 } 774 qdf_export_symbol(tgt_dfs_set_phyerr_filter_offload); 775 #endif 776 777 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 778 QDF_STATUS 779 tgt_dfs_send_avg_params_to_fw(struct wlan_objmgr_pdev *pdev, 780 struct dfs_radar_found_params *params) 781 { 782 struct wlan_objmgr_psoc *psoc; 783 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 784 struct wlan_dfs *dfs; 785 QDF_STATUS status = QDF_STATUS_E_FAILURE; 786 787 dfs = wlan_pdev_get_dfs_obj(pdev); 788 if (!dfs) { 789 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 790 return status; 791 } 792 793 psoc = wlan_pdev_get_psoc(pdev); 794 if (!psoc) { 795 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 796 return status; 797 } 798 799 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 800 if (dfs_tx_ops && dfs_tx_ops->dfs_send_avg_radar_params_to_fw) 801 status = dfs_tx_ops->dfs_send_avg_radar_params_to_fw(pdev, 802 params); 803 804 if (QDF_IS_STATUS_SUCCESS(status)) { 805 dfs->dfs_average_params_sent = 1; 806 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 807 "Average radar parameters sent %d", 808 dfs->dfs_average_params_sent); 809 } 810 811 return status; 812 } 813 814 qdf_export_symbol(tgt_dfs_send_avg_params_to_fw); 815 816 QDF_STATUS tgt_dfs_action_on_status_from_fw(struct wlan_objmgr_pdev *pdev, 817 uint32_t *status) 818 { 819 struct wlan_dfs *dfs; 820 821 dfs = wlan_pdev_get_dfs_obj(pdev); 822 if (!dfs) { 823 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 824 return QDF_STATUS_E_FAILURE; 825 } 826 827 dfs_action_on_fw_radar_status_check(dfs, status); 828 829 return QDF_STATUS_SUCCESS; 830 } 831 832 qdf_export_symbol(tgt_dfs_action_on_status_from_fw); 833 834 QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev) 835 { 836 struct wlan_dfs *dfs; 837 838 if (!tgt_dfs_is_pdev_5ghz(pdev)) 839 return QDF_STATUS_SUCCESS; 840 841 dfs = wlan_pdev_get_dfs_obj(pdev); 842 if (!dfs) { 843 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 844 return QDF_STATUS_E_FAILURE; 845 } 846 847 dfs_reset_spoof_test(dfs); 848 849 return QDF_STATUS_SUCCESS; 850 } 851 852 qdf_export_symbol(tgt_dfs_reset_spoof_test); 853 #endif 854 855 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 856 QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev, 857 bool usenol) 858 { 859 struct wlan_objmgr_psoc *psoc; 860 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 861 862 psoc = wlan_pdev_get_psoc(pdev); 863 if (!psoc) { 864 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 865 return QDF_STATUS_E_FAILURE; 866 } 867 868 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 869 if (dfs_tx_ops && dfs_tx_ops->dfs_send_usenol_pdev_param) 870 return dfs_tx_ops->dfs_send_usenol_pdev_param(pdev, usenol); 871 872 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 873 "dfs_tx_ops=%pK", dfs_tx_ops); 874 875 return QDF_STATUS_E_FAILURE; 876 } 877 878 qdf_export_symbol(tgt_dfs_send_usenol_pdev_param); 879 880 QDF_STATUS tgt_dfs_send_subchan_marking(struct wlan_objmgr_pdev *pdev, 881 bool subchanmark) 882 { 883 struct wlan_objmgr_psoc *psoc; 884 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 885 886 psoc = wlan_pdev_get_psoc(pdev); 887 if (!psoc) { 888 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 889 return QDF_STATUS_E_FAILURE; 890 } 891 892 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 893 if (!dfs_tx_ops) { 894 dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, 895 "dfs_tx_ops=%pK", dfs_tx_ops); 896 return QDF_STATUS_E_FAILURE; 897 } 898 899 if (dfs_tx_ops->dfs_send_subchan_marking_pdev_param) 900 return dfs_tx_ops->dfs_send_subchan_marking_pdev_param( 901 pdev, subchanmark); 902 903 dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, 904 "dfs_send_subchan_marking_pdev_param is null"); 905 906 return QDF_STATUS_E_FAILURE; 907 } 908 909 qdf_export_symbol(tgt_dfs_send_subchan_marking); 910 #endif 911 912 void tgt_dfs_enable_stadfs(struct wlan_objmgr_pdev *pdev, bool val) 913 { 914 struct wlan_dfs *dfs; 915 916 dfs = wlan_pdev_get_dfs_obj(pdev); 917 if (!dfs) { 918 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 919 return; 920 } 921 922 dfs->dfs_is_stadfs_enabled = val; 923 } 924 925 bool tgt_dfs_is_stadfs_enabled(struct wlan_objmgr_pdev *pdev) 926 { 927 struct wlan_dfs *dfs; 928 929 dfs = wlan_pdev_get_dfs_obj(pdev); 930 if (!dfs) { 931 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 932 return false; 933 } 934 935 return dfs->dfs_is_stadfs_enabled; 936 } 937 938 #ifdef QCA_SUPPORT_AGILE_DFS 939 void tgt_dfs_set_fw_adfs_support(struct wlan_objmgr_pdev *pdev, 940 bool fw_adfs_support_160, 941 bool fw_adfs_support_non_160) 942 { 943 struct wlan_dfs *dfs; 944 945 dfs = wlan_pdev_get_dfs_obj(pdev); 946 if (!dfs) { 947 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 948 return; 949 } 950 951 dfs_set_fw_adfs_support(dfs, 952 fw_adfs_support_160, 953 fw_adfs_support_non_160); 954 } 955 956 qdf_export_symbol(tgt_dfs_set_fw_adfs_support); 957 #endif 958 959 void tgt_dfs_init_tmp_psoc_nol(struct wlan_objmgr_pdev *pdev, 960 uint8_t num_radios) 961 { 962 struct wlan_dfs *dfs; 963 964 dfs = wlan_pdev_get_dfs_obj(pdev); 965 if (!dfs) { 966 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 967 return; 968 } 969 970 dfs_init_tmp_psoc_nol(dfs, num_radios); 971 } 972 973 qdf_export_symbol(tgt_dfs_init_tmp_psoc_nol); 974 975 void tgt_dfs_deinit_tmp_psoc_nol(struct wlan_objmgr_pdev *pdev) 976 { 977 struct wlan_dfs *dfs; 978 979 dfs = wlan_pdev_get_dfs_obj(pdev); 980 if (!dfs) { 981 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 982 return; 983 } 984 985 dfs_deinit_tmp_psoc_nol(dfs); 986 } 987 988 qdf_export_symbol(tgt_dfs_deinit_tmp_psoc_nol); 989 990 void tgt_dfs_save_dfs_nol_in_psoc(struct wlan_objmgr_pdev *pdev, 991 uint8_t pdev_id) 992 { 993 struct wlan_dfs *dfs; 994 995 dfs = wlan_pdev_get_dfs_obj(pdev); 996 if (!dfs) { 997 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 998 return; 999 } 1000 1001 dfs_save_dfs_nol_in_psoc(dfs, pdev_id); 1002 } 1003 1004 qdf_export_symbol(tgt_dfs_save_dfs_nol_in_psoc); 1005 1006 void tgt_dfs_reinit_nol_from_psoc_copy(struct wlan_objmgr_pdev *pdev, 1007 uint8_t pdev_id, 1008 uint16_t low_5ghz_freq, 1009 uint16_t high_5ghz_freq) 1010 { 1011 struct wlan_dfs *dfs; 1012 1013 dfs = wlan_pdev_get_dfs_obj(pdev); 1014 if (!dfs) { 1015 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 1016 return; 1017 } 1018 1019 dfs_reinit_nol_from_psoc_copy(dfs, 1020 pdev_id, 1021 low_5ghz_freq, 1022 high_5ghz_freq); 1023 } 1024 1025 qdf_export_symbol(tgt_dfs_reinit_nol_from_psoc_copy); 1026 1027 void tgt_dfs_reinit_precac_lists(struct wlan_objmgr_pdev *src_pdev, 1028 struct wlan_objmgr_pdev *dest_pdev, 1029 uint16_t low_5g_freq, 1030 uint16_t high_5g_freq) 1031 { 1032 struct wlan_dfs *src_dfs, *dest_dfs; 1033 1034 src_dfs = wlan_pdev_get_dfs_obj(src_pdev); 1035 if (!src_dfs) { 1036 dfs_err(src_dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 1037 return; 1038 } 1039 dest_dfs = wlan_pdev_get_dfs_obj(dest_pdev); 1040 if (!dest_dfs) { 1041 dfs_err(dest_dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 1042 return; 1043 } 1044 1045 dfs_reinit_precac_lists(src_dfs, dest_dfs, low_5g_freq, high_5g_freq); 1046 } 1047 1048 void tgt_dfs_complete_deferred_tasks(struct wlan_objmgr_pdev *pdev) 1049 { 1050 struct wlan_dfs *dfs; 1051 1052 dfs = wlan_pdev_get_dfs_obj(pdev); 1053 if (!dfs) { 1054 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 1055 return; 1056 } 1057 1058 dfs_complete_deferred_tasks(dfs); 1059 } 1060