1 /* 2 * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 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 /* Include Files */ 21 #include "wlan_ipa_core.h" 22 #include "wlan_ipa_main.h" 23 #include "cdp_txrx_ipa.h" 24 #include "cdp_txrx_ctrl.h" 25 #include "wal_rx_desc.h" 26 #include "qdf_str.h" 27 #include "host_diag_core_event.h" 28 #include "wlan_objmgr_vdev_obj.h" 29 #include "qdf_platform.h" 30 #include <wmi_unified_param.h> 31 #include <wlan_osif_priv.h> 32 #include <net/cfg80211.h> 33 #ifdef QCA_LL_TX_FLOW_CONTROL_V2 34 #include <cdp_txrx_flow_ctrl_v2.h> 35 #include <cdp_txrx_peer_ops.h> 36 #endif 37 #include <qal_vbus_dev.h> 38 39 #define IPA_SPS_DESC_SIZE 8 40 #define IPA_DEFAULT_HDL 0 41 #ifdef IPA_WDS_EASYMESH_FEATURE 42 #define IPA_TA_PEER_ID_ATTRI 2 43 #endif 44 45 static struct wlan_ipa_priv *gp_ipa; 46 static void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx); 47 static void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx); 48 49 static inline 50 bool wlan_ipa_is_driver_unloading(struct wlan_ipa_priv *ipa_ctx) 51 { 52 if (ipa_ctx->driver_is_unloading) 53 return ipa_ctx->driver_is_unloading(); 54 return false; 55 } 56 57 static struct wlan_ipa_iface_2_client { 58 qdf_ipa_client_type_t cons_client; 59 qdf_ipa_client_type_t prod_client; 60 } wlan_ipa_iface_2_client[WLAN_IPA_CLIENT_MAX_IFACE] = { 61 { 62 QDF_IPA_CLIENT_WLAN2_CONS, QDF_IPA_CLIENT_WLAN1_PROD 63 }, 64 { 65 QDF_IPA_CLIENT_MCC2_CONS, QDF_IPA_CLIENT_WLAN1_PROD 66 }, 67 #if WLAN_IPA_CLIENT_MAX_IFACE >= 3 68 { 69 QDF_IPA_CLIENT_WLAN4_CONS, QDF_IPA_CLIENT_WLAN1_PROD 70 }, 71 #if WLAN_IPA_CLIENT_MAX_IFACE == 4 72 { 73 QDF_IPA_CLIENT_WLAN4_CONS, QDF_IPA_CLIENT_WLAN1_PROD 74 }, 75 #endif 76 #endif 77 }; 78 79 /* Local Function Prototypes */ 80 static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt, 81 unsigned long data); 82 static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, 83 unsigned long data); 84 static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx, 85 qdf_ipa_wdi_init_in_params_t *in); 86 static void wlan_ipa_msg_wds_update(bool ipa_wds, qdf_ipa_wlan_msg_t *msg); 87 88 /** 89 * wlan_ipa_uc_sta_is_enabled() - Is STA mode IPA uC offload enabled? 90 * @ipa_cfg: IPA config 91 * 92 * Return: true if STA mode IPA uC offload is enabled, false otherwise 93 */ 94 static inline bool wlan_ipa_uc_sta_is_enabled(struct wlan_ipa_config *ipa_cfg) 95 { 96 return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_UC_STA_ENABLE_MASK); 97 } 98 99 /** 100 * wlan_ipa_is_pre_filter_enabled() - Is IPA pre-filter enabled? 101 * @ipa_cfg: IPA config 102 * 103 * Return: true if pre-filter is enabled, otherwise false 104 */ 105 static inline 106 bool wlan_ipa_is_pre_filter_enabled(struct wlan_ipa_config *ipa_cfg) 107 { 108 return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, 109 WLAN_IPA_PRE_FILTER_ENABLE_MASK); 110 } 111 112 /** 113 * wlan_ipa_is_ipv6_enabled() - Is IPA IPv6 enabled? 114 * @ipa_cfg: IPA config 115 * 116 * Return: true if IPv6 is enabled, otherwise false 117 */ 118 static inline bool wlan_ipa_is_ipv6_enabled(struct wlan_ipa_config *ipa_cfg) 119 { 120 return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_IPV6_ENABLE_MASK); 121 } 122 123 /** 124 * wlan_ipa_is_sta_only_offload_enabled() - Is IPA STA only offload enabled 125 * 126 * STA only IPA offload is needed on MDM platforms to support 127 * tethering scenarios in STA-SAP configurations when SAP is idle. 128 * 129 * Currently in STA-SAP configurations, IPA pipes are enabled only 130 * when a wifi client is connected to SAP. 131 * 132 * Impact of this API is only limited to when IPA pipes are enabled 133 * and disabled. To take effect, WLAN_IPA_UC_STA_ENABLE_MASK needs to 134 * set to 1. 135 * 136 * Return: true if MDM_PLATFORM is defined, false otherwise 137 */ 138 #ifdef MDM_PLATFORM 139 static inline bool wlan_ipa_is_sta_only_offload_enabled(void) 140 { 141 return true; 142 } 143 #else 144 static inline bool wlan_ipa_is_sta_only_offload_enabled(void) 145 { 146 return false; 147 } 148 #endif 149 150 /** 151 * wlan_ipa_msg_free_fn() - Free an IPA message 152 * @buff: pointer to the IPA message 153 * @len: length of the IPA message 154 * @type: type of IPA message 155 * 156 * Return: None 157 */ 158 static void wlan_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type) 159 { 160 ipa_debug("msg type:%d, len:%d", type, len); 161 qdf_mem_free(buff); 162 } 163 164 /** 165 * wlan_ipa_uc_loaded_uc_cb() - IPA UC loaded event callback 166 * @priv_ctxt: IPA context 167 * 168 * Will be called by IPA context. 169 * It's atomic context, then should be scheduled to kworker thread 170 * 171 * Return: None 172 */ 173 static void wlan_ipa_uc_loaded_uc_cb(void *priv_ctxt) 174 { 175 struct wlan_ipa_priv *ipa_ctx; 176 struct op_msg_type *msg; 177 struct uc_op_work_struct *uc_op_work; 178 179 if (!ipa_cb_is_ready()) { 180 ipa_info("IPA is not READY"); 181 return; 182 } 183 184 if (!priv_ctxt) { 185 ipa_err("Invalid IPA context"); 186 return; 187 } 188 189 ipa_ctx = priv_ctxt; 190 191 uc_op_work = &ipa_ctx->uc_op_work[WLAN_IPA_UC_OPCODE_UC_READY]; 192 if (!list_empty(&uc_op_work->work.work.entry)) { 193 /* uc_op_work is not initialized yet */ 194 ipa_ctx->uc_loaded = true; 195 return; 196 } 197 198 msg = qdf_mem_malloc(sizeof(*msg)); 199 if (!msg) 200 return; 201 202 msg->op_code = WLAN_IPA_UC_OPCODE_UC_READY; 203 204 /* When the same uC OPCODE is already pended, just return */ 205 if (uc_op_work->msg) 206 goto done; 207 208 uc_op_work->msg = msg; 209 210 if (!qdf_atomic_read(&ipa_ctx->deinit_in_prog)) { 211 qdf_sched_work(0, &uc_op_work->work); 212 } else { 213 uc_op_work->msg = NULL; 214 goto done; 215 } 216 217 /* work handler will free the msg buffer */ 218 return; 219 220 done: 221 qdf_mem_free(msg); 222 } 223 224 struct wlan_ipa_priv *wlan_ipa_get_obj_context(void) 225 { 226 return gp_ipa; 227 } 228 229 /** 230 * wlan_ipa_send_pkt_to_tl() - Send an IPA packet to TL 231 * @iface_context: interface-specific IPA context 232 * @ipa_tx_desc: packet data descriptor 233 * 234 * Return: None 235 */ 236 static void wlan_ipa_send_pkt_to_tl( 237 struct wlan_ipa_iface_context *iface_context, 238 qdf_ipa_rx_data_t *ipa_tx_desc) 239 { 240 struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx; 241 struct wlan_objmgr_pdev *pdev; 242 struct wlan_objmgr_psoc *psoc; 243 qdf_device_t osdev; 244 qdf_nbuf_t skb; 245 struct wlan_ipa_tx_desc *tx_desc; 246 qdf_dma_addr_t paddr; 247 QDF_STATUS status; 248 249 if (!ipa_ctx) 250 return; 251 pdev = ipa_ctx->pdev; 252 psoc = wlan_pdev_get_psoc(pdev); 253 osdev = wlan_psoc_get_qdf_dev(psoc); 254 255 qdf_spin_lock_bh(&iface_context->interface_lock); 256 /* 257 * During CAC period, data packets shouldn't be sent over the air so 258 * drop all the packets here 259 */ 260 if (iface_context->device_mode == QDF_SAP_MODE || 261 iface_context->device_mode == QDF_P2P_GO_MODE) { 262 if (ipa_ctx->dfs_cac_block_tx) { 263 ipa_free_skb(ipa_tx_desc); 264 qdf_spin_unlock_bh(&iface_context->interface_lock); 265 iface_context->stats.num_tx_cac_drop++; 266 wlan_ipa_wdi_rm_try_release(ipa_ctx); 267 return; 268 } 269 } 270 271 if (!osdev) { 272 ipa_free_skb(ipa_tx_desc); 273 iface_context->stats.num_tx_drop++; 274 qdf_spin_unlock_bh(&iface_context->interface_lock); 275 wlan_ipa_wdi_rm_try_release(ipa_ctx); 276 return; 277 } 278 qdf_spin_unlock_bh(&iface_context->interface_lock); 279 280 skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc); 281 282 qdf_mem_zero(skb->cb, sizeof(skb->cb)); 283 284 /* Store IPA Tx buffer ownership into SKB CB */ 285 qdf_nbuf_ipa_owned_set(skb); 286 287 if (qdf_mem_smmu_s1_enabled(osdev)) { 288 status = qdf_nbuf_map(osdev, skb, QDF_DMA_TO_DEVICE); 289 if (QDF_IS_STATUS_SUCCESS(status)) { 290 paddr = qdf_nbuf_get_frag_paddr(skb, 0); 291 } else { 292 ipa_free_skb(ipa_tx_desc); 293 qdf_spin_lock_bh(&iface_context->interface_lock); 294 iface_context->stats.num_tx_drop++; 295 qdf_spin_unlock_bh(&iface_context->interface_lock); 296 wlan_ipa_wdi_rm_try_release(ipa_ctx); 297 return; 298 } 299 } else { 300 paddr = QDF_IPA_RX_DATA_DMA_ADDR(ipa_tx_desc); 301 } 302 303 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 304 qdf_nbuf_mapped_paddr_set(skb, 305 paddr + 306 WLAN_IPA_WLAN_FRAG_HEADER + 307 WLAN_IPA_WLAN_IPA_HEADER); 308 QDF_IPA_RX_DATA_SKB_LEN(ipa_tx_desc) -= 309 WLAN_IPA_WLAN_FRAG_HEADER + WLAN_IPA_WLAN_IPA_HEADER; 310 } else { 311 qdf_nbuf_mapped_paddr_set(skb, paddr); 312 } 313 314 qdf_spin_lock_bh(&ipa_ctx->q_lock); 315 /* get free Tx desc and assign ipa_tx_desc pointer */ 316 if (ipa_ctx->tx_desc_free_list.count && 317 qdf_list_remove_front(&ipa_ctx->tx_desc_free_list, 318 (qdf_list_node_t **)&tx_desc) == 319 QDF_STATUS_SUCCESS) { 320 tx_desc->ipa_tx_desc_ptr = ipa_tx_desc; 321 ipa_ctx->stats.num_tx_desc_q_cnt++; 322 qdf_spin_unlock_bh(&ipa_ctx->q_lock); 323 /* Store Tx Desc index into SKB CB */ 324 qdf_nbuf_ipa_priv_set(skb, tx_desc->id); 325 } else { 326 ipa_ctx->stats.num_tx_desc_error++; 327 qdf_spin_unlock_bh(&ipa_ctx->q_lock); 328 329 if (qdf_mem_smmu_s1_enabled(osdev)) { 330 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) 331 qdf_nbuf_mapped_paddr_set(skb, paddr); 332 333 qdf_nbuf_unmap(osdev, skb, QDF_DMA_TO_DEVICE); 334 } 335 336 qdf_ipa_free_skb(ipa_tx_desc); 337 wlan_ipa_wdi_rm_try_release(ipa_ctx); 338 return; 339 } 340 341 skb = cdp_ipa_tx_send_data_frame(ipa_ctx->dp_soc, 342 iface_context->session_id, 343 QDF_IPA_RX_DATA_SKB(ipa_tx_desc)); 344 if (skb) { 345 qdf_nbuf_free(skb); 346 iface_context->stats.num_tx_err++; 347 return; 348 } 349 350 atomic_inc(&ipa_ctx->tx_ref_cnt); 351 352 iface_context->stats.num_tx++; 353 } 354 355 /** 356 * wlan_ipa_forward() - handle packet forwarding to wlan tx 357 * @ipa_ctx: pointer to ipa ipa context 358 * @iface_ctx: interface context 359 * @skb: data pointer 360 * 361 * if exception packet has set forward bit, copied new packet should be 362 * forwarded to wlan tx. if wlan subsystem is in suspend state, packet should 363 * put into pm queue and tx procedure will be differed 364 * 365 * Return: None 366 */ 367 static void wlan_ipa_forward(struct wlan_ipa_priv *ipa_ctx, 368 struct wlan_ipa_iface_context *iface_ctx, 369 qdf_nbuf_t skb) 370 { 371 struct wlan_ipa_pm_tx_cb *pm_tx_cb; 372 373 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 374 375 /* Set IPA ownership for intra-BSS Tx packets to avoid skb_orphan */ 376 qdf_nbuf_ipa_owned_set(skb); 377 378 /* WLAN subsystem is in suspend, put in queue */ 379 if (ipa_ctx->suspended) { 380 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 381 ipa_info_rl("Tx in suspend, put in queue"); 382 qdf_mem_zero(skb->cb, sizeof(skb->cb)); 383 pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; 384 pm_tx_cb->exception = true; 385 pm_tx_cb->iface_context = iface_ctx; 386 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 387 qdf_nbuf_queue_add(&ipa_ctx->pm_queue_head, skb); 388 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 389 ipa_ctx->stats.num_tx_queued++; 390 } else { 391 /* Resume, put packet into WLAN TX */ 392 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 393 394 if (ipa_ctx->softap_xmit) { 395 if (ipa_ctx->softap_xmit(skb, iface_ctx->dev)) { 396 ipa_err_rl("packet Tx fail"); 397 ipa_ctx->stats.num_tx_fwd_err++; 398 } else { 399 ipa_ctx->stats.num_tx_fwd_ok++; 400 } 401 } else { 402 dev_kfree_skb_any(skb); 403 } 404 } 405 } 406 407 /** 408 * wlan_ipa_intrabss_forward() - Forward intra bss packets. 409 * @ipa_ctx: pointer to IPA IPA struct 410 * @iface_ctx: ipa interface context 411 * @desc: Firmware descriptor 412 * @skb: Data buffer 413 * 414 * Return: 415 * WLAN_IPA_FORWARD_PKT_NONE 416 * WLAN_IPA_FORWARD_PKT_DISCARD 417 * WLAN_IPA_FORWARD_PKT_LOCAL_STACK 418 * 419 */ 420 421 #ifndef QCA_IPA_LL_TX_FLOW_CONTROL 422 static inline 423 bool wlan_ipa_tx_desc_thresh_reached(struct cdp_soc_t *soc, uint8_t vdev_id) 424 { 425 return cdp_tx_desc_thresh_reached(soc, vdev_id); 426 } 427 428 static inline 429 bool wlan_ipa_get_peer_state(struct cdp_soc_t *soc, uint8_t vdev_id, 430 uint8_t *peer_mac) 431 { 432 if (cdp_peer_state_get(soc, vdev_id, peer_mac) == 433 OL_TXRX_PEER_STATE_AUTH) 434 return true; 435 436 return false; 437 } 438 #else 439 static inline 440 bool wlan_ipa_tx_desc_thresh_reached(struct cdp_soc_t *soc, uint8_t vdev_id) 441 { 442 return false; 443 } 444 445 static inline 446 bool wlan_ipa_get_peer_state(struct cdp_soc_t *soc, uint8_t vdev_id, 447 uint8_t *peer_mac) 448 { 449 return cdp_peer_get_authorize(soc, vdev_id, peer_mac); 450 } 451 #endif 452 453 static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward( 454 struct wlan_ipa_priv *ipa_ctx, 455 struct wlan_ipa_iface_context *iface_ctx, 456 uint8_t desc, 457 qdf_nbuf_t skb) 458 { 459 int ret = WLAN_IPA_FORWARD_PKT_NONE; 460 void *soc = ipa_ctx->dp_soc; 461 462 if ((desc & FW_RX_DESC_FORWARD_M)) { 463 if (wlan_ipa_tx_desc_thresh_reached(soc, 464 iface_ctx->session_id)) { 465 /* Drop the packet*/ 466 ipa_ctx->stats.num_tx_fwd_err++; 467 goto drop_pkt; 468 } 469 470 ipa_debug_rl("Forward packet to Tx (fw_desc=%d)", desc); 471 ipa_ctx->ipa_tx_forward++; 472 473 if ((desc & FW_RX_DESC_DISCARD_M)) { 474 wlan_ipa_forward(ipa_ctx, iface_ctx, skb); 475 ipa_ctx->ipa_rx_internal_drop_count++; 476 ipa_ctx->ipa_rx_discard++; 477 ret = WLAN_IPA_FORWARD_PKT_DISCARD; 478 } else { 479 struct sk_buff *cloned_skb = skb_clone(skb, GFP_ATOMIC); 480 481 if (cloned_skb) 482 wlan_ipa_forward(ipa_ctx, iface_ctx, 483 cloned_skb); 484 else 485 ipa_err_rl("tx skb alloc failed"); 486 ret = WLAN_IPA_FORWARD_PKT_LOCAL_STACK; 487 } 488 } 489 return ret; 490 491 drop_pkt: 492 dev_kfree_skb_any(skb); 493 ret = WLAN_IPA_FORWARD_PKT_DISCARD; 494 return ret; 495 } 496 497 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || \ 498 defined(CONFIG_IPA_WDI_UNIFIED_API) 499 /* 500 * TODO: Get WDI version through FW capabilities 501 */ 502 #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ 503 defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) || \ 504 defined(QCA_WIFI_WCN7850) || defined(QCA_WIFI_QCN9000) 505 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx) 506 { 507 ipa_ctx->wdi_version = IPA_WDI_3; 508 } 509 #elif defined(QCA_WIFI_KIWI) || defined(QCA_WIFI_KIWI_V2) 510 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx) 511 { 512 ipa_ctx->wdi_version = IPA_WDI_3_V2; 513 } 514 #elif defined(QCA_WIFI_3_0) 515 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx) 516 { 517 ipa_ctx->wdi_version = IPA_WDI_2; 518 } 519 #else 520 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx) 521 { 522 ipa_ctx->wdi_version = IPA_WDI_1; 523 } 524 #endif 525 526 static inline bool wlan_ipa_wdi_is_smmu_enabled(struct wlan_ipa_priv *ipa_ctx, 527 qdf_device_t osdev) 528 { 529 return ipa_ctx->is_smmu_enabled && qdf_mem_smmu_s1_enabled(osdev); 530 } 531 532 #ifdef IPA_WDS_EASYMESH_FEATURE 533 /** 534 * wlan_ipa_ast_notify_cb() - IPA AST create/update CB 535 * @priv: IPA context 536 * @data: Structure used for updating the AST table 537 * 538 * Will be called by IPA context. 539 * 540 * Return: None 541 */ 542 static void wlan_ipa_ast_notify_cb(void *priv, void *data) 543 { 544 qdf_ipa_ast_info_type_t *ast_info; 545 struct wlan_ipa_priv *ipa_ctx; 546 547 if (!data) { 548 dp_err("Invalid IPA AST data context"); 549 return; 550 } 551 552 if (!priv) { 553 dp_err("Invalid IPA context"); 554 return; 555 } 556 557 ast_info = (qdf_ipa_ast_info_type_t *)data; 558 ipa_ctx = (struct wlan_ipa_priv *)priv; 559 560 cdp_ipa_ast_create(ipa_ctx->dp_soc, ast_info); 561 } 562 #else 563 static inline void wlan_ipa_ast_notify_cb(void *priv, void *data) 564 { 565 } 566 #endif 567 568 static inline QDF_STATUS 569 wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx, 570 qdf_device_t osdev) 571 { 572 qdf_ipa_sys_connect_params_t *sys_in = NULL; 573 int i; 574 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 575 576 sys_in = qdf_mem_malloc(sizeof(*sys_in) * WLAN_IPA_MAX_IFACE); 577 if (!sys_in) 578 return QDF_STATUS_E_NOMEM; 579 580 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) 581 qdf_mem_copy(sys_in + i, 582 &ipa_ctx->sys_pipe[i].ipa_sys_params, 583 sizeof(qdf_ipa_sys_connect_params_t)); 584 585 qdf_status = cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, 586 wlan_ipa_i2w_cb, wlan_ipa_w2i_cb, 587 wlan_ipa_wdi_meter_notifier_cb, 588 ipa_ctx->config->desc_size, 589 ipa_ctx, 590 wlan_ipa_is_rm_enabled(ipa_ctx->config), 591 &ipa_ctx->tx_pipe_handle, 592 &ipa_ctx->rx_pipe_handle, 593 wlan_ipa_wdi_is_smmu_enabled(ipa_ctx, osdev), 594 sys_in, ipa_ctx->over_gsi, ipa_ctx->hdl, 595 (qdf_ipa_wdi_hdl_t)ipa_ctx->instance_id, 596 wlan_ipa_ast_notify_cb); 597 598 qdf_mem_free(sys_in); 599 600 return qdf_status; 601 } 602 603 #ifdef FEATURE_METERING 604 /** 605 * wlan_ipa_wdi_init_metering() - IPA WDI metering init 606 * @ipa_ctx: IPA context 607 * @in: IPA WDI in param 608 * 609 * Return: QDF_STATUS 610 */ 611 static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt, 612 qdf_ipa_wdi_init_in_params_t *in) 613 { 614 QDF_IPA_WDI_INIT_IN_PARAMS_WDI_NOTIFY(in) = 615 wlan_ipa_wdi_meter_notifier_cb; 616 } 617 #else 618 static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt, 619 qdf_ipa_wdi_init_in_params_t *in) 620 { 621 } 622 #endif 623 624 #ifdef IPA_WDS_EASYMESH_FEATURE 625 /** 626 * wlan_ipa_update_wds_params(); 627 * @ipa_ctx: IPA context 628 * @in: IPA wdi init in params 629 * 630 * This function is to update wds status to IPA in wdi init params 631 * 632 * Return: None 633 */ 634 static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx, 635 qdf_ipa_wdi_init_in_params_t *in) 636 { 637 QDF_IPA_WDI_INIT_IN_PARAMS_WDS_UPDATE(in) = ipa_ctx->config->ipa_wds; 638 } 639 640 /** 641 * wlan_ipa_msg_wds_update(); 642 * @ipa_wds: IPA WDS status 643 * @msg: Meta data message for IPA 644 * 645 * This function is to update wds status to IPA in meta message 646 * 647 * Return: None 648 */ 649 static void wlan_ipa_msg_wds_update(bool ipa_wds, 650 qdf_ipa_wlan_msg_t *msg) 651 { 652 QDF_IPA_WLAN_MSG_WDS_UPDATE(msg) = ipa_wds; 653 } 654 #else 655 static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx, 656 qdf_ipa_wdi_init_in_params_t *in) 657 { 658 } 659 660 static void wlan_ipa_msg_wds_update(bool ipa_wds, 661 qdf_ipa_wlan_msg_t *msg) 662 { 663 } 664 #endif 665 666 /** 667 * wlan_ipa_wdi_init() - IPA WDI init 668 * @ipa_ctx: IPA context 669 * 670 * Return: QDF_STATUS 671 */ 672 static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx) 673 { 674 qdf_ipa_wdi_init_in_params_t in; 675 qdf_ipa_wdi_init_out_params_t out; 676 int ret; 677 678 ipa_ctx->uc_loaded = false; 679 680 qdf_mem_zero(&in, sizeof(in)); 681 qdf_mem_zero(&out, sizeof(out)); 682 683 QDF_IPA_WDI_INIT_IN_PARAMS_WDI_VERSION(&in) = ipa_ctx->wdi_version; 684 QDF_IPA_WDI_INIT_IN_PARAMS_NOTIFY(&in) = wlan_ipa_uc_loaded_uc_cb; 685 QDF_IPA_WDI_INIT_IN_PARAMS_PRIV(&in) = ipa_ctx; 686 QDF_IPA_WDI_INIT_IN_PARAMS_INSTANCE_ID(&in) = ipa_ctx->instance_id; 687 wlan_ipa_update_wds_params(ipa_ctx, &in); 688 wlan_ipa_wdi_init_metering(ipa_ctx, &in); 689 ret = qdf_ipa_wdi_init(&in, &out); 690 if (ret) { 691 ipa_err("ipa_wdi_init failed with ret=%d", ret); 692 return QDF_STATUS_E_FAILURE; 693 } 694 695 ipa_ctx->over_gsi = 696 QDF_IPA_WDI_INIT_OUT_PARAMS_IS_OVER_GSI(&out); 697 ipa_ctx->is_smmu_enabled = 698 QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out); 699 ipa_ctx->hdl = QDF_IPA_WDI_INIT_OUT_PARAMS_HANDLE(&out); 700 701 ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d, handle: %d", 702 ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled, ipa_ctx->hdl); 703 704 if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) { 705 ipa_debug("IPA uC READY"); 706 ipa_ctx->uc_loaded = true; 707 } else { 708 ipa_info("IPA uc not ready"); 709 return QDF_STATUS_E_BUSY; 710 } 711 712 return QDF_STATUS_SUCCESS; 713 } 714 715 static inline int wlan_ipa_wdi_cleanup(qdf_ipa_wdi_hdl_t hdl) 716 { 717 int ret; 718 719 ret = qdf_ipa_wdi_cleanup(hdl); 720 if (ret) 721 ipa_info("ipa_wdi_cleanup failed ret=%d", ret); 722 return ret; 723 } 724 725 static inline int wlan_ipa_wdi_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx, 726 struct ipa_sys_connect_params *sys, 727 uint32_t *handle) 728 { 729 return 0; 730 } 731 732 static inline int wlan_ipa_wdi_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx, 733 uint32_t handle) 734 { 735 return 0; 736 } 737 738 /** 739 * wlan_ipa_pm_flush() - flush queued packets 740 * @work: pointer to the scheduled work 741 * 742 * Called during PM resume to send packets to TL which were queued 743 * while host was in the process of suspending. 744 * 745 * Return: None 746 */ 747 static void wlan_ipa_pm_flush(void *data) 748 { 749 struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data; 750 struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL; 751 qdf_nbuf_t skb; 752 uint32_t dequeued = 0; 753 754 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 755 while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) != 756 NULL)) { 757 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 758 759 pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; 760 dequeued++; 761 762 if (pm_tx_cb->exception) { 763 if (ipa_ctx->softap_xmit && 764 pm_tx_cb->iface_context->dev) { 765 ipa_ctx->softap_xmit(skb, 766 pm_tx_cb->iface_context->dev); 767 ipa_ctx->stats.num_tx_fwd_ok++; 768 } else { 769 dev_kfree_skb_any(skb); 770 } 771 } else { 772 wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, 773 pm_tx_cb->ipa_tx_desc); 774 } 775 776 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 777 } 778 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 779 780 ipa_ctx->stats.num_tx_dequeued += dequeued; 781 if (dequeued > ipa_ctx->stats.num_max_pm_queue) 782 ipa_ctx->stats.num_max_pm_queue = dequeued; 783 } 784 785 int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr) 786 { 787 if (!ipa_cb_is_ready()) { 788 ipa_info("IPA is not READY"); 789 return 0; 790 } 791 792 if (!num_buf) { 793 ipa_info("No buffers to map/unmap"); 794 return 0; 795 } 796 /** 797 * This API will compile for prelithium chipset 798 * where we have only one soc so passing default 799 * handle to IPA which is 0. 800 */ 801 if (map) 802 return qdf_ipa_wdi_create_smmu_mapping(IPA_DEFAULT_HDL, 803 num_buf, buf_arr); 804 else 805 return qdf_ipa_wdi_release_smmu_mapping(IPA_DEFAULT_HDL, 806 num_buf, buf_arr); 807 return 0; 808 } 809 810 #ifdef MDM_PLATFORM 811 /** 812 * is_rx_dest_bridge_dev() - is RX skb bridge device terminated 813 * @iface_ctx: pointer to WLAN IPA interface context 814 * @nbuf: skb buffer 815 * 816 * Check if skb is destined for bridge device, where SAP is a bridge 817 * port of it. 818 * 819 * FIXME: If there's a BH lockless API to check if destination MAC 820 * address is a valid peer, this check can be deleted. Currently 821 * dp_find_peer_by_addr() is used to check if destination MAC 822 * is a valid peer. Since WLAN IPA RX is in process context, 823 * qdf_spin_lock_bh in dp_find_peer_by_addr() turns to spin_lock_bh 824 * and this BH lock hurts netif_rx. 825 * 826 * Return: true/false 827 */ 828 static bool is_rx_dest_bridge_dev(struct wlan_ipa_iface_context *iface_ctx, 829 qdf_nbuf_t nbuf) 830 { 831 qdf_netdev_t master_ndev; 832 qdf_netdev_t ndev; 833 struct ethhdr *eh; 834 uint8_t da_is_bcmc; 835 bool ret; 836 837 /* 838 * WDI 3.0 skb->cb[] info from IPA driver 839 * skb->cb[0] = vdev_id 840 * skb->cb[1].bit#1 = da_is_bcmc 841 */ 842 da_is_bcmc = ((uint8_t)nbuf->cb[1]) & 0x2; 843 if (da_is_bcmc) 844 return false; 845 846 ndev = iface_ctx->dev; 847 if (!ndev) 848 return false; 849 850 if (!netif_is_bridge_port(ndev)) 851 return false; 852 853 qal_vbus_rcu_read_lock(); 854 855 master_ndev = netdev_master_upper_dev_get_rcu(ndev); 856 if (!master_ndev) { 857 ret = false; 858 goto out; 859 } 860 861 eh = (struct ethhdr *)qdf_nbuf_data(nbuf); 862 if (qdf_mem_cmp(eh->h_dest, master_ndev->dev_addr, QDF_MAC_ADDR_SIZE)) { 863 ret = false; 864 goto out; 865 } 866 867 ret = true; 868 869 out: 870 qal_vbus_rcu_read_unlock(); 871 return ret; 872 } 873 #else /* !MDM_PLATFORM */ 874 static bool is_rx_dest_bridge_dev(struct wlan_ipa_iface_context *iface_ctx, 875 qdf_nbuf_t nbuf) 876 { 877 return false; 878 } 879 #endif /* MDM_PLATFORM */ 880 881 static enum wlan_ipa_forward_type 882 wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx, 883 struct wlan_ipa_iface_context *iface_ctx, 884 qdf_nbuf_t nbuf) 885 { 886 uint8_t fw_desc = 0; 887 bool fwd_success; 888 int ret; 889 890 /* legacy intra-bss fowarding for WDI 1.0 and 2.0 */ 891 if (ipa_ctx->wdi_version < IPA_WDI_3) { 892 fw_desc = (uint8_t)nbuf->cb[1]; 893 return wlan_ipa_intrabss_forward(ipa_ctx, iface_ctx, fw_desc, 894 nbuf); 895 } 896 897 if (is_rx_dest_bridge_dev(iface_ctx, nbuf)) { 898 fwd_success = 0; 899 ret = WLAN_IPA_FORWARD_PKT_LOCAL_STACK; 900 goto exit; 901 } 902 903 if (cdp_ipa_rx_intrabss_fwd(ipa_ctx->dp_soc, iface_ctx->session_id, 904 nbuf, &fwd_success)) { 905 ipa_ctx->ipa_rx_internal_drop_count++; 906 ipa_ctx->ipa_rx_discard++; 907 908 ret = WLAN_IPA_FORWARD_PKT_DISCARD; 909 } else { 910 ret = WLAN_IPA_FORWARD_PKT_LOCAL_STACK; 911 } 912 913 exit: 914 if (fwd_success) 915 ipa_ctx->stats.num_tx_fwd_ok++; 916 else 917 ipa_ctx->stats.num_tx_fwd_err++; 918 919 return ret; 920 } 921 922 #else /* CONFIG_IPA_WDI_UNIFIED_API */ 923 924 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx) 925 { 926 } 927 928 static inline int wlan_ipa_wdi_is_smmu_enabled(struct wlan_ipa_priv *ipa_ctx, 929 qdf_device_t osdev) 930 { 931 return qdf_mem_smmu_s1_enabled(osdev); 932 } 933 934 static inline QDF_STATUS wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx, 935 qdf_device_t osdev) 936 { 937 return cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, 938 wlan_ipa_i2w_cb, wlan_ipa_w2i_cb, 939 wlan_ipa_wdi_meter_notifier_cb, 940 ipa_ctx->config->desc_size, 941 ipa_ctx, wlan_ipa_is_rm_enabled(ipa_ctx->config), 942 &ipa_ctx->tx_pipe_handle, 943 &ipa_ctx->rx_pipe_handle); 944 } 945 946 static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx) 947 { 948 struct ipa_wdi_uc_ready_params uc_ready_param; 949 950 ipa_ctx->uc_loaded = false; 951 uc_ready_param.priv = (void *)ipa_ctx; 952 uc_ready_param.notify = wlan_ipa_uc_loaded_uc_cb; 953 if (qdf_ipa_uc_reg_rdyCB(&uc_ready_param)) { 954 ipa_info("UC Ready CB register fail"); 955 return QDF_STATUS_E_FAILURE; 956 } 957 958 if (true == uc_ready_param.is_uC_ready) { 959 ipa_info("UC Ready"); 960 ipa_ctx->uc_loaded = true; 961 } else { 962 return QDF_STATUS_E_BUSY; 963 } 964 965 return QDF_STATUS_SUCCESS; 966 } 967 968 static inline int wlan_ipa_wdi_cleanup(void) 969 { 970 int ret; 971 972 ret = qdf_ipa_uc_dereg_rdyCB(); 973 if (ret) 974 ipa_info("UC Ready CB deregister fail"); 975 return ret; 976 } 977 978 static inline int wlan_ipa_wdi_setup_sys_pipe( 979 struct wlan_ipa_priv *ipa_ctx, 980 struct ipa_sys_connect_params *sys, uint32_t *handle) 981 { 982 return qdf_ipa_setup_sys_pipe(sys, handle); 983 } 984 985 static inline int wlan_ipa_wdi_teardown_sys_pipe( 986 struct wlan_ipa_priv *ipa_ctx, 987 uint32_t handle) 988 { 989 return qdf_ipa_teardown_sys_pipe(handle); 990 } 991 992 /** 993 * wlan_ipa_pm_flush() - flush queued packets 994 * @work: pointer to the scheduled work 995 * 996 * Called during PM resume to send packets to TL which were queued 997 * while host was in the process of suspending. 998 * 999 * Return: None 1000 */ 1001 static void wlan_ipa_pm_flush(void *data) 1002 { 1003 struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data; 1004 struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL; 1005 qdf_nbuf_t skb; 1006 uint32_t dequeued = 0; 1007 1008 qdf_wake_lock_acquire(&ipa_ctx->wake_lock, 1009 WIFI_POWER_EVENT_WAKELOCK_IPA); 1010 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 1011 while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) != 1012 NULL)) { 1013 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 1014 1015 pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; 1016 dequeued++; 1017 1018 if (pm_tx_cb->exception) { 1019 if (ipa_ctx->softap_xmit && 1020 pm_tx_cb->iface_context->dev) { 1021 ipa_ctx->softap_xmit(skb, 1022 pm_tx_cb->iface_context->dev); 1023 ipa_ctx->stats.num_tx_fwd_ok++; 1024 } else { 1025 dev_kfree_skb_any(skb); 1026 } 1027 } else { 1028 wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, 1029 pm_tx_cb->ipa_tx_desc); 1030 } 1031 1032 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 1033 } 1034 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 1035 qdf_wake_lock_release(&ipa_ctx->wake_lock, 1036 WIFI_POWER_EVENT_WAKELOCK_IPA); 1037 1038 ipa_ctx->stats.num_tx_dequeued += dequeued; 1039 if (dequeued > ipa_ctx->stats.num_max_pm_queue) 1040 ipa_ctx->stats.num_max_pm_queue = dequeued; 1041 } 1042 1043 int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr) 1044 { 1045 if (!num_buf) { 1046 ipa_info("No buffers to map/unmap"); 1047 return 0; 1048 } 1049 1050 if (map) 1051 return qdf_ipa_wdi_create_smmu_mapping(IPA_DEFAULT_HDL, 1052 num_buf, buf_arr); 1053 else 1054 return qdf_ipa_wdi_release_smmu_mapping(IPA_DEFAULT_HDL, 1055 num_buf, buf_arr); 1056 return 0; 1057 } 1058 1059 static enum wlan_ipa_forward_type 1060 wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx, 1061 struct wlan_ipa_iface_context *iface_ctx, 1062 qdf_nbuf_t nbuf) 1063 { 1064 uint8_t fw_desc; 1065 1066 fw_desc = (uint8_t)nbuf->cb[1]; 1067 1068 return wlan_ipa_intrabss_forward(ipa_ctx, iface_ctx, fw_desc, nbuf); 1069 } 1070 1071 #endif /* CONFIG_IPA_WDI_UNIFIED_API */ 1072 1073 /** 1074 * wlan_ipa_send_sta_eapol_to_nw() - Send Rx EAPOL pkt for STA to Kernel 1075 * @skb: network buffer 1076 * 1077 * Called when a EAPOL packet is received via IPA Exception path 1078 * before wlan_ipa_setup_iface is done for STA. 1079 * 1080 * Return: 0 on success, err_code for failure. 1081 */ 1082 static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb, 1083 struct wlan_objmgr_pdev *pdev) 1084 { 1085 struct wlan_ipa_priv *ipa_ctx; 1086 struct ethhdr *eh; 1087 struct wlan_objmgr_vdev *vdev = NULL; 1088 1089 ipa_ctx = ipa_pdev_get_priv_obj(pdev); 1090 if (!ipa_ctx) 1091 return -EINVAL; 1092 1093 eh = (struct ethhdr *)qdf_nbuf_data(skb); 1094 vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev( 1095 pdev, eh->h_dest, WLAN_IPA_ID); 1096 if (!vdev) { 1097 ipa_err_rl("Invalid vdev"); 1098 return -EINVAL; 1099 } 1100 1101 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) { 1102 ipa_err_rl("device_mode is not STA"); 1103 wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID); 1104 return -EINVAL; 1105 } 1106 1107 skb->destructor = wlan_ipa_uc_rt_debug_destructor; 1108 1109 if (ipa_ctx->send_to_nw) 1110 ipa_ctx->send_to_nw(skb, vdev->vdev_nif.osdev->wdev->netdev); 1111 1112 ipa_ctx->ipa_rx_net_send_count++; 1113 ipa_ctx->stats.num_rx_no_iface_eapol++; 1114 wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID); 1115 return 0; 1116 } 1117 1118 /** 1119 * wlan_ipa_send_skb_to_network() - Send skb to kernel 1120 * @skb: network buffer 1121 * @iface_ctx: IPA interface context 1122 * 1123 * Called when a network buffer is received which should not be routed 1124 * to the IPA module. 1125 * 1126 * Return: None 1127 */ 1128 static void 1129 wlan_ipa_send_skb_to_network(qdf_nbuf_t skb, 1130 struct wlan_ipa_iface_context *iface_ctx) 1131 { 1132 struct wlan_ipa_priv *ipa_ctx; 1133 1134 ipa_ctx = iface_ctx->ipa_ctx; 1135 1136 if (!iface_ctx->dev) { 1137 ipa_debug_rl("Invalid interface"); 1138 ipa_ctx->ipa_rx_internal_drop_count++; 1139 dev_kfree_skb_any(skb); 1140 return; 1141 } 1142 1143 skb->destructor = wlan_ipa_uc_rt_debug_destructor; 1144 1145 if (ipa_ctx->send_to_nw) 1146 ipa_ctx->send_to_nw(skb, iface_ctx->dev); 1147 1148 ipa_ctx->ipa_rx_net_send_count++; 1149 } 1150 1151 /** 1152 * wlan_ipa_eapol_intrabss_fwd_check() - Check if eapol pkt intrabss fwd is 1153 * allowed or not 1154 * @ipa_ctx: IPA global context 1155 * @vdev_id: vdev id 1156 * @nbuf: network buffer 1157 * 1158 * Return: true if intrabss fwd is allowed for eapol else false 1159 */ 1160 static bool 1161 wlan_ipa_eapol_intrabss_fwd_check(struct wlan_ipa_priv *ipa_ctx, 1162 uint8_t vdev_id, qdf_nbuf_t nbuf) 1163 { 1164 uint8_t *vdev_mac_addr; 1165 1166 vdev_mac_addr = cdp_get_vdev_mac_addr(ipa_ctx->dp_soc, vdev_id); 1167 1168 if (!vdev_mac_addr) 1169 return false; 1170 1171 if (qdf_mem_cmp(qdf_nbuf_data(nbuf) + QDF_NBUF_DEST_MAC_OFFSET, 1172 vdev_mac_addr, QDF_MAC_ADDR_SIZE)) 1173 return false; 1174 1175 return true; 1176 } 1177 1178 #ifdef MDM_PLATFORM 1179 static inline void 1180 wlan_ipa_set_sap_client_auth(struct wlan_ipa_priv *ipa_ctx, uint8_t *peer_mac, 1181 uint8_t is_authenticated) 1182 { 1183 uint8_t idx; 1184 struct ipa_uc_stas_map *sta_map; 1185 1186 for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) { 1187 sta_map = &ipa_ctx->assoc_stas_map[idx]; 1188 if (sta_map->is_reserved && 1189 qdf_is_macaddr_equal(&sta_map->mac_addr, 1190 (struct qdf_mac_addr *)peer_mac)) { 1191 sta_map->is_authenticated = is_authenticated; 1192 break; 1193 } 1194 } 1195 } 1196 1197 static inline uint8_t 1198 wlan_ipa_get_sap_client_auth(struct wlan_ipa_priv *ipa_ctx, uint8_t *peer_mac) 1199 { 1200 uint8_t idx; 1201 struct ipa_uc_stas_map *sta_map; 1202 1203 for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) { 1204 sta_map = &ipa_ctx->assoc_stas_map[idx]; 1205 if (sta_map->is_reserved && 1206 qdf_is_macaddr_equal(&sta_map->mac_addr, 1207 (struct qdf_mac_addr *)peer_mac)) { 1208 return sta_map->is_authenticated; 1209 } 1210 } 1211 1212 return false; 1213 } 1214 1215 #ifdef IPA_WDS_EASYMESH_FEATURE 1216 static inline uint8_t 1217 wlan_ipa_get_peer_auth_state(ol_txrx_soc_handle dp_soc, uint8_t *peer_mac, 1218 struct wlan_ipa_iface_context *iface) 1219 { 1220 uint8_t is_authenticated = false; 1221 struct cdp_ast_entry_info ast_info = {0}; 1222 1223 if (ipa_is_wds_enabled()) { 1224 cdp_peer_get_ast_info_by_soc(dp_soc, peer_mac, 1225 &ast_info); 1226 peer_mac = &ast_info.peer_mac_addr[0]; 1227 is_authenticated = wlan_ipa_get_peer_state(dp_soc, 1228 iface->session_id, 1229 peer_mac); 1230 } else { 1231 is_authenticated = wlan_ipa_get_peer_state(dp_soc, 1232 iface->session_id, 1233 peer_mac); 1234 } 1235 1236 return is_authenticated; 1237 } 1238 #else 1239 static inline uint8_t 1240 wlan_ipa_get_peer_auth_state(ol_txrx_soc_handle dp_soc, uint8_t *peer_mac, 1241 struct wlan_ipa_iface_context *iface) 1242 { 1243 uint8_t is_authenticated = false; 1244 1245 is_authenticated = wlan_ipa_get_peer_state(dp_soc, iface->session_id, 1246 peer_mac); 1247 1248 return is_authenticated; 1249 } 1250 #endif 1251 1252 static inline bool 1253 wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc, 1254 struct wlan_ipa_iface_context *iface, 1255 uint8_t *peer_mac) 1256 { 1257 uint8_t is_authenticated = false; 1258 1259 if (iface->device_mode == QDF_SAP_MODE) { 1260 is_authenticated = wlan_ipa_get_sap_client_auth(iface->ipa_ctx, 1261 peer_mac); 1262 if (is_authenticated) 1263 return is_authenticated; 1264 1265 is_authenticated = wlan_ipa_get_peer_auth_state(dp_soc, 1266 peer_mac, 1267 iface); 1268 1269 if (is_authenticated) 1270 wlan_ipa_set_sap_client_auth(iface->ipa_ctx, 1271 peer_mac, 1272 true); 1273 1274 } else if (iface->device_mode == QDF_STA_MODE) { 1275 is_authenticated = iface->is_authenticated; 1276 if (is_authenticated) 1277 return is_authenticated; 1278 is_authenticated = wlan_ipa_get_peer_state(dp_soc, 1279 iface->session_id, 1280 peer_mac); 1281 if (is_authenticated) 1282 iface->is_authenticated = true; 1283 } 1284 1285 return is_authenticated; 1286 } 1287 #else /* !MDM_PLATFORM */ 1288 static inline void 1289 wlan_ipa_set_sap_client_auth(struct wlan_ipa_priv *ipa_ctx, uint8_t *peer_mac, 1290 uint8_t is_authenticated) 1291 {} 1292 1293 static inline bool 1294 wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc, 1295 struct wlan_ipa_iface_context *iface, 1296 uint8_t *peer_mac) 1297 { 1298 uint8_t is_authenticated = 0; 1299 1300 is_authenticated = wlan_ipa_get_peer_state(dp_soc, 1301 iface->session_id, 1302 peer_mac); 1303 1304 return is_authenticated; 1305 } 1306 #endif /* MDM_PLATFORM */ 1307 1308 /** 1309 * __wlan_ipa_w2i_cb() - WLAN to IPA callback handler 1310 * @priv: pointer to private data registered with IPA (we register a 1311 * pointer to the global IPA context) 1312 * @evt: the IPA event which triggered the callback 1313 * @data: data associated with the event 1314 * 1315 * Return: None 1316 */ 1317 static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, 1318 unsigned long data) 1319 { 1320 struct wlan_ipa_priv *ipa_ctx = NULL; 1321 qdf_nbuf_t skb; 1322 uint8_t iface_id; 1323 uint8_t session_id = 0xff; 1324 struct wlan_ipa_iface_context *iface_context; 1325 bool is_eapol_wapi = false; 1326 struct qdf_mac_addr peer_mac_addr = QDF_MAC_ADDR_ZERO_INIT; 1327 1328 ipa_ctx = (struct wlan_ipa_priv *)priv; 1329 if (!ipa_ctx) { 1330 if (evt == IPA_RECEIVE) { 1331 skb = (qdf_nbuf_t)data; 1332 dev_kfree_skb_any(skb); 1333 } 1334 return; 1335 } 1336 1337 switch (evt) { 1338 case IPA_RECEIVE: 1339 skb = (qdf_nbuf_t) data; 1340 if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 1341 session_id = (uint8_t)skb->cb[0]; 1342 iface_id = ipa_ctx->vdev_to_iface[session_id]; 1343 ipa_ctx->stats.num_rx_excep++; 1344 qdf_nbuf_pull_head(skb, WLAN_IPA_UC_WLAN_CLD_HDR_LEN); 1345 } else { 1346 iface_id = WLAN_IPA_GET_IFACE_ID(skb->data); 1347 qdf_nbuf_pull_head(skb, WLAN_IPA_WLAN_CLD_HDR_LEN); 1348 } 1349 1350 if (iface_id >= WLAN_IPA_MAX_IFACE) { 1351 ipa_err_rl("Invalid iface_id %u,session_id %x %x %x %x", 1352 iface_id, session_id, (uint8_t)skb->cb[1], 1353 (uint8_t)skb->cb[2], (uint8_t)skb->cb[3]); 1354 1355 if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) { 1356 ipa_err_rl("EAPOL pkt. Sending to NW!"); 1357 if (!wlan_ipa_send_sta_eapol_to_nw( 1358 skb, ipa_ctx->pdev)) 1359 break; 1360 } 1361 ipa_err_rl("Pkt Dropped!"); 1362 ipa_ctx->ipa_rx_internal_drop_count++; 1363 dev_kfree_skb_any(skb); 1364 return; 1365 } 1366 1367 iface_context = &ipa_ctx->iface_context[iface_id]; 1368 if (iface_context->session_id >= WLAN_IPA_MAX_SESSION) { 1369 ipa_err_rl("session_id of iface_id %u is invalid:%d", 1370 iface_id, iface_context->session_id); 1371 ipa_ctx->ipa_rx_internal_drop_count++; 1372 dev_kfree_skb_any(skb); 1373 return; 1374 } 1375 iface_context->stats.num_rx_ipa_excep++; 1376 1377 if (iface_context->device_mode == QDF_STA_MODE) 1378 qdf_copy_macaddr(&peer_mac_addr, &iface_context->bssid); 1379 else if (iface_context->device_mode == QDF_SAP_MODE) 1380 qdf_mem_copy(&peer_mac_addr.bytes[0], 1381 qdf_nbuf_data(skb) + 1382 QDF_NBUF_SRC_MAC_OFFSET, 1383 QDF_MAC_ADDR_SIZE); 1384 1385 if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) { 1386 is_eapol_wapi = true; 1387 if (iface_context->device_mode == QDF_SAP_MODE && 1388 !wlan_ipa_eapol_intrabss_fwd_check(ipa_ctx, 1389 iface_context->session_id, skb)) { 1390 ipa_err_rl("EAPOL intrabss fwd drop DA:" QDF_MAC_ADDR_FMT, 1391 QDF_MAC_ADDR_REF(qdf_nbuf_data(skb) + 1392 QDF_NBUF_DEST_MAC_OFFSET)); 1393 ipa_ctx->ipa_rx_internal_drop_count++; 1394 dev_kfree_skb_any(skb); 1395 return; 1396 } 1397 } else if (qdf_nbuf_is_ipv4_wapi_pkt(skb)) { 1398 is_eapol_wapi = true; 1399 } 1400 1401 /* 1402 * Check for peer authorized state before allowing 1403 * non-EAPOL/WAPI frames to be intrabss forwarded 1404 * or submitted to stack. 1405 */ 1406 if (!wlan_ipa_is_peer_authenticated(ipa_ctx->dp_soc, 1407 iface_context, 1408 &peer_mac_addr.bytes[0]) && 1409 !is_eapol_wapi) { 1410 ipa_err_rl("Non EAPOL/WAPI packet received when peer " QDF_MAC_ADDR_FMT " is unauthorized", 1411 QDF_MAC_ADDR_REF(peer_mac_addr.bytes)); 1412 ipa_ctx->ipa_rx_internal_drop_count++; 1413 dev_kfree_skb_any(skb); 1414 return; 1415 } 1416 1417 /* Disable to forward Intra-BSS Rx packets when 1418 * ap_isolate=1 in hostapd.conf 1419 */ 1420 if (!ipa_ctx->disable_intrabss_fwd[iface_context->session_id] && 1421 iface_context->device_mode == QDF_SAP_MODE) { 1422 /* 1423 * When INTRA_BSS_FWD_OFFLOAD is enabled, FW will send 1424 * all Rx packets to IPA uC, which need to be forwarded 1425 * to other interface. 1426 * And, IPA driver will send back to WLAN host driver 1427 * through exception pipe with fw_desc field set by FW. 1428 * Here we are checking fw_desc field for FORWARD bit 1429 * set, and forward to Tx. Then copy to kernel stack 1430 * only when DISCARD bit is not set. 1431 */ 1432 if (WLAN_IPA_FORWARD_PKT_DISCARD == 1433 wlan_ipa_rx_intrabss_fwd(ipa_ctx, iface_context, 1434 skb)) 1435 break; 1436 } else { 1437 ipa_debug_rl("Intra-BSS fwd disabled for session_id %u", 1438 iface_context->session_id); 1439 } 1440 1441 wlan_ipa_send_skb_to_network(skb, iface_context); 1442 break; 1443 1444 default: 1445 ipa_err_rl("w2i cb wrong event: 0x%x", evt); 1446 return; 1447 } 1448 } 1449 1450 #ifndef MDM_PLATFORM 1451 /** 1452 * wlan_ipa_w2i_cb() - SSR wrapper for __wlan_ipa_w2i_cb 1453 * @priv: pointer to private data registered with IPA (we register a 1454 * pointer to the global IPA context) 1455 * @evt: the IPA event which triggered the callback 1456 * @data: data associated with the event 1457 * 1458 * Return: None 1459 */ 1460 static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, 1461 unsigned long data) 1462 { 1463 struct qdf_op_sync *op_sync; 1464 1465 if (qdf_op_protect(&op_sync)) { 1466 if (evt == IPA_RECEIVE) { 1467 struct wlan_ipa_priv *ipa_ctx = priv; 1468 qdf_nbuf_t skb = (qdf_nbuf_t)data; 1469 1470 ipa_ctx->ipa_rx_internal_drop_count++; 1471 dev_kfree_skb_any(skb); 1472 } 1473 1474 return; 1475 } 1476 1477 __wlan_ipa_w2i_cb(priv, evt, data); 1478 1479 qdf_op_unprotect(op_sync); 1480 } 1481 #else /* MDM_PLATFORM */ 1482 static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, 1483 unsigned long data) 1484 { 1485 __wlan_ipa_w2i_cb(priv, evt, data); 1486 } 1487 #endif /* MDM_PLATFORM */ 1488 1489 #if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL) 1490 1491 /** 1492 * __wlan_ipa_i2w_cb() - IPA to WLAN callback 1493 * @priv: pointer to private data registered with IPA (we register a 1494 * pointer to the interface-specific IPA context) 1495 * @evt: the IPA event which triggered the callback 1496 * @data: data associated with the event 1497 * 1498 * Return: None 1499 */ 1500 static void __wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt, 1501 unsigned long data) 1502 { 1503 struct wlan_ipa_priv *ipa_ctx = NULL; 1504 qdf_ipa_rx_data_t *ipa_tx_desc; 1505 struct wlan_ipa_iface_context *iface_context; 1506 qdf_nbuf_t skb; 1507 struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL; 1508 1509 iface_context = (struct wlan_ipa_iface_context *)priv; 1510 ipa_tx_desc = (qdf_ipa_rx_data_t *)data; 1511 ipa_ctx = iface_context->ipa_ctx; 1512 1513 if (evt != IPA_RECEIVE) { 1514 ipa_err_rl("Event is not IPA_RECEIVE"); 1515 ipa_free_skb(ipa_tx_desc); 1516 iface_context->stats.num_tx_drop++; 1517 return; 1518 } 1519 1520 skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc); 1521 1522 /* 1523 * If PROD resource is not requested here then there may be cases where 1524 * IPA hardware may be clocked down because of not having proper 1525 * dependency graph between WLAN CONS and modem PROD pipes. Adding the 1526 * workaround to request PROD resource while data is going over CONS 1527 * pipe to prevent the IPA hardware clockdown. 1528 */ 1529 wlan_ipa_wdi_rm_request(ipa_ctx); 1530 1531 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 1532 /* 1533 * If host is still suspended then queue the packets and these will be 1534 * drained later when resume completes. When packet is arrived here and 1535 * host is suspended, this means that there is already resume is in 1536 * progress. 1537 */ 1538 if (ipa_ctx->suspended) { 1539 qdf_mem_zero(skb->cb, sizeof(skb->cb)); 1540 pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; 1541 pm_tx_cb->iface_context = iface_context; 1542 pm_tx_cb->ipa_tx_desc = ipa_tx_desc; 1543 qdf_nbuf_queue_add(&ipa_ctx->pm_queue_head, skb); 1544 ipa_ctx->stats.num_tx_queued++; 1545 1546 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 1547 return; 1548 } 1549 1550 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 1551 1552 /* 1553 * If we are here means, host is not suspended, wait for the work queue 1554 * to finish. 1555 */ 1556 qdf_flush_work(&ipa_ctx->pm_work); 1557 1558 return wlan_ipa_send_pkt_to_tl(iface_context, ipa_tx_desc); 1559 } 1560 1561 /** 1562 * wlan_ipa_i2w_cb() - IPA to WLAN callback 1563 * @priv: pointer to private data registered with IPA (we register a 1564 * pointer to the interface-specific IPA context) 1565 * @evt: the IPA event which triggered the callback 1566 * @data: data associated with the event 1567 * 1568 * Return: None 1569 */ 1570 static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt, 1571 unsigned long data) 1572 { 1573 struct qdf_op_sync *op_sync; 1574 1575 if (qdf_op_protect(&op_sync)) { 1576 qdf_ipa_rx_data_t *ipa_tx_desc = (qdf_ipa_rx_data_t *)data; 1577 struct wlan_ipa_iface_context *iface_context = priv; 1578 1579 ipa_free_skb(ipa_tx_desc); 1580 iface_context->stats.num_tx_drop++; 1581 1582 return; 1583 } 1584 1585 __wlan_ipa_i2w_cb(priv, evt, data); 1586 1587 qdf_op_unprotect(op_sync); 1588 } 1589 1590 #else /* QCA_LL_TX_FLOW_CONTROL_V2 */ 1591 1592 /** 1593 * wlan_ipa_i2w_cb() - IPA to WLAN callback 1594 * @priv: pointer to private data registered with IPA (we register a 1595 * pointer to the interface-specific IPA context) 1596 * @evt: the IPA event which triggered the callback 1597 * @data: data associated with the event 1598 * 1599 * Return: None 1600 */ 1601 static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt, 1602 unsigned long data) 1603 { 1604 } 1605 1606 #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ 1607 1608 QDF_STATUS wlan_ipa_suspend(struct wlan_ipa_priv *ipa_ctx) 1609 { 1610 /* 1611 * Check if IPA is ready for suspend, If we are here means, there is 1612 * high chance that suspend would go through but just to avoid any race 1613 * condition after suspend started, these checks are conducted before 1614 * allowing to suspend. 1615 */ 1616 if (atomic_read(&ipa_ctx->tx_ref_cnt)) 1617 return QDF_STATUS_E_AGAIN; 1618 1619 if (!wlan_ipa_is_rm_released(ipa_ctx)) 1620 return QDF_STATUS_E_AGAIN; 1621 1622 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 1623 ipa_ctx->suspended = true; 1624 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 1625 1626 if (ipa_ctx->config->ipa_force_voting && 1627 !ipa_ctx->ipa_pipes_down) 1628 wlan_ipa_set_perf_level(ipa_ctx, 1629 ipa_ctx->config->bus_bw_high, 1630 ipa_ctx->config->bus_bw_high); 1631 1632 return QDF_STATUS_SUCCESS; 1633 } 1634 1635 QDF_STATUS wlan_ipa_resume(struct wlan_ipa_priv *ipa_ctx) 1636 { 1637 qdf_sched_work(0, &ipa_ctx->pm_work); 1638 1639 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 1640 ipa_ctx->suspended = false; 1641 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 1642 1643 return QDF_STATUS_SUCCESS; 1644 } 1645 1646 QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx) 1647 { 1648 int result; 1649 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 1650 1651 ipa_debug("enter"); 1652 1653 qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock); 1654 if (ipa_ctx->pipes_enable_in_progress) { 1655 ipa_warn("IPA Pipes Enable in progress"); 1656 qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock); 1657 return QDF_STATUS_E_ALREADY; 1658 } 1659 ipa_ctx->pipes_enable_in_progress = true; 1660 qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock); 1661 1662 if (qdf_atomic_read(&ipa_ctx->waiting_on_pending_tx)) 1663 wlan_ipa_reset_pending_tx_timer(ipa_ctx); 1664 1665 if (qdf_atomic_read(&ipa_ctx->pipes_disabled)) { 1666 result = cdp_ipa_enable_pipes(ipa_ctx->dp_soc, 1667 ipa_ctx->dp_pdev_id, 1668 ipa_ctx->hdl); 1669 if (result) { 1670 ipa_err("Enable IPA WDI PIPE failed: ret=%d", result); 1671 qdf_status = QDF_STATUS_E_FAILURE; 1672 goto end; 1673 } 1674 qdf_atomic_set(&ipa_ctx->pipes_disabled, 0); 1675 } 1676 1677 qdf_event_reset(&ipa_ctx->ipa_resource_comp); 1678 1679 if (qdf_atomic_read(&ipa_ctx->autonomy_disabled)) { 1680 cdp_ipa_enable_autonomy(ipa_ctx->dp_soc, 1681 ipa_ctx->dp_pdev_id); 1682 qdf_atomic_set(&ipa_ctx->autonomy_disabled, 0); 1683 } 1684 end: 1685 qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock); 1686 if (!qdf_atomic_read(&ipa_ctx->autonomy_disabled) && 1687 !qdf_atomic_read(&ipa_ctx->pipes_disabled)) 1688 ipa_ctx->ipa_pipes_down = false; 1689 1690 ipa_ctx->pipes_enable_in_progress = false; 1691 qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock); 1692 1693 ipa_debug("exit: ipa_pipes_down=%d", ipa_ctx->ipa_pipes_down); 1694 return qdf_status; 1695 } 1696 1697 QDF_STATUS 1698 wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx, bool force_disable) 1699 { 1700 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 1701 1702 ipa_debug("enter: force_disable %u autonomy_disabled %u pipes_disabled %u", 1703 force_disable, 1704 qdf_atomic_read(&ipa_ctx->autonomy_disabled), 1705 qdf_atomic_read(&ipa_ctx->pipes_disabled)); 1706 1707 qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock); 1708 if (ipa_ctx->ipa_pipes_down || ipa_ctx->pipes_down_in_progress) { 1709 qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock); 1710 ipa_info("IPA WDI Pipes are already deactivated"); 1711 return QDF_STATUS_E_ALREADY; 1712 } 1713 ipa_ctx->pipes_down_in_progress = true; 1714 qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock); 1715 1716 1717 if (!qdf_atomic_read(&ipa_ctx->autonomy_disabled)) { 1718 cdp_ipa_disable_autonomy(ipa_ctx->dp_soc, 1719 ipa_ctx->dp_pdev_id); 1720 qdf_atomic_set(&ipa_ctx->autonomy_disabled, 1); 1721 } 1722 1723 if (!qdf_atomic_read(&ipa_ctx->pipes_disabled)) { 1724 if (!force_disable) { 1725 wlan_ipa_set_pending_tx_timer(ipa_ctx); 1726 } else { 1727 qdf_status = cdp_ipa_disable_pipes(ipa_ctx->dp_soc, 1728 ipa_ctx->dp_pdev_id, 1729 ipa_ctx->hdl); 1730 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1731 ipa_err("Disable IPA WDI PIPE failed: ret=%u", 1732 qdf_status); 1733 qdf_status = QDF_STATUS_E_FAILURE; 1734 goto end; 1735 } 1736 qdf_atomic_set(&ipa_ctx->pipes_disabled, 1); 1737 wlan_ipa_reset_pending_tx_timer(ipa_ctx); 1738 } 1739 } 1740 1741 end: 1742 qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock); 1743 if (qdf_atomic_read(&ipa_ctx->pipes_disabled) && 1744 qdf_atomic_read(&ipa_ctx->autonomy_disabled)) { 1745 ipa_ctx->ipa_pipes_down = true; 1746 } 1747 ipa_ctx->pipes_down_in_progress = false; 1748 qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock); 1749 1750 ipa_debug("exit: ipa_pipes_down %u autonomy_disabled %u pipes_disabled %u", 1751 ipa_ctx->ipa_pipes_down, 1752 qdf_atomic_read(&ipa_ctx->autonomy_disabled), 1753 qdf_atomic_read(&ipa_ctx->pipes_disabled)); 1754 return qdf_status; 1755 } 1756 1757 /** 1758 * wlan_ipa_uc_find_add_assoc_sta() - Find associated station 1759 * @ipa_ctx: Global IPA IPA context 1760 * @sta_add: Should station be added 1761 * @mac_addr: mac address of station being queried 1762 * 1763 * Return: true if the station was found 1764 */ 1765 static bool wlan_ipa_uc_find_add_assoc_sta(struct wlan_ipa_priv *ipa_ctx, 1766 bool sta_add, 1767 uint8_t *mac_addr) 1768 { 1769 bool sta_found = false; 1770 uint8_t idx; 1771 1772 for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) { 1773 if ((ipa_ctx->assoc_stas_map[idx].is_reserved) && 1774 (qdf_is_macaddr_equal( 1775 &ipa_ctx->assoc_stas_map[idx].mac_addr, 1776 (struct qdf_mac_addr *)mac_addr))) { 1777 sta_found = true; 1778 break; 1779 } 1780 } 1781 if (sta_add && sta_found) { 1782 ipa_err("STA already exist, cannot add: " QDF_MAC_ADDR_FMT, 1783 QDF_MAC_ADDR_REF(mac_addr)); 1784 return sta_found; 1785 } 1786 if (sta_add) { 1787 for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) { 1788 if (!ipa_ctx->assoc_stas_map[idx].is_reserved) { 1789 ipa_ctx->assoc_stas_map[idx].is_reserved = true; 1790 qdf_mem_copy(&ipa_ctx->assoc_stas_map[idx]. 1791 mac_addr, mac_addr, 1792 QDF_NET_ETH_LEN); 1793 return sta_found; 1794 } 1795 } 1796 } 1797 if (!sta_add && !sta_found) { 1798 ipa_info("STA does not exist, cannot delete: " 1799 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); 1800 return sta_found; 1801 } 1802 if (!sta_add) { 1803 for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) { 1804 if ((ipa_ctx->assoc_stas_map[idx].is_reserved) && 1805 (qdf_is_macaddr_equal( 1806 &ipa_ctx->assoc_stas_map[idx].mac_addr, 1807 (struct qdf_mac_addr *)mac_addr))) { 1808 ipa_ctx->assoc_stas_map[idx].is_reserved = 1809 false; 1810 qdf_mem_zero( 1811 &ipa_ctx->assoc_stas_map[idx].mac_addr, 1812 QDF_NET_ETH_LEN); 1813 return sta_found; 1814 } 1815 } 1816 } 1817 1818 return sta_found; 1819 } 1820 1821 /** 1822 * wlan_ipa_get_ifaceid() - Get IPA context interface ID 1823 * @ipa_ctx: IPA context 1824 * @session_id: Session ID 1825 * 1826 * Return: None 1827 */ 1828 static int wlan_ipa_get_ifaceid(struct wlan_ipa_priv *ipa_ctx, 1829 uint8_t session_id) 1830 { 1831 struct wlan_ipa_iface_context *iface_ctx; 1832 int i; 1833 1834 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 1835 iface_ctx = &ipa_ctx->iface_context[i]; 1836 if (iface_ctx->session_id == session_id) 1837 break; 1838 } 1839 1840 return i; 1841 } 1842 1843 /** 1844 * wlan_ipa_cleanup_iface() - Cleanup IPA on a given interface 1845 * @iface_context: interface-specific IPA context 1846 * 1847 * Return: None 1848 */ 1849 static void wlan_ipa_cleanup_iface(struct wlan_ipa_iface_context *iface_context, 1850 uint8_t *mac_addr) 1851 { 1852 struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx; 1853 1854 ipa_debug("enter"); 1855 ipa_err("net:%pK mode:%d MAC:"QDF_MAC_ADDR_FMT" id:%d", 1856 iface_context->dev, iface_context->device_mode, 1857 QDF_MAC_ADDR_REF(mac_addr), iface_context->session_id); 1858 1859 if (iface_context->session_id == WLAN_IPA_MAX_SESSION) 1860 return; 1861 1862 if (mac_addr && qdf_mem_cmp(iface_context->mac_addr, 1863 mac_addr, QDF_MAC_ADDR_SIZE)) { 1864 ipa_err("MAC mismatch "QDF_MAC_ADDR_FMT":"QDF_MAC_ADDR_FMT"", 1865 QDF_MAC_ADDR_REF(mac_addr), 1866 QDF_MAC_ADDR_REF(iface_context->mac_addr)); 1867 } 1868 1869 if (cdp_ipa_cleanup_iface(ipa_ctx->dp_soc, 1870 iface_context->dev->name, 1871 wlan_ipa_is_ipv6_enabled(ipa_ctx->config), 1872 ipa_ctx->hdl)) { 1873 ipa_err("ipa_cleanup_iface failed"); 1874 } 1875 1876 if (iface_context->device_mode == QDF_SAP_MODE) 1877 ipa_ctx->num_sap_connected--; 1878 1879 qdf_spin_lock_bh(&iface_context->interface_lock); 1880 if (qdf_atomic_read(&iface_context->disconn_count) == 1881 qdf_atomic_read(&iface_context->conn_count) - 1) { 1882 qdf_atomic_inc(&iface_context->disconn_count); 1883 } else { 1884 ipa_err("connect/disconnect out of sync"); 1885 QDF_BUG(0); 1886 } 1887 1888 iface_context->is_authenticated = false; 1889 iface_context->dev = NULL; 1890 iface_context->device_mode = QDF_MAX_NO_OF_MODE; 1891 iface_context->session_id = WLAN_IPA_MAX_SESSION; 1892 qdf_mem_set(iface_context->mac_addr, QDF_MAC_ADDR_SIZE, 0); 1893 qdf_spin_unlock_bh(&iface_context->interface_lock); 1894 iface_context->ifa_address = 0; 1895 qdf_zero_macaddr(&iface_context->bssid); 1896 if (!iface_context->ipa_ctx->num_iface) { 1897 ipa_err("NUM INTF 0, Invalid"); 1898 QDF_ASSERT(0); 1899 } 1900 iface_context->ipa_ctx->num_iface--; 1901 ipa_debug("exit: num_iface=%d", iface_context->ipa_ctx->num_iface); 1902 } 1903 1904 #if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL) 1905 1906 /** 1907 * wlan_ipa_nbuf_cb() - IPA TX complete callback 1908 * @skb: packet buffer which was transmitted 1909 * 1910 * Return: None 1911 */ 1912 static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb) 1913 { 1914 struct wlan_ipa_priv *ipa_ctx = gp_ipa; 1915 qdf_ipa_rx_data_t *ipa_tx_desc; 1916 struct wlan_ipa_tx_desc *tx_desc; 1917 uint16_t id; 1918 struct wlan_objmgr_pdev *pdev; 1919 struct wlan_objmgr_psoc *psoc; 1920 qdf_device_t osdev; 1921 1922 if (!qdf_nbuf_ipa_owned_get(skb)) { 1923 dev_kfree_skb_any(skb); 1924 return; 1925 } 1926 1927 if (!ipa_ctx) 1928 return; 1929 pdev = ipa_ctx->pdev; 1930 psoc = wlan_pdev_get_psoc(pdev); 1931 osdev = wlan_psoc_get_qdf_dev(psoc); 1932 1933 if (osdev && qdf_mem_smmu_s1_enabled(osdev)) { 1934 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 1935 qdf_dma_addr_t paddr = QDF_NBUF_CB_PADDR(skb); 1936 1937 qdf_nbuf_mapped_paddr_set(skb, 1938 paddr - 1939 WLAN_IPA_WLAN_FRAG_HEADER - 1940 WLAN_IPA_WLAN_IPA_HEADER); 1941 } 1942 1943 qdf_nbuf_unmap(osdev, skb, QDF_DMA_TO_DEVICE); 1944 } 1945 1946 /* Get Tx desc pointer from SKB CB */ 1947 id = qdf_nbuf_ipa_priv_get(skb); 1948 tx_desc = &ipa_ctx->tx_desc_pool[id]; 1949 ipa_tx_desc = tx_desc->ipa_tx_desc_ptr; 1950 1951 /* Return Tx Desc to IPA */ 1952 qdf_ipa_free_skb(ipa_tx_desc); 1953 1954 /* Return to free tx desc list */ 1955 qdf_spin_lock_bh(&ipa_ctx->q_lock); 1956 tx_desc->ipa_tx_desc_ptr = NULL; 1957 qdf_list_insert_back(&ipa_ctx->tx_desc_free_list, &tx_desc->node); 1958 ipa_ctx->stats.num_tx_desc_q_cnt--; 1959 qdf_spin_unlock_bh(&ipa_ctx->q_lock); 1960 1961 ipa_ctx->stats.num_tx_comp_cnt++; 1962 1963 qdf_atomic_dec(&ipa_ctx->tx_ref_cnt); 1964 1965 wlan_ipa_wdi_rm_try_release(ipa_ctx); 1966 } 1967 1968 #else /* QCA_LL_TX_FLOW_CONTROL_V2 */ 1969 1970 /** 1971 * wlan_ipa_nbuf_cb() - IPA TX complete callback 1972 * @skb: packet buffer which was transmitted 1973 * 1974 * Return: None 1975 */ 1976 static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb) 1977 { 1978 dev_kfree_skb_any(skb); 1979 } 1980 1981 #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ 1982 1983 #ifdef IPA_WDI3_TX_TWO_PIPES 1984 #define WLAN_IPA_SESSION_ID_SHIFT 1 1985 static uint8_t wlan_ipa_set_session_id(uint8_t session_id, bool is_2g_iface) 1986 { 1987 return (session_id << WLAN_IPA_SESSION_ID_SHIFT) | is_2g_iface; 1988 } 1989 #else 1990 static uint8_t wlan_ipa_set_session_id(uint8_t session_id, bool is_2g_iface) 1991 { 1992 return session_id; 1993 } 1994 #endif 1995 1996 /** 1997 * wlan_ipa_setup_iface() - Setup IPA on a given interface 1998 * @ipa_ctx: IPA IPA global context 1999 * @net_dev: Interface net device 2000 * @device_mode: Net interface device mode 2001 * @adapter: Interface upon which IPA is being setup 2002 * @session_id: Station ID of the API instance 2003 * @mac_addr: MAC addr of the API instance 2004 * @is_2g_iface: true if Net interface is operating on 2G band, otherwise false 2005 * 2006 * Return: QDF STATUS 2007 */ 2008 static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx, 2009 qdf_netdev_t net_dev, 2010 uint8_t device_mode, 2011 uint8_t session_id, 2012 uint8_t *mac_addr, 2013 bool is_2g_iface) 2014 { 2015 struct wlan_ipa_iface_context *iface_context = NULL; 2016 int i; 2017 QDF_STATUS status; 2018 2019 ipa_err("net:%pK mode:%d MAC:"QDF_MAC_ADDR_FMT" id:%d", 2020 net_dev, device_mode, QDF_MAC_ADDR_REF(mac_addr), session_id); 2021 2022 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 2023 iface_context = &(ipa_ctx->iface_context[i]); 2024 if (iface_context->dev == net_dev) { 2025 if (iface_context->device_mode == device_mode) { 2026 /** 2027 * Lower layer may send multiple START_BSS_EVENT 2028 * in DFS mode or during channel change. 2029 * Since these indications are sent by lower 2030 * layer as SAP updates and IPA doesn't have to 2031 * do anything for these updates so ignoring! 2032 */ 2033 if (device_mode == QDF_SAP_MODE) { 2034 ipa_debug("found iface %u device_mode %u", 2035 i, device_mode); 2036 return QDF_STATUS_SUCCESS; 2037 } else if (device_mode == QDF_STA_MODE && 2038 qdf_mem_cmp( 2039 iface_context->mac_addr, 2040 mac_addr, 2041 QDF_MAC_ADDR_SIZE) == 0) { 2042 ipa_err("same STA iface already connected"); 2043 } 2044 2045 } 2046 2047 ipa_err("Obsolete iface %u found, device_mode %u, will remove it.", 2048 i, iface_context->device_mode); 2049 wlan_ipa_cleanup_iface(iface_context, NULL); 2050 } else if (iface_context->session_id == session_id) { 2051 ipa_err("Obsolete iface %u found, net_dev %pK, will remove it.", 2052 i, iface_context->dev); 2053 wlan_ipa_cleanup_iface(iface_context, NULL); 2054 } 2055 } 2056 2057 if (WLAN_IPA_MAX_IFACE == ipa_ctx->num_iface) { 2058 ipa_err("Max interface reached %d", WLAN_IPA_MAX_IFACE); 2059 status = QDF_STATUS_E_NOMEM; 2060 iface_context = NULL; 2061 QDF_ASSERT(0); 2062 goto end; 2063 } 2064 2065 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 2066 if (ipa_ctx->iface_context[i].session_id == 2067 WLAN_IPA_MAX_SESSION) { 2068 iface_context = &(ipa_ctx->iface_context[i]); 2069 break; 2070 } 2071 } 2072 2073 if (!iface_context) { 2074 ipa_err("All the IPA interfaces are in use"); 2075 status = QDF_STATUS_E_NOMEM; 2076 QDF_ASSERT(0); 2077 goto end; 2078 } 2079 2080 qdf_spin_lock_bh(&iface_context->interface_lock); 2081 if (qdf_atomic_read(&iface_context->conn_count) == 2082 qdf_atomic_read(&iface_context->disconn_count)) { 2083 qdf_atomic_inc(&iface_context->conn_count); 2084 } else { 2085 ipa_err("connect/disconnect out of sync"); 2086 QDF_BUG(0); 2087 } 2088 2089 iface_context->dev = net_dev; 2090 iface_context->device_mode = device_mode; 2091 iface_context->session_id = session_id; 2092 qdf_mem_copy(iface_context->mac_addr, mac_addr, QDF_MAC_ADDR_SIZE); 2093 qdf_spin_unlock_bh(&iface_context->interface_lock); 2094 2095 status = cdp_ipa_setup_iface(ipa_ctx->dp_soc, net_dev->name, 2096 net_dev->dev_addr, 2097 iface_context->prod_client, 2098 iface_context->cons_client, 2099 wlan_ipa_set_session_id(session_id, 2100 is_2g_iface), 2101 wlan_ipa_is_ipv6_enabled(ipa_ctx->config), 2102 ipa_ctx->hdl); 2103 if (status != QDF_STATUS_SUCCESS) 2104 goto end; 2105 2106 /* Register IPA Tx desc free callback */ 2107 qdf_nbuf_reg_free_cb(wlan_ipa_nbuf_cb); 2108 2109 ipa_ctx->num_iface++; 2110 2111 if (device_mode == QDF_SAP_MODE) 2112 ipa_ctx->num_sap_connected++; 2113 2114 ipa_debug("exit: num_iface=%d", ipa_ctx->num_iface); 2115 2116 return status; 2117 2118 end: 2119 if (iface_context) 2120 wlan_ipa_cleanup_iface(iface_context, mac_addr); 2121 2122 return status; 2123 } 2124 2125 #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ 2126 defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) || \ 2127 defined(QCA_WIFI_WCN7850) || defined(QCA_WIFI_QCN9000) || \ 2128 defined(QCA_WIFI_KIWI) || defined(QCA_WIFI_KIWI_V2) 2129 2130 #ifdef QCA_CONFIG_RPS 2131 void ipa_set_rps(struct wlan_ipa_priv *ipa_ctx, enum QDF_OPMODE mode, 2132 bool enable) 2133 { 2134 struct wlan_ipa_iface_context *iface_ctx; 2135 wlan_ipa_rps_enable cb = ipa_ctx->rps_enable; 2136 int i; 2137 2138 if (!cb) 2139 return; 2140 2141 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 2142 iface_ctx = &ipa_ctx->iface_context[i]; 2143 if (iface_ctx->device_mode == mode) 2144 cb(iface_ctx->session_id, enable); 2145 } 2146 } 2147 #endif 2148 2149 #ifdef QCA_CONFIG_RPS 2150 /** 2151 * wlan_ipa_uc_handle_first_con() - Handle first uC IPA connection 2152 * @ipa_ctx: IPA context 2153 * 2154 * Return: QDF STATUS 2155 */ 2156 static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx) 2157 { 2158 ipa_debug("enter"); 2159 2160 if (qdf_ipa_get_lan_rx_napi() && (ipa_ctx->num_sap_connected > 1)) { 2161 ipa_debug("Multiple SAP connected. Not enabling pipes. Exit"); 2162 return QDF_STATUS_E_PERM; 2163 } 2164 2165 if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sta_connected) 2166 ipa_set_rps(ipa_ctx, QDF_STA_MODE, true); 2167 2168 if (wlan_ipa_uc_enable_pipes(ipa_ctx) != QDF_STATUS_SUCCESS) { 2169 ipa_err("IPA WDI Pipe activation failed"); 2170 return QDF_STATUS_E_BUSY; 2171 } 2172 2173 ipa_debug("exit"); 2174 2175 return QDF_STATUS_SUCCESS; 2176 } 2177 #else 2178 static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx) 2179 { 2180 ipa_debug("enter"); 2181 2182 if (wlan_ipa_uc_enable_pipes(ipa_ctx) != QDF_STATUS_SUCCESS) { 2183 ipa_err("IPA WDI Pipe activation failed"); 2184 return QDF_STATUS_E_BUSY; 2185 } 2186 2187 ipa_debug("exit"); 2188 2189 return QDF_STATUS_SUCCESS; 2190 } 2191 #endif 2192 2193 static 2194 void wlan_ipa_uc_handle_last_discon(struct wlan_ipa_priv *ipa_ctx, 2195 bool force_disable) 2196 { 2197 ipa_debug("enter"); 2198 2199 wlan_ipa_uc_disable_pipes(ipa_ctx, force_disable); 2200 2201 if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sta_connected) 2202 ipa_set_rps(ipa_ctx, QDF_STA_MODE, false); 2203 2204 ipa_debug("exit: IPA WDI Pipes deactivated"); 2205 } 2206 2207 bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx) 2208 { 2209 return !ipa_ctx->ipa_pipes_down; 2210 } 2211 2212 /* Time(ms) to wait for pending TX comps after last SAP client disconnects */ 2213 #define WLAN_IPA_TX_PENDING_TIMEOUT_MS 15000 2214 2215 static void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx) 2216 { 2217 ipa_ctx->pending_tx_start_ticks = qdf_system_ticks(); 2218 qdf_atomic_set(&ipa_ctx->waiting_on_pending_tx, 1); 2219 ipa_info("done. pending_tx_start_ticks %llu wait_on_pending %u", 2220 ipa_ctx->pending_tx_start_ticks, 2221 qdf_atomic_read(&ipa_ctx->waiting_on_pending_tx)); 2222 } 2223 2224 bool wlan_ipa_is_tx_pending(struct wlan_ipa_priv *ipa_ctx) 2225 { 2226 bool ret = false; 2227 uint64_t diff_ms = 0; 2228 uint64_t current_ticks = 0; 2229 2230 if (!ipa_ctx) { 2231 ipa_err("IPA private context is NULL"); 2232 return false; 2233 } 2234 2235 if (!qdf_atomic_read(&ipa_ctx->waiting_on_pending_tx)) { 2236 ipa_debug("nothing pending"); 2237 return false; 2238 } 2239 2240 current_ticks = qdf_system_ticks(); 2241 2242 diff_ms = qdf_system_ticks_to_msecs(current_ticks - 2243 ipa_ctx->pending_tx_start_ticks); 2244 2245 if (diff_ms < WLAN_IPA_TX_PENDING_TIMEOUT_MS) { 2246 ret = true; 2247 } else { 2248 ipa_debug("disabling pipes"); 2249 wlan_ipa_uc_disable_pipes(ipa_ctx, true); 2250 } 2251 2252 ipa_debug("diff_ms %llu pending_tx_start_ticks %llu current_ticks %llu wait_on_pending %u", 2253 diff_ms, ipa_ctx->pending_tx_start_ticks, current_ticks, 2254 qdf_atomic_read(&ipa_ctx->waiting_on_pending_tx)); 2255 2256 return ret; 2257 } 2258 2259 static void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx) 2260 { 2261 ipa_ctx->pending_tx_start_ticks = 0; 2262 qdf_atomic_set(&ipa_ctx->waiting_on_pending_tx, 0); 2263 ipa_info("done"); 2264 } 2265 2266 #else 2267 2268 /** 2269 * wlan_ipa_uc_handle_first_con() - Handle first uC IPA connection 2270 * @ipa_ctx: IPA context 2271 * 2272 * Return: QDF STATUS 2273 */ 2274 static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx) 2275 { 2276 ipa_debug("enter"); 2277 2278 ipa_ctx->activated_fw_pipe = 0; 2279 ipa_ctx->resource_loading = true; 2280 2281 /* If RM feature enabled 2282 * Request PROD Resource first 2283 * PROD resource may return sync or async manners 2284 */ 2285 if (wlan_ipa_is_rm_enabled(ipa_ctx->config)) { 2286 if (!wlan_ipa_wdi_rm_request_resource(ipa_ctx, 2287 IPA_RM_RESOURCE_WLAN_PROD)) { 2288 /* RM PROD request sync return 2289 * enable pipe immediately 2290 */ 2291 if (wlan_ipa_uc_enable_pipes(ipa_ctx)) { 2292 ipa_err("IPA WDI Pipe activation failed"); 2293 ipa_ctx->resource_loading = false; 2294 return QDF_STATUS_E_BUSY; 2295 } 2296 } else { 2297 ipa_err("IPA WDI Pipe activation deferred"); 2298 } 2299 } else { 2300 /* RM Disabled 2301 * Just enabled all the PIPEs 2302 */ 2303 if (wlan_ipa_uc_enable_pipes(ipa_ctx)) { 2304 ipa_err("IPA WDI Pipe activation failed"); 2305 ipa_ctx->resource_loading = false; 2306 return QDF_STATUS_E_BUSY; 2307 } 2308 ipa_ctx->resource_loading = false; 2309 } 2310 2311 ipa_debug("exit"); 2312 2313 return QDF_STATUS_SUCCESS; 2314 } 2315 2316 /** 2317 * wlan_ipa_uc_handle_last_discon() - Handle last uC IPA disconnection 2318 * @ipa_ctx: IPA context 2319 * @force_disable: force IPA pipes disablement 2320 * 2321 * Return: None 2322 */ 2323 static 2324 void wlan_ipa_uc_handle_last_discon(struct wlan_ipa_priv *ipa_ctx, 2325 bool force_disable) 2326 { 2327 ipa_debug("enter"); 2328 2329 ipa_ctx->resource_unloading = true; 2330 qdf_event_reset(&ipa_ctx->ipa_resource_comp); 2331 ipa_info("Disable FW RX PIPE"); 2332 cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, false, false); 2333 2334 ipa_debug("exit: IPA WDI Pipes deactivated"); 2335 } 2336 2337 bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx) 2338 { 2339 return (WLAN_IPA_UC_NUM_WDI_PIPE == ipa_ctx->activated_fw_pipe); 2340 } 2341 2342 static inline 2343 void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx) 2344 { 2345 } 2346 2347 bool wlan_ipa_is_tx_pending(struct wlan_ipa_priv *ipa_ctx) 2348 { 2349 return false; 2350 } 2351 2352 static inline 2353 void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx) 2354 { 2355 } 2356 2357 #endif 2358 2359 static inline 2360 bool wlan_sap_no_client_connected(struct wlan_ipa_priv *ipa_ctx) 2361 { 2362 return !(ipa_ctx->sap_num_connected_sta); 2363 } 2364 2365 static inline 2366 bool wlan_sta_is_connected(struct wlan_ipa_priv *ipa_ctx) 2367 { 2368 return ipa_ctx->sta_connected; 2369 } 2370 2371 static inline 2372 bool wlan_ipa_uc_is_loaded(struct wlan_ipa_priv *ipa_ctx) 2373 { 2374 return ipa_ctx->uc_loaded; 2375 } 2376 2377 #ifdef INTRA_BSS_FWD_OFFLOAD 2378 /** 2379 * wlan_ipa_intrabss_enable_disable() - wdi intrabss enable/disable notify to fw 2380 * @ipa_ctx: global IPA context 2381 * @offload_type: MCC or SCC 2382 * @session_id: Session Id 2383 * @enable: intrabss enable or disable 2384 * 2385 * Return: none 2386 */ 2387 static void wlan_ipa_intrabss_enable_disable(struct wlan_ipa_priv *ipa_ctx, 2388 uint8_t session_id, 2389 bool enable) 2390 { 2391 struct ipa_intrabss_control_params intrabss_req = {0}; 2392 uint32_t intra_bss_fwd = 0; 2393 2394 if (!enable || ipa_ctx->disable_intrabss_fwd[session_id]) { 2395 ipa_debug("%s: ipa_offload->enable=%d, rx_fwd_disabled=%d", 2396 __func__, enable, 2397 ipa_ctx->disable_intrabss_fwd[session_id]); 2398 intra_bss_fwd = 1; 2399 } 2400 2401 intrabss_req.vdev_id = session_id; 2402 intrabss_req.enable = intra_bss_fwd; 2403 2404 if (QDF_STATUS_SUCCESS != 2405 ipa_send_intrabss_enable_disable(ipa_ctx->pdev, &intrabss_req)) { 2406 ipa_err("intrabss offload vdev_id=%d, enable=%d failure", 2407 session_id, intra_bss_fwd); 2408 } 2409 } 2410 #else 2411 static inline 2412 void wlan_ipa_intrabss_enable_disable(struct wlan_ipa_priv *ipa_ctx, 2413 uint8_t session_id, 2414 bool enable) 2415 {} 2416 #endif 2417 2418 /** 2419 * wlan_ipa_uc_offload_enable_disable() - wdi enable/disable notify to fw 2420 * @ipa_ctx: global IPA context 2421 * @offload_type: MCC or SCC 2422 * @session_id: Session Id 2423 * @enable: TX offload enable or disable 2424 * 2425 * Return: none 2426 */ 2427 static void wlan_ipa_uc_offload_enable_disable(struct wlan_ipa_priv *ipa_ctx, 2428 uint32_t offload_type, 2429 uint8_t session_id, 2430 bool enable) 2431 { 2432 2433 struct ipa_uc_offload_control_params req = {0}; 2434 2435 if (session_id >= WLAN_IPA_MAX_SESSION) { 2436 ipa_err("invalid session id: %d", session_id); 2437 return; 2438 } 2439 2440 if (enable == ipa_ctx->vdev_offload_enabled[session_id]) { 2441 ipa_info("IPA offload status is already set"); 2442 ipa_info("offload_type=%d, vdev_id=%d, enable=%d", 2443 offload_type, session_id, enable); 2444 return; 2445 } 2446 2447 ipa_info("offload_type=%d, session_id=%d, enable=%d", 2448 offload_type, session_id, enable); 2449 2450 req.offload_type = offload_type; 2451 req.vdev_id = session_id; 2452 req.enable = enable; 2453 2454 if (QDF_STATUS_SUCCESS != 2455 ipa_send_uc_offload_enable_disable(ipa_ctx->pdev, &req)) { 2456 ipa_err("Fail to enable IPA offload"); 2457 ipa_err("offload type=%d, vdev_id=%d, enable=%d", 2458 offload_type, session_id, enable); 2459 } else { 2460 ipa_ctx->vdev_offload_enabled[session_id] = enable; 2461 } 2462 2463 wlan_ipa_intrabss_enable_disable(ipa_ctx, session_id, enable); 2464 } 2465 2466 #ifdef WDI3_STATS_BW_MONITOR 2467 static void wlan_ipa_uc_bw_monitor(struct wlan_ipa_priv *ipa_ctx, bool stop) 2468 { 2469 qdf_ipa_wdi_bw_info_t bw_info; 2470 uint32_t bw_low = ipa_ctx->config->ipa_bw_low; 2471 uint32_t bw_medium = ipa_ctx->config->ipa_bw_medium; 2472 uint32_t bw_high = ipa_ctx->config->ipa_bw_high; 2473 int ret; 2474 2475 bw_info.num = WLAN_IPA_UC_BW_MONITOR_LEVEL; 2476 /* IPA uc will mobitor three bw levels for wlan client */ 2477 QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_1(&bw_info) = bw_low; 2478 QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_2(&bw_info) = bw_medium; 2479 QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_3(&bw_info) = bw_high; 2480 QDF_IPA_WDI_BW_INFO_START_STOP(&bw_info) = stop; 2481 2482 ret = qdf_ipa_uc_bw_monitor(&bw_info); 2483 if (ret) 2484 ipa_err("ipa uc bw monitor fails"); 2485 2486 if (!stop) { 2487 cdp_ipa_set_perf_level(ipa_ctx->dp_soc, 2488 QDF_IPA_CLIENT_WLAN2_CONS, 2489 ipa_ctx->config->ipa_bw_low); 2490 ipa_ctx->curr_bw_level = WLAN_IPA_BW_LEVEL_LOW; 2491 } 2492 2493 ipa_debug("ipa uc bw monitor %s", stop ? "stop" : "start"); 2494 } 2495 #else 2496 static inline 2497 void wlan_ipa_uc_bw_monitor(struct wlan_ipa_priv *ipa_ctx, bool stop) 2498 { 2499 } 2500 #endif 2501 2502 /** 2503 * wlan_ipa_send_msg() - Allocate and send message to IPA 2504 * @net_dev: Interface net device 2505 * @type: event enum of type ipa_wlan_event 2506 * @mac_address: MAC address associated with the event 2507 * 2508 * Return: QDF STATUS 2509 */ 2510 static QDF_STATUS wlan_ipa_send_msg(qdf_netdev_t net_dev, 2511 qdf_ipa_wlan_event type, 2512 uint8_t *mac_addr) 2513 { 2514 qdf_ipa_msg_meta_t meta; 2515 qdf_ipa_wlan_msg_t *msg; 2516 2517 QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t); 2518 2519 msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); 2520 if (!msg) 2521 return QDF_STATUS_E_NOMEM; 2522 2523 QDF_IPA_SET_META_MSG_TYPE(&meta, type); 2524 strlcpy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name, IPA_RESOURCE_NAME_MAX); 2525 qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN); 2526 QDF_IPA_WLAN_MSG_NETDEV_IF_ID(msg) = net_dev->ifindex; 2527 2528 ipa_debug("%s: Evt: %d", QDF_IPA_WLAN_MSG_NAME(msg), QDF_IPA_MSG_META_MSG_TYPE(&meta)); 2529 2530 if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) { 2531 ipa_err("%s: Evt: %d fail", 2532 QDF_IPA_WLAN_MSG_NAME(msg), 2533 QDF_IPA_MSG_META_MSG_TYPE(&meta)); 2534 qdf_mem_free(msg); 2535 return QDF_STATUS_E_FAILURE; 2536 } 2537 2538 return QDF_STATUS_SUCCESS; 2539 } 2540 2541 #ifdef QCA_CONFIG_RPS 2542 void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx, 2543 qdf_ipa_wlan_event type) 2544 { 2545 struct wlan_ipa_iface_context *iface_ctx; 2546 int i; 2547 2548 if (type == QDF_IPA_AP_DISCONNECT) { 2549 ipa_debug("Multiple SAP disconnecting. Enabling IPA"); 2550 2551 if (ipa_ctx->sap_num_connected_sta > 0) 2552 wlan_ipa_uc_handle_first_con(ipa_ctx); 2553 2554 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 2555 iface_ctx = &ipa_ctx->iface_context[i]; 2556 2557 if (iface_ctx->device_mode == QDF_SAP_MODE) { 2558 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 2559 WMI_AP_RX_DATA_OFFLOAD, 2560 iface_ctx->session_id, 2561 true); 2562 break; 2563 } 2564 } 2565 } else if (type == QDF_IPA_AP_CONNECT) { 2566 ipa_debug("Multiple SAP connected. Disabling IPA"); 2567 2568 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 2569 iface_ctx = &ipa_ctx->iface_context[i]; 2570 2571 if (iface_ctx->device_mode == QDF_SAP_MODE) { 2572 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 2573 WMI_AP_RX_DATA_OFFLOAD, 2574 iface_ctx->session_id, 2575 false); 2576 } 2577 } 2578 2579 if (!ipa_ctx->ipa_pipes_down) 2580 wlan_ipa_uc_handle_last_discon(ipa_ctx, true); 2581 } 2582 } 2583 #endif 2584 2585 static inline void 2586 wlan_ipa_save_bssid_iface_ctx(struct wlan_ipa_priv *ipa_ctx, uint8_t iface_id, 2587 uint8_t *mac_addr) 2588 { 2589 qdf_mem_copy(ipa_ctx->iface_context[iface_id].bssid.bytes, 2590 mac_addr, QDF_MAC_ADDR_SIZE); 2591 } 2592 2593 #ifdef IPA_WDS_EASYMESH_FEATURE 2594 /** wlan_ipa_set_peer_id() - Set ta_peer_id in IPA 2595 * @ipa_ctx: ipa context 2596 * @meta: Meta data for IPA 2597 * @net_dev: Interface net device 2598 * @type: WLAN IPA event 2599 * @mac_addr: mac_addr of peer 2600 * 2601 * Return: QDF STATUS 2602 */ 2603 static QDF_STATUS 2604 wlan_ipa_set_peer_id(struct wlan_ipa_priv *ipa_ctx, 2605 qdf_ipa_msg_meta_t *meta, 2606 qdf_netdev_t net_dev, 2607 qdf_ipa_wlan_event type, 2608 uint8_t *mac_addr) 2609 { 2610 uint8_t ta_peer_id; 2611 struct cdp_ast_entry_info peer_ast_info = {0}; 2612 struct cdp_soc_t *cdp_soc; 2613 qdf_ipa_wlan_msg_ex_t *msg_ex; 2614 bool status; 2615 2616 QDF_IPA_MSG_META_MSG_LEN(meta) = 2617 (sizeof(qdf_ipa_wlan_msg_ex_t) + 2618 sizeof(qdf_ipa_wlan_hdr_attrib_val_t) * 2619 IPA_TA_PEER_ID_ATTRI); 2620 2621 msg_ex = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(meta)); 2622 if (!msg_ex) 2623 return QDF_STATUS_E_NOMEM; 2624 2625 strlcpy(msg_ex->name, net_dev->name, IPA_RESOURCE_NAME_MAX); 2626 msg_ex->num_of_attribs = IPA_TA_PEER_ID_ATTRI; 2627 ipa_info("Num of attribute set to: %d", IPA_TA_PEER_ID_ATTRI); 2628 2629 msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR; 2630 if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 2631 msg_ex->attribs[0].offset = 2632 WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET; 2633 } else { 2634 msg_ex->attribs[0].offset = 2635 WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET; 2636 } 2637 memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, IPA_MAC_ADDR_SIZE); 2638 2639 msg_ex->attribs[1].attrib_type = WLAN_HDR_ATTRIB_TA_PEER_ID; 2640 cdp_soc = (struct cdp_soc_t *)ipa_ctx->dp_soc; 2641 status = cdp_peer_get_ast_info_by_soc(cdp_soc, mac_addr, 2642 &peer_ast_info); 2643 2644 if (!status) { 2645 qdf_mem_free(msg_ex); 2646 return QDF_STATUS_E_FAILURE; 2647 } 2648 2649 ta_peer_id = peer_ast_info.peer_id; 2650 ipa_info("ta_peer_id set to: %d", ta_peer_id); 2651 msg_ex->attribs[1].u.ta_peer_id = ta_peer_id; 2652 2653 if (qdf_ipa_send_msg(meta, msg_ex, wlan_ipa_msg_free_fn)) { 2654 ipa_info("%s: Evt: %d send ipa msg fail", 2655 net_dev->name, type); 2656 qdf_mem_free(msg_ex); 2657 return QDF_STATUS_E_FAILURE; 2658 } 2659 ipa_ctx->stats.num_send_msg++; 2660 2661 return QDF_STATUS_SUCCESS; 2662 } 2663 #else 2664 static QDF_STATUS 2665 wlan_ipa_set_peer_id(struct wlan_ipa_priv *ipa_ctx, 2666 qdf_ipa_msg_meta_t *meta, 2667 qdf_netdev_t net_dev, 2668 qdf_ipa_wlan_event type, 2669 uint8_t *mac_addr) 2670 { 2671 qdf_ipa_wlan_msg_ex_t *msg_ex; 2672 2673 QDF_IPA_MSG_META_MSG_LEN(meta) = 2674 (sizeof(qdf_ipa_wlan_msg_ex_t) + 2675 sizeof(qdf_ipa_wlan_hdr_attrib_val_t)); 2676 2677 msg_ex = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(meta)); 2678 if (!msg_ex) 2679 return QDF_STATUS_E_NOMEM; 2680 2681 strlcpy(msg_ex->name, net_dev->name, IPA_RESOURCE_NAME_MAX); 2682 msg_ex->num_of_attribs = 1; 2683 msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR; 2684 2685 if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 2686 msg_ex->attribs[0].offset = 2687 WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET; 2688 } else { 2689 msg_ex->attribs[0].offset = WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET; 2690 } 2691 memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, IPA_MAC_ADDR_SIZE); 2692 2693 if (qdf_ipa_send_msg(meta, msg_ex, wlan_ipa_msg_free_fn)) { 2694 ipa_info("%s: Evt: %d send ipa msg fail", 2695 net_dev->name, type); 2696 qdf_mem_free(msg_ex); 2697 return QDF_STATUS_E_FAILURE; 2698 } 2699 ipa_ctx->stats.num_send_msg++; 2700 2701 return QDF_STATUS_SUCCESS; 2702 } 2703 #endif 2704 2705 /** 2706 * __wlan_ipa_wlan_evt() - IPA event handler 2707 * @net_dev: Interface net device 2708 * @device_mode: Net interface device mode 2709 * @session_id: session id for the event 2710 * @type: event enum of type ipa_wlan_event 2711 * @mac_address: MAC address associated with the event 2712 * @is_2g_iface: @net_dev is 2G or not for QDF_IPA_STA_CONNECT and 2713 * QDF_IPA_AP_CONNECT 2714 * 2715 * This function is meant to be called from within wlan_ipa_ctx.c 2716 * 2717 * Return: QDF STATUS 2718 */ 2719 static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, 2720 uint8_t session_id, 2721 qdf_ipa_wlan_event type, 2722 uint8_t *mac_addr, bool is_2g_iface, 2723 struct wlan_ipa_priv *ipa_obj) 2724 { 2725 struct wlan_ipa_priv *ipa_ctx; 2726 struct wlan_ipa_iface_context *iface_ctx = NULL; 2727 qdf_ipa_msg_meta_t meta; 2728 qdf_ipa_wlan_msg_t *msg; 2729 qdf_ipa_wlan_msg_ex_t *msg_ex = NULL; 2730 int i; 2731 QDF_STATUS status; 2732 uint8_t sta_session_id = WLAN_IPA_MAX_SESSION; 2733 struct wlan_objmgr_pdev *pdev; 2734 struct wlan_objmgr_psoc *psoc; 2735 struct wlan_objmgr_vdev *vdev; 2736 bool ipa_wds = false; 2737 2738 ipa_debug("%s: EVT: %d, MAC: "QDF_MAC_ADDR_FMT", session_id: %u", 2739 net_dev->name, type, QDF_MAC_ADDR_REF(mac_addr), session_id); 2740 2741 if (type >= QDF_IPA_WLAN_EVENT_MAX) 2742 return QDF_STATUS_E_INVAL; 2743 2744 ipa_ctx = ipa_obj; 2745 if (wlan_ipa_uc_is_enabled(ipa_ctx->config) && 2746 !wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && 2747 (device_mode != QDF_SAP_MODE)) { 2748 return QDF_STATUS_SUCCESS; 2749 } 2750 2751 pdev = ipa_ctx->pdev; 2752 psoc = wlan_pdev_get_psoc(pdev); 2753 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, 2754 WLAN_IPA_ID); 2755 QDF_BUG(session_id < WLAN_IPA_MAX_SESSION); 2756 2757 if (vdev) 2758 wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID); 2759 else 2760 ipa_err("vdev is NULL, session_id: %u", session_id); 2761 2762 if (ipa_ctx->sta_connected) { 2763 iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE); 2764 if (iface_ctx) 2765 sta_session_id = iface_ctx->session_id; 2766 else 2767 ipa_err("sta iface_ctx is NULL"); 2768 } 2769 2770 /* 2771 * During IPA UC resource loading/unloading new events can be issued. 2772 */ 2773 if (wlan_ipa_uc_is_enabled(ipa_ctx->config) && 2774 (ipa_ctx->resource_loading || ipa_ctx->resource_unloading)) { 2775 unsigned int pending_event_count; 2776 struct wlan_ipa_uc_pending_event *pending_event = NULL; 2777 2778 ipa_info("Event:%d IPA resource %s inprogress", type, 2779 ipa_ctx->resource_loading ? 2780 "load" : "unload"); 2781 2782 /* Wait until completion of the long/unloading */ 2783 status = qdf_wait_for_event_completion( 2784 &ipa_ctx->ipa_resource_comp, 2785 IPA_RESOURCE_COMP_WAIT_TIME); 2786 if (status != QDF_STATUS_SUCCESS) { 2787 /* 2788 * If timed out, store the events separately and 2789 * handle them later. 2790 */ 2791 ipa_info("IPA resource %s timed out", 2792 ipa_ctx->resource_loading ? 2793 "load" : "unload"); 2794 2795 if (type == QDF_IPA_AP_DISCONNECT) { 2796 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 2797 WMI_AP_RX_DATA_OFFLOAD, 2798 session_id, false); 2799 } else if (type == QDF_IPA_CLIENT_CONNECT_EX && 2800 wlan_sap_no_client_connected(ipa_ctx)) { 2801 if (wlan_sta_is_connected(ipa_ctx) && 2802 wlan_ipa_uc_is_loaded(ipa_ctx) && 2803 wlan_ipa_uc_sta_is_enabled(ipa_ctx-> 2804 config) && 2805 !wlan_ipa_is_sta_only_offload_enabled()) { 2806 wlan_ipa_uc_offload_enable_disable( 2807 ipa_ctx, 2808 WMI_STA_RX_DATA_OFFLOAD, 2809 sta_session_id, true); 2810 } 2811 } 2812 2813 qdf_mutex_acquire(&ipa_ctx->ipa_lock); 2814 2815 pending_event_count = 2816 qdf_list_size(&ipa_ctx->pending_event); 2817 if (pending_event_count >= 2818 WLAN_IPA_MAX_PENDING_EVENT_COUNT) { 2819 ipa_info("Reached max pending evt count"); 2820 qdf_list_remove_front( 2821 &ipa_ctx->pending_event, 2822 (qdf_list_node_t **)&pending_event); 2823 } else { 2824 pending_event = 2825 (struct wlan_ipa_uc_pending_event *) 2826 qdf_mem_malloc(sizeof( 2827 struct wlan_ipa_uc_pending_event)); 2828 } 2829 2830 if (!pending_event) { 2831 qdf_mutex_release(&ipa_ctx->ipa_lock); 2832 return QDF_STATUS_E_NOMEM; 2833 } 2834 2835 pending_event->net_dev = net_dev; 2836 pending_event->device_mode = device_mode; 2837 pending_event->session_id = session_id; 2838 pending_event->type = type; 2839 pending_event->is_loading = ipa_ctx->resource_loading; 2840 qdf_mem_copy(pending_event->mac_addr, 2841 mac_addr, QDF_MAC_ADDR_SIZE); 2842 pending_event->is_2g_iface = is_2g_iface; 2843 qdf_list_insert_back(&ipa_ctx->pending_event, 2844 &pending_event->node); 2845 2846 qdf_mutex_release(&ipa_ctx->ipa_lock); 2847 2848 /* Cleanup interface */ 2849 if (type == QDF_IPA_STA_DISCONNECT || 2850 type == QDF_IPA_AP_DISCONNECT) { 2851 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 2852 iface_ctx = &ipa_ctx->iface_context[i]; 2853 if (iface_ctx->dev == net_dev) { 2854 wlan_ipa_cleanup_iface( 2855 iface_ctx, 2856 mac_addr); 2857 break; 2858 } 2859 } 2860 2861 if (qdf_ipa_get_lan_rx_napi() && 2862 ipa_ctx->num_sap_connected == 1) { 2863 wlan_ipa_handle_multiple_sap_evt(ipa_ctx, 2864 type); 2865 } 2866 } 2867 2868 return QDF_STATUS_SUCCESS; 2869 } 2870 ipa_info("IPA resource %s completed", 2871 ipa_ctx->resource_loading ? 2872 "load" : "unload"); 2873 } 2874 2875 ipa_ctx->stats.event[type]++; 2876 2877 QDF_IPA_SET_META_MSG_TYPE(&meta, type); 2878 switch (type) { 2879 case QDF_IPA_STA_CONNECT: 2880 qdf_mutex_acquire(&ipa_ctx->event_lock); 2881 2882 /* STA already connected and without disconnect, connect again 2883 * This is Roaming scenario, clean up ipa iface first, then add 2884 * ipa iface later, sta_connected-- first, sta_connected++ 2885 * later to reflect real sta number on DUT. 2886 */ 2887 if (ipa_ctx->sta_connected) { 2888 iface_ctx = wlan_ipa_get_iface_by_mode_netdev( 2889 ipa_ctx, net_dev, QDF_STA_MODE); 2890 if (iface_ctx) { 2891 ipa_ctx->sta_connected--; 2892 wlan_ipa_cleanup_iface(iface_ctx, NULL); 2893 } 2894 status = wlan_ipa_send_msg(net_dev, 2895 QDF_IPA_STA_DISCONNECT, 2896 mac_addr); 2897 if (status != QDF_STATUS_SUCCESS) { 2898 ipa_err("QDF_IPA_STA_DISCONNECT send failed %u", 2899 status); 2900 qdf_mutex_release(&ipa_ctx->event_lock); 2901 goto end; 2902 } 2903 } 2904 2905 status = wlan_ipa_setup_iface(ipa_ctx, net_dev, device_mode, 2906 session_id, mac_addr, 2907 is_2g_iface); 2908 if (status != QDF_STATUS_SUCCESS) { 2909 ipa_err("wlan_ipa_setup_iface failed %u", status); 2910 qdf_mutex_release(&ipa_ctx->event_lock); 2911 goto end; 2912 } 2913 2914 ipa_ctx->vdev_to_iface[session_id] = 2915 wlan_ipa_get_ifaceid(ipa_ctx, session_id); 2916 2917 wlan_ipa_save_bssid_iface_ctx(ipa_ctx, 2918 ipa_ctx->vdev_to_iface[session_id], 2919 mac_addr); 2920 2921 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && 2922 (ipa_ctx->sap_num_connected_sta > 0 || 2923 wlan_ipa_is_sta_only_offload_enabled()) && 2924 !ipa_ctx->sta_connected) { 2925 qdf_mutex_release(&ipa_ctx->event_lock); 2926 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 2927 WMI_STA_RX_DATA_OFFLOAD, session_id, 2928 true); 2929 qdf_mutex_acquire(&ipa_ctx->event_lock); 2930 qdf_atomic_set(&ipa_ctx->stats_quota, 1); 2931 } 2932 2933 if (!wlan_ipa_is_sta_only_offload_enabled()) { 2934 ipa_debug("IPA STA only offload not enabled"); 2935 } else if (ipa_ctx->uc_loaded && 2936 !ipa_ctx->sap_num_connected_sta && 2937 !ipa_ctx->sta_connected) { 2938 status = wlan_ipa_uc_handle_first_con(ipa_ctx); 2939 if (status) { 2940 qdf_mutex_release(&ipa_ctx->event_lock); 2941 ipa_info("handle 1st conn failed %d", status); 2942 wlan_ipa_uc_offload_enable_disable( 2943 ipa_ctx, 2944 WMI_STA_RX_DATA_OFFLOAD, 2945 session_id, 2946 false); 2947 ipa_ctx->vdev_to_iface[session_id] = 2948 WLAN_IPA_MAX_SESSION; 2949 goto end; 2950 } 2951 } 2952 2953 ipa_ctx->sta_connected++; 2954 2955 if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sap_num_connected_sta) 2956 ipa_set_rps_per_vdev(ipa_ctx, session_id, true); 2957 2958 qdf_mutex_release(&ipa_ctx->event_lock); 2959 2960 ipa_debug("sta_connected=%d vdev_to_iface[%u] %u", 2961 ipa_ctx->sta_connected, 2962 session_id, 2963 ipa_ctx->vdev_to_iface[session_id]); 2964 break; 2965 2966 case QDF_IPA_AP_CONNECT: 2967 qdf_mutex_acquire(&ipa_ctx->event_lock); 2968 2969 /* For DFS channel we get two start_bss event (before and after 2970 * CAC). Also when ACS range includes both DFS and non DFS 2971 * channels, we could possibly change channel many times due to 2972 * RADAR detection and chosen channel may not be a DFS channels. 2973 * So dont return error here. Just discard the event. 2974 */ 2975 if (ipa_ctx->vdev_to_iface[session_id] != 2976 WLAN_IPA_MAX_SESSION) { 2977 qdf_mutex_release(&ipa_ctx->event_lock); 2978 return 0; 2979 } 2980 2981 status = wlan_ipa_setup_iface(ipa_ctx, net_dev, device_mode, 2982 session_id, mac_addr, 2983 is_2g_iface); 2984 if (status != QDF_STATUS_SUCCESS) { 2985 qdf_mutex_release(&ipa_ctx->event_lock); 2986 ipa_err("%s: Evt: %d, Interface setup failed", 2987 msg_ex->name, QDF_IPA_MSG_META_MSG_TYPE(&meta)); 2988 goto end; 2989 } 2990 2991 if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 2992 qdf_mutex_release(&ipa_ctx->event_lock); 2993 if (qdf_ipa_get_lan_rx_napi() && 2994 (ipa_ctx->num_sap_connected > 1)) { 2995 wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type); 2996 } else { 2997 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 2998 WMI_AP_RX_DATA_OFFLOAD, 2999 session_id, true); 3000 } 3001 qdf_mutex_acquire(&ipa_ctx->event_lock); 3002 } 3003 3004 ipa_ctx->vdev_to_iface[session_id] = 3005 wlan_ipa_get_ifaceid(ipa_ctx, session_id); 3006 ipa_debug("vdev_to_iface[%u]=%u", 3007 session_id, 3008 ipa_ctx->vdev_to_iface[session_id]); 3009 ipa_wds = ipa_ctx->config->ipa_wds; 3010 qdf_mutex_release(&ipa_ctx->event_lock); 3011 break; 3012 3013 case QDF_IPA_STA_DISCONNECT: 3014 qdf_mutex_acquire(&ipa_ctx->event_lock); 3015 3016 if (!ipa_ctx->sta_connected) { 3017 struct wlan_ipa_iface_context *iface; 3018 3019 qdf_mutex_release(&ipa_ctx->event_lock); 3020 ipa_info("%s: Evt: %d, STA already disconnected", 3021 msg_ex->name, 3022 QDF_IPA_MSG_META_MSG_TYPE(&meta)); 3023 3024 iface = wlan_ipa_get_iface_by_mode_netdev(ipa_ctx, 3025 net_dev, 3026 QDF_STA_MODE); 3027 if (iface) 3028 wlan_ipa_cleanup_iface(iface, mac_addr); 3029 3030 return QDF_STATUS_E_INVAL; 3031 } 3032 3033 ipa_ctx->sta_connected--; 3034 3035 if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 3036 ipa_debug("%s: IPA UC OFFLOAD NOT ENABLED", 3037 msg_ex->name); 3038 } else { 3039 /* 3040 * Disable IPA pipes when 3041 * 1. STA is the last interface or 3042 * 2. STA only offload enabled and no clients connected 3043 * to SAP 3044 */ 3045 if ((ipa_ctx->num_iface == 1 || 3046 (wlan_ipa_is_sta_only_offload_enabled() && 3047 !ipa_ctx->sap_num_connected_sta)) && 3048 wlan_ipa_is_fw_wdi_activated(ipa_ctx) && 3049 !ipa_ctx->ipa_pipes_down && 3050 (ipa_ctx->resource_unloading == false)) { 3051 if (wlan_ipa_is_driver_unloading(ipa_ctx)) { 3052 /* 3053 * We disable WDI pipes directly here 3054 * since IPA_OPCODE_TX/RX_SUSPEND 3055 * message will not be processed when 3056 * unloading WLAN driver is in progress 3057 */ 3058 wlan_ipa_uc_disable_pipes(ipa_ctx, 3059 true); 3060 } else { 3061 wlan_ipa_uc_handle_last_discon(ipa_ctx, 3062 true); 3063 } 3064 } 3065 } 3066 3067 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && 3068 (ipa_ctx->sap_num_connected_sta > 0 || 3069 wlan_ipa_is_sta_only_offload_enabled())) { 3070 qdf_atomic_set(&ipa_ctx->stats_quota, 0); 3071 qdf_mutex_release(&ipa_ctx->event_lock); 3072 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 3073 WMI_STA_RX_DATA_OFFLOAD, session_id, false); 3074 qdf_mutex_acquire(&ipa_ctx->event_lock); 3075 } 3076 3077 ipa_ctx->vdev_to_iface[session_id] = WLAN_IPA_MAX_SESSION; 3078 ipa_debug("vdev_to_iface[%u]=%u", session_id, 3079 ipa_ctx->vdev_to_iface[session_id]); 3080 3081 iface_ctx = wlan_ipa_get_iface_by_mode_netdev(ipa_ctx, 3082 net_dev, 3083 QDF_STA_MODE); 3084 if (iface_ctx) 3085 wlan_ipa_cleanup_iface(iface_ctx, mac_addr); 3086 3087 if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sap_num_connected_sta) 3088 ipa_set_rps_per_vdev(ipa_ctx, session_id, false); 3089 3090 qdf_mutex_release(&ipa_ctx->event_lock); 3091 3092 ipa_debug("sta_connected=%d", ipa_ctx->sta_connected); 3093 break; 3094 3095 case QDF_IPA_AP_DISCONNECT: 3096 qdf_mutex_acquire(&ipa_ctx->event_lock); 3097 3098 if ((ipa_ctx->num_iface == 1) && 3099 wlan_ipa_is_fw_wdi_activated(ipa_ctx) && 3100 !ipa_ctx->ipa_pipes_down && 3101 (ipa_ctx->resource_unloading == false)) { 3102 if (wlan_ipa_is_driver_unloading(ipa_ctx)) { 3103 /* 3104 * We disable WDI pipes directly here since 3105 * IPA_OPCODE_TX/RX_SUSPEND message will not be 3106 * processed when unloading WLAN driver is in 3107 * progress 3108 */ 3109 wlan_ipa_uc_disable_pipes(ipa_ctx, true); 3110 } else { 3111 /* 3112 * This shouldn't happen : 3113 * No interface left but WDI pipes are still 3114 * active - force close WDI pipes 3115 */ 3116 ipa_err("No interface left but WDI pipes are still active"); 3117 wlan_ipa_uc_handle_last_discon(ipa_ctx, true); 3118 } 3119 } 3120 3121 if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 3122 qdf_mutex_release(&ipa_ctx->event_lock); 3123 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 3124 WMI_AP_RX_DATA_OFFLOAD, session_id, false); 3125 qdf_mutex_acquire(&ipa_ctx->event_lock); 3126 ipa_ctx->vdev_to_iface[session_id] = 3127 WLAN_IPA_MAX_SESSION; 3128 ipa_debug("vdev_to_iface[%u]=%u", 3129 session_id, 3130 ipa_ctx->vdev_to_iface[session_id]); 3131 } 3132 3133 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 3134 iface_ctx = &ipa_ctx->iface_context[i]; 3135 if (iface_ctx->dev == net_dev) { 3136 wlan_ipa_cleanup_iface(iface_ctx, mac_addr); 3137 break; 3138 } 3139 } 3140 3141 if (qdf_ipa_get_lan_rx_napi() && 3142 (ipa_ctx->num_sap_connected == 1)) 3143 wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type); 3144 3145 qdf_mutex_release(&ipa_ctx->event_lock); 3146 break; 3147 3148 case QDF_IPA_CLIENT_CONNECT_EX: 3149 if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 3150 ipa_debug("%s: Evt: %d, IPA UC OFFLOAD NOT ENABLED", 3151 net_dev->name, type); 3152 return QDF_STATUS_SUCCESS; 3153 } 3154 3155 qdf_mutex_acquire(&ipa_ctx->event_lock); 3156 if (wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, true, 3157 mac_addr)) { 3158 qdf_mutex_release(&ipa_ctx->event_lock); 3159 ipa_err("%s: STA found, addr: " QDF_MAC_ADDR_FMT, 3160 net_dev->name, 3161 QDF_MAC_ADDR_REF(mac_addr)); 3162 return QDF_STATUS_SUCCESS; 3163 } 3164 3165 /* Enable IPA UC Data PIPEs when first STA connected */ 3166 if (ipa_ctx->sap_num_connected_sta == 0 && 3167 ipa_ctx->uc_loaded == true) { 3168 3169 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && 3170 ipa_ctx->sta_connected && 3171 !wlan_ipa_is_sta_only_offload_enabled()) { 3172 qdf_mutex_release(&ipa_ctx->event_lock); 3173 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 3174 WMI_STA_RX_DATA_OFFLOAD, 3175 sta_session_id, true); 3176 qdf_mutex_acquire(&ipa_ctx->event_lock); 3177 qdf_atomic_set(&ipa_ctx->stats_quota, 1); 3178 } 3179 3180 /* 3181 * IPA pipes already enabled if STA only offload 3182 * is enabled and STA is connected to remote AP. 3183 */ 3184 if (wlan_ipa_is_sta_only_offload_enabled() && 3185 ipa_ctx->sta_connected) { 3186 ipa_debug("IPA pipes already enabled"); 3187 } else if (wlan_ipa_uc_handle_first_con(ipa_ctx)) { 3188 ipa_info("%s: handle 1st con fail", 3189 net_dev->name); 3190 3191 if (wlan_ipa_uc_sta_is_enabled( 3192 ipa_ctx->config) && 3193 ipa_ctx->sta_connected && 3194 !wlan_ipa_is_sta_only_offload_enabled()) { 3195 qdf_atomic_set(&ipa_ctx->stats_quota, 3196 0); 3197 qdf_mutex_release(&ipa_ctx->event_lock); 3198 wlan_ipa_uc_offload_enable_disable( 3199 ipa_ctx, 3200 WMI_STA_RX_DATA_OFFLOAD, 3201 sta_session_id, false); 3202 } else { 3203 qdf_mutex_release(&ipa_ctx->event_lock); 3204 } 3205 3206 return QDF_STATUS_E_BUSY; 3207 } 3208 wlan_ipa_uc_bw_monitor(ipa_ctx, false); 3209 ipa_info("first sap client connected"); 3210 } 3211 3212 ipa_ctx->sap_num_connected_sta++; 3213 3214 qdf_mutex_release(&ipa_ctx->event_lock); 3215 3216 QDF_IPA_SET_META_MSG_TYPE(&meta, type); 3217 3218 status = wlan_ipa_set_peer_id(ipa_ctx, &meta, net_dev, 3219 type, (uint8_t *)mac_addr); 3220 if (QDF_IS_STATUS_ERROR(status)) 3221 return QDF_STATUS_E_FAILURE; 3222 3223 ipa_debug("sap_num_connected_sta=%d", 3224 ipa_ctx->sap_num_connected_sta); 3225 3226 return QDF_STATUS_SUCCESS; 3227 3228 case WLAN_CLIENT_DISCONNECT: 3229 if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 3230 ipa_debug("%s: IPA UC OFFLOAD NOT ENABLED", 3231 msg_ex->name); 3232 return QDF_STATUS_SUCCESS; 3233 } 3234 3235 qdf_mutex_acquire(&ipa_ctx->event_lock); 3236 wlan_ipa_set_sap_client_auth(ipa_ctx, mac_addr, false); 3237 if (!ipa_ctx->sap_num_connected_sta) { 3238 qdf_mutex_release(&ipa_ctx->event_lock); 3239 ipa_debug("%s: Evt: %d, Client already disconnected", 3240 msg_ex->name, 3241 QDF_IPA_MSG_META_MSG_TYPE(&meta)); 3242 3243 return QDF_STATUS_SUCCESS; 3244 } 3245 if (!wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, false, 3246 mac_addr)) { 3247 qdf_mutex_release(&ipa_ctx->event_lock); 3248 ipa_debug("%s: STA NOT found, not valid: " 3249 QDF_MAC_ADDR_FMT, 3250 msg_ex->name, QDF_MAC_ADDR_REF(mac_addr)); 3251 3252 return QDF_STATUS_SUCCESS; 3253 } 3254 ipa_ctx->sap_num_connected_sta--; 3255 3256 /* 3257 * Disable IPA pipes when 3258 * 1. last client disconnected and 3259 * 2. STA is not connected if STA only offload is enabled 3260 */ 3261 if (!ipa_ctx->sap_num_connected_sta && 3262 ipa_ctx->uc_loaded && 3263 !(wlan_ipa_is_sta_only_offload_enabled() && 3264 ipa_ctx->sta_connected)) { 3265 if ((false == ipa_ctx->resource_unloading) && 3266 wlan_ipa_is_fw_wdi_activated(ipa_ctx) && 3267 !ipa_ctx->ipa_pipes_down) { 3268 if (wlan_ipa_is_driver_unloading(ipa_ctx)) { 3269 /* 3270 * We disable WDI pipes directly here 3271 * since IPA_OPCODE_TX/RX_SUSPEND 3272 * message will not be processed when 3273 * unloading WLAN driver is in progress 3274 */ 3275 3276 wlan_ipa_uc_bw_monitor(ipa_ctx, true); 3277 wlan_ipa_uc_disable_pipes(ipa_ctx, 3278 true); 3279 } else { 3280 /* 3281 * If STA is connected, wait for IPA TX 3282 * completions before disabling 3283 * IPA pipes 3284 */ 3285 wlan_ipa_uc_handle_last_discon(ipa_ctx, 3286 !ipa_ctx->sta_connected); 3287 wlan_ipa_uc_bw_monitor(ipa_ctx, true); 3288 } 3289 ipa_info("last sap client disconnected"); 3290 } 3291 3292 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && 3293 ipa_ctx->sta_connected && 3294 !wlan_ipa_is_sta_only_offload_enabled()) { 3295 qdf_atomic_set(&ipa_ctx->stats_quota, 0); 3296 qdf_mutex_release(&ipa_ctx->event_lock); 3297 wlan_ipa_uc_offload_enable_disable(ipa_ctx, 3298 WMI_STA_RX_DATA_OFFLOAD, 3299 sta_session_id, false); 3300 } else { 3301 qdf_mutex_release(&ipa_ctx->event_lock); 3302 } 3303 } else { 3304 qdf_mutex_release(&ipa_ctx->event_lock); 3305 } 3306 3307 ipa_debug("sap_num_connected_sta=%d", 3308 ipa_ctx->sap_num_connected_sta); 3309 break; 3310 3311 default: 3312 return QDF_STATUS_SUCCESS; 3313 } 3314 3315 QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t); 3316 msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); 3317 if (!msg) 3318 return QDF_STATUS_E_NOMEM; 3319 3320 QDF_IPA_SET_META_MSG_TYPE(&meta, type); 3321 strlcpy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name, 3322 IPA_RESOURCE_NAME_MAX); 3323 qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN); 3324 QDF_IPA_WLAN_MSG_NETDEV_IF_ID(msg) = net_dev->ifindex; 3325 3326 wlan_ipa_msg_wds_update(ipa_wds, msg); 3327 3328 ipa_debug("%s: Evt: %d", QDF_IPA_WLAN_MSG_NAME(msg), 3329 QDF_IPA_MSG_META_MSG_TYPE(&meta)); 3330 3331 if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) { 3332 3333 ipa_err("%s: Evt: %d fail", 3334 QDF_IPA_WLAN_MSG_NAME(msg), 3335 QDF_IPA_MSG_META_MSG_TYPE(&meta)); 3336 qdf_mem_free(msg); 3337 3338 return QDF_STATUS_E_FAILURE; 3339 } 3340 3341 ipa_ctx->stats.num_send_msg++; 3342 3343 end: 3344 return QDF_STATUS_SUCCESS; 3345 } 3346 3347 /** 3348 * wlan_host_to_ipa_wlan_event() - convert wlan_ipa_wlan_event to ipa_wlan_event 3349 * @wlan_ipa_event_type: event to be converted to an ipa_wlan_event 3350 * 3351 * Return: qdf_ipa_wlan_event representing the wlan_ipa_wlan_event 3352 */ 3353 static qdf_ipa_wlan_event 3354 wlan_host_to_ipa_wlan_event(enum wlan_ipa_wlan_event wlan_ipa_event_type) 3355 { 3356 qdf_ipa_wlan_event ipa_event; 3357 3358 switch (wlan_ipa_event_type) { 3359 case WLAN_IPA_CLIENT_CONNECT: 3360 ipa_event = QDF_IPA_CLIENT_CONNECT; 3361 break; 3362 case WLAN_IPA_CLIENT_DISCONNECT: 3363 ipa_event = QDF_IPA_CLIENT_DISCONNECT; 3364 break; 3365 case WLAN_IPA_AP_CONNECT: 3366 ipa_event = QDF_IPA_AP_CONNECT; 3367 break; 3368 case WLAN_IPA_AP_DISCONNECT: 3369 ipa_event = QDF_IPA_AP_DISCONNECT; 3370 break; 3371 case WLAN_IPA_STA_CONNECT: 3372 ipa_event = QDF_IPA_STA_CONNECT; 3373 break; 3374 case WLAN_IPA_STA_DISCONNECT: 3375 ipa_event = QDF_IPA_STA_DISCONNECT; 3376 break; 3377 case WLAN_IPA_CLIENT_CONNECT_EX: 3378 ipa_event = QDF_IPA_CLIENT_CONNECT_EX; 3379 break; 3380 case WLAN_IPA_WLAN_EVENT_MAX: 3381 default: 3382 ipa_event = QDF_IPA_WLAN_EVENT_MAX; 3383 break; 3384 } 3385 3386 return ipa_event; 3387 } 3388 3389 #ifdef IPA_P2P_SUPPORT 3390 /** 3391 * wlan_ipa_device_mode_switch() - Switch P2p GO/CLI to SAP/STA mode 3392 * @device_mode: device mode 3393 * 3394 * Return: New device mode after switching 3395 */ 3396 static uint8_t wlan_ipa_device_mode_switch(uint8_t device_mode) 3397 { 3398 switch (device_mode) { 3399 case QDF_P2P_CLIENT_MODE: 3400 return QDF_STA_MODE; 3401 case QDF_P2P_GO_MODE: 3402 return QDF_SAP_MODE; 3403 default: 3404 break; 3405 } 3406 3407 return device_mode; 3408 } 3409 #else 3410 static uint8_t wlan_ipa_device_mode_switch(uint8_t device_mode) 3411 { 3412 return device_mode; 3413 } 3414 #endif 3415 3416 /** 3417 * wlan_ipa_wlan_evt() - SSR wrapper for __wlan_ipa_wlan_evt 3418 * @net_dev: Interface net device 3419 * @device_mode: Net interface device mode 3420 * @session_id: session id for the event 3421 * @ipa_event_type: event enum of type wlan_ipa_wlan_event 3422 * @mac_address: MAC address associated with the event 3423 * @is_2g_iface: @net_dev is 2g interface or not 3424 * 3425 * Return: QDF_STATUS 3426 */ 3427 QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, 3428 uint8_t session_id, 3429 enum wlan_ipa_wlan_event ipa_event_type, 3430 uint8_t *mac_addr, bool is_2g_iface, 3431 struct wlan_ipa_priv *ipa_obj) 3432 { 3433 qdf_ipa_wlan_event type = wlan_host_to_ipa_wlan_event(ipa_event_type); 3434 QDF_STATUS status = QDF_STATUS_SUCCESS; 3435 3436 device_mode = wlan_ipa_device_mode_switch(device_mode); 3437 3438 /* Data path offload only support for STA and SAP mode */ 3439 if ((device_mode == QDF_STA_MODE) || 3440 (device_mode == QDF_SAP_MODE)) 3441 status = __wlan_ipa_wlan_evt(net_dev, device_mode, 3442 session_id, type, mac_addr, 3443 is_2g_iface, ipa_obj); 3444 3445 return status; 3446 } 3447 3448 /** 3449 * wlan_ipa_uc_proc_pending_event() - Process IPA uC pending events 3450 * @ipa_ctx: Global IPA IPA context 3451 * @is_loading: Indicate if invoked during loading 3452 * 3453 * Return: None 3454 */ 3455 static void 3456 wlan_ipa_uc_proc_pending_event(struct wlan_ipa_priv *ipa_ctx, bool is_loading) 3457 { 3458 unsigned int pending_event_count; 3459 struct wlan_ipa_uc_pending_event *pending_event = NULL; 3460 3461 pending_event_count = qdf_list_size(&ipa_ctx->pending_event); 3462 ipa_debug("Pending Event Count %d", pending_event_count); 3463 if (!pending_event_count) { 3464 ipa_debug("No Pending Event"); 3465 return; 3466 } 3467 3468 qdf_list_remove_front(&ipa_ctx->pending_event, 3469 (qdf_list_node_t **)&pending_event); 3470 while (pending_event) { 3471 struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev; 3472 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 3473 struct wlan_objmgr_vdev *vdev = 3474 wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 3475 pending_event->session_id, 3476 WLAN_IPA_ID); 3477 if (pending_event->is_loading == is_loading && vdev) { 3478 __wlan_ipa_wlan_evt(pending_event->net_dev, 3479 pending_event->device_mode, 3480 pending_event->session_id, 3481 pending_event->type, 3482 pending_event->mac_addr, 3483 pending_event->is_2g_iface, ipa_ctx); 3484 } 3485 3486 if (vdev) 3487 wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID); 3488 qdf_mem_free(pending_event); 3489 pending_event = NULL; 3490 qdf_list_remove_front(&ipa_ctx->pending_event, 3491 (qdf_list_node_t **)&pending_event); 3492 } 3493 } 3494 3495 #if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL) 3496 3497 /** 3498 * wlan_ipa_free_tx_desc_list() - Free IPA Tx desc list 3499 * @ipa_ctx: IPA context 3500 * 3501 * Return: None 3502 */ 3503 static inline void wlan_ipa_free_tx_desc_list(struct wlan_ipa_priv *ipa_ctx) 3504 { 3505 int i; 3506 qdf_ipa_rx_data_t *ipa_tx_desc; 3507 uint32_t pool_size; 3508 3509 if (!ipa_ctx->tx_desc_pool) 3510 return; 3511 3512 qdf_spin_lock_bh(&ipa_ctx->q_lock); 3513 pool_size = ipa_ctx->tx_desc_free_list.max_size; 3514 for (i = 0; i < pool_size; i++) { 3515 ipa_tx_desc = ipa_ctx->tx_desc_pool[i].ipa_tx_desc_ptr; 3516 if (ipa_tx_desc) 3517 qdf_ipa_free_skb(ipa_tx_desc); 3518 3519 if (ipa_ctx->tx_desc_free_list.count && 3520 qdf_list_remove_node(&ipa_ctx->tx_desc_free_list, 3521 &ipa_ctx->tx_desc_pool[i].node) != 3522 QDF_STATUS_SUCCESS) 3523 ipa_err("Failed to remove node from tx desc freelist"); 3524 } 3525 qdf_spin_unlock_bh(&ipa_ctx->q_lock); 3526 3527 qdf_list_destroy(&ipa_ctx->tx_desc_free_list); 3528 qdf_mem_free(ipa_ctx->tx_desc_pool); 3529 ipa_ctx->tx_desc_pool = NULL; 3530 3531 ipa_ctx->stats.num_tx_desc_q_cnt = 0; 3532 ipa_ctx->stats.num_tx_desc_error = 0; 3533 } 3534 3535 /** 3536 * wlan_ipa_alloc_tx_desc_free_list() - Allocate IPA Tx desc list 3537 * @ipa_ctx: IPA context 3538 * 3539 * Return: QDF_STATUS 3540 */ 3541 static QDF_STATUS 3542 wlan_ipa_alloc_tx_desc_free_list(struct wlan_ipa_priv *ipa_ctx) 3543 { 3544 int i; 3545 uint32_t max_desc_cnt; 3546 3547 max_desc_cnt = ipa_ctx->config->txbuf_count; 3548 3549 ipa_ctx->tx_desc_pool = qdf_mem_malloc(sizeof(struct wlan_ipa_tx_desc) * 3550 max_desc_cnt); 3551 if (!ipa_ctx->tx_desc_pool) 3552 return QDF_STATUS_E_NOMEM; 3553 3554 qdf_list_create(&ipa_ctx->tx_desc_free_list, max_desc_cnt); 3555 3556 qdf_spin_lock_bh(&ipa_ctx->q_lock); 3557 for (i = 0; i < max_desc_cnt; i++) { 3558 ipa_ctx->tx_desc_pool[i].id = i; 3559 ipa_ctx->tx_desc_pool[i].ipa_tx_desc_ptr = NULL; 3560 qdf_list_insert_back(&ipa_ctx->tx_desc_free_list, 3561 &ipa_ctx->tx_desc_pool[i].node); 3562 } 3563 3564 ipa_ctx->stats.num_tx_desc_q_cnt = 0; 3565 ipa_ctx->stats.num_tx_desc_error = 0; 3566 3567 qdf_spin_unlock_bh(&ipa_ctx->q_lock); 3568 3569 return QDF_STATUS_SUCCESS; 3570 } 3571 3572 /** 3573 * wlan_ipa_setup_tx_sys_pipe() - Setup IPA Tx system pipes 3574 * @ipa_ctx: Global IPA IPA context 3575 * @desc_fifo_sz: Number of descriptors 3576 * 3577 * Return: 0 on success, negative errno on error 3578 */ 3579 static int wlan_ipa_setup_tx_sys_pipe(struct wlan_ipa_priv *ipa_ctx, 3580 int32_t desc_fifo_sz) 3581 { 3582 int i, ret = 0; 3583 qdf_ipa_sys_connect_params_t *ipa; 3584 3585 /*setup TX pipes */ 3586 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 3587 ipa = &ipa_ctx->sys_pipe[i].ipa_sys_params; 3588 3589 ipa->client = wlan_ipa_iface_2_client[i].cons_client; 3590 ipa->desc_fifo_sz = desc_fifo_sz; 3591 ipa->priv = &ipa_ctx->iface_context[i]; 3592 ipa->notify = wlan_ipa_i2w_cb; 3593 3594 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 3595 ipa->ipa_ep_cfg.hdr.hdr_len = 3596 WLAN_IPA_UC_WLAN_TX_HDR_LEN; 3597 ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT; 3598 ipa->ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1; 3599 ipa->ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 0; 3600 ipa->ipa_ep_cfg.hdr.hdr_additional_const_len = 3601 WLAN_IPA_UC_WLAN_8023_HDR_SIZE; 3602 ipa->ipa_ep_cfg.hdr_ext.hdr_little_endian = true; 3603 } else { 3604 ipa->ipa_ep_cfg.hdr.hdr_len = WLAN_IPA_WLAN_TX_HDR_LEN; 3605 } 3606 ipa->ipa_ep_cfg.mode.mode = IPA_BASIC; 3607 3608 ret = wlan_ipa_wdi_setup_sys_pipe(ipa_ctx, ipa, 3609 &ipa_ctx->sys_pipe[i].conn_hdl); 3610 if (ret) { 3611 ipa_err("Failed for pipe %d ret: %d", i, ret); 3612 return ret; 3613 } 3614 ipa_ctx->sys_pipe[i].conn_hdl_valid = 1; 3615 } 3616 3617 return ret; 3618 } 3619 #else /* QCA_LL_TX_FLOW_CONTROL_V2 */ 3620 3621 /** 3622 * wlan_ipa_free_tx_desc_list() - Free IPA Tx desc list 3623 * @ipa_ctx: IPA context 3624 * 3625 * Return: None 3626 */ 3627 static inline void wlan_ipa_free_tx_desc_list(struct wlan_ipa_priv *ipa_ctx) 3628 { 3629 } 3630 3631 /** 3632 * wlan_ipa_alloc_tx_desc_free_list() - Allocate IPA Tx desc list 3633 * @ipa_ctx: IPA context 3634 * 3635 * Return: QDF_STATUS 3636 */ 3637 static QDF_STATUS 3638 wlan_ipa_alloc_tx_desc_free_list(struct wlan_ipa_priv *ipa_ctx) 3639 { 3640 return QDF_STATUS_SUCCESS; 3641 } 3642 3643 /** 3644 * wlan_ipa_setup_tx_sys_pipe() - Setup IPA Tx system pipes 3645 * @ipa_ctx: IPA context 3646 * @desc_fifo_sz: Number of descriptors 3647 * 3648 * Return: 0 on success, negative errno on error 3649 */ 3650 static int wlan_ipa_setup_tx_sys_pipe(struct wlan_ipa_priv *ipa_ctx, 3651 int32_t desc_fifo_sz) 3652 { 3653 /* 3654 * The Tx system pipes are not needed for MCC when TX_FLOW_CONTROL_V2 3655 * is enabled, where per vdev descriptors are supported in firmware. 3656 */ 3657 return 0; 3658 } 3659 #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ 3660 3661 #if defined(CONFIG_IPA_WDI_UNIFIED_API) && defined(IPA_WDI3_GSI) 3662 /** 3663 * wlan_ipa_get_rx_ipa_client() - Get IPA RX ipa client 3664 * @ipa_ctx: IPA context 3665 * 3666 * Return: rx ipa sys client 3667 */ 3668 static inline uint8_t wlan_ipa_get_rx_ipa_client(struct wlan_ipa_priv *ipa_ctx) 3669 { 3670 if (ipa_ctx->over_gsi) 3671 return IPA_CLIENT_WLAN2_PROD; 3672 else 3673 return IPA_CLIENT_WLAN1_PROD; 3674 } 3675 3676 /** 3677 * wlan_ipa_uc_send_wdi_control_msg() - Set WDI control message 3678 * @ctrl: WDI control value 3679 * 3680 * Send WLAN_WDI_ENABLE for ctrl = true and WLAN_WDI_DISABLE otherwise. 3681 * 3682 * Return: QDF_STATUS 3683 */ 3684 static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(struct wlan_ipa_priv *ipa_ctx, 3685 bool ctrl) 3686 { 3687 return QDF_STATUS_SUCCESS; 3688 } 3689 3690 #else 3691 static inline uint8_t wlan_ipa_get_rx_ipa_client(struct wlan_ipa_priv *ipa_ctx) 3692 { 3693 return IPA_CLIENT_WLAN1_PROD; 3694 } 3695 3696 static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(struct wlan_ipa_priv *ipa_ctx, 3697 bool ctrl) 3698 { 3699 struct wlan_ipa_priv *ipa_obj = ipa_ctx; 3700 qdf_ipa_msg_meta_t meta; 3701 qdf_ipa_wlan_msg_t *ipa_msg; 3702 int ret = 0; 3703 3704 /* WDI enable message to IPA */ 3705 QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*ipa_msg); 3706 ipa_msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); 3707 if (!ipa_msg) 3708 return QDF_STATUS_E_NOMEM; 3709 3710 if (ctrl) { 3711 QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_ENABLE); 3712 ipa_obj->stats.event[QDF_WDI_ENABLE]++; 3713 } else { 3714 QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_DISABLE); 3715 ipa_obj->stats.event[QDF_WDI_DISABLE]++; 3716 } 3717 3718 ipa_debug("ipa_send_msg(Evt:%d)", QDF_IPA_MSG_META_MSG_TYPE(&meta)); 3719 ret = qdf_ipa_send_msg(&meta, ipa_msg, wlan_ipa_msg_free_fn); 3720 if (ret) { 3721 ipa_err("ipa_send_msg(Evt:%d)-fail=%d", 3722 QDF_IPA_MSG_META_MSG_TYPE(&meta), ret); 3723 qdf_mem_free(ipa_msg); 3724 return QDF_STATUS_E_FAILURE; 3725 } 3726 3727 return QDF_STATUS_SUCCESS; 3728 } 3729 #endif 3730 3731 /** 3732 * wlan_ipa_setup_rx_sys_pipe() - Setup IPA Rx system pipes 3733 * @ipa_ctx: Global IPA IPA context 3734 * @desc_fifo_sz: Number of descriptors 3735 * 3736 * Return: 0 on success, negative errno on error 3737 */ 3738 static int wlan_ipa_setup_rx_sys_pipe(struct wlan_ipa_priv *ipa_ctx, 3739 int32_t desc_fifo_sz) 3740 { 3741 int ret = 0; 3742 qdf_ipa_sys_connect_params_t *ipa; 3743 3744 /* 3745 * Hard code it here, this can be extended if in case 3746 * PROD pipe is also per interface. 3747 * Right now there is no advantage of doing this. 3748 */ 3749 ipa = &ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].ipa_sys_params; 3750 3751 ipa->client = wlan_ipa_get_rx_ipa_client(ipa_ctx); 3752 ipa->desc_fifo_sz = desc_fifo_sz; 3753 ipa->priv = ipa_ctx; 3754 ipa->notify = wlan_ipa_w2i_cb; 3755 3756 ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT; 3757 ipa->ipa_ep_cfg.hdr.hdr_len = WLAN_IPA_WLAN_RX_HDR_LEN; 3758 ipa->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1; 3759 ipa->ipa_ep_cfg.mode.mode = IPA_BASIC; 3760 3761 ret = qdf_ipa_setup_sys_pipe(ipa, 3762 &ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].conn_hdl); 3763 if (ret) { 3764 ipa_err("Failed for RX pipe: %d", ret); 3765 return ret; 3766 } 3767 ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].conn_hdl_valid = 1; 3768 3769 return ret; 3770 } 3771 3772 /** 3773 * wlan_ipa_teardown_sys_pipe() - Tear down all IPA Sys pipes 3774 * @ipa_ctx: Global IPA IPA context 3775 * 3776 * Return: None 3777 */ 3778 static void wlan_ipa_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx) 3779 { 3780 int ret, i; 3781 3782 if (!ipa_ctx) 3783 return; 3784 3785 for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++) { 3786 if (ipa_ctx->sys_pipe[i].conn_hdl_valid) { 3787 ret = wlan_ipa_wdi_teardown_sys_pipe(ipa_ctx, 3788 ipa_ctx->sys_pipe[i].conn_hdl); 3789 if (ret) 3790 ipa_err("Failed:%d", ret); 3791 3792 ipa_ctx->sys_pipe[i].conn_hdl_valid = 0; 3793 } 3794 } 3795 3796 wlan_ipa_free_tx_desc_list(ipa_ctx); 3797 } 3798 3799 /** 3800 * wlan_ipa_setup_sys_pipe() - Setup all IPA system pipes 3801 * @ipa_ctx: Global IPA IPA context 3802 * 3803 * Return: 0 on success, negative errno on error 3804 */ 3805 static int wlan_ipa_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx) 3806 { 3807 int ret = 0; 3808 uint32_t desc_fifo_sz; 3809 3810 /* The maximum number of descriptors that can be provided to a BAM at 3811 * once is one less than the total number of descriptors that the buffer 3812 * can contain. 3813 * If max_num_of_descriptors = (BAM_PIPE_DESCRIPTOR_FIFO_SIZE / sizeof 3814 * (SPS_DESCRIPTOR)), then (max_num_of_descriptors - 1) descriptors can 3815 * be provided at once. 3816 * Because of above requirement, one extra descriptor will be added to 3817 * make sure hardware always has one descriptor. 3818 */ 3819 desc_fifo_sz = ipa_ctx->config->desc_size + IPA_SPS_DESC_SIZE; 3820 3821 ret = wlan_ipa_setup_tx_sys_pipe(ipa_ctx, desc_fifo_sz); 3822 if (ret) { 3823 ipa_err("Failed for TX pipe: %d", ret); 3824 goto setup_sys_pipe_fail; 3825 } 3826 3827 if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 3828 ret = wlan_ipa_setup_rx_sys_pipe(ipa_ctx, desc_fifo_sz); 3829 if (ret) { 3830 ipa_err("Failed for RX pipe: %d", ret); 3831 goto setup_sys_pipe_fail; 3832 } 3833 } 3834 3835 /* Allocate free Tx desc list */ 3836 ret = wlan_ipa_alloc_tx_desc_free_list(ipa_ctx); 3837 if (ret) 3838 goto setup_sys_pipe_fail; 3839 3840 return ret; 3841 3842 setup_sys_pipe_fail: 3843 wlan_ipa_teardown_sys_pipe(ipa_ctx); 3844 3845 return ret; 3846 } 3847 3848 #if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL) 3849 QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx, 3850 bool mcc_mode) 3851 { 3852 qdf_ipa_msg_meta_t meta; 3853 qdf_ipa_wlan_msg_t *msg; 3854 int ret; 3855 3856 if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) 3857 return QDF_STATUS_SUCCESS; 3858 3859 /* Send SCC/MCC Switching event to IPA */ 3860 QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*msg); 3861 msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); 3862 if (!msg) 3863 return QDF_STATUS_E_NOMEM; 3864 3865 if (mcc_mode) { 3866 QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_MCC); 3867 ipa_ctx->stats.event[QDF_SWITCH_TO_MCC]++; 3868 } else { 3869 QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_SCC); 3870 ipa_ctx->stats.event[QDF_SWITCH_TO_SCC]++; 3871 } 3872 3873 WLAN_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, 3874 "ipa_send_msg(Evt:%d)", 3875 QDF_IPA_MSG_META_MSG_TYPE(&meta)); 3876 3877 ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn); 3878 3879 if (ret) { 3880 ipa_err("ipa_send_msg(Evt:%d) - fail=%d", 3881 QDF_IPA_MSG_META_MSG_TYPE(&meta), ret); 3882 qdf_mem_free(msg); 3883 return QDF_STATUS_E_FAILURE; 3884 } 3885 3886 return QDF_STATUS_SUCCESS; 3887 } 3888 3889 static void wlan_ipa_mcc_work_handler(void *data) 3890 { 3891 struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data; 3892 3893 wlan_ipa_send_mcc_scc_msg(ipa_ctx, ipa_ctx->mcc_mode); 3894 } 3895 #endif 3896 3897 /** 3898 * wlan_ipa_setup() - IPA initialization function 3899 * @ipa_ctx: IPA context 3900 * @ipa_cfg: IPA config 3901 * 3902 * Allocate ipa_ctx resources, ipa pipe resource and register 3903 * wlan interface with IPA module. 3904 * 3905 * Return: QDF_STATUS enumeration 3906 */ 3907 QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx, 3908 struct wlan_ipa_config *ipa_cfg) 3909 { 3910 int ret, i; 3911 struct wlan_ipa_iface_context *iface_context = NULL; 3912 QDF_STATUS status; 3913 3914 ipa_debug("enter"); 3915 3916 gp_ipa = ipa_ctx; 3917 ipa_ctx->num_iface = 0; 3918 ipa_ctx->config = ipa_cfg; 3919 3920 wlan_ipa_wdi_get_wdi_version(ipa_ctx); 3921 3922 /* Create the interface context */ 3923 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 3924 iface_context = &ipa_ctx->iface_context[i]; 3925 iface_context->ipa_ctx = ipa_ctx; 3926 iface_context->cons_client = 3927 wlan_ipa_iface_2_client[i].cons_client; 3928 iface_context->prod_client = 3929 wlan_ipa_iface_2_client[i].prod_client; 3930 iface_context->iface_id = i; 3931 iface_context->dev = NULL; 3932 iface_context->device_mode = QDF_MAX_NO_OF_MODE; 3933 iface_context->session_id = WLAN_IPA_MAX_SESSION; 3934 qdf_atomic_init(&iface_context->conn_count); 3935 qdf_atomic_init(&iface_context->disconn_count); 3936 qdf_spinlock_create(&iface_context->interface_lock); 3937 } 3938 3939 qdf_create_work(0, &ipa_ctx->pm_work, wlan_ipa_pm_flush, ipa_ctx); 3940 qdf_spinlock_create(&ipa_ctx->pm_lock); 3941 qdf_spinlock_create(&ipa_ctx->q_lock); 3942 qdf_spinlock_create(&ipa_ctx->enable_disable_lock); 3943 ipa_ctx->pipes_down_in_progress = false; 3944 ipa_ctx->pipes_enable_in_progress = false; 3945 qdf_nbuf_queue_init(&ipa_ctx->pm_queue_head); 3946 qdf_list_create(&ipa_ctx->pending_event, 1000); 3947 qdf_mutex_create(&ipa_ctx->event_lock); 3948 qdf_mutex_create(&ipa_ctx->ipa_lock); 3949 qdf_atomic_init(&ipa_ctx->deinit_in_prog); 3950 3951 status = wlan_ipa_wdi_setup_rm(ipa_ctx); 3952 if (status != QDF_STATUS_SUCCESS) 3953 goto fail_setup_rm; 3954 3955 for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++) 3956 qdf_mem_zero(&ipa_ctx->sys_pipe[i], 3957 sizeof(struct wlan_ipa_sys_pipe)); 3958 3959 if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 3960 qdf_mem_zero(&ipa_ctx->stats, sizeof(ipa_ctx->stats)); 3961 ipa_ctx->sap_num_connected_sta = 0; 3962 ipa_ctx->ipa_tx_packets_diff = 0; 3963 ipa_ctx->ipa_rx_packets_diff = 0; 3964 ipa_ctx->ipa_p_tx_packets = 0; 3965 ipa_ctx->ipa_p_rx_packets = 0; 3966 ipa_ctx->resource_loading = false; 3967 ipa_ctx->resource_unloading = false; 3968 ipa_ctx->num_sap_connected = 0; 3969 ipa_ctx->sta_connected = 0; 3970 ipa_ctx->ipa_pipes_down = true; 3971 qdf_atomic_set(&ipa_ctx->pipes_disabled, 1); 3972 qdf_atomic_set(&ipa_ctx->autonomy_disabled, 1); 3973 ipa_ctx->wdi_enabled = false; 3974 3975 status = wlan_ipa_wdi_init(ipa_ctx); 3976 if (status == QDF_STATUS_SUCCESS) { 3977 /* Setup IPA system pipes */ 3978 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 3979 ret = wlan_ipa_setup_sys_pipe(ipa_ctx); 3980 if (ret) 3981 goto ipa_wdi_destroy; 3982 3983 qdf_create_work(0, &ipa_ctx->mcc_work, 3984 wlan_ipa_mcc_work_handler, 3985 ipa_ctx); 3986 } 3987 } else if (status == QDF_STATUS_E_BUSY) { 3988 ret = wlan_ipa_uc_send_wdi_control_msg(ipa_ctx, false); 3989 if (ret) { 3990 ipa_err("IPA WDI msg send failed: ret=%d", ret); 3991 goto ipa_wdi_destroy; 3992 } 3993 } else { 3994 ipa_err("IPA WDI init failed: ret=%d", status); 3995 goto ipa_wdi_destroy; 3996 } 3997 } else { 3998 ret = wlan_ipa_setup_sys_pipe(ipa_ctx); 3999 if (ret) 4000 goto ipa_wdi_destroy; 4001 } 4002 4003 qdf_event_create(&ipa_ctx->ipa_resource_comp); 4004 4005 ipa_debug("exit: success"); 4006 4007 return QDF_STATUS_SUCCESS; 4008 4009 ipa_wdi_destroy: 4010 wlan_ipa_wdi_destroy_rm(ipa_ctx); 4011 4012 fail_setup_rm: 4013 qdf_spinlock_destroy(&ipa_ctx->pm_lock); 4014 qdf_spinlock_destroy(&ipa_ctx->q_lock); 4015 qdf_spinlock_destroy(&ipa_ctx->enable_disable_lock); 4016 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 4017 iface_context = &ipa_ctx->iface_context[i]; 4018 qdf_spinlock_destroy(&iface_context->interface_lock); 4019 } 4020 qdf_mutex_destroy(&ipa_ctx->event_lock); 4021 qdf_mutex_destroy(&ipa_ctx->ipa_lock); 4022 qdf_list_destroy(&ipa_ctx->pending_event); 4023 gp_ipa = NULL; 4024 ipa_debug("exit: fail"); 4025 4026 return QDF_STATUS_E_FAILURE; 4027 } 4028 4029 void wlan_ipa_flush(struct wlan_ipa_priv *ipa_ctx) 4030 { 4031 qdf_nbuf_t skb; 4032 struct wlan_ipa_pm_tx_cb *pm_tx_cb; 4033 4034 if (!wlan_ipa_is_enabled(ipa_ctx->config)) 4035 return; 4036 4037 qdf_cancel_work(&ipa_ctx->pm_work); 4038 4039 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 4040 4041 while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) 4042 != NULL)) { 4043 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 4044 4045 pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; 4046 4047 if (pm_tx_cb->exception) { 4048 dev_kfree_skb_any(skb); 4049 } else { 4050 if (pm_tx_cb->ipa_tx_desc) 4051 ipa_free_skb(pm_tx_cb->ipa_tx_desc); 4052 } 4053 4054 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 4055 } 4056 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 4057 } 4058 4059 QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx) 4060 { 4061 struct wlan_ipa_iface_context *iface_context; 4062 int i; 4063 4064 if (!ipa_cb_is_ready()) 4065 return QDF_STATUS_SUCCESS; 4066 qdf_event_destroy(&ipa_ctx->ipa_resource_comp); 4067 if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) 4068 wlan_ipa_teardown_sys_pipe(ipa_ctx); 4069 4070 /* Teardown IPA sys_pipe for MCC */ 4071 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 4072 wlan_ipa_teardown_sys_pipe(ipa_ctx); 4073 if (ipa_ctx->uc_loaded) 4074 qdf_cancel_work(&ipa_ctx->mcc_work); 4075 } 4076 4077 wlan_ipa_wdi_destroy_rm(ipa_ctx); 4078 4079 wlan_ipa_flush(ipa_ctx); 4080 4081 qdf_spinlock_destroy(&ipa_ctx->pm_lock); 4082 qdf_spinlock_destroy(&ipa_ctx->q_lock); 4083 qdf_spinlock_destroy(&ipa_ctx->enable_disable_lock); 4084 qdf_destroy_work(0, &ipa_ctx->pm_work); 4085 4086 /* destroy the interface lock */ 4087 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 4088 iface_context = &ipa_ctx->iface_context[i]; 4089 qdf_spinlock_destroy(&iface_context->interface_lock); 4090 } 4091 4092 if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 4093 wlan_ipa_wdi_cleanup(ipa_ctx->hdl); 4094 qdf_mutex_destroy(&ipa_ctx->event_lock); 4095 qdf_mutex_destroy(&ipa_ctx->ipa_lock); 4096 qdf_list_destroy(&ipa_ctx->pending_event); 4097 4098 } 4099 4100 gp_ipa = NULL; 4101 4102 /* Acquire lock */ 4103 ipa_init_deinit_lock(); 4104 if (g_instances_added) 4105 g_instances_added--; 4106 /* Unlock */ 4107 ipa_init_deinit_unlock(); 4108 4109 ipa_ctx->handle_initialized = false; 4110 4111 return QDF_STATUS_SUCCESS; 4112 } 4113 4114 struct wlan_ipa_iface_context 4115 *wlan_ipa_get_iface(struct wlan_ipa_priv *ipa_ctx, uint8_t mode) 4116 { 4117 struct wlan_ipa_iface_context *iface_ctx = NULL; 4118 int i; 4119 4120 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 4121 iface_ctx = &ipa_ctx->iface_context[i]; 4122 4123 if (iface_ctx->device_mode == mode) 4124 return iface_ctx; 4125 } 4126 4127 return NULL; 4128 } 4129 4130 struct wlan_ipa_iface_context * 4131 wlan_ipa_get_iface_by_mode_netdev(struct wlan_ipa_priv *ipa_ctx, 4132 qdf_netdev_t ndev, uint8_t mode) 4133 { 4134 struct wlan_ipa_iface_context *iface_ctx = NULL; 4135 int i; 4136 4137 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 4138 iface_ctx = &ipa_ctx->iface_context[i]; 4139 4140 if (iface_ctx->device_mode == mode && iface_ctx->dev == ndev) 4141 return iface_ctx; 4142 } 4143 4144 return NULL; 4145 } 4146 4147 void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode) 4148 { 4149 if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) 4150 return; 4151 4152 if (ipa_ctx->mcc_mode == mcc_mode) 4153 return; 4154 4155 ipa_ctx->mcc_mode = mcc_mode; 4156 qdf_sched_work(0, &ipa_ctx->mcc_work); 4157 } 4158 4159 /** 4160 * wlan_ipa_uc_loaded_handler() - Process IPA uC loaded indication 4161 * @ipa_ctx: ipa ipa local context 4162 * 4163 * Will handle IPA UC image loaded indication comes from IPA kernel 4164 * 4165 * Return: None 4166 */ 4167 static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx) 4168 { 4169 struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev; 4170 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4171 qdf_device_t qdf_dev = wlan_psoc_get_qdf_dev(psoc); 4172 QDF_STATUS status; 4173 4174 ipa_info("UC READY"); 4175 4176 if (true == ipa_ctx->uc_loaded) { 4177 ipa_info("UC already loaded"); 4178 return; 4179 } 4180 4181 if (!qdf_dev) { 4182 ipa_err("qdf_dev is null"); 4183 return; 4184 } 4185 4186 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 4187 /* Setup IPA system pipes */ 4188 status = wlan_ipa_setup_sys_pipe(ipa_ctx); 4189 if (status) { 4190 ipa_err("Fail to setup sys pipes (status=%d)", status); 4191 return; 4192 } 4193 qdf_create_work(0, &ipa_ctx->mcc_work, 4194 wlan_ipa_mcc_work_handler, ipa_ctx); 4195 } 4196 4197 /* Connect pipe */ 4198 status = wlan_ipa_wdi_setup(ipa_ctx, qdf_dev); 4199 if (status) { 4200 ipa_err("Failure to setup IPA pipes (status=%d)", 4201 status); 4202 goto connect_pipe_fail; 4203 } 4204 /* Setup the Tx buffer SMMU mapings */ 4205 status = cdp_ipa_tx_buf_smmu_mapping(ipa_ctx->dp_soc, 4206 ipa_ctx->dp_pdev_id); 4207 if (status) { 4208 ipa_err("Failure to map Tx buffers for IPA(status=%d)", 4209 status); 4210 goto smmu_map_fail; 4211 } 4212 ipa_info("TX buffers mapped to IPA"); 4213 cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); 4214 wlan_ipa_init_metering(ipa_ctx); 4215 4216 if (QDF_IS_STATUS_ERROR(wlan_ipa_init_perf_level(ipa_ctx))) 4217 ipa_err("Failed to init perf level"); 4218 4219 /* 4220 * Enable IPA/FW PIPEs if 4221 * 1. any clients connected to SAP or 4222 * 2. STA connected to remote AP if STA only offload is enabled 4223 */ 4224 if (ipa_ctx->sap_num_connected_sta || 4225 (wlan_ipa_is_sta_only_offload_enabled() && 4226 ipa_ctx->sta_connected)) { 4227 ipa_debug("Client already connected, enable IPA/FW PIPEs"); 4228 wlan_ipa_uc_handle_first_con(ipa_ctx); 4229 } 4230 4231 ipa_ctx->uc_loaded = true; 4232 4233 return; 4234 4235 smmu_map_fail: 4236 qdf_ipa_wdi_disconn_pipes(ipa_ctx->hdl); 4237 4238 connect_pipe_fail: 4239 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 4240 qdf_cancel_work(&ipa_ctx->mcc_work); 4241 wlan_ipa_teardown_sys_pipe(ipa_ctx); 4242 } 4243 } 4244 4245 /** 4246 * wlan_ipa_uc_op_cb() - IPA uC operation callback 4247 * @op_msg: operation message received from firmware 4248 * @usr_ctxt: user context registered with TL (we register the IPA Global 4249 * context) 4250 * 4251 * Return: None 4252 */ 4253 static void wlan_ipa_uc_op_cb(struct op_msg_type *op_msg, 4254 struct wlan_ipa_priv *ipa_ctx) 4255 { 4256 struct op_msg_type *msg = op_msg; 4257 struct ipa_uc_fw_stats *uc_fw_stat; 4258 4259 if (!ipa_ctx || !op_msg) { 4260 ipa_err("INVALID ARG"); 4261 return; 4262 } 4263 4264 if (msg->op_code >= WLAN_IPA_UC_OPCODE_MAX) { 4265 ipa_err("INVALID OPCODE %d", msg->op_code); 4266 qdf_mem_free(op_msg); 4267 return; 4268 } 4269 4270 ipa_debug("OPCODE=%d", msg->op_code); 4271 4272 if ((msg->op_code == WLAN_IPA_UC_OPCODE_TX_RESUME) || 4273 (msg->op_code == WLAN_IPA_UC_OPCODE_RX_RESUME)) { 4274 qdf_mutex_acquire(&ipa_ctx->ipa_lock); 4275 ipa_ctx->activated_fw_pipe++; 4276 if (wlan_ipa_is_fw_wdi_activated(ipa_ctx)) { 4277 ipa_ctx->resource_loading = false; 4278 qdf_event_set(&ipa_ctx->ipa_resource_comp); 4279 if (ipa_ctx->wdi_enabled == false) { 4280 ipa_ctx->wdi_enabled = true; 4281 if (wlan_ipa_uc_send_wdi_control_msg(ipa_ctx, true) == 0) 4282 wlan_ipa_send_mcc_scc_msg(ipa_ctx, 4283 ipa_ctx->mcc_mode); 4284 } 4285 wlan_ipa_uc_proc_pending_event(ipa_ctx, true); 4286 if (ipa_ctx->pending_cons_req) 4287 wlan_ipa_wdi_rm_notify_completion( 4288 QDF_IPA_RM_RESOURCE_GRANTED, 4289 QDF_IPA_RM_RESOURCE_WLAN_CONS); 4290 ipa_ctx->pending_cons_req = false; 4291 } 4292 qdf_mutex_release(&ipa_ctx->ipa_lock); 4293 } else if ((msg->op_code == WLAN_IPA_UC_OPCODE_TX_SUSPEND) || 4294 (msg->op_code == WLAN_IPA_UC_OPCODE_RX_SUSPEND)) { 4295 qdf_mutex_acquire(&ipa_ctx->ipa_lock); 4296 4297 if (msg->op_code == WLAN_IPA_UC_OPCODE_RX_SUSPEND) { 4298 wlan_ipa_uc_disable_pipes(ipa_ctx, true); 4299 ipa_info("Disable FW TX PIPE"); 4300 cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, 4301 false, true); 4302 } 4303 4304 ipa_ctx->activated_fw_pipe--; 4305 if (!ipa_ctx->activated_fw_pipe) { 4306 /* 4307 * Async return success from FW 4308 * Disable/suspend all the PIPEs 4309 */ 4310 ipa_ctx->resource_unloading = false; 4311 qdf_event_set(&ipa_ctx->ipa_resource_comp); 4312 if (wlan_ipa_is_rm_enabled(ipa_ctx->config)) 4313 wlan_ipa_wdi_rm_release_resource(ipa_ctx, 4314 QDF_IPA_RM_RESOURCE_WLAN_PROD); 4315 wlan_ipa_uc_proc_pending_event(ipa_ctx, false); 4316 ipa_ctx->pending_cons_req = false; 4317 } 4318 qdf_mutex_release(&ipa_ctx->ipa_lock); 4319 } else if ((msg->op_code == WLAN_IPA_UC_OPCODE_STATS) && 4320 (ipa_ctx->stat_req_reason == WLAN_IPA_UC_STAT_REASON_DEBUG)) { 4321 uc_fw_stat = (struct ipa_uc_fw_stats *) 4322 ((uint8_t *)op_msg + sizeof(struct op_msg_type)); 4323 4324 /* WLAN FW WDI stats */ 4325 wlan_ipa_print_fw_wdi_stats(ipa_ctx, uc_fw_stat); 4326 } else if ((msg->op_code == WLAN_IPA_UC_OPCODE_STATS) && 4327 (ipa_ctx->stat_req_reason == WLAN_IPA_UC_STAT_REASON_BW_CAL)) { 4328 /* STATs from FW */ 4329 uc_fw_stat = (struct ipa_uc_fw_stats *) 4330 ((uint8_t *)op_msg + sizeof(struct op_msg_type)); 4331 qdf_mutex_acquire(&ipa_ctx->ipa_lock); 4332 ipa_ctx->ipa_tx_packets_diff = BW_GET_DIFF( 4333 uc_fw_stat->tx_pkts_completed, 4334 ipa_ctx->ipa_p_tx_packets); 4335 ipa_ctx->ipa_rx_packets_diff = BW_GET_DIFF( 4336 (uc_fw_stat->rx_num_ind_drop_no_space + 4337 uc_fw_stat->rx_num_ind_drop_no_buf + 4338 uc_fw_stat->rx_num_pkts_indicated), 4339 ipa_ctx->ipa_p_rx_packets); 4340 4341 ipa_ctx->ipa_p_tx_packets = uc_fw_stat->tx_pkts_completed; 4342 ipa_ctx->ipa_p_rx_packets = 4343 (uc_fw_stat->rx_num_ind_drop_no_space + 4344 uc_fw_stat->rx_num_ind_drop_no_buf + 4345 uc_fw_stat->rx_num_pkts_indicated); 4346 qdf_mutex_release(&ipa_ctx->ipa_lock); 4347 } else if (msg->op_code == WLAN_IPA_UC_OPCODE_UC_READY) { 4348 qdf_mutex_acquire(&ipa_ctx->ipa_lock); 4349 wlan_ipa_uc_loaded_handler(ipa_ctx); 4350 qdf_mutex_release(&ipa_ctx->ipa_lock); 4351 } else if (wlan_ipa_uc_op_metering(ipa_ctx, op_msg)) { 4352 ipa_err("Invalid message: op_code=%d, reason=%d", 4353 msg->op_code, ipa_ctx->stat_req_reason); 4354 } 4355 4356 qdf_mem_free(op_msg); 4357 } 4358 4359 /** 4360 * __wlan_ipa_uc_fw_op_event_handler - IPA uC FW OPvent handler 4361 * @data: uC OP work 4362 * 4363 * Return: None 4364 */ 4365 static void __wlan_ipa_uc_fw_op_event_handler(void *data) 4366 { 4367 struct op_msg_type *msg; 4368 struct uc_op_work_struct *uc_op_work = 4369 (struct uc_op_work_struct *)data; 4370 struct wlan_ipa_priv *ipa_ctx = uc_op_work->ipa_priv_bp; 4371 4372 msg = uc_op_work->msg; 4373 uc_op_work->msg = NULL; 4374 ipa_debug("posted msg %d", msg->op_code); 4375 4376 wlan_ipa_uc_op_cb(msg, ipa_ctx); 4377 } 4378 4379 /** 4380 * wlan_ipa_uc_fw_op_event_handler - SSR wrapper for 4381 * __wlan_ipa_uc_fw_op_event_handler 4382 * @data: uC OP work 4383 * 4384 * Return: None 4385 */ 4386 static void wlan_ipa_uc_fw_op_event_handler(void *data) 4387 { 4388 if (qdf_is_recovering()) { 4389 ipa_err("in recovering"); 4390 return; 4391 } 4392 4393 __wlan_ipa_uc_fw_op_event_handler(data); 4394 } 4395 4396 /** 4397 * wlan_ipa_uc_op_event_handler() - IPA UC OP event handler 4398 * @op_msg: operation message received from firmware 4399 * @ipa_ctx: Global IPA context 4400 * 4401 * Return: None 4402 */ 4403 static void wlan_ipa_uc_op_event_handler(uint8_t *op_msg, void *ctx) 4404 { 4405 struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)ctx; 4406 struct op_msg_type *msg; 4407 struct uc_op_work_struct *uc_op_work; 4408 4409 if (!ipa_ctx) 4410 goto end; 4411 4412 msg = (struct op_msg_type *)op_msg; 4413 4414 if (msg->op_code >= WLAN_IPA_UC_OPCODE_MAX) { 4415 ipa_err("Invalid OP Code (%d)", msg->op_code); 4416 goto end; 4417 } 4418 4419 uc_op_work = &ipa_ctx->uc_op_work[msg->op_code]; 4420 if (uc_op_work->msg) { 4421 /* When the same uC OPCODE is already pended, just return */ 4422 goto end; 4423 } 4424 4425 uc_op_work->msg = msg; 4426 qdf_sched_work(0, &uc_op_work->work); 4427 return; 4428 4429 end: 4430 qdf_mem_free(op_msg); 4431 } 4432 4433 QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx, 4434 qdf_device_t osdev) 4435 { 4436 uint8_t i; 4437 QDF_STATUS status = QDF_STATUS_SUCCESS; 4438 4439 if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) 4440 return QDF_STATUS_SUCCESS; 4441 4442 ipa_debug("enter"); 4443 4444 if (!osdev) { 4445 ipa_err("osdev null"); 4446 status = QDF_STATUS_E_FAILURE; 4447 goto fail_return; 4448 } 4449 4450 for (i = 0; i < WLAN_IPA_MAX_SESSION; i++) { 4451 ipa_ctx->vdev_to_iface[i] = WLAN_IPA_MAX_SESSION; 4452 ipa_ctx->vdev_offload_enabled[i] = false; 4453 ipa_ctx->disable_intrabss_fwd[i] = false; 4454 } 4455 4456 if (cdp_ipa_get_resource(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id)) { 4457 ipa_err("IPA UC resource alloc fail"); 4458 status = QDF_STATUS_E_FAILURE; 4459 goto fail_return; 4460 } 4461 4462 for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) { 4463 ipa_ctx->uc_op_work[i].osdev = osdev; 4464 ipa_ctx->uc_op_work[i].msg = NULL; 4465 ipa_ctx->uc_op_work[i].ipa_priv_bp = ipa_ctx; 4466 qdf_create_work(0, &ipa_ctx->uc_op_work[i].work, 4467 wlan_ipa_uc_fw_op_event_handler, 4468 &ipa_ctx->uc_op_work[i]); 4469 } 4470 4471 if (true == ipa_ctx->uc_loaded) { 4472 status = wlan_ipa_wdi_setup(ipa_ctx, osdev); 4473 if (status) { 4474 ipa_err("Failure to setup IPA pipes (status=%d)", 4475 status); 4476 status = QDF_STATUS_E_FAILURE; 4477 4478 if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 4479 qdf_cancel_work(&ipa_ctx->mcc_work); 4480 wlan_ipa_teardown_sys_pipe(ipa_ctx); 4481 } 4482 ipa_ctx->uc_loaded = false; 4483 4484 goto fail_return; 4485 } 4486 4487 /* Setup the Tx buffer SMMU mapings */ 4488 status = cdp_ipa_tx_buf_smmu_mapping(ipa_ctx->dp_soc, 4489 ipa_ctx->dp_pdev_id); 4490 if (status) { 4491 ipa_err("Failure to map Tx buffers for IPA(status=%d)", 4492 status); 4493 return status; 4494 } 4495 ipa_info("TX buffers mapped to IPA"); 4496 cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, 4497 ipa_ctx->dp_pdev_id); 4498 wlan_ipa_init_metering(ipa_ctx); 4499 4500 if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS) 4501 ipa_err("Failed to init perf level"); 4502 } 4503 4504 cdp_ipa_register_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, 4505 wlan_ipa_uc_op_event_handler, (void *)ipa_ctx); 4506 fail_return: 4507 ipa_debug("exit: status=%d", status); 4508 return status; 4509 } 4510 4511 /** 4512 * wlan_ipa_cleanup_pending_event() - Cleanup IPA pending event list 4513 * @ipa_ctx: pointer to IPA IPA struct 4514 * 4515 * Return: none 4516 */ 4517 static void wlan_ipa_cleanup_pending_event(struct wlan_ipa_priv *ipa_ctx) 4518 { 4519 struct wlan_ipa_uc_pending_event *pending_event = NULL; 4520 4521 while (qdf_list_remove_front(&ipa_ctx->pending_event, 4522 (qdf_list_node_t **)&pending_event) == QDF_STATUS_SUCCESS) 4523 qdf_mem_free(pending_event); 4524 } 4525 4526 QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx) 4527 { 4528 QDF_STATUS status = QDF_STATUS_SUCCESS; 4529 int i; 4530 4531 ipa_debug("enter"); 4532 4533 if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) 4534 return status; 4535 4536 wlan_ipa_uc_disable_pipes(ipa_ctx, true); 4537 4538 cdp_ipa_deregister_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); 4539 qdf_atomic_set(&ipa_ctx->deinit_in_prog, 1); 4540 4541 for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) { 4542 qdf_cancel_work(&ipa_ctx->uc_op_work[i].work); 4543 qdf_mem_free(ipa_ctx->uc_op_work[i].msg); 4544 ipa_ctx->uc_op_work[i].msg = NULL; 4545 } 4546 4547 cdp_ipa_iounmap_doorbell_vaddr(ipa_ctx->dp_soc, 4548 ipa_ctx->dp_pdev_id); 4549 4550 if (true == ipa_ctx->uc_loaded) { 4551 cdp_ipa_tx_buf_smmu_unmapping(ipa_ctx->dp_soc, 4552 ipa_ctx->dp_pdev_id); 4553 status = cdp_ipa_cleanup(ipa_ctx->dp_soc, 4554 ipa_ctx->dp_pdev_id, 4555 ipa_ctx->tx_pipe_handle, 4556 ipa_ctx->rx_pipe_handle, ipa_ctx->hdl); 4557 if (status) 4558 ipa_err("Failure to cleanup IPA pipes (status=%d)", 4559 status); 4560 } 4561 4562 qdf_mutex_acquire(&ipa_ctx->ipa_lock); 4563 wlan_ipa_cleanup_pending_event(ipa_ctx); 4564 qdf_mutex_release(&ipa_ctx->ipa_lock); 4565 4566 ipa_debug("exit: ret=%d", status); 4567 return status; 4568 } 4569 4570 /** 4571 * wlan_ipa_uc_send_evt() - send event to ipa 4572 * @net_dev: Interface net device 4573 * @type: event type 4574 * @mac_addr: pointer to mac address 4575 * 4576 * Send event to IPA driver 4577 * 4578 * Return: QDF_STATUS 4579 */ 4580 static QDF_STATUS wlan_ipa_uc_send_evt(qdf_netdev_t net_dev, 4581 qdf_ipa_wlan_event type, 4582 uint8_t *mac_addr, 4583 struct wlan_ipa_priv *ipa_priv) 4584 { 4585 struct wlan_ipa_priv *ipa_ctx; 4586 qdf_ipa_msg_meta_t meta; 4587 qdf_ipa_wlan_msg_t *msg; 4588 4589 if (!ipa_priv) 4590 return QDF_STATUS_E_INVAL; 4591 4592 ipa_ctx = ipa_priv; 4593 4594 QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t); 4595 msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); 4596 if (!msg) 4597 return QDF_STATUS_E_NOMEM; 4598 4599 QDF_IPA_SET_META_MSG_TYPE(&meta, type); 4600 qdf_str_lcopy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name, 4601 IPA_RESOURCE_NAME_MAX); 4602 qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN); 4603 QDF_IPA_WLAN_MSG_NETDEV_IF_ID(msg) = net_dev->ifindex; 4604 4605 if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) { 4606 ipa_err("%s: Evt: %d fail", 4607 QDF_IPA_WLAN_MSG_NAME(msg), 4608 QDF_IPA_MSG_META_MSG_TYPE(&meta)); 4609 qdf_mem_free(msg); 4610 4611 return QDF_STATUS_E_FAILURE; 4612 } 4613 4614 ipa_ctx->stats.num_send_msg++; 4615 4616 return QDF_STATUS_SUCCESS; 4617 } 4618 4619 void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx, 4620 qdf_netdev_t net_dev) 4621 { 4622 struct wlan_ipa_iface_context *iface_ctx; 4623 int i; 4624 4625 ipa_debug("enter"); 4626 4627 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 4628 iface_ctx = &ipa_ctx->iface_context[i]; 4629 if (iface_ctx && iface_ctx->device_mode == QDF_STA_MODE && 4630 iface_ctx->dev && iface_ctx->dev == net_dev) { 4631 wlan_ipa_uc_send_evt(net_dev, QDF_IPA_STA_DISCONNECT, 4632 net_dev->dev_addr, ipa_ctx); 4633 wlan_ipa_cleanup_iface(iface_ctx, NULL); 4634 } 4635 } 4636 4637 ipa_debug("exit"); 4638 } 4639 4640 QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx, 4641 qdf_netdev_t net_dev) 4642 { 4643 struct wlan_ipa_iface_context *iface_ctx; 4644 QDF_STATUS status; 4645 4646 ipa_debug("enter"); 4647 4648 iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_SAP_MODE); 4649 if (iface_ctx) 4650 status = wlan_ipa_uc_send_evt(net_dev, QDF_IPA_AP_DISCONNECT, 4651 net_dev->dev_addr, ipa_ctx); 4652 else 4653 return QDF_STATUS_E_INVAL; 4654 4655 ipa_debug("exit :%d", status); 4656 4657 return status; 4658 } 4659 4660 void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx, 4661 qdf_netdev_t net_dev) 4662 { 4663 struct wlan_ipa_iface_context *iface_ctx; 4664 int i; 4665 4666 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 4667 iface_ctx = &ipa_ctx->iface_context[i]; 4668 if (iface_ctx->dev == net_dev) { 4669 wlan_ipa_cleanup_iface(iface_ctx, NULL); 4670 break; 4671 } 4672 } 4673 } 4674 4675 void wlan_ipa_uc_ssr_cleanup(struct wlan_ipa_priv *ipa_ctx) 4676 { 4677 struct wlan_ipa_iface_context *iface; 4678 int i; 4679 4680 ipa_info("enter"); 4681 4682 for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { 4683 iface = &ipa_ctx->iface_context[i]; 4684 if (iface->dev) { 4685 if (iface->device_mode == QDF_SAP_MODE) 4686 wlan_ipa_uc_send_evt(iface->dev, 4687 QDF_IPA_AP_DISCONNECT, 4688 iface->dev->dev_addr, 4689 ipa_ctx); 4690 else if (iface->device_mode == QDF_STA_MODE) 4691 wlan_ipa_uc_send_evt(iface->dev, 4692 QDF_IPA_STA_DISCONNECT, 4693 iface->dev->dev_addr, 4694 ipa_ctx); 4695 wlan_ipa_cleanup_iface(iface, NULL); 4696 } 4697 } 4698 } 4699 4700 void wlan_ipa_fw_rejuvenate_send_msg(struct wlan_ipa_priv *ipa_ctx) 4701 { 4702 qdf_ipa_msg_meta_t meta; 4703 qdf_ipa_wlan_msg_t *msg; 4704 int ret; 4705 4706 meta.msg_len = sizeof(*msg); 4707 msg = qdf_mem_malloc(meta.msg_len); 4708 if (!msg) 4709 return; 4710 4711 QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_FWR_SSR_BEFORE_SHUTDOWN); 4712 ipa_debug("ipa_send_msg(Evt:%d)", 4713 meta.msg_type); 4714 ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn); 4715 4716 if (ret) { 4717 ipa_err("ipa_send_msg(Evt:%d)-fail=%d", 4718 meta.msg_type, ret); 4719 qdf_mem_free(msg); 4720 } 4721 ipa_ctx->stats.num_send_msg++; 4722 } 4723 4724 void wlan_ipa_flush_pending_vdev_events(struct wlan_ipa_priv *ipa_ctx, 4725 uint8_t vdev_id) 4726 { 4727 struct wlan_ipa_uc_pending_event *event; 4728 struct wlan_ipa_uc_pending_event *next_event; 4729 4730 qdf_mutex_acquire(&ipa_ctx->ipa_lock); 4731 4732 qdf_list_for_each_del(&ipa_ctx->pending_event, event, next_event, 4733 node) { 4734 if (event->session_id == vdev_id) { 4735 qdf_list_remove_node(&ipa_ctx->pending_event, 4736 &event->node); 4737 qdf_mem_free(event); 4738 } 4739 } 4740 4741 qdf_mutex_release(&ipa_ctx->ipa_lock); 4742 } 4743