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 static struct target_if_ctx *g_target_if_ctx; 88 89 struct target_if_ctx *target_if_get_ctx() 90 { 91 return g_target_if_ctx; 92 } 93 94 struct wlan_objmgr_psoc *target_if_get_psoc_from_scn_hdl(void *scn_handle) 95 { 96 struct wlan_objmgr_psoc *psoc; 97 98 qdf_spin_lock_bh(&g_target_if_ctx->lock); 99 if (scn_handle && g_target_if_ctx->get_psoc_hdl_cb) 100 psoc = g_target_if_ctx->get_psoc_hdl_cb(scn_handle); 101 else 102 psoc = NULL; 103 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 104 105 return psoc; 106 } 107 108 struct wlan_objmgr_pdev *target_if_get_pdev_from_scn_hdl(void *scn_handle) 109 { 110 struct wlan_objmgr_pdev *pdev; 111 112 qdf_spin_lock_bh(&g_target_if_ctx->lock); 113 if (scn_handle && g_target_if_ctx->get_pdev_hdl_cb) 114 pdev = g_target_if_ctx->get_pdev_hdl_cb(scn_handle); 115 else 116 pdev = NULL; 117 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 118 119 return pdev; 120 } 121 122 #ifdef DIRECT_BUF_RX_ENABLE 123 static QDF_STATUS target_if_direct_buf_rx_init(void) 124 { 125 return direct_buf_rx_init(); 126 } 127 128 static QDF_STATUS target_if_direct_buf_rx_deinit(void) 129 { 130 return direct_buf_rx_deinit(); 131 } 132 #else 133 static QDF_STATUS target_if_direct_buf_rx_init(void) 134 { 135 return QDF_STATUS_SUCCESS; 136 } 137 138 static QDF_STATUS target_if_direct_buf_rx_deinit(void) 139 { 140 return QDF_STATUS_SUCCESS; 141 } 142 #endif /* DIRECT_BUF_RX_ENABLE */ 143 144 QDF_STATUS target_if_init(get_psoc_handle_callback psoc_hdl_cb) 145 { 146 g_target_if_ctx = qdf_mem_malloc(sizeof(*g_target_if_ctx)); 147 if (!g_target_if_ctx) { 148 QDF_ASSERT(0); 149 return QDF_STATUS_E_NOMEM; 150 } 151 152 qdf_spinlock_create(&g_target_if_ctx->lock); 153 154 qdf_spin_lock_bh(&g_target_if_ctx->lock); 155 g_target_if_ctx->magic = TGT_MAGIC; 156 g_target_if_ctx->get_psoc_hdl_cb = psoc_hdl_cb; 157 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 158 159 target_if_direct_buf_rx_init(); 160 161 return QDF_STATUS_SUCCESS; 162 } 163 164 QDF_STATUS target_if_deinit(void) 165 { 166 if (!g_target_if_ctx) { 167 QDF_ASSERT(0); 168 target_if_err("target if ctx is null"); 169 return QDF_STATUS_E_INVAL; 170 } 171 172 qdf_spin_lock_bh(&g_target_if_ctx->lock); 173 g_target_if_ctx->magic = 0; 174 g_target_if_ctx->get_psoc_hdl_cb = NULL; 175 g_target_if_ctx->get_pdev_hdl_cb = NULL; 176 g_target_if_ctx->service_ready_cb = NULL; 177 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 178 179 qdf_spinlock_destroy(&g_target_if_ctx->lock); 180 qdf_mem_free(g_target_if_ctx); 181 g_target_if_ctx = NULL; 182 183 target_if_direct_buf_rx_deinit(); 184 185 return QDF_STATUS_SUCCESS; 186 } 187 188 qdf_export_symbol(target_if_deinit); 189 190 QDF_STATUS target_if_store_pdev_target_if_ctx( 191 get_pdev_handle_callback pdev_hdl_cb) 192 { 193 if (!g_target_if_ctx) { 194 QDF_ASSERT(0); 195 target_if_err("target if ctx is null"); 196 return QDF_STATUS_E_INVAL; 197 } 198 199 qdf_spin_lock_bh(&g_target_if_ctx->lock); 200 g_target_if_ctx->get_pdev_hdl_cb = pdev_hdl_cb; 201 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 202 203 return QDF_STATUS_SUCCESS; 204 } 205 206 #ifndef WLAN_OFFCHAN_TXRX_ENABLE 207 static void target_if_offchan_txrx_ops_register( 208 struct wlan_lmac_if_tx_ops *tx_ops) 209 { 210 } 211 #endif /* WLAN_OFFCHAN_TXRX_ENABLE */ 212 213 #ifndef WLAN_ATF_ENABLE 214 static void target_if_atf_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 215 { 216 } 217 #endif /* WLAN_ATF_ENABLE */ 218 219 #ifndef WLAN_SA_API_ENABLE 220 static void target_if_sa_api_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 221 { 222 } 223 #endif /* WLAN_SA_API_ENABLE */ 224 225 #ifndef WLAN_CFR_ENABLE 226 static void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 227 { 228 } 229 #endif 230 231 #ifdef WLAN_SUPPORT_FILS 232 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 233 { 234 target_if_fd_register_tx_ops(tx_ops); 235 } 236 #else 237 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 238 { 239 } 240 #endif 241 242 #ifdef WIFI_POS_CONVERGED 243 static void target_if_wifi_pos_tx_ops_register( 244 struct wlan_lmac_if_tx_ops *tx_ops) 245 { 246 target_if_wifi_pos_register_tx_ops(tx_ops); 247 } 248 #else 249 static void target_if_wifi_pos_tx_ops_register( 250 struct wlan_lmac_if_tx_ops *tx_ops) 251 { 252 } 253 #endif 254 #ifdef QCA_SUPPORT_SON 255 static void target_if_son_tx_ops_register( 256 struct wlan_lmac_if_tx_ops *tx_ops) 257 { 258 target_if_son_register_tx_ops(tx_ops); 259 return; 260 } 261 #else 262 static void target_if_son_tx_ops_register( 263 struct wlan_lmac_if_tx_ops *tx_ops) 264 { 265 return; 266 } 267 #endif 268 269 #ifdef FEATURE_WLAN_TDLS 270 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 271 { 272 target_if_tdls_register_tx_ops(tx_ops); 273 } 274 #else 275 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 276 { 277 } 278 #endif /* FEATURE_WLAN_TDLS */ 279 280 #ifdef DFS_COMPONENT_ENABLE 281 static void target_if_dfs_tx_ops_register( 282 struct wlan_lmac_if_tx_ops *tx_ops) 283 { 284 target_if_register_dfs_tx_ops(tx_ops); 285 } 286 #else 287 static void target_if_dfs_tx_ops_register( 288 struct wlan_lmac_if_tx_ops *tx_ops) 289 { 290 } 291 #endif /* DFS_COMPONENT_ENABLE */ 292 293 #ifdef WLAN_CONV_SPECTRAL_ENABLE 294 static void target_if_sptrl_tx_ops_register( 295 struct wlan_lmac_if_tx_ops *tx_ops) 296 { 297 target_if_sptrl_register_tx_ops(tx_ops); 298 } 299 #else 300 static void target_if_sptrl_tx_ops_register( 301 struct wlan_lmac_if_tx_ops *tx_ops) 302 { 303 } 304 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 305 306 #ifdef DIRECT_BUF_RX_ENABLE 307 static void target_if_direct_buf_rx_tx_ops_register( 308 struct wlan_lmac_if_tx_ops *tx_ops) 309 { 310 target_if_direct_buf_rx_register_tx_ops(tx_ops); 311 } 312 #else 313 static void target_if_direct_buf_rx_tx_ops_register( 314 struct wlan_lmac_if_tx_ops *tx_ops) 315 { 316 } 317 #endif /* DIRECT_BUF_RX_ENABLE */ 318 319 #ifdef WLAN_SUPPORT_GREEN_AP 320 static QDF_STATUS target_if_green_ap_tx_ops_register( 321 struct wlan_lmac_if_tx_ops *tx_ops) 322 { 323 return target_if_register_green_ap_tx_ops(tx_ops); 324 } 325 #else 326 static QDF_STATUS target_if_green_ap_tx_ops_register( 327 struct wlan_lmac_if_tx_ops *tx_ops) 328 { 329 return QDF_STATUS_SUCCESS; 330 } 331 #endif /* WLAN_SUPPORT_GREEN_AP */ 332 #if defined(WLAN_CONV_CRYPTO_SUPPORTED) && defined(CRYPTO_SET_KEY_CONVERGED) 333 static void target_if_crypto_tx_ops_register( 334 struct wlan_lmac_if_tx_ops *tx_ops) 335 { 336 target_if_crypto_register_tx_ops(tx_ops); 337 } 338 #else 339 static inline void target_if_crypto_tx_ops_register( 340 struct wlan_lmac_if_tx_ops *tx_ops) 341 { 342 } 343 #endif 344 345 #ifdef FEATURE_COEX 346 static QDF_STATUS 347 target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 348 { 349 return target_if_coex_register_tx_ops(tx_ops); 350 } 351 #else 352 static inline QDF_STATUS 353 target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 354 { 355 return QDF_STATUS_SUCCESS; 356 } 357 #endif 358 359 static void target_if_target_tx_ops_register( 360 struct wlan_lmac_if_tx_ops *tx_ops) 361 { 362 struct wlan_lmac_if_target_tx_ops *target_tx_ops; 363 364 if (!tx_ops) { 365 target_if_err("invalid tx_ops"); 366 return; 367 } 368 369 target_tx_ops = &tx_ops->target_tx_ops; 370 371 target_tx_ops->tgt_is_tgt_type_ar900b = 372 target_is_tgt_type_ar900b; 373 374 target_tx_ops->tgt_is_tgt_type_ipq4019 = 375 target_is_tgt_type_ipq4019; 376 377 target_tx_ops->tgt_is_tgt_type_qca9984 = 378 target_is_tgt_type_qca9984; 379 380 target_tx_ops->tgt_is_tgt_type_qca9888 = 381 target_is_tgt_type_qca9888; 382 383 target_tx_ops->tgt_is_tgt_type_adrastea = 384 target_is_tgt_type_adrastea; 385 386 target_tx_ops->tgt_get_tgt_type = 387 lmac_get_tgt_type; 388 389 target_tx_ops->tgt_get_tgt_version = 390 lmac_get_tgt_version; 391 392 target_tx_ops->tgt_get_tgt_revision = 393 lmac_get_tgt_revision; 394 } 395 396 static QDF_STATUS 397 target_if_cp_stats_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 398 { 399 return target_if_cp_stats_register_tx_ops(tx_ops); 400 } 401 402 static QDF_STATUS 403 target_if_vdev_mgr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 404 { 405 return target_if_vdev_mgr_register_tx_ops(tx_ops); 406 } 407 408 #ifdef QCA_WIFI_FTM 409 static 410 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 411 { 412 target_if_ftm_register_tx_ops(tx_ops); 413 } 414 #else 415 static 416 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 417 { 418 } 419 #endif 420 static 421 QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 422 { 423 /* call regulatory callback to register tx ops */ 424 target_if_register_regulatory_tx_ops(tx_ops); 425 426 /* call umac callback to register legacy tx ops */ 427 wlan_lmac_if_umac_tx_ops_register(tx_ops); 428 429 /* Register scan tx ops */ 430 target_if_scan_tx_ops_register(tx_ops); 431 432 target_if_atf_tx_ops_register(tx_ops); 433 434 target_if_sa_api_tx_ops_register(tx_ops); 435 436 target_if_cfr_tx_ops_register(tx_ops); 437 438 target_if_wifi_pos_tx_ops_register(tx_ops); 439 440 target_if_dfs_tx_ops_register(tx_ops); 441 442 target_if_son_tx_ops_register(tx_ops); 443 444 target_if_tdls_tx_ops_register(tx_ops); 445 446 target_if_fd_tx_ops_register(tx_ops); 447 448 target_if_target_tx_ops_register(tx_ops); 449 450 target_if_offchan_txrx_ops_register(tx_ops); 451 452 target_if_green_ap_tx_ops_register(tx_ops); 453 454 target_if_ftm_tx_ops_register(tx_ops); 455 456 target_if_cp_stats_tx_ops_register(tx_ops); 457 458 target_if_crypto_tx_ops_register(tx_ops); 459 460 target_if_vdev_mgr_tx_ops_register(tx_ops); 461 462 target_if_coex_tx_ops_register(tx_ops); 463 464 /* Converged UMAC components to register their TX-ops here */ 465 return QDF_STATUS_SUCCESS; 466 } 467 468 QDF_STATUS target_if_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 469 { 470 /* Converged UMAC components to register their TX-ops */ 471 target_if_register_umac_tx_ops(tx_ops); 472 473 /* Components parallel to UMAC to register their TX-ops here */ 474 target_if_sptrl_tx_ops_register(tx_ops); 475 476 /* Register direct buffer rx component tx ops here */ 477 target_if_direct_buf_rx_tx_ops_register(tx_ops); 478 479 #ifdef CONVERGED_P2P_ENABLE 480 /* Converged UMAC components to register P2P TX-ops */ 481 target_if_p2p_register_tx_ops(tx_ops); 482 #endif 483 484 return QDF_STATUS_SUCCESS; 485 } 486 qdf_export_symbol(target_if_register_tx_ops); 487 488 wmi_legacy_service_ready_callback 489 target_if_get_psoc_legacy_service_ready_cb(void) 490 { 491 wmi_legacy_service_ready_callback service_ready_cb; 492 493 qdf_spin_lock_bh(&g_target_if_ctx->lock); 494 if (g_target_if_ctx->service_ready_cb) 495 service_ready_cb = g_target_if_ctx->service_ready_cb; 496 else 497 service_ready_cb = NULL; 498 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 499 500 return service_ready_cb; 501 } 502 qdf_export_symbol(target_if_get_psoc_legacy_service_ready_cb); 503 504 QDF_STATUS target_if_register_legacy_service_ready_cb( 505 wmi_legacy_service_ready_callback service_ready_cb) 506 { 507 qdf_spin_lock_bh(&g_target_if_ctx->lock); 508 g_target_if_ctx->service_ready_cb = service_ready_cb; 509 qdf_spin_unlock_bh(&g_target_if_ctx->lock); 510 511 return QDF_STATUS_SUCCESS; 512 } 513 qdf_export_symbol(target_if_register_legacy_service_ready_cb); 514 515 QDF_STATUS target_if_alloc_pdev_tgt_info(struct wlan_objmgr_pdev *pdev) 516 { 517 struct target_pdev_info *tgt_pdev_info; 518 519 if (!pdev) { 520 target_if_err("pdev is null"); 521 return QDF_STATUS_E_INVAL; 522 } 523 524 tgt_pdev_info = qdf_mem_malloc(sizeof(*tgt_pdev_info)); 525 526 if (!tgt_pdev_info) 527 return QDF_STATUS_E_NOMEM; 528 529 wlan_pdev_set_tgt_if_handle(pdev, tgt_pdev_info); 530 531 return QDF_STATUS_SUCCESS; 532 } 533 534 QDF_STATUS target_if_free_pdev_tgt_info(struct wlan_objmgr_pdev *pdev) 535 { 536 struct target_pdev_info *tgt_pdev_info; 537 538 if (!pdev) { 539 target_if_err("pdev is null"); 540 return QDF_STATUS_E_INVAL; 541 } 542 543 tgt_pdev_info = wlan_pdev_get_tgt_if_handle(pdev); 544 545 wlan_pdev_set_tgt_if_handle(pdev, NULL); 546 547 qdf_mem_free(tgt_pdev_info); 548 549 return QDF_STATUS_SUCCESS; 550 } 551 552 QDF_STATUS target_if_alloc_psoc_tgt_info(struct wlan_objmgr_psoc *psoc) 553 { 554 struct target_psoc_info *tgt_psoc_info; 555 556 if (!psoc) { 557 target_if_err("psoc is null"); 558 return QDF_STATUS_E_INVAL; 559 } 560 561 tgt_psoc_info = qdf_mem_malloc(sizeof(*tgt_psoc_info)); 562 563 if (!tgt_psoc_info) 564 return QDF_STATUS_E_NOMEM; 565 566 wlan_psoc_set_tgt_if_handle(psoc, tgt_psoc_info); 567 target_psoc_set_preferred_hw_mode(tgt_psoc_info, WMI_HOST_HW_MODE_MAX); 568 569 qdf_event_create(&tgt_psoc_info->info.event); 570 571 return QDF_STATUS_SUCCESS; 572 } 573 574 QDF_STATUS target_if_free_psoc_tgt_info(struct wlan_objmgr_psoc *psoc) 575 { 576 struct target_psoc_info *tgt_psoc_info; 577 struct wlan_psoc_host_service_ext_param *ext_param; 578 579 if (!psoc) { 580 target_if_err("psoc is null"); 581 return QDF_STATUS_E_INVAL; 582 } 583 584 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 585 586 ext_param = target_psoc_get_service_ext_param(tgt_psoc_info); 587 if (!ext_param) { 588 target_if_err("tgt_psoc_info is NULL"); 589 return QDF_STATUS_E_INVAL; 590 } 591 init_deinit_chainmask_table_free(ext_param); 592 init_deinit_dbr_ring_cap_free(tgt_psoc_info); 593 init_deinit_spectral_scaling_params_free(tgt_psoc_info); 594 595 qdf_event_destroy(&tgt_psoc_info->info.event); 596 597 wlan_psoc_set_tgt_if_handle(psoc, NULL); 598 599 qdf_mem_free(tgt_psoc_info); 600 601 return QDF_STATUS_SUCCESS; 602 } 603 604 bool target_is_tgt_type_ar900b(uint32_t target_type) 605 { 606 return target_type == TARGET_TYPE_AR900B; 607 } 608 609 bool target_is_tgt_type_ipq4019(uint32_t target_type) 610 { 611 return target_type == TARGET_TYPE_IPQ4019; 612 } 613 614 bool target_is_tgt_type_qca9984(uint32_t target_type) 615 { 616 return target_type == TARGET_TYPE_QCA9984; 617 } 618 619 bool target_is_tgt_type_qca9888(uint32_t target_type) 620 { 621 return target_type == TARGET_TYPE_QCA9888; 622 } 623 624 bool target_is_tgt_type_adrastea(uint32_t target_type) 625 { 626 return target_type == TARGET_TYPE_ADRASTEA; 627 } 628