From e091b01ac44e70d450a8d050855b5f3f0f510695 Mon Sep 17 00:00:00 2001 From: Cheng Zeng Date: Wed, 1 Dec 2021 14:52:56 +0800 Subject: [PATCH 1/4] msm: gsi: Read 64-bit ring RP value from registers The DMA address allocated may be in 64-bit address range if dma mask is set to 64-bit, the MSB register value is required. Signed-off-by: Cheng Zeng --- drivers/platform/msm/gsi/gsi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 6663e79dc528..b70eed7d647c 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -1752,7 +1752,14 @@ static inline uint64_t gsi_read_event_ring_rp_ddr(struct gsi_evt_ring_props* pro static inline uint64_t gsi_read_event_ring_rp_reg(struct gsi_evt_ring_props* props, uint8_t id, int ee) { - return gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_4_OFFS(id, ee)); + uint64_t rp; + + rp = gsi_readl(gsi_ctx->base + + GSI_EE_n_EV_CH_k_CNTXT_4_OFFS(id, ee)); + rp |= ((uint64_t)gsi_readl(gsi_ctx->base + + GSI_EE_n_EV_CH_k_CNTXT_5_OFFS(id, ee))) << 32; + + return rp; } int gsi_alloc_evt_ring(struct gsi_evt_ring_props *props, unsigned long dev_hdl, From 37dc636f49b41c649fde148a157630c9293d9c42 Mon Sep 17 00:00:00 2001 From: Cheng Zeng Date: Wed, 1 Dec 2021 19:04:57 +0800 Subject: [PATCH 2/4] msm: ipa: Get device pointers if smmu is disabled If arm-smmu is not configured, smmu cb will not be probed, still need to get pdev and uc_pdev. Signed-off-by: Cheng Zeng --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 4621d5f6140b..514ad94e3e5d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -9191,6 +9191,8 @@ static int ipa3_attach_to_smmu(void) } } } else { + ipa3_ctx->pdev = &ipa3_ctx->master_pdev->dev; + ipa3_ctx->uc_pdev = &ipa3_ctx->master_pdev->dev; IPADBG("smmu is disabled\n"); } return 0; From 1234f5d764ff58b9ae55d8f788c9d3243031166a Mon Sep 17 00:00:00 2001 From: Jagadeesh Date: Wed, 22 Dec 2021 22:13:08 +0530 Subject: [PATCH 3/4] msm: ipa3: fix to cleanup the dma allocation. When commit header table from memory to HW, adding fix to clean dma allocation if it fails in multiple mapping attempts and also to clean the allocated mapping of hdr table after commit to HW. Change-Id: Icbf1b855e34625ffe8f8356a59cddf85a91b0160 Signed-off-by: Jagadeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index 1183d8e275c0..b90ce38b505c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -190,13 +190,13 @@ int __ipa_commit_hdr_v3_0(void) if (ipa3_generate_hdr_hw_tbl(&hdr_mem)) { IPAERR("fail to generate HDR HW TBL\n"); - goto end; + goto failure_hdr; } if (ipa3_generate_hdr_proc_ctx_hw_tbl(hdr_mem.phys_base, &ctx_mem, &aligned_ctx_mem)) { IPAERR("fail to generate HDR PROC CTX HW TBL\n"); - goto end; + goto failure_hdr_proc; } /* IC to close the coal frame before HPS Clear if coal is enabled */ @@ -322,6 +322,7 @@ int __ipa_commit_hdr_v3_0(void) else rc = 0; +end: if (ipa3_ctx->hdr_tbl_lcl) { dma_free_coherent(ipa3_ctx->pdev, hdr_mem.size, hdr_mem.base, hdr_mem.phys_base); @@ -333,6 +334,9 @@ int __ipa_commit_hdr_v3_0(void) ipa3_ctx->hdr_mem.base, ipa3_ctx->hdr_mem.phys_base); ipa3_ctx->hdr_mem = hdr_mem; + } else { + dma_free_coherent(ipa3_ctx->pdev, hdr_mem.size, + hdr_mem.base,hdr_mem.phys_base); } } @@ -347,10 +351,12 @@ int __ipa_commit_hdr_v3_0(void) ipa3_ctx->hdr_proc_ctx_mem.base, ipa3_ctx->hdr_proc_ctx_mem.phys_base); ipa3_ctx->hdr_proc_ctx_mem = ctx_mem; + } else { + dma_free_coherent(ipa3_ctx->pdev, ctx_mem.size, + ctx_mem.base,ctx_mem.phys_base); } } -end: if (coal_cmd_pyld) ipahal_destroy_imm_cmd(coal_cmd_pyld); @@ -361,6 +367,12 @@ end: ipahal_destroy_imm_cmd(hdr_cmd_pyld); return rc; + +failure_hdr_proc: + dma_free_coherent(ipa3_ctx->pdev, hdr_mem.size, hdr_mem.base, + hdr_mem.phys_base); +failure_hdr: + return rc; } static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx, From 24278e36be43a983bd62130824ecae6beaffe3e7 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Fri, 15 Oct 2021 10:14:30 -0700 Subject: [PATCH 4/4] msm: ipa: use lower order pages When order 3 pages are not available, make changes to use lower order pages to ensure buffers are provided to HW. Change-Id: I9eea764d678820b0d3f485525310c506ea29c45e Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c | 6 ++- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 50 ++++++++++++++----- drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 3 ++ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 51e813244211..b07fc3554ef5 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -1357,7 +1357,8 @@ static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf, "lan_repl_rx_empty=%u\n" "flow_enable=%u\n" "flow_disable=%u\n" - "rx_page_drop_cnt=%u\n", + "rx_page_drop_cnt=%u\n" + "lower_order=%u\n", ipa3_ctx->stats.tx_sw_pkts, ipa3_ctx->stats.tx_hw_pkts, ipa3_ctx->stats.tx_non_linear, @@ -1374,7 +1375,8 @@ static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf, ipa3_ctx->stats.lan_repl_rx_empty, ipa3_ctx->stats.flow_enable, ipa3_ctx->stats.flow_disable, - ipa3_ctx->stats.rx_page_drop_cnt + ipa3_ctx->stats.rx_page_drop_cnt, + ipa3_ctx->stats.lower_order ); cnt += nbytes; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 83e65d8799e0..e92f84afa1e7 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -2042,6 +2042,27 @@ fail_kmem_cache_alloc: } } +static struct page *ipa3_alloc_page( + gfp_t flag, u32 *page_order, bool try_lower) +{ + struct page *page = NULL; + u32 p_order = *page_order; + + page = __dev_alloc_pages(flag, p_order); + /* We will only try 1 page order lower. */ + if (unlikely(!page)) { + if (try_lower && p_order > 0) { + p_order = p_order - 1; + page = __dev_alloc_pages(flag, p_order); + if (likely(page)) + ipa3_ctx->stats.lower_order++; + } + } + *page_order = p_order; + return page; +} + + static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page( gfp_t flag, bool is_tmp_alloc) { @@ -2052,12 +2073,18 @@ static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page( flag); if (unlikely(!rx_pkt)) return NULL; - rx_pkt->len = PAGE_SIZE << IPA_WAN_PAGE_ORDER; - rx_pkt->page_data.page = __dev_alloc_pages(flag, - IPA_WAN_PAGE_ORDER); + + rx_pkt->page_data.page_order = IPA_WAN_PAGE_ORDER; + /* Try a lower order page for order 3 pages in case allocation fails. */ + rx_pkt->page_data.page = ipa3_alloc_page(flag, + &rx_pkt->page_data.page_order, + (is_tmp_alloc && rx_pkt->page_data.page_order == 3)); + if (unlikely(!rx_pkt->page_data.page)) goto fail_page_alloc; + rx_pkt->len = PAGE_SIZE << rx_pkt->page_data.page_order; + rx_pkt->page_data.dma_addr = dma_map_page(ipa3_ctx->pdev, rx_pkt->page_data.page, 0, rx_pkt->len, DMA_FROM_DEVICE); @@ -2075,7 +2102,7 @@ static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page( return rx_pkt; fail_dma_mapping: - __free_pages(rx_pkt->page_data.page, IPA_WAN_PAGE_ORDER); + __free_pages(rx_pkt->page_data.page, rx_pkt->page_data.page_order); fail_page_alloc: kmem_cache_free(ipa3_ctx->rx_pkt_wrapper_cache, rx_pkt); return NULL; @@ -2769,8 +2796,7 @@ static void free_rx_page(void *chan_user_data, void *xfer_user_data) } dma_unmap_page(ipa3_ctx->pdev, rx_pkt->page_data.dma_addr, rx_pkt->len, DMA_FROM_DEVICE); - __free_pages(rx_pkt->page_data.page, - IPA_WAN_PAGE_ORDER); + __free_pages(rx_pkt->page_data.page, rx_pkt->page_data.page_order); kmem_cache_free(ipa3_ctx->rx_pkt_wrapper_cache, rx_pkt); } @@ -2821,8 +2847,7 @@ static void ipa3_cleanup_rx(struct ipa3_sys_context *sys) rx_pkt->page_data.dma_addr, rx_pkt->len, DMA_FROM_DEVICE); - __free_pages(rx_pkt->page_data.page, - IPA_WAN_PAGE_ORDER); + __free_pages(rx_pkt->page_data.page, rx_pkt->page_data.page_order); } kmem_cache_free(ipa3_ctx->rx_pkt_wrapper_cache, rx_pkt); @@ -2842,7 +2867,7 @@ static void ipa3_cleanup_rx(struct ipa3_sys_context *sys) rx_pkt->len, DMA_FROM_DEVICE); __free_pages(rx_pkt->page_data.page, - IPA_WAN_PAGE_ORDER); + rx_pkt->page_data.page_order); kmem_cache_free( ipa3_ctx->rx_pkt_wrapper_cache, rx_pkt); @@ -3642,8 +3667,7 @@ static struct sk_buff *handle_page_completion(struct gsi_chan_xfer_notify } else { dma_unmap_page(ipa3_ctx->pdev, rx_page.dma_addr, rx_pkt->len, DMA_FROM_DEVICE); - __free_pages(rx_pkt->page_data.page, - IPA_WAN_PAGE_ORDER); + __free_pages(rx_pkt->page_data.page, rx_pkt->page_data.page_order); } rx_pkt->sys->free_rx_wrapper(rx_pkt); IPA_STATS_INC_CNT(ipa3_ctx->stats.rx_page_drop_cnt); @@ -3671,7 +3695,7 @@ static struct sk_buff *handle_page_completion(struct gsi_chan_xfer_notify dma_unmap_page(ipa3_ctx->pdev, rx_page.dma_addr, rx_pkt->len, DMA_FROM_DEVICE); __free_pages(rx_pkt->page_data.page, - IPA_WAN_PAGE_ORDER); + rx_pkt->page_data.page_order); } rx_pkt->sys->free_rx_wrapper(rx_pkt); } @@ -3696,7 +3720,7 @@ static struct sk_buff *handle_page_completion(struct gsi_chan_xfer_notify skb_shinfo(rx_skb)->nr_frags, rx_page.page, 0, size, - PAGE_SIZE << IPA_WAN_PAGE_ORDER); + PAGE_SIZE << rx_page.page_order); } } else { return NULL; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index ed025daa26ba..317790528af9 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -506,11 +506,13 @@ enum ipa3_wdi_polling_mode { * @page: skb page * @dma_addr: DMA address of this Rx packet * @is_tmp_alloc: skb page from tmp_alloc or recycle_list + * @page_order: page order associated with the page. */ struct ipa_rx_page_data { struct page *page; dma_addr_t dma_addr; bool is_tmp_alloc; + u32 page_order; }; struct ipa3_active_client_htable_entry { @@ -1446,6 +1448,7 @@ struct ipa3_stats { u32 tx_non_linear; u32 rx_page_drop_cnt; struct ipa3_page_recycle_stats page_recycle_stats[2]; + u64 lower_order; }; /* offset for each stats */