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