Loading drivers/platform/msm/ipa/ipa_v2/ipa.c +21 −15 Original line number Diff line number Diff line Loading @@ -294,23 +294,25 @@ void ipa_flow_control(enum ipa_client_type ipa_client, /* Check if ep is valid. */ ep_idx = ipa2_get_ep_mapping(ipa_client); if (ep_idx == -1) { IPAERR("Invalid IPA client\n"); IPADBG("Invalid IPA client\n"); return; } ep = &ipa_ctx->ep[ep_idx]; if (!ep->valid) { IPAERR("EP not valid.\n"); if (!ep->valid || (ep->client != IPA_CLIENT_USB_PROD)) { IPADBG("EP not valid/Not applicable for client.\n"); return; } spin_lock(&ipa_ctx->disconnect_lock); /* Check if the QMAP_ID matches. */ if (ep->cfg.meta.qmap_id != qmap_id) { IPADBG("Flow control indication not for the same flow: %u %u\n", IPADBG("Flow control ind not for same flow: %u %u\n", ep->cfg.meta.qmap_id, qmap_id); spin_unlock(&ipa_ctx->disconnect_lock); return; } if (!ep->disconnect_in_progress) { if (enable) { IPADBG("Enabling Flow\n"); ep_ctrl.ipa_ep_delay = false; Loading @@ -322,6 +324,10 @@ void ipa_flow_control(enum ipa_client_type ipa_client, } ep_ctrl.ipa_ep_suspend = false; ipa2_cfg_ep_ctrl(ep_idx, &ep_ctrl); } else { IPADBG("EP disconnect is in progress\n"); } spin_unlock(&ipa_ctx->disconnect_lock); } static void ipa_wan_msg_free_cb(void *buff, u32 len, u32 type) Loading Loading @@ -2274,7 +2280,7 @@ static int ipa_setup_apps_pipes(void) * thread may nullify it - e.g. on EP disconnect. * This lock intended to protect the access to the source EP call-back */ spin_lock_init(&ipa_ctx->lan_rx_clnt_notify_lock); spin_lock_init(&ipa_ctx->disconnect_lock); if (ipa2_setup_sys_pipe(&sys_in, &ipa_ctx->clnt_hdl_data_in)) { IPAERR(":setup sys pipe failed.\n"); result = -EPERM; Loading drivers/platform/msm/ipa/ipa_v2/ipa_client.c +14 −2 Original line number Diff line number Diff line Loading @@ -530,6 +530,7 @@ int ipa2_disconnect(u32 clnt_hdl) unsigned long peer_bam; unsigned long base; struct iommu_domain *smmu_domain; struct ipa_ep_cfg_ctrl ep_ctrl = {0}; if (unlikely(!ipa_ctx)) { IPAERR("IPA driver was not initialized\n"); Loading @@ -547,6 +548,11 @@ int ipa2_disconnect(u32 clnt_hdl) if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); /* Set Disconnect in Progress flag. */ spin_lock(&ipa_ctx->disconnect_lock); ep->disconnect_in_progress = true; spin_unlock(&ipa_ctx->disconnect_lock); /* Notify uc to stop monitoring holb on USB BAM Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(ep->client)) { ipa_uc_monitor_holb(ep->client, false); Loading Loading @@ -630,9 +636,15 @@ int ipa2_disconnect(u32 clnt_hdl) ipa_delete_dflt_flt_rules(clnt_hdl); spin_lock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_lock(&ipa_ctx->disconnect_lock); /* If flow is enabled/disabled at this point, we restore the ep state.*/ if (ep->client == IPA_CLIENT_USB_PROD) { ep_ctrl.ipa_ep_delay = false; ep_ctrl.ipa_ep_suspend = false; ipa2_cfg_ep_ctrl(clnt_hdl, &ep_ctrl); } memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context)); spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_unlock(&ipa_ctx->disconnect_lock); ipa_dec_client_disable_clks(); Loading drivers/platform/msm/ipa/ipa_v2/ipa_dp.c +3 −3 Original line number Diff line number Diff line Loading @@ -2372,13 +2372,13 @@ static int ipa_rx_pyld_hdlr(struct sk_buff *rx_skb, struct ipa_sys_context *sys) src_pipe = WLAN_PROD_TX_EP; ep = &ipa_ctx->ep[src_pipe]; spin_lock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_lock(&ipa_ctx->disconnect_lock); if (unlikely(src_pipe >= ipa_ctx->ipa_num_pipes || !ep->valid || !ep->client_notify)) { IPAERR("drop pipe=%d ep_valid=%d client_notify=%p\n", src_pipe, ep->valid, ep->client_notify); dev_kfree_skb_any(rx_skb); spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_unlock(&ipa_ctx->disconnect_lock); return 0; } Loading @@ -2397,7 +2397,7 @@ static int ipa_rx_pyld_hdlr(struct sk_buff *rx_skb, struct ipa_sys_context *sys) skb_pull(rx_skb, pull_len); ep->client_notify(ep->priv, IPA_RECEIVE, (unsigned long)(rx_skb)); spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_unlock(&ipa_ctx->disconnect_lock); return 0; } Loading drivers/platform/msm/ipa/ipa_v2/ipa_i.h +4 −2 Original line number Diff line number Diff line Loading @@ -504,6 +504,7 @@ struct ipa_wlan_comm_memb { * descriptors replenish function to be called to * avoid the RX pipe to run out of descriptors * and cause HOLB. * @disconnect_in_progress: Indicates client disconnect in progress. */ struct ipa_ep_context { int valid; Loading Loading @@ -532,6 +533,7 @@ struct ipa_ep_context { struct ipa_wlan_stats wstats; u32 wdi_state; u32 rx_replenish_threshold; bool disconnect_in_progress; /* sys MUST be the last element of this struct */ struct ipa_sys_context *sys; }; Loading Loading @@ -1126,7 +1128,7 @@ struct ipacm_client_info { * @tag_process_before_gating: indicates whether to start tag process before * gating IPA clocks * @sps_pm: sps power management related information * @lan_rx_clnt_notify_lock: protects LAN_CONS packet receive notification CB * @disconnect_lock: protects LAN_CONS packet receive notification CB * @pipe_mem_pool: pipe memory pool * @dma_pool: special purpose DMA pool * @ipa_active_clients: structure for reference counting connected IPA clients Loading Loading @@ -1206,7 +1208,7 @@ struct ipa_context { u32 clnt_hdl_cmd; u32 clnt_hdl_data_in; u32 clnt_hdl_data_out; spinlock_t lan_rx_clnt_notify_lock; spinlock_t disconnect_lock; u8 a5_pipe_index; struct list_head intf_list; struct list_head msg_list; Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +21 −15 Original line number Diff line number Diff line Loading @@ -293,23 +293,25 @@ void ipa3_flow_control(enum ipa_client_type ipa_client, /* Check if ep is valid. */ ep_idx = ipa3_get_ep_mapping(ipa_client); if (ep_idx == -1) { IPAERR("Invalid IPA client\n"); IPADBG("Invalid IPA client\n"); return; } ep = &ipa3_ctx->ep[ep_idx]; if (!ep->valid) { IPAERR("EP not valid.\n"); if (!ep->valid || (ep->client != IPA_CLIENT_USB_PROD)) { IPADBG("EP not valid/Not applicable for client.\n"); return; } spin_lock(&ipa3_ctx->disconnect_lock); /* Check if the QMAP_ID matches. */ if (ep->cfg.meta.qmap_id != qmap_id) { IPADBG("Flow control indication not for the same flow: %u %u\n", IPADBG("Flow control ind not for same flow: %u %u\n", ep->cfg.meta.qmap_id, qmap_id); spin_unlock(&ipa3_ctx->disconnect_lock); return; } if (!ep->disconnect_in_progress) { if (enable) { IPADBG("Enabling Flow\n"); ep_ctrl.ipa_ep_delay = false; Loading @@ -321,6 +323,10 @@ void ipa3_flow_control(enum ipa_client_type ipa_client, } ep_ctrl.ipa_ep_suspend = false; ipa3_cfg_ep_ctrl(ep_idx, &ep_ctrl); } else { IPADBG("EP disconnect is in progress\n"); } spin_unlock(&ipa3_ctx->disconnect_lock); } static void ipa3_wan_msg_free_cb(void *buff, u32 len, u32 type) Loading Loading @@ -2453,7 +2459,7 @@ static int ipa3_setup_apps_pipes(void) * thread may nullify it - e.g. on EP disconnect. * This lock intended to protect the access to the source EP call-back */ spin_lock_init(&ipa3_ctx->lan_rx_clnt_notify_lock); spin_lock_init(&ipa3_ctx->disconnect_lock); if (ipa3_setup_sys_pipe(&sys_in, &ipa3_ctx->clnt_hdl_data_in)) { IPAERR(":setup sys pipe failed.\n"); result = -EPERM; Loading Loading
drivers/platform/msm/ipa/ipa_v2/ipa.c +21 −15 Original line number Diff line number Diff line Loading @@ -294,23 +294,25 @@ void ipa_flow_control(enum ipa_client_type ipa_client, /* Check if ep is valid. */ ep_idx = ipa2_get_ep_mapping(ipa_client); if (ep_idx == -1) { IPAERR("Invalid IPA client\n"); IPADBG("Invalid IPA client\n"); return; } ep = &ipa_ctx->ep[ep_idx]; if (!ep->valid) { IPAERR("EP not valid.\n"); if (!ep->valid || (ep->client != IPA_CLIENT_USB_PROD)) { IPADBG("EP not valid/Not applicable for client.\n"); return; } spin_lock(&ipa_ctx->disconnect_lock); /* Check if the QMAP_ID matches. */ if (ep->cfg.meta.qmap_id != qmap_id) { IPADBG("Flow control indication not for the same flow: %u %u\n", IPADBG("Flow control ind not for same flow: %u %u\n", ep->cfg.meta.qmap_id, qmap_id); spin_unlock(&ipa_ctx->disconnect_lock); return; } if (!ep->disconnect_in_progress) { if (enable) { IPADBG("Enabling Flow\n"); ep_ctrl.ipa_ep_delay = false; Loading @@ -322,6 +324,10 @@ void ipa_flow_control(enum ipa_client_type ipa_client, } ep_ctrl.ipa_ep_suspend = false; ipa2_cfg_ep_ctrl(ep_idx, &ep_ctrl); } else { IPADBG("EP disconnect is in progress\n"); } spin_unlock(&ipa_ctx->disconnect_lock); } static void ipa_wan_msg_free_cb(void *buff, u32 len, u32 type) Loading Loading @@ -2274,7 +2280,7 @@ static int ipa_setup_apps_pipes(void) * thread may nullify it - e.g. on EP disconnect. * This lock intended to protect the access to the source EP call-back */ spin_lock_init(&ipa_ctx->lan_rx_clnt_notify_lock); spin_lock_init(&ipa_ctx->disconnect_lock); if (ipa2_setup_sys_pipe(&sys_in, &ipa_ctx->clnt_hdl_data_in)) { IPAERR(":setup sys pipe failed.\n"); result = -EPERM; Loading
drivers/platform/msm/ipa/ipa_v2/ipa_client.c +14 −2 Original line number Diff line number Diff line Loading @@ -530,6 +530,7 @@ int ipa2_disconnect(u32 clnt_hdl) unsigned long peer_bam; unsigned long base; struct iommu_domain *smmu_domain; struct ipa_ep_cfg_ctrl ep_ctrl = {0}; if (unlikely(!ipa_ctx)) { IPAERR("IPA driver was not initialized\n"); Loading @@ -547,6 +548,11 @@ int ipa2_disconnect(u32 clnt_hdl) if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); /* Set Disconnect in Progress flag. */ spin_lock(&ipa_ctx->disconnect_lock); ep->disconnect_in_progress = true; spin_unlock(&ipa_ctx->disconnect_lock); /* Notify uc to stop monitoring holb on USB BAM Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(ep->client)) { ipa_uc_monitor_holb(ep->client, false); Loading Loading @@ -630,9 +636,15 @@ int ipa2_disconnect(u32 clnt_hdl) ipa_delete_dflt_flt_rules(clnt_hdl); spin_lock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_lock(&ipa_ctx->disconnect_lock); /* If flow is enabled/disabled at this point, we restore the ep state.*/ if (ep->client == IPA_CLIENT_USB_PROD) { ep_ctrl.ipa_ep_delay = false; ep_ctrl.ipa_ep_suspend = false; ipa2_cfg_ep_ctrl(clnt_hdl, &ep_ctrl); } memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context)); spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_unlock(&ipa_ctx->disconnect_lock); ipa_dec_client_disable_clks(); Loading
drivers/platform/msm/ipa/ipa_v2/ipa_dp.c +3 −3 Original line number Diff line number Diff line Loading @@ -2372,13 +2372,13 @@ static int ipa_rx_pyld_hdlr(struct sk_buff *rx_skb, struct ipa_sys_context *sys) src_pipe = WLAN_PROD_TX_EP; ep = &ipa_ctx->ep[src_pipe]; spin_lock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_lock(&ipa_ctx->disconnect_lock); if (unlikely(src_pipe >= ipa_ctx->ipa_num_pipes || !ep->valid || !ep->client_notify)) { IPAERR("drop pipe=%d ep_valid=%d client_notify=%p\n", src_pipe, ep->valid, ep->client_notify); dev_kfree_skb_any(rx_skb); spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_unlock(&ipa_ctx->disconnect_lock); return 0; } Loading @@ -2397,7 +2397,7 @@ static int ipa_rx_pyld_hdlr(struct sk_buff *rx_skb, struct ipa_sys_context *sys) skb_pull(rx_skb, pull_len); ep->client_notify(ep->priv, IPA_RECEIVE, (unsigned long)(rx_skb)); spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock); spin_unlock(&ipa_ctx->disconnect_lock); return 0; } Loading
drivers/platform/msm/ipa/ipa_v2/ipa_i.h +4 −2 Original line number Diff line number Diff line Loading @@ -504,6 +504,7 @@ struct ipa_wlan_comm_memb { * descriptors replenish function to be called to * avoid the RX pipe to run out of descriptors * and cause HOLB. * @disconnect_in_progress: Indicates client disconnect in progress. */ struct ipa_ep_context { int valid; Loading Loading @@ -532,6 +533,7 @@ struct ipa_ep_context { struct ipa_wlan_stats wstats; u32 wdi_state; u32 rx_replenish_threshold; bool disconnect_in_progress; /* sys MUST be the last element of this struct */ struct ipa_sys_context *sys; }; Loading Loading @@ -1126,7 +1128,7 @@ struct ipacm_client_info { * @tag_process_before_gating: indicates whether to start tag process before * gating IPA clocks * @sps_pm: sps power management related information * @lan_rx_clnt_notify_lock: protects LAN_CONS packet receive notification CB * @disconnect_lock: protects LAN_CONS packet receive notification CB * @pipe_mem_pool: pipe memory pool * @dma_pool: special purpose DMA pool * @ipa_active_clients: structure for reference counting connected IPA clients Loading Loading @@ -1206,7 +1208,7 @@ struct ipa_context { u32 clnt_hdl_cmd; u32 clnt_hdl_data_in; u32 clnt_hdl_data_out; spinlock_t lan_rx_clnt_notify_lock; spinlock_t disconnect_lock; u8 a5_pipe_index; struct list_head intf_list; struct list_head msg_list; Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +21 −15 Original line number Diff line number Diff line Loading @@ -293,23 +293,25 @@ void ipa3_flow_control(enum ipa_client_type ipa_client, /* Check if ep is valid. */ ep_idx = ipa3_get_ep_mapping(ipa_client); if (ep_idx == -1) { IPAERR("Invalid IPA client\n"); IPADBG("Invalid IPA client\n"); return; } ep = &ipa3_ctx->ep[ep_idx]; if (!ep->valid) { IPAERR("EP not valid.\n"); if (!ep->valid || (ep->client != IPA_CLIENT_USB_PROD)) { IPADBG("EP not valid/Not applicable for client.\n"); return; } spin_lock(&ipa3_ctx->disconnect_lock); /* Check if the QMAP_ID matches. */ if (ep->cfg.meta.qmap_id != qmap_id) { IPADBG("Flow control indication not for the same flow: %u %u\n", IPADBG("Flow control ind not for same flow: %u %u\n", ep->cfg.meta.qmap_id, qmap_id); spin_unlock(&ipa3_ctx->disconnect_lock); return; } if (!ep->disconnect_in_progress) { if (enable) { IPADBG("Enabling Flow\n"); ep_ctrl.ipa_ep_delay = false; Loading @@ -321,6 +323,10 @@ void ipa3_flow_control(enum ipa_client_type ipa_client, } ep_ctrl.ipa_ep_suspend = false; ipa3_cfg_ep_ctrl(ep_idx, &ep_ctrl); } else { IPADBG("EP disconnect is in progress\n"); } spin_unlock(&ipa3_ctx->disconnect_lock); } static void ipa3_wan_msg_free_cb(void *buff, u32 len, u32 type) Loading Loading @@ -2453,7 +2459,7 @@ static int ipa3_setup_apps_pipes(void) * thread may nullify it - e.g. on EP disconnect. * This lock intended to protect the access to the source EP call-back */ spin_lock_init(&ipa3_ctx->lan_rx_clnt_notify_lock); spin_lock_init(&ipa3_ctx->disconnect_lock); if (ipa3_setup_sys_pipe(&sys_in, &ipa3_ctx->clnt_hdl_data_in)) { IPAERR(":setup sys pipe failed.\n"); result = -EPERM; Loading