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