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