1 /* 2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: API for interacting with target interface. 21 * 22 */ 23 24 #include "target_if.h" 25 #include "target_type.h" 26 #ifdef WLAN_ATF_ENABLE 27 #include "target_if_atf.h" 28 #endif 29 #ifdef WLAN_SA_API_ENABLE 30 #include "target_if_sa_api.h" 31 #endif 32 #ifdef WLAN_CFR_ENABLE 33 #include "target_if_cfr.h" 34 #endif 35 #ifdef WLAN_CONV_SPECTRAL_ENABLE 36 #include "target_if_spectral.h" 37 #endif 38 #include <target_if_reg.h> 39 #include <target_if_scan.h> 40 #include <target_if_ftm.h> 41 #ifdef DFS_COMPONENT_ENABLE 42 #include <target_if_dfs.h> 43 #endif 44 45 #ifdef CONVERGED_P2P_ENABLE 46 #include "target_if_p2p.h" 47 #endif 48 49 #ifdef WIFI_POS_CONVERGED 50 #include "target_if_wifi_pos.h" 51 #endif 52 53 #ifdef FEATURE_WLAN_TDLS 54 #include "target_if_tdls.h" 55 #endif 56 #ifdef QCA_SUPPORT_SON 57 #include <target_if_son.h> 58 #endif 59 #ifdef WLAN_OFFCHAN_TXRX_ENABLE 60 #include <target_if_offchan_txrx_api.h> 61 #endif 62 #ifdef WLAN_SUPPORT_GREEN_AP 63 #include <target_if_green_ap.h> 64 #endif 65 #include <init_deinit_lmac.h> 66 #include <service_ready_util.h> 67 68 #ifdef DIRECT_BUF_RX_ENABLE 69 #include <target_if_direct_buf_rx_api.h> 70 #endif 71 72 #ifdef WLAN_SUPPORT_FILS 73 #include <target_if_fd.h> 74 #endif 75 #include "qdf_module.h" 76 77 #include <target_if_cp_stats.h> 78 #ifdef CRYPTO_SET_KEY_CONVERGED 79 #include <target_if_crypto.h> 80 #endif 81 #include <target_if_vdev_mgr_tx_ops.h> 82 83 #ifdef FEATURE_COEX 84 #include <target_if_coex.h> 85 #endif 86 87 #ifdef DCS_INTERFERENCE_DETECTION 88 #include <target_if_dcs.h> 89 #endif 90 91 static struct target_if_ctx *g_target_if_ctx; 92 93 struct target_if_ctx *target_if_get_ctx() 94 { 95 return g_target_if_ctx; 96 } 97 98 struct wlan_objmgr_psoc *target_if_get_psoc_from_scn_hdl(void *scn_handle) 99 { 100 struct wlan_objmgr_psoc *psoc; 101 102 qdf_spin_lock_bh(&g_target_if_ctx->lock); 103 if (scn_handle && g_target_if_ctx->get_psoc_hdl_cb) 104 psoc = g_target_if_ctx->get_psoc_hdl_cb(scn_handle); 105 else 106 psoc = NULL; 107 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 108 109 return psoc; 110 } 111 112 struct wlan_objmgr_pdev *target_if_get_pdev_from_scn_hdl(void *scn_handle) 113 { 114 struct wlan_objmgr_pdev *pdev; 115 116 qdf_spin_lock_bh(&g_target_if_ctx->lock); 117 if (scn_handle && g_target_if_ctx->get_pdev_hdl_cb) 118 pdev = g_target_if_ctx->get_pdev_hdl_cb(scn_handle); 119 else 120 pdev = NULL; 121 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 122 123 return pdev; 124 } 125 126 #ifdef DIRECT_BUF_RX_ENABLE 127 static QDF_STATUS target_if_direct_buf_rx_init(void) 128 { 129 return direct_buf_rx_init(); 130 } 131 132 static QDF_STATUS target_if_direct_buf_rx_deinit(void) 133 { 134 return direct_buf_rx_deinit(); 135 } 136 #else 137 static QDF_STATUS target_if_direct_buf_rx_init(void) 138 { 139 return QDF_STATUS_SUCCESS; 140 } 141 142 static QDF_STATUS target_if_direct_buf_rx_deinit(void) 143 { 144 return QDF_STATUS_SUCCESS; 145 } 146 #endif /* DIRECT_BUF_RX_ENABLE */ 147 148 QDF_STATUS target_if_init(get_psoc_handle_callback psoc_hdl_cb) 149 { 150 g_target_if_ctx = qdf_mem_malloc(sizeof(*g_target_if_ctx)); 151 if (!g_target_if_ctx) { 152 QDF_ASSERT(0); 153 return QDF_STATUS_E_NOMEM; 154 } 155 156 qdf_spinlock_create(&g_target_if_ctx->lock); 157 158 qdf_spin_lock_bh(&g_target_if_ctx->lock); 159 g_target_if_ctx->magic = TGT_MAGIC; 160 g_target_if_ctx->get_psoc_hdl_cb = psoc_hdl_cb; 161 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 162 163 target_if_direct_buf_rx_init(); 164 165 return QDF_STATUS_SUCCESS; 166 } 167 168 QDF_STATUS target_if_deinit(void) 169 { 170 if (!g_target_if_ctx) { 171 QDF_ASSERT(0); 172 target_if_err("target if ctx is null"); 173 return QDF_STATUS_E_INVAL; 174 } 175 176 qdf_spin_lock_bh(&g_target_if_ctx->lock); 177 g_target_if_ctx->magic = 0; 178 g_target_if_ctx->get_psoc_hdl_cb = NULL; 179 g_target_if_ctx->get_pdev_hdl_cb = NULL; 180 g_target_if_ctx->service_ready_cb = NULL; 181 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 182 183 qdf_spinlock_destroy(&g_target_if_ctx->lock); 184 qdf_mem_free(g_target_if_ctx); 185 g_target_if_ctx = NULL; 186 187 target_if_direct_buf_rx_deinit(); 188 189 return QDF_STATUS_SUCCESS; 190 } 191 192 qdf_export_symbol(target_if_deinit); 193 194 QDF_STATUS target_if_store_pdev_target_if_ctx( 195 get_pdev_handle_callback pdev_hdl_cb) 196 { 197 if (!g_target_if_ctx) { 198 QDF_ASSERT(0); 199 target_if_err("target if ctx is null"); 200 return QDF_STATUS_E_INVAL; 201 } 202 203 qdf_spin_lock_bh(&g_target_if_ctx->lock); 204 g_target_if_ctx->get_pdev_hdl_cb = pdev_hdl_cb; 205 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 206 207 return QDF_STATUS_SUCCESS; 208 } 209 210 #ifndef WLAN_OFFCHAN_TXRX_ENABLE 211 static void target_if_offchan_txrx_ops_register( 212 struct wlan_lmac_if_tx_ops *tx_ops) 213 { 214 } 215 #endif /* WLAN_OFFCHAN_TXRX_ENABLE */ 216 217 #ifndef WLAN_ATF_ENABLE 218 static void target_if_atf_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 219 { 220 } 221 #endif /* WLAN_ATF_ENABLE */ 222 223 #ifndef WLAN_SA_API_ENABLE 224 static void target_if_sa_api_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 225 { 226 } 227 #endif /* WLAN_SA_API_ENABLE */ 228 229 #ifndef WLAN_CFR_ENABLE 230 static void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 231 { 232 } 233 #endif 234 235 #ifdef WLAN_SUPPORT_FILS 236 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 237 { 238 target_if_fd_register_tx_ops(tx_ops); 239 } 240 #else 241 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 242 { 243 } 244 #endif 245 246 #ifdef WIFI_POS_CONVERGED 247 static void target_if_wifi_pos_tx_ops_register( 248 struct wlan_lmac_if_tx_ops *tx_ops) 249 { 250 target_if_wifi_pos_register_tx_ops(tx_ops); 251 } 252 #else 253 static void target_if_wifi_pos_tx_ops_register( 254 struct wlan_lmac_if_tx_ops *tx_ops) 255 { 256 } 257 #endif 258 #ifdef QCA_SUPPORT_SON 259 static void target_if_son_tx_ops_register( 260 struct wlan_lmac_if_tx_ops *tx_ops) 261 { 262 target_if_son_register_tx_ops(tx_ops); 263 return; 264 } 265 #else 266 static void target_if_son_tx_ops_register( 267 struct wlan_lmac_if_tx_ops *tx_ops) 268 { 269 return; 270 } 271 #endif 272 273 #ifdef FEATURE_WLAN_TDLS 274 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 275 { 276 target_if_tdls_register_tx_ops(tx_ops); 277 } 278 #else 279 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 280 { 281 } 282 #endif /* FEATURE_WLAN_TDLS */ 283 284 #ifdef DFS_COMPONENT_ENABLE 285 static void target_if_dfs_tx_ops_register( 286 struct wlan_lmac_if_tx_ops *tx_ops) 287 { 288 target_if_register_dfs_tx_ops(tx_ops); 289 } 290 #else 291 static void target_if_dfs_tx_ops_register( 292 struct wlan_lmac_if_tx_ops *tx_ops) 293 { 294 } 295 #endif /* DFS_COMPONENT_ENABLE */ 296 297 #ifdef WLAN_CONV_SPECTRAL_ENABLE 298 static void target_if_sptrl_tx_ops_register( 299 struct wlan_lmac_if_tx_ops *tx_ops) 300 { 301 target_if_sptrl_register_tx_ops(tx_ops); 302 } 303 #else 304 static void target_if_sptrl_tx_ops_register( 305 struct wlan_lmac_if_tx_ops *tx_ops) 306 { 307 } 308 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 309 310 #ifdef DIRECT_BUF_RX_ENABLE 311 static void target_if_direct_buf_rx_tx_ops_register( 312 struct wlan_lmac_if_tx_ops *tx_ops) 313 { 314 target_if_direct_buf_rx_register_tx_ops(tx_ops); 315 } 316 #else 317 static void target_if_direct_buf_rx_tx_ops_register( 318 struct wlan_lmac_if_tx_ops *tx_ops) 319 { 320 } 321 #endif /* DIRECT_BUF_RX_ENABLE */ 322 323 #ifdef WLAN_SUPPORT_GREEN_AP 324 static QDF_STATUS target_if_green_ap_tx_ops_register( 325 struct wlan_lmac_if_tx_ops *tx_ops) 326 { 327 return target_if_register_green_ap_tx_ops(tx_ops); 328 } 329 #else 330 static QDF_STATUS target_if_green_ap_tx_ops_register( 331 struct wlan_lmac_if_tx_ops *tx_ops) 332 { 333 return QDF_STATUS_SUCCESS; 334 } 335 #endif /* WLAN_SUPPORT_GREEN_AP */ 336 #if defined(WLAN_CONV_CRYPTO_SUPPORTED) && defined(CRYPTO_SET_KEY_CONVERGED) 337 static void target_if_crypto_tx_ops_register( 338 struct wlan_lmac_if_tx_ops *tx_ops) 339 { 340 target_if_crypto_register_tx_ops(tx_ops); 341 } 342 #else 343 static inline void target_if_crypto_tx_ops_register( 344 struct wlan_lmac_if_tx_ops *tx_ops) 345 { 346 } 347 #endif 348 349 #ifdef FEATURE_COEX 350 static QDF_STATUS 351 target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 352 { 353 return target_if_coex_register_tx_ops(tx_ops); 354 } 355 #else 356 static inline QDF_STATUS 357 target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 358 { 359 return QDF_STATUS_SUCCESS; 360 } 361 #endif 362 363 static void target_if_target_tx_ops_register( 364 struct wlan_lmac_if_tx_ops *tx_ops) 365 { 366 struct wlan_lmac_if_target_tx_ops *target_tx_ops; 367 368 if (!tx_ops) { 369 target_if_err("invalid tx_ops"); 370 return; 371 } 372 373 target_tx_ops = &tx_ops->target_tx_ops; 374 375 target_tx_ops->tgt_is_tgt_type_ar900b = 376 target_is_tgt_type_ar900b; 377 378 target_tx_ops->tgt_is_tgt_type_ipq4019 = 379 target_is_tgt_type_ipq4019; 380 381 target_tx_ops->tgt_is_tgt_type_qca9984 = 382 target_is_tgt_type_qca9984; 383 384 target_tx_ops->tgt_is_tgt_type_qca9888 = 385 target_is_tgt_type_qca9888; 386 387 target_tx_ops->tgt_is_tgt_type_adrastea = 388 target_is_tgt_type_adrastea; 389 390 target_tx_ops->tgt_get_tgt_type = 391 lmac_get_tgt_type; 392 393 target_tx_ops->tgt_get_tgt_version = 394 lmac_get_tgt_version; 395 396 target_tx_ops->tgt_get_tgt_revision = 397 lmac_get_tgt_revision; 398 } 399 400 static QDF_STATUS 401 target_if_cp_stats_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 402 { 403 return target_if_cp_stats_register_tx_ops(tx_ops); 404 } 405 406 #ifdef DCS_INTERFERENCE_DETECTION 407 static QDF_STATUS 408 target_if_dcs_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 409 { 410 return target_if_dcs_register_tx_ops(tx_ops); 411 } 412 #else 413 static QDF_STATUS 414 target_if_dcs_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 415 { 416 return QDF_STATUS_SUCCESS; 417 } 418 #endif 419 420 static QDF_STATUS 421 target_if_vdev_mgr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 422 { 423 return target_if_vdev_mgr_register_tx_ops(tx_ops); 424 } 425 426 #ifdef QCA_WIFI_FTM 427 static 428 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 429 { 430 target_if_ftm_register_tx_ops(tx_ops); 431 } 432 #else 433 static 434 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 435 { 436 } 437 #endif 438 static 439 QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 440 { 441 /* call regulatory callback to register tx ops */ 442 target_if_register_regulatory_tx_ops(tx_ops); 443 444 /* call umac callback to register legacy tx ops */ 445 wlan_lmac_if_umac_tx_ops_register(tx_ops); 446 447 /* Register scan tx ops */ 448 target_if_scan_tx_ops_register(tx_ops); 449 450 target_if_atf_tx_ops_register(tx_ops); 451 452 target_if_sa_api_tx_ops_register(tx_ops); 453 454 target_if_cfr_tx_ops_register(tx_ops); 455 456 target_if_wifi_pos_tx_ops_register(tx_ops); 457 458 target_if_dfs_tx_ops_register(tx_ops); 459 460 target_if_son_tx_ops_register(tx_ops); 461 462 target_if_tdls_tx_ops_register(tx_ops); 463 464 target_if_fd_tx_ops_register(tx_ops); 465 466 target_if_target_tx_ops_register(tx_ops); 467 468 target_if_offchan_txrx_ops_register(tx_ops); 469 470 target_if_green_ap_tx_ops_register(tx_ops); 471 472 target_if_ftm_tx_ops_register(tx_ops); 473 474 target_if_cp_stats_tx_ops_register(tx_ops); 475 476 target_if_dcs_tx_ops_register(tx_ops); 477 478 target_if_crypto_tx_ops_register(tx_ops); 479 480 target_if_vdev_mgr_tx_ops_register(tx_ops); 481 482 target_if_coex_tx_ops_register(tx_ops); 483 484 /* Converged UMAC components to register their TX-ops here */ 485 return QDF_STATUS_SUCCESS; 486 } 487 488 QDF_STATUS target_if_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 489 { 490 /* Converged UMAC components to register their TX-ops */ 491 target_if_register_umac_tx_ops(tx_ops); 492 493 /* Components parallel to UMAC to register their TX-ops here */ 494 target_if_sptrl_tx_ops_register(tx_ops); 495 496 /* Register direct buffer rx component tx ops here */ 497 target_if_direct_buf_rx_tx_ops_register(tx_ops); 498 499 #ifdef CONVERGED_P2P_ENABLE 500 /* Converged UMAC components to register P2P TX-ops */ 501 target_if_p2p_register_tx_ops(tx_ops); 502 #endif 503 504 return QDF_STATUS_SUCCESS; 505 } 506 qdf_export_symbol(target_if_register_tx_ops); 507 508 wmi_legacy_service_ready_callback 509 target_if_get_psoc_legacy_service_ready_cb(void) 510 { 511 wmi_legacy_service_ready_callback service_ready_cb; 512 513 qdf_spin_lock_bh(&g_target_if_ctx->lock); 514 if (g_target_if_ctx->service_ready_cb) 515 service_ready_cb = g_target_if_ctx->service_ready_cb; 516 else 517 service_ready_cb = NULL; 518 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 519 520 return service_ready_cb; 521 } 522 qdf_export_symbol(target_if_get_psoc_legacy_service_ready_cb); 523 524 QDF_STATUS target_if_register_legacy_service_ready_cb( 525 wmi_legacy_service_ready_callback service_ready_cb) 526 { 527 qdf_spin_lock_bh(&g_target_if_ctx->lock); 528 g_target_if_ctx->service_ready_cb = service_ready_cb; 529 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 530 531 return QDF_STATUS_SUCCESS; 532 } 533 qdf_export_symbol(target_if_register_legacy_service_ready_cb); 534 535 QDF_STATUS target_if_alloc_pdev_tgt_info(struct wlan_objmgr_pdev *pdev) 536 { 537 struct target_pdev_info *tgt_pdev_info; 538 539 if (!pdev) { 540 target_if_err("pdev is null"); 541 return QDF_STATUS_E_INVAL; 542 } 543 544 tgt_pdev_info = qdf_mem_malloc(sizeof(*tgt_pdev_info)); 545 546 if (!tgt_pdev_info) 547 return QDF_STATUS_E_NOMEM; 548 549 wlan_pdev_set_tgt_if_handle(pdev, tgt_pdev_info); 550 551 return QDF_STATUS_SUCCESS; 552 } 553 554 QDF_STATUS target_if_free_pdev_tgt_info(struct wlan_objmgr_pdev *pdev) 555 { 556 struct target_pdev_info *tgt_pdev_info; 557 558 if (!pdev) { 559 target_if_err("pdev is null"); 560 return QDF_STATUS_E_INVAL; 561 } 562 563 tgt_pdev_info = wlan_pdev_get_tgt_if_handle(pdev); 564 565 wlan_pdev_set_tgt_if_handle(pdev, NULL); 566 567 qdf_mem_free(tgt_pdev_info); 568 569 return QDF_STATUS_SUCCESS; 570 } 571 572 QDF_STATUS target_if_alloc_psoc_tgt_info(struct wlan_objmgr_psoc *psoc) 573 { 574 struct target_psoc_info *tgt_psoc_info; 575 576 if (!psoc) { 577 target_if_err("psoc is null"); 578 return QDF_STATUS_E_INVAL; 579 } 580 581 tgt_psoc_info = qdf_mem_malloc(sizeof(*tgt_psoc_info)); 582 583 if (!tgt_psoc_info) 584 return QDF_STATUS_E_NOMEM; 585 586 wlan_psoc_set_tgt_if_handle(psoc, tgt_psoc_info); 587 target_psoc_set_preferred_hw_mode(tgt_psoc_info, WMI_HOST_HW_MODE_MAX); 588 589 qdf_event_create(&tgt_psoc_info->info.event); 590 591 return QDF_STATUS_SUCCESS; 592 } 593 594 QDF_STATUS target_if_free_psoc_tgt_info(struct wlan_objmgr_psoc *psoc) 595 { 596 struct target_psoc_info *tgt_psoc_info; 597 struct wlan_psoc_host_service_ext_param *ext_param; 598 599 if (!psoc) { 600 target_if_err("psoc is null"); 601 return QDF_STATUS_E_INVAL; 602 } 603 604 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 605 606 ext_param = target_psoc_get_service_ext_param(tgt_psoc_info); 607 if (!ext_param) { 608 target_if_err("tgt_psoc_info is NULL"); 609 return QDF_STATUS_E_INVAL; 610 } 611 init_deinit_chainmask_table_free(ext_param); 612 init_deinit_dbr_ring_cap_free(tgt_psoc_info); 613 init_deinit_spectral_scaling_params_free(tgt_psoc_info); 614 615 qdf_event_destroy(&tgt_psoc_info->info.event); 616 617 wlan_psoc_set_tgt_if_handle(psoc, NULL); 618 619 qdf_mem_free(tgt_psoc_info); 620 621 return QDF_STATUS_SUCCESS; 622 } 623 624 bool target_is_tgt_type_ar900b(uint32_t target_type) 625 { 626 return target_type == TARGET_TYPE_AR900B; 627 } 628 629 bool target_is_tgt_type_ipq4019(uint32_t target_type) 630 { 631 return target_type == TARGET_TYPE_IPQ4019; 632 } 633 634 bool target_is_tgt_type_qca9984(uint32_t target_type) 635 { 636 return target_type == TARGET_TYPE_QCA9984; 637 } 638 639 bool target_is_tgt_type_qca9888(uint32_t target_type) 640 { 641 return target_type == TARGET_TYPE_QCA9888; 642 } 643 644 bool target_is_tgt_type_adrastea(uint32_t target_type) 645 { 646 return target_type == TARGET_TYPE_ADRASTEA; 647 } 648