From fb1282f82f173d7358baa625195ee4fbdfdb09be Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Tue, 16 Jun 2020 17:42:38 +0530 Subject: [PATCH 1/8] msm: ipa3: Fix to map the npn phy address only once Ethenet driver npn phy address was same for UL/DL pipes, currently this address was mapped twice. Added changes to map the map npn phy address only once. Change-Id: Icd713943326aad38ecf8e080a73d1d6bb8f641d2 Signed-off-by: Ashok Vuyyuru --- .../msm/ipa/ipa_clients/ipa_uc_offload.c | 4 ++ drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c | 45 ++++++++++--------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c index 2a978706b250..b8794cedd293 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c @@ -467,6 +467,10 @@ static int ipa_uc_offload_conn_pipes_internal(struct ipa_uc_offload_conn_in_para return -EPERM; } + /*Store the connection info, required during disconnect pipe */ + memcpy(&offload_ctx->conn, &inp->u.ntn, + sizeof(struct ipa_ntn_conn_in_params)); + switch (offload_ctx->proto) { case IPA_UC_NTN: ret = ipa_uc_ntn_conn_pipes(&inp->u.ntn, &outp->u.ntn, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c index 3adf6e11b83d..16dbc1412352 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c @@ -259,7 +259,7 @@ static int ipa3_uc_send_ntn_setup_pipe_cmd( } static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, - bool map) + bool map, bool map_unmap_once) { struct iommu_domain *smmu_domain; int result; @@ -275,14 +275,16 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, return -EINVAL; } - result = ipa3_smmu_map_peer_reg(rounddown(params->ntn_reg_base_ptr_pa, - PAGE_SIZE), map, IPA_SMMU_CB_UC); - if (result) { - IPAERR("failed to %s uC regs %d\n", - map ? "map" : "unmap", result); - goto fail; + if (map_unmap_once) { + result = ipa3_smmu_map_peer_reg(rounddown( + params->ntn_reg_base_ptr_pa, PAGE_SIZE), + map, IPA_SMMU_CB_UC); + if (result) { + IPAERR("failed to %s uC regs %d\n", + map ? "map" : "unmap", result); + goto fail; + } } - if (params->smmu_enabled) { IPADBG("smmu is enabled on EMAC\n"); result = ipa3_smmu_map_peer_buff((u64)params->ring_base_iova, @@ -345,14 +347,13 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, IPAERR("Fail to map 0x%llx\n", iova); } else { result = iommu_unmap(smmu_domain, iova_p, size_p); - if (result != params->data_buff_size) + if (result != size_p) { IPAERR("Fail to unmap 0x%llx\n", iova); - } - if (result) { - if (params->smmu_enabled) - goto fail_map_data_buff_smmu_enabled; - else - goto fail_map_data_buff_smmu_disabled; + if (params->smmu_enabled) + goto fail_map_data_buff_smmu_enabled; + else + goto fail_map_data_buff_smmu_disabled; + } } } return 0; @@ -392,6 +393,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, int ipa_ep_idx_ul; int ipa_ep_idx_dl; int result = 0; + bool unmapped = false; if (in == NULL) { IPAERR("invalid input\n"); @@ -445,7 +447,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, goto fail; } - result = ipa3_smmu_map_uc_ntn_pipes(&in->ul, true); + result = ipa3_smmu_map_uc_ntn_pipes(&in->ul, true, true); if (result) { IPAERR("failed to map SMMU for UL %d\n", result); goto fail; @@ -484,7 +486,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, goto fail_disable_dp_ul; } - result = ipa3_smmu_map_uc_ntn_pipes(&in->dl, true); + result = ipa3_smmu_map_uc_ntn_pipes(&in->dl, true, false); if (result) { IPAERR("failed to map SMMU for DL %d\n", result); goto fail_disable_dp_ul; @@ -515,11 +517,12 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, fail_disable_dp_dl: ipa3_disable_data_path(ipa_ep_idx_dl); fail_smmu_unmap_dl: - ipa3_smmu_map_uc_ntn_pipes(&in->dl, false); + ipa3_smmu_map_uc_ntn_pipes(&in->dl, false, true); + unmapped = true; fail_disable_dp_ul: ipa3_disable_data_path(ipa_ep_idx_ul); fail_smmu_unmap_ul: - ipa3_smmu_map_uc_ntn_pipes(&in->ul, false); + ipa3_smmu_map_uc_ntn_pipes(&in->ul, false, !unmapped); fail: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return result; @@ -600,7 +603,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, } /* unmap the DL pipe */ - result = ipa3_smmu_map_uc_ntn_pipes(¶ms->dl, false); + result = ipa3_smmu_map_uc_ntn_pipes(¶ms->dl, false, true); if (result) { IPAERR("failed to unmap SMMU for DL %d\n", result); goto fail; @@ -621,7 +624,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, } /* unmap the UL pipe */ - result = ipa3_smmu_map_uc_ntn_pipes(¶ms->ul, false); + result = ipa3_smmu_map_uc_ntn_pipes(¶ms->ul, false, false); if (result) { IPAERR("failed to unmap SMMU for UL %d\n", result); goto fail; From a2ea5ff32c50bf9bfc944d1ffe7c111839301e70 Mon Sep 17 00:00:00 2001 From: Akshay Pandit Date: Wed, 7 Oct 2020 14:01:28 +0530 Subject: [PATCH 2/8] msm: ipa3: fix the unmap logic Ethenet driver npn phy address was same for UL/DL pipes, currently this address was unmapped during DL pipe disconnect where UL pipe still avtive, move the logic to do the unmamp to the last pipe disconnect. Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c index 16dbc1412352..85a26d32c888 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c @@ -603,7 +603,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, } /* unmap the DL pipe */ - result = ipa3_smmu_map_uc_ntn_pipes(¶ms->dl, false, true); + result = ipa3_smmu_map_uc_ntn_pipes(¶ms->dl, false, false); if (result) { IPAERR("failed to unmap SMMU for DL %d\n", result); goto fail; @@ -624,7 +624,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, } /* unmap the UL pipe */ - result = ipa3_smmu_map_uc_ntn_pipes(¶ms->ul, false, false); + result = ipa3_smmu_map_uc_ntn_pipes(¶ms->ul, false, true); if (result) { IPAERR("failed to unmap SMMU for UL %d\n", result); goto fail; From 81310e8512c375026c06791a6d47e13b1bb45c26 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Wed, 7 Oct 2020 16:02:27 -0700 Subject: [PATCH 3/8] msm: ipa: fix to delete napi tx object Make changes to delete NAPI TX object when pipe setup fails. Change-Id: Ie7124fc9f996795b1a955166a9cae198f6a57f03 Signed-off-by: Chaitanya Pratapa --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index dd341697d6ea..59e2434c5533 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1202,7 +1202,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) if (ipa3_assign_policy(sys_in, ep->sys)) { IPAERR("failed to sys ctx for client %d\n", sys_in->client); result = -ENOMEM; - goto fail_gen2; + goto fail_napi; } ep->valid = 1; @@ -1219,17 +1219,17 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) ep->sys->status_stat = kzalloc(sizeof(struct ipa3_status_stats), GFP_KERNEL); if (!ep->sys->status_stat) - goto fail_gen2; + goto fail_napi; } if (!ep->skip_ep_cfg) { if (ipa3_cfg_ep(ipa_ep_idx, &sys_in->ipa_ep_cfg)) { IPAERR("fail to configure EP.\n"); - goto fail_gen2; + goto fail_napi; } if (ipa3_cfg_ep_status(ipa_ep_idx, &ep->status)) { IPAERR("fail to configure status of EP.\n"); - goto fail_gen2; + goto fail_napi; } IPADBG("ep %d configuration successful\n", ipa_ep_idx); } else { @@ -1239,7 +1239,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) result = ipa_gsi_setup_channel(sys_in, ep); if (result) { IPAERR("Failed to setup GSI channel\n"); - goto fail_gen2; + goto fail_napi; } *clnt_hdl = ipa_ep_idx; @@ -1250,7 +1250,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) IPAERR("failed to alloc repl for client %d\n", sys_in->client); result = -ENOMEM; - goto fail_gen2; + goto fail_napi; } atomic_set(&ep->sys->repl->pending, 0); ep->sys->repl->capacity = ep->sys->rx_pool_sz + 1; @@ -1275,7 +1275,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) IPAERR("failed to alloc repl for client %d\n", sys_in->client); result = -ENOMEM; - goto fail_gen2; + goto fail_napi; } atomic_set(&ep->sys->page_recycle_repl->pending, 0); ep->sys->page_recycle_repl->capacity = @@ -1380,6 +1380,11 @@ fail_page_recycle_repl: ep->sys->page_recycle_repl->capacity = 0; kfree(ep->sys->page_recycle_repl); } +fail_napi: + /* Delete NAPI TX object. */ + if (ipa3_ctx->tx_napi_enable && + (IPA_CLIENT_IS_PROD(sys_in->client))) + netif_napi_del(&ep->sys->napi_tx); fail_gen2: ipa_pm_deregister(ep->sys->pm_hdl); fail_pm: From eca7b0f54fb1ebd4a52948c1abea419ea261d273 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Mon, 20 Jul 2020 14:45:50 +0530 Subject: [PATCH 4/8] msm: ipa3: Fix to unmap sgt pages with correct size scatterlist pages not unmapped properly, it was leading to issue when mapping the same pages again. Adding changes to store scatterlist information properly and unmap the page with correct length. Change-Id: If11926608f633ce1d66150b1e4b6c515adc48049 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 35 +++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 22d92a3e1c1d..cb261fbea9ee 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -420,14 +420,33 @@ int ipa3_smmu_map_peer_buff(u64 iova, u32 size, bool map, struct sg_table *sgt, } } } else { - res = iommu_unmap(smmu_domain, - rounddown(iova, PAGE_SIZE), - roundup(size + iova - rounddown(iova, PAGE_SIZE), - PAGE_SIZE)); - if (res != roundup(size + iova - rounddown(iova, PAGE_SIZE), - PAGE_SIZE)) { - IPAERR("Fail to unmap 0x%llx\n", iova); - return -EINVAL; + if (sgt != NULL) { + va = rounddown(iova, PAGE_SIZE); + len = 0; + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + len = PAGE_ALIGN(sg->offset + sg->length); + res = iommu_unmap(smmu_domain, va, + roundup(len, PAGE_SIZE)); + if (res != + roundup(len, PAGE_SIZE)) { + IPAERR("Fail to unmap iova=%llx\n", + iova); + return -EINVAL; + } + va += len; + count++; + } + } else { + res = iommu_unmap(smmu_domain, + rounddown(iova, PAGE_SIZE), + roundup(size + iova - + rounddown(iova, PAGE_SIZE), + PAGE_SIZE)); + if (res != roundup(size + iova - + rounddown(iova, PAGE_SIZE), PAGE_SIZE)) { + IPAERR("Fail to unmap 0x%llx\n", iova); + return -EINVAL; + } } } IPADBG("Peer buff %s 0x%llx\n", map ? "map" : "unmap", iova); From 09b94adf7ea943317faf9e06799ffb5c517ebd74 Mon Sep 17 00:00:00 2001 From: Akshay Pandit Date: Wed, 7 Oct 2020 12:45:46 +0530 Subject: [PATCH 5/8] ipa3: Fix to save sgt table info in proper context Sg table tables are not contiguous page due to this while copying total sg table it failing. To avoid this copying the each sg table individually. Acked-by: Akshay Pandit Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 4ed805bf37e0..918a037392d5 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -384,6 +384,8 @@ int ipa_smmu_store_sgt(struct sg_table **out_ch_ptr, struct sg_table *in_sgt_ptr) { unsigned int nents; + int i; + struct scatterlist *in_sg, *out_sg; if (in_sgt_ptr != NULL) { *out_ch_ptr = kzalloc(sizeof(struct sg_table), GFP_KERNEL); @@ -401,8 +403,12 @@ int ipa_smmu_store_sgt(struct sg_table **out_ch_ptr, return -ENOMEM; } - memcpy((*out_ch_ptr)->sgl, in_sgt_ptr->sgl, - nents*sizeof((*out_ch_ptr)->sgl)); + out_sg = (*out_ch_ptr)->sgl; + for_each_sg(in_sgt_ptr->sgl, in_sg, in_sgt_ptr->nents, i) { + memcpy(out_sg, in_sg, sizeof(struct scatterlist)); + out_sg++; + } + (*out_ch_ptr)->nents = nents; (*out_ch_ptr)->orig_nents = in_sgt_ptr->orig_nents; } From 7e92b9e0e88a821c9179b20df79e54962c367710 Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Tue, 8 Oct 2019 14:12:42 -0700 Subject: [PATCH 6/8] msm: ipa: Fix setting disconnect in progress flag When USB is disconnected USB driver deregisters callback with IPA driver. If there are exception packets coming to USB driver at the same time there is a possiblity of race condition where callback is de-registered and IPA driver tries to access it. Make changes to restrict the callback access when disconnect is in progress. Change-Id: I85d2876847bfd0b23f19b2b81e1aab68729b2e31 Acked-by: Chaitanya Pratapa Signed-off-by: Praveen Kurapati Signed-off-by: Bojun Pan --- drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 22d92a3e1c1d..2b36491a5c5d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -1523,6 +1523,9 @@ int ipa3_release_gsi_channel(u32 clnt_hdl) if (!ep->keep_ipa_awake) IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl)); + /* Set the disconnect in progress flag to avoid calling cb.*/ + atomic_set(&ep->disconnect_in_progress, 1); + gsi_res = gsi_dealloc_channel(ep->gsi_chan_hdl); if (gsi_res != GSI_STATUS_SUCCESS) { IPAERR("Error deallocating channel: %d\n", gsi_res); From 63d979273d4b8f5ab4fc550c1c3e12d899bf96fe Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Thu, 24 Oct 2019 19:45:20 -0700 Subject: [PATCH 7/8] msm: ipa: Fix rndis client disconnection gracefully if there are packets coming from rndis client to device IPA driver tries to gives those packets to network driver. If at the same time USB disconnection is in progress, there can be a possibility of race where callback is called with NULL private data and it can result in a undefined behavior at client driver. Make changes to add proper checks to handle the scenario gracefully. Change-Id: I7b3a5731ae21362dc67c53a2de464b17a223d4ba Signed-off-by: Praveen Kurapati Signed-off-by: Chaitanya Pratapa --- .../platform/msm/ipa/ipa_clients/ecm_ipa.c | 8 +++++++ .../platform/msm/ipa/ipa_clients/rndis_ipa.c | 10 +++++++++ drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 5 +++++ drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 21 ++++++++++++++----- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c b/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c index 8dfe1920c56b..0c319f951e5a 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c +++ b/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c @@ -659,13 +659,21 @@ static void ecm_ipa_packet_receive_notify packet_len = skb->len; ECM_IPA_DEBUG("packet RX, len=%d\n", skb->len); + if (unlikely(ecm_ipa_ctx == NULL)) { + ECM_IPA_DEBUG("Private context is NULL. Drop SKB.\n"); + dev_kfree_skb_any(skb); + return; + } + if (unlikely(ecm_ipa_ctx->state != ECM_IPA_CONNECTED_AND_UP)) { ECM_IPA_DEBUG("Missing pipe connected and/or iface up\n"); + dev_kfree_skb_any(skb); return; } if (unlikely(evt != IPA_RECEIVE)) { ECM_IPA_ERROR("A none IPA_RECEIVE event in ecm_ipa_receive\n"); + dev_kfree_skb_any(skb); return; } diff --git a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c index c201aa342084..8b93ee9b0e35 100644 --- a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c +++ b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c @@ -1135,6 +1135,12 @@ static void rndis_ipa_packet_receive_notify( ("packet Rx, len=%d\n", skb->len); + if (unlikely(rndis_ipa_ctx == NULL)) { + RNDIS_IPA_DEBUG("Private context is NULL. Drop SKB.\n"); + dev_kfree_skb_any(skb); + return; + } + if (unlikely(rndis_ipa_ctx->rx_dump_enable)) rndis_ipa_dump_skb(skb); @@ -1142,11 +1148,15 @@ static void rndis_ipa_packet_receive_notify( RNDIS_IPA_DEBUG("use connect()/up() before receive()\n"); RNDIS_IPA_DEBUG("packet dropped (length=%d)\n", skb->len); + rndis_ipa_ctx->rx_dropped++; + dev_kfree_skb_any(skb); return; } if (evt != IPA_RECEIVE) { RNDIS_IPA_ERROR_RL("a none IPA_RECEIVE event in driver RX\n"); + rndis_ipa_ctx->rx_dropped++; + dev_kfree_skb_any(skb); return; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 2b36491a5c5d..f4b4b24da406 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -1524,7 +1524,10 @@ int ipa3_release_gsi_channel(u32 clnt_hdl) IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl)); /* Set the disconnect in progress flag to avoid calling cb.*/ + spin_lock(&ipa3_ctx->disconnect_lock); atomic_set(&ep->disconnect_in_progress, 1); + spin_unlock(&ipa3_ctx->disconnect_lock); + gsi_res = gsi_dealloc_channel(ep->gsi_chan_hdl); if (gsi_res != GSI_STATUS_SUCCESS) { @@ -1544,7 +1547,9 @@ int ipa3_release_gsi_channel(u32 clnt_hdl) if (!ep->keep_ipa_awake) IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl)); + spin_lock(&ipa3_ctx->disconnect_lock); memset(&ipa3_ctx->ep[clnt_hdl], 0, sizeof(struct ipa3_ep_context)); + spin_unlock(&ipa3_ctx->disconnect_lock); IPADBG("exit\n"); return 0; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index dd341697d6ea..298f4343ea4c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -3402,14 +3402,18 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) unsigned int src_pipe; u32 metadata; u8 ucp; + void (*client_notify)(void *client_priv, enum ipa_dp_evt_type evt, + unsigned long data); + void *client_priv; ipahal_pkt_status_parse_thin(rx_skb->data, &status); src_pipe = status.endp_src_idx; metadata = status.metadata; ucp = status.ucp; ep = &ipa3_ctx->ep[src_pipe]; - if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes)) { - IPAERR_RL("drop pipe=%d\n", src_pipe); + if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes) || + unlikely(atomic_read(&ep->disconnect_in_progress))) { + IPAERR("drop pipe=%d\n", src_pipe); dev_kfree_skb_any(rx_skb); return; } @@ -3431,12 +3435,19 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) metadata, *(u32 *)rx_skb->cb); IPADBG_LOW("ucp: %d\n", *(u8 *)(rx_skb->cb + 4)); + spin_lock(&ipa3_ctx->disconnect_lock); if (likely((!atomic_read(&ep->disconnect_in_progress)) && - ep->valid && ep->client_notify)) - ep->client_notify(ep->priv, IPA_RECEIVE, + ep->valid && ep->client_notify)) { + client_notify = ep->client_notify; + client_priv = ep->priv; + spin_unlock(&ipa3_ctx->disconnect_lock); + client_notify(client_priv, IPA_RECEIVE, (unsigned long)(rx_skb)); - else + } else { + spin_unlock(&ipa3_ctx->disconnect_lock); dev_kfree_skb_any(rx_skb); + } + } static void ipa3_recycle_rx_wrapper(struct ipa3_rx_pkt_wrapper *rx_pkt) From 5ed3cc3fcdf29066cd633c436034cd5167a3a492 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Mon, 12 Oct 2020 11:24:41 +0530 Subject: [PATCH 8/8] msm: ipa3: Send enable force clear only for producer pipe Enable forceclear only supported for producer pipe so avoid sending the force clear command to consumer pipes. Signed-off-by: Ashok Vuyyuru Change-Id: I850f360f18c6598af6914c9cd2c89cacad1ac4c9 --- drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c | 36 ++++++++++--------- drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c | 34 +++++++++--------- drivers/platform/msm/ipa/ipa_v3/ipa_wigig_i.c | 34 +++++++++--------- 3 files changed, 55 insertions(+), 49 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c index 1260c115afb1..6905fd163476 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c @@ -2636,23 +2636,25 @@ int ipa3_suspend_gsi_wdi_pipe(u32 clnt_hdl) } if (ep->valid) { IPADBG("suspended pipe %d\n", ipa_ep_idx); - source_pipe_bitmask = 1 << - ipa3_get_ep_mapping(ep->client); - res = ipa3_enable_force_clear(clnt_hdl, - false, source_pipe_bitmask); - if (res) { - /* - * assuming here modem SSR, AP can remove - * the delay in this case - */ - IPAERR("failed to force clear %d\n", res); - IPAERR("remove delay from SCND reg\n"); - ep_ctrl_scnd.endp_delay = false; - ipahal_write_reg_n_fields( - IPA_ENDP_INIT_CTRL_SCND_n, clnt_hdl, - &ep_ctrl_scnd); - } else { - disable_force_clear = true; + if (IPA_CLIENT_IS_PROD(ep->client)) { + source_pipe_bitmask = 1 << + ipa3_get_ep_mapping(ep->client); + res = ipa3_enable_force_clear(clnt_hdl, + false, source_pipe_bitmask); + if (res) { + /* + * assuming here modem SSR, AP can remove + * the delay in this case + */ + IPAERR("failed to force clear %d\n", res); + IPAERR("remove delay from SCND reg\n"); + ep_ctrl_scnd.endp_delay = false; + ipahal_write_reg_n_fields( + IPA_ENDP_INIT_CTRL_SCND_n, clnt_hdl, + &ep_ctrl_scnd); + } else { + disable_force_clear = true; + } } retry_gsi_stop: res = ipa3_stop_gsi_channel(ipa_ep_idx); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c index aa7f27bb041e..8288d77831a4 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c @@ -962,23 +962,25 @@ int ipa3_disable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) * as IPA uC will fail to suspend the pipe otherwise. */ ep = &ipa3_ctx->ep[ipa_ep_idx_rx]; - source_pipe_bitmask = 1 << + if (IPA_CLIENT_IS_PROD(ep->client)) { + source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ep->client); - result = ipa3_enable_force_clear(ipa_ep_idx_rx, - false, source_pipe_bitmask); - if (result) { - /* - * assuming here modem SSR, AP can remove - * the delay in this case - */ - IPAERR("failed to force clear %d\n", result); - IPAERR("remove delay from SCND reg\n"); - ep_ctrl_scnd.endp_delay = false; - ipahal_write_reg_n_fields( - IPA_ENDP_INIT_CTRL_SCND_n, ipa_ep_idx_rx, - &ep_ctrl_scnd); - } else { - disable_force_clear = true; + result = ipa3_enable_force_clear(ipa_ep_idx_rx, + false, source_pipe_bitmask); + if (result) { + /* + * assuming here modem SSR, AP can remove + * the delay in this case + */ + IPAERR("failed to force clear %d\n", result); + IPAERR("remove delay from SCND reg\n"); + ep_ctrl_scnd.endp_delay = false; + ipahal_write_reg_n_fields( + IPA_ENDP_INIT_CTRL_SCND_n, ipa_ep_idx_rx, + &ep_ctrl_scnd); + } else { + disable_force_clear = true; + } } /* stop gsi rx channel */ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_wigig_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_wigig_i.c index 2aca4cbba146..e50a93c281c1 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_wigig_i.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wigig_i.c @@ -1809,22 +1809,24 @@ int ipa3_disable_wigig_pipe_i(enum ipa_client_type client) } IPADBG("pipe %d\n", ipa_ep_idx); - source_pipe_bitmask = 1 << ipa_ep_idx; - res = ipa3_enable_force_clear(ipa_ep_idx, - false, source_pipe_bitmask); - if (res) { - /* - * assuming here modem SSR, AP can remove - * the delay in this case - */ - IPAERR("failed to force clear %d\n", res); - IPAERR("remove delay from SCND reg\n"); - ep_ctrl_scnd.endp_delay = false; - ipahal_write_reg_n_fields( - IPA_ENDP_INIT_CTRL_SCND_n, ipa_ep_idx, - &ep_ctrl_scnd); - } else { - disable_force_clear = true; + if (IPA_CLIENT_IS_PROD(ep->client)) { + source_pipe_bitmask = 1 << ipa_ep_idx; + res = ipa3_enable_force_clear(ipa_ep_idx, + false, source_pipe_bitmask); + if (res) { + /* + * assuming here modem SSR, AP can remove + * the delay in this case + */ + IPAERR("failed to force clear %d\n", res); + IPAERR("remove delay from SCND reg\n"); + ep_ctrl_scnd.endp_delay = false; + ipahal_write_reg_n_fields( + IPA_ENDP_INIT_CTRL_SCND_n, ipa_ep_idx, + &ep_ctrl_scnd); + } else { + disable_force_clear = true; + } } retry_gsi_stop: res = ipa3_stop_gsi_channel(ipa_ep_idx);