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