From 9cd88fea7f9cf95434c9bc1db91ac1fbca97dece Mon Sep 17 00:00:00 2001 From: Jagadeesh Ponduru Date: Tue, 7 Sep 2021 11:21:05 +0530 Subject: [PATCH 01/33] msm: ipa3: Configure HOLB for WLAN2 consumer pipe To avoid temporary stall on WLAN client enabling the HOLB on WLAN2 consumer pipe. Change-Id: I3920205f7f62dbdd240da162fab4158ab8e070b4 Signed-off-by: Jagadeeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 8ca62014e5cf..867fb64bbb39 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -67,6 +67,7 @@ int ipa3_enable_data_path(u32 clnt_hdl) holb_cfg.en = IPA_HOLB_TMR_EN; } else if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_11 && (ep->client == IPA_CLIENT_WLAN1_CONS || + ep->client == IPA_CLIENT_WLAN2_CONS || ep->client == IPA_CLIENT_USB_CONS)) { holb_cfg.en = IPA_HOLB_TMR_EN; holb_cfg.tmr_val = IPA_HOLB_TMR_VAL_4_5; From bcd36e8871da844b7a1be6cc2c70559391d5c4b9 Mon Sep 17 00:00:00 2001 From: Praveen Kurapati Date: Mon, 30 Aug 2021 11:18:13 +0530 Subject: [PATCH 02/33] msm: ipa3: Reduced excessive logs from ipa Due to excessive logs from ipa it blocks other tasks execution. Ratelimit added inorder to reduce the logs. Change-Id: I00ae9b1e62dd14d82e22d3c788b68d0474a8de87 Signed-off-by: Praveen Kurapati --- drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c index 31bd41369d73..8eb0627c8aa3 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include @@ -56,6 +56,16 @@ IPA_GSB_DRV_NAME " %s:%d " fmt, ## args); \ } while (0) +#define IPA_GSB_ERR_RL(fmt, args...) \ + do { \ + pr_err_ratelimited_ipa(IPA_GSB_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa3_get_ipc_logbuf(), \ + IPA_GSB_DRV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa3_get_ipc_logbuf_low(), \ + IPA_GSB_DRV_NAME " %s:%d " fmt, ## args); \ + } while (0) + #define IPA_GSB_MAX_MSG_LEN 512 #ifdef CONFIG_DEBUG_FS @@ -1184,7 +1194,7 @@ static int ipa_bridge_tx_dp_internal(u32 hdl, struct sk_buff *skb, } if (unlikely(!ipa_gsb_ctx->iface[hdl]->is_resumed)) { - IPA_GSB_ERR("iface %d was suspended\n", hdl); + IPA_GSB_ERR_RL("iface %d was suspended\n", hdl); return -EFAULT; } From 9e52c6925fe4108d968fc2ecd33c8a77eb0a0b8f Mon Sep 17 00:00:00 2001 From: Cheng Zeng Date: Tue, 7 Sep 2021 18:15:39 +0800 Subject: [PATCH 03/33] msm: ipa3: Fix null pointer dereference error If smmu is not enabled, smmu context device check was missing before accessing it which was resulting in null pointer dereference. Now adding check before accessing it. Change-Id: I94393524c79847a165ba605d34906525640b359a Signed-off-by: Cheng Zeng --- drivers/platform/msm/ipa/ipa_v3/ipa_nat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c index 5edd4776669e..8ced02501f84 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c @@ -179,7 +179,7 @@ static int ipa3_nat_ipv6ct_mmap( /* * Check if no smmu or non dma coherent */ - if (!cb->valid || !dev_is_dma_coherent(cb->dev)) { + if (cb && cb->dev && (!cb->valid || !dev_is_dma_coherent(cb->dev))) { IPADBG("Either smmu valid=%u and/or DMA coherent=%u false\n", cb->valid, !dev_is_dma_coherent(cb->dev)); From 27b85ef3569673c2bfa1715f7a842a0acd138421 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Fri, 10 Sep 2021 15:57:50 -0700 Subject: [PATCH 04/33] msm: ipa: Fix to free up all pending EOB pages Make changes to free up all pending EOB pages when SKB allocation used to handle EOT is failed as we could end up in a frag overflow. Change-Id: I80ae84d00d1bbf2cf89e97261d2fe8c3742eda04 Signed-off-by: Chaitanya Pratapa Signed-off-by: Jagadeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 83d2d1476508..2589f2b35c8e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -3658,17 +3658,21 @@ static struct sk_buff *handle_page_completion(struct gsi_chan_xfer_notify sys->ep->client == IPA_CLIENT_APPS_LAN_CONS) { rx_skb = alloc_skb(0, GFP_ATOMIC); if (unlikely(!rx_skb)) { - IPAERR("skb alloc failure\n"); - list_del(&rx_pkt->link); - if (!rx_page.is_tmp_alloc) { - init_page_count(rx_page.page); - } 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); + IPAERR("skb alloc failure, free all pending pages\n"); + list_for_each_entry_safe(rx_pkt, tmp, head, link) { + rx_page = rx_pkt->page_data; + size = rx_pkt->data_len; + list_del_init(&rx_pkt->link); + if (!rx_page.is_tmp_alloc) { + init_page_count(rx_page.page); + } 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); + } + rx_pkt->sys->free_rx_wrapper(rx_pkt); } - rx_pkt->sys->free_rx_wrapper(rx_pkt); IPA_STATS_INC_CNT(ipa3_ctx->stats.rx_page_drop_cnt); return NULL; } From e0f12e040a5ed5a9a7433d5a0fd414968280ba0c Mon Sep 17 00:00:00 2001 From: Raghavendar rao l Date: Wed, 5 May 2021 19:27:31 +0530 Subject: [PATCH 05/33] msm: ipa3: Add retry attempts for subsystem loading Whenever subsystem loading fails to load ipa firmware, updated change to load untill it succeeds. Change-Id: I8b600e8e03030dfbd2e255a4a2148bef942dfe11 Signed-off-by: Raghavendar rao l --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 30 ++++++++++++++++--------- drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 2 ++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index cd5c4a7e7fa3..bb61c7ae70ad 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -51,7 +51,7 @@ #endif #define DRV_NAME "ipa" - +#define DELAY_BEFORE_FW_LOAD 500 #define IPA_SUBSYSTEM_NAME "ipa_fws" #define IPA_UC_SUBSYSTEM_NAME "ipa_uc" @@ -126,6 +126,7 @@ static int ipa3_alloc_pkt_init(void); static void ipa3_load_ipa_fw(struct work_struct *work); static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw); +static DECLARE_DELAYED_WORK(ipa3_fw_load_failure_handle, ipa3_load_ipa_fw); static void ipa_dec_clients_disable_clks_on_wq(struct work_struct *work); static DECLARE_DELAYED_WORK(ipa_dec_clients_disable_clks_on_wq_work, @@ -6812,12 +6813,14 @@ static void ipa3_load_ipa_fw(struct work_struct *work) IPADBG("Entry\n"); IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - - result = ipa3_attach_to_smmu(); - if (result) { - IPAERR("IPA attach to smmu failed %d\n", result); - IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); - return; + if(!ipa3_ctx->ipa_pil_load) + { + result = ipa3_attach_to_smmu(); + if (result) { + IPAERR("IPA attach to smmu failed %d\n", result); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + return; + } } if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_EMULATION && @@ -6836,13 +6839,18 @@ static void ipa3_load_ipa_fw(struct work_struct *work) result = ipa3_manual_load_ipa_fws(); } - IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); if (result) { - IPAERR("IPA FW loading process has failed result=%d\n", - result); + + ipa3_ctx->ipa_pil_load++; + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + IPADBG("IPA firmware loading deffered to a work queue\n"); + queue_delayed_work(ipa3_ctx->transport_power_mgmt_wq, + &ipa3_fw_load_failure_handle, + msecs_to_jiffies(DELAY_BEFORE_FW_LOAD)); return; } + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); mutex_lock(&ipa3_ctx->fw_load_data.lock); ipa3_ctx->fw_load_data.state = IPA_FW_LOAD_STATE_LOADED; mutex_unlock(&ipa3_ctx->fw_load_data.lock); @@ -6902,7 +6910,7 @@ static void ipa_fw_load_sm_handle_event(enum ipa_fw_load_event ev) if (ipa3_ctx->fw_load_data.state == IPA_FW_LOAD_STATE_INIT) { ipa3_ctx->fw_load_data.state = IPA_FW_LOAD_STATE_SMMU_DONE; - goto out; + goto sched_fw_load; } if (ipa3_ctx->fw_load_data.state == IPA_FW_LOAD_STATE_FWFILE_READY) { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index a6a742fee493..c4e9c7c78e40 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2155,6 +2155,8 @@ struct ipa3_context { bool modem_load_ipa_fw; bool fnr_stats_not_supported; bool is_device_crashed; + int ipa_pil_load; + }; struct ipa3_plat_drv_res { From 8c256e028ecf31262a73910322f3b2052eddfb82 Mon Sep 17 00:00:00 2001 From: Jagadeesh Ponduru Date: Thu, 30 Sep 2021 16:47:26 +0530 Subject: [PATCH 06/33] msm: ipa3: Add change to not reset HOLB timer For Q6 endpoints add change to not reset the HOLB timer value to zero instead of default value. Add change to enable HOLB twice for IPA 4.x targets. Change-Id: Ic9596e711b037d24ae25835cb6dd193ec040d723 Signed-off-by: Praveen Kurapati Signed-off-by: Jagadeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 12 +++++++----- drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 6 ++++-- drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 4 ++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index cd5c4a7e7fa3..eef1991b52d9 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -3566,16 +3566,18 @@ static void ipa3_q6_avoid_holb(void) * setting HOLB on Q6 pipes, and from APPS perspective * they are not valid, therefore, the above function * will fail. + * Also don't reset the HOLB timer to 0 for Q6 pipes. */ - ipahal_write_reg_n_fields( - IPA_ENDP_INIT_HOL_BLOCK_TIMER_n, - ep_idx, &ep_holb); + + ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_EN_n, ep_idx, &ep_holb); - /* IPA4.5 issue requires HOLB_EN to be written twice */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) + /* For targets > IPA_4.0 issue requires HOLB_EN to + * be written twice. + */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_EN_n, ep_idx, &ep_holb); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 8ca62014e5cf..a0978bc5c72d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -1497,8 +1497,10 @@ int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset, u32 tmr_val, IPA_ENDP_INIT_HOL_BLOCK_EN_n, pipe_idx, &ep_holb); - /* IPA4.5 issue requires HOLB_EN to be written twice */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) + /* For targets > IPA_4.0 issue requires HOLB_EN to be + * written twice. + */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_EN_n, pipe_idx, &ep_holb); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 0695a368e945..5c3edacfa78a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -6332,8 +6332,8 @@ int ipa3_cfg_ep_holb(u32 clnt_hdl, const struct ipa_ep_cfg_holb *ep_holb) ipa3_ctx->ep[clnt_hdl].holb.en = IPA_HOLB_TMR_EN; ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_EN_n, clnt_hdl, ep_holb); - /* IPA4.5 issue requires HOLB_EN to be written twice */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) + /* For targets > IPA_4.0 issue requires HOLB_EN to be written twice */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_EN_n, clnt_hdl, ep_holb); From a1ff843b17af00d02710e3e0501252212a52fbb2 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Mon, 28 Sep 2020 16:26:47 +0530 Subject: [PATCH 07/33] msm: ipa3: Add wait queue for the adpl add changes to wait queue for the adpl. Change-Id: I5330cbf7fe1439e04c011c143bdd68657469c36e Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_odl.c | 11 ++++++----- drivers/platform/msm/ipa/ipa_v3/ipa_odl.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c b/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c index a5dee263c49b..68fbabcdeb2d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c @@ -250,6 +250,7 @@ int ipa3_send_adpl_msg(unsigned long skb_data) list_add_tail(&msg->link, &ipa3_odl_ctx->adpl_msg_list); atomic_inc(&ipa3_odl_ctx->stats.numer_in_queue); mutex_unlock(&ipa3_odl_ctx->adpl_msg_lock); + wake_up(&ipa3_odl_ctx->adpl_msg_waitq); IPA_STATS_INC_CNT(ipa3_odl_ctx->stats.odl_rx_pkt); return 0; @@ -527,7 +528,9 @@ static ssize_t ipa_adpl_read(struct file *filp, char __user *buf, size_t count, int ret = 0; char __user *start = buf; struct ipa3_push_msg_odl *msg; + DEFINE_WAIT_FUNC(wait, woken_wake_function); + add_wait_queue(&ipa3_odl_ctx->adpl_msg_waitq, &wait); while (1) { IPADBG_LOW("Writing message to adpl pipe\n"); if (!ipa3_odl_ctx->odl_state.odl_open) @@ -572,9 +575,6 @@ static ssize_t ipa_adpl_read(struct file *filp, char __user *buf, size_t count, IPA_STATS_INC_CNT(ipa3_odl_ctx->stats.odl_tx_diag_pkt); kfree(msg); msg = NULL; - } else { - ret = -EAGAIN; - break; } ret = -EAGAIN; @@ -587,9 +587,9 @@ static ssize_t ipa_adpl_read(struct file *filp, char __user *buf, size_t count, if (start != buf) break; - + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - + remove_wait_queue(&ipa3_odl_ctx->adpl_msg_waitq, &wait); if (start != buf && ret != -EFAULT) ret = buf - start; @@ -665,6 +665,7 @@ int ipa_odl_init(void) odl_cdev = ipa3_odl_ctx->odl_cdev; INIT_LIST_HEAD(&ipa3_odl_ctx->adpl_msg_list); + init_waitqueue_head(&ipa3_odl_ctx->adpl_msg_waitq); mutex_init(&ipa3_odl_ctx->adpl_msg_lock); mutex_init(&ipa3_odl_ctx->pipe_lock); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_odl.h b/drivers/platform/msm/ipa/ipa_v3/ipa_odl.h index c39d01dbb57f..e700b442b3ec 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_odl.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_odl.h @@ -58,6 +58,7 @@ struct ipa_odl_context { bool odl_ctl_msg_wq_flag; struct ipa3_odlstats stats; u32 odl_pm_hdl; + wait_queue_head_t adpl_msg_waitq; }; struct ipa3_push_msg_odl { From 2b90d4b534e12a3423b9267a327e56307ba71881 Mon Sep 17 00:00:00 2001 From: Jagadeesh Ponduru Date: Thu, 7 Oct 2021 11:05:59 +0530 Subject: [PATCH 08/33] msm: ipa3: increasing the uC interrupt timeout value Increased the timeout value of ipa3_uc_send_cmd from 10 to 20 in ipa3_uc_debug_stats_alloc function. Change-Id: I5be5839c60b84226872a22e8a05bb712e395e62d Signed-off-by: Jagadeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/ipa_uc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c index b50625b5d688..4200d188284c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c @@ -1439,7 +1439,7 @@ int ipa3_uc_debug_stats_alloc( result = ipa3_uc_send_cmd((u32)(cmd.phys_base), command, IPA_HW_2_CPU_OFFLOAD_CMD_STATUS_SUCCESS, - false, 10 * HZ); + false, 20 * HZ); if (result) { IPAERR("fail to alloc offload stats\n"); goto cleanup; From 53b139775c8317a9a2111a80ec253c4cafd65540 Mon Sep 17 00:00:00 2001 From: Piyush Dhyani Date: Wed, 8 Sep 2021 12:44:57 +0530 Subject: [PATCH 09/33] msm: ipa3: Queue nop desc again if it fails. Currently during nop desc send, we are setting nop pending flag to false before queing desc, due to which we are not able to queue nop desc again if it fails for first time. Now setting nop pending flag to false only if we successfully queued nop desc. Change-Id: Ice0b3726f2ff0e81c0e5b041346e0ba06619ef62 Signed-off-by: Piyush Dhyani --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 2589f2b35c8e..5ba5c7c6fb81 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -345,20 +345,22 @@ static void ipa3_send_nop_desc(struct work_struct *work) return; } list_add_tail(&tx_pkt->link, &sys->head_desc_list); - sys->len++; - sys->nop_pending = false; memset(&nop_xfer, 0, sizeof(nop_xfer)); nop_xfer.type = GSI_XFER_ELEM_NOP; nop_xfer.flags = GSI_XFER_FLAG_EOT; nop_xfer.xfer_user_data = tx_pkt; if (gsi_queue_xfer(sys->ep->gsi_chan_hdl, 1, &nop_xfer, true)) { + list_del(&tx_pkt->link); + kmem_cache_free(ipa3_ctx->tx_pkt_wrapper_cache, tx_pkt); spin_unlock_bh(&sys->spinlock); IPAERR("gsi_queue_xfer for ch:%lu failed\n", sys->ep->gsi_chan_hdl); queue_work(sys->wq, &sys->work); return; } + sys->len++; + sys->nop_pending = false; spin_unlock_bh(&sys->spinlock); /* make sure TAG process is sent before clocks are gated */ From 22bd494f8ed51f4dae3a1c22b8793f150cfac415 Mon Sep 17 00:00:00 2001 From: Jagadeesh Ponduru Date: Thu, 14 Oct 2021 14:10:02 +0530 Subject: [PATCH 10/33] msm: ipa3: Pointer Check and Fix overflow in Header Deletion During header deletion, if there is a HPC referencing to a header, and the header is deleted, the later commit will cause writing garbage values to the HW during commit. Change-Id: Ib8bb490e38c57d975c21e5848850cd79263c95fe Signed-off-by: Jagadeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index ab04374b3afe..96d783245e39 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include "ipa_i.h" @@ -90,6 +90,12 @@ static int ipa3_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem, 0 : 1; } } + /* Check the pointer and header length to avoid dangerous overflow in HW */ + if (unlikely(!entry->hdr || !entry->hdr->offset_entry || + !entry->offset_entry || + entry->hdr->hdr_len == 0 || + entry->hdr->hdr_len > ipa_hdr_bin_sz[IPA_HDR_BIN_MAX - 1])) + return -EINVAL; ret = ipahal_cp_proc_ctx_to_hw_buff(entry->type, mem->base, entry->offset_entry->offset, @@ -747,7 +753,7 @@ int __ipa3_del_hdr(u32 hdr_hdl, bool by_user) return 0; } - if (entry->is_hdr_proc_ctx) { + if (entry->is_hdr_proc_ctx || entry->proc_ctx) { dma_unmap_single(ipa3_ctx->pdev, entry->phys_base, entry->hdr_len, From cfe6d558b261d799bffa7ffc56a232ee5cec6b68 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Wed, 20 Oct 2021 01:13:15 +0530 Subject: [PATCH 11/33] msm: ipa3: Fix to NULL terminate the header pointer in proc header table While resetting the header rules if it find invalid header ID it will return before freeting proc header table it was leading to use after free when accessing the header pointer from proc header table. Adding changes to NULL terminating header pointer in proc header table after header table deleted from the list. Change-Id: If270d855d3907e61368336316161a250053e1e62 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index 96d783245e39..1183d8e275c0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -1084,6 +1084,7 @@ int ipa3_reset_hdr(bool user_only) if (ipa3_id_find(entry->id) == NULL) { mutex_unlock(&ipa3_ctx->lock); + IPAERR_RL("Invalid header ID\n"); WARN_ON_RATELIMIT_IPA(1); return -EFAULT; } @@ -1094,6 +1095,7 @@ int ipa3_reset_hdr(bool user_only) entry->phys_base, entry->hdr_len, DMA_TO_DEVICE); + entry->proc_ctx->hdr = NULL; entry->proc_ctx = NULL; } else { /* move the offset entry to free list */ @@ -1151,6 +1153,7 @@ int ipa3_reset_hdr(bool user_only) if (ipa3_id_find(ctx_entry->id) == NULL) { mutex_unlock(&ipa3_ctx->lock); + IPAERR_RL("Invalid proc header ID\n"); WARN_ON_RATELIMIT_IPA(1); return -EFAULT; } From 1573aa5bb1e2346e9389b8e8312737056d2561be Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Fri, 4 Jun 2021 14:28:33 +0530 Subject: [PATCH 12/33] msm: ipa3: Adding changes to support the deep sleep mode Adding changes to support the deep sleep mode on monaco target. Change-Id: I50016848fde9533a856203bc2ad89bf851179a7b Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 07c9fc828d24..d14a04e22540 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -2965,6 +2965,9 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, } switch (code) { +#if IS_ENABLED(CONFIG_DEEPSLEEP) + case SUBSYS_BEFORE_DS_ENTRY: +#endif case SUBSYS_BEFORE_SHUTDOWN: IPAWANINFO("IPA received MPSS BEFORE_SHUTDOWN\n"); /*Stop netdev first to stop queueing pkts to Q6 */ @@ -2986,6 +2989,9 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, ipa3_odl_pipe_cleanup(true); IPAWANINFO("IPA BEFORE_SHUTDOWN handling is complete\n"); break; +#if IS_ENABLED(CONFIG_DEEPSLEEP) + case SUBSYS_AFTER_DS_ENTRY: +#endif case SUBSYS_AFTER_SHUTDOWN: IPAWANINFO("IPA Received MPSS AFTER_SHUTDOWN\n"); if (atomic_read(&rmnet_ipa3_ctx->is_ssr) && @@ -2997,6 +3003,9 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, IPAWANINFO("IPA AFTER_SHUTDOWN handling is complete\n"); break; +#if IS_ENABLED(CONFIG_DEEPSLEEP) + case SUBSYS_BEFORE_DS_EXIT: +#endif case SUBSYS_BEFORE_POWERUP: IPAWANINFO("IPA received MPSS BEFORE_POWERUP\n"); if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) { @@ -3009,6 +3018,9 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, ipa3_reset_freeze_vote(); IPAWANINFO("IPA BEFORE_POWERUP handling is complete\n"); break; +#if IS_ENABLED(CONFIG_DEEPSLEEP) + case SUBSYS_AFTER_DS_EXIT: +#endif case SUBSYS_AFTER_POWERUP: IPAWANINFO("IPA received MPSS AFTER_POWERUP\n"); if (!atomic_read(&rmnet_ipa3_ctx->is_initialized) && From 7f159650b10334bc77f274b2245ff29f3480cddc Mon Sep 17 00:00:00 2001 From: Raghavendar rao l Date: Thu, 21 Oct 2021 22:20:55 +0530 Subject: [PATCH 13/33] msm: ipa3: Retry to attach smmu nodes if fails Updated change to retry attaching smmu nodes if it fails, in a deffered work queue with 500msec delay. Change-Id: Ia54d801543224caf81085fedfd16305eca99995e Signed-off-by: Raghavendar rao l --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 67 +++++++++++++++++++------ drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 1 + 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 8e0055204e1c..4621d5f6140b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6815,14 +6815,15 @@ static void ipa3_load_ipa_fw(struct work_struct *work) IPADBG("Entry\n"); IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - if(!ipa3_ctx->ipa_pil_load) - { - result = ipa3_attach_to_smmu(); - if (result) { - IPAERR("IPA attach to smmu failed %d\n", result); - IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); - return; - } + + result = ipa3_attach_to_smmu(); + if (result) { + IPAERR("IPA attach to smmu failed %d\n", result); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + queue_delayed_work(ipa3_ctx->transport_power_mgmt_wq, + &ipa3_fw_load_failure_handle, + msecs_to_jiffies(DELAY_BEFORE_FW_LOAD)); + return; } if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_EMULATION && @@ -8817,6 +8818,7 @@ static int ipa_smmu_wlan_cb_probe(struct device *dev) } } + cb->done = true; return 0; } @@ -8896,10 +8898,35 @@ static int ipa_smmu_uc_cb_probe(struct device *dev) ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_UC] = (bypass != 0); ipa3_ctx->uc_pdev = dev; - + cb->done = true; return 0; } +static void ipa3_ap_iommu_unmap(struct ipa_smmu_cb_ctx *cb, const u32 *add_map, u32 add_map_size) { + + int i, res; + + /* iterate of each entry of the additional mapping array */ + for (i = 0; i < add_map_size / sizeof(u32); i += 3) { + u32 iova = be32_to_cpu(add_map[i]); + u32 pa = be32_to_cpu(add_map[i + 1]); + u32 size = be32_to_cpu(add_map[i + 2]); + unsigned long iova_p; + phys_addr_t pa_p; + u32 size_p; + + IPA_SMMU_ROUND_TO_PAGE(iova, pa, size, + iova_p, pa_p, size_p); + IPADBG_LOW("unmapping 0x%lx to 0x%pa size %d\n", + iova_p, &pa_p, size_p); + + res = iommu_unmap(cb->iommu_domain,iova_p, size_p); + if(res != size_p) { + pr_err("iommu unmap failed for AP cb\n"); + ipa_assert(); + } + } +} static int ipa_smmu_ap_cb_probe(struct device *dev) { struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP); @@ -9034,6 +9061,8 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) if (ret < 0 && ret != -EEXIST) { IPAERR("unable to allocate smem MODEM entry\n"); cb->valid = false; + if(add_map) + ipa3_ap_iommu_unmap(cb, add_map, add_map_size); return -EFAULT; } smem_addr = qcom_smem_get(SMEM_MODEM, @@ -9042,6 +9071,8 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) if (IS_ERR(smem_addr)) { IPAERR("unable to acquire smem MODEM entry\n"); cb->valid = false; + if(add_map) + ipa3_ap_iommu_unmap(cb, add_map, add_map_size); return -EFAULT; } if (smem_size != ipa_smem_size) @@ -9062,6 +9093,7 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) smmu_info.present[IPA_SMMU_CB_AP] = true; + cb->done = true; ipa3_ctx->pdev = dev; cb->next_addr = cb->va_end; @@ -9114,18 +9146,26 @@ static int ipa_smmu_11ad_cb_probe(struct device *dev) IPADBG("11AD using shared CB\n"); cb->shared = true; } - + cb->done = true; return 0; } static int ipa_smmu_cb_probe(struct device *dev, enum ipa_smmu_cb_type cb_type) { + struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(cb_type); + + if((cb != NULL) && (cb->done == true)) { + IPADBG("SMMU CB type %d already initialized\n", cb_type); + return 0; + } switch (cb_type) { case IPA_SMMU_CB_AP: + ipa3_ctx->pdev = &ipa3_ctx->master_pdev->dev; return ipa_smmu_ap_cb_probe(dev); case IPA_SMMU_CB_WLAN: return ipa_smmu_wlan_cb_probe(dev); case IPA_SMMU_CB_UC: + ipa3_ctx->uc_pdev = &ipa3_ctx->master_pdev->dev; return ipa_smmu_uc_cb_probe(dev); case IPA_SMMU_CB_11AD: return ipa_smmu_11ad_cb_probe(dev); @@ -9140,16 +9180,15 @@ static int ipa3_attach_to_smmu(void) struct ipa_smmu_cb_ctx *cb; int i, result; - ipa3_ctx->pdev = &ipa3_ctx->master_pdev->dev; - ipa3_ctx->uc_pdev = &ipa3_ctx->master_pdev->dev; - if (smmu_info.arm_smmu) { IPADBG("smmu is enabled\n"); for (i = 0; i < IPA_SMMU_CB_MAX; i++) { cb = ipa3_get_smmu_ctx(i); result = ipa_smmu_cb_probe(cb->dev, i); - if (result) + if (result) { IPAERR("probe failed for cb %d\n", i); + return result; + } } } else { IPADBG("smmu is disabled\n"); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index c4e9c7c78e40..ed025daa26ba 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -544,6 +544,7 @@ struct ipa_smmu_cb_ctx { u32 va_end; bool shared; bool is_cache_coherent; + bool done; }; /** From f34eede3cb2127afa8c350b5dd8cc515caa7c5fe Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Thu, 26 Aug 2021 11:46:30 -0700 Subject: [PATCH 14/33] msm: ipa: remove initing head again if dma mapping fails Remove Initializing rx_pkt link if dma mapping fails. Change-Id: I49d08555c875fc9039805ef8775be3b676f51d08 Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 5ba5c7c6fb81..25bc4cb2bc53 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -2611,7 +2611,6 @@ static void ipa3_replenish_rx_cache_recycle(struct ipa3_sys_context *sys) fail_dma_mapping: spin_lock_bh(&sys->spinlock); list_add_tail(&rx_pkt->link, &sys->rcycl_list); - INIT_LIST_HEAD(&rx_pkt->link); spin_unlock_bh(&sys->spinlock); fail_kmem_cache_alloc: if (rx_len_cached == 0) { From 676280f3558cead6391251a85aeaac68954d9d4c Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Wed, 22 Sep 2021 12:23:37 -0700 Subject: [PATCH 15/33] msm: ipa: add skb recycle if dma fails during replenish Add skb recycle when dma mapping fails during rx cache replenishing. Change-Id: I4ea2b1581f4d9a404248ce39bb916e58e368b7e4 Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 5ba5c7c6fb81..31f687130598 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -2569,7 +2569,7 @@ static void ipa3_replenish_rx_cache_recycle(struct ipa3_sys_context *sys) spin_lock_bh(&sys->spinlock); rx_pkt = list_first_entry(&sys->rcycl_list, struct ipa3_rx_pkt_wrapper, link); - list_del(&rx_pkt->link); + list_del_init(&rx_pkt->link); spin_unlock_bh(&sys->spinlock); ptr = skb_put(rx_pkt->data.skb, sys->rx_buff_sz); rx_pkt->data.dma_addr = dma_map_single(ipa3_ctx->pdev, @@ -2610,6 +2610,7 @@ static void ipa3_replenish_rx_cache_recycle(struct ipa3_sys_context *sys) goto done; fail_dma_mapping: spin_lock_bh(&sys->spinlock); + ipa3_skb_recycle(rx_pkt->data.skb); list_add_tail(&rx_pkt->link, &sys->rcycl_list); INIT_LIST_HEAD(&rx_pkt->link); spin_unlock_bh(&sys->spinlock); From ebc5bfb2c3d5c486fb14ebf1d7659dd11723b4bd Mon Sep 17 00:00:00 2001 From: Raghavendar rao l Date: Thu, 21 Oct 2021 22:20:55 +0530 Subject: [PATCH 16/33] msm: ipa3: Retry to attach smmu nodes if fails Updated change to retry attaching smmu nodes if it fails, in a deffered work queue with 500msec delay. Change-Id: Ia54d801543224caf81085fedfd16305eca99995e Signed-off-by: Raghavendar rao l --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 67 +++++++++++++++++++------ drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 1 + 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 8e0055204e1c..4621d5f6140b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6815,14 +6815,15 @@ static void ipa3_load_ipa_fw(struct work_struct *work) IPADBG("Entry\n"); IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - if(!ipa3_ctx->ipa_pil_load) - { - result = ipa3_attach_to_smmu(); - if (result) { - IPAERR("IPA attach to smmu failed %d\n", result); - IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); - return; - } + + result = ipa3_attach_to_smmu(); + if (result) { + IPAERR("IPA attach to smmu failed %d\n", result); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + queue_delayed_work(ipa3_ctx->transport_power_mgmt_wq, + &ipa3_fw_load_failure_handle, + msecs_to_jiffies(DELAY_BEFORE_FW_LOAD)); + return; } if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_EMULATION && @@ -8817,6 +8818,7 @@ static int ipa_smmu_wlan_cb_probe(struct device *dev) } } + cb->done = true; return 0; } @@ -8896,10 +8898,35 @@ static int ipa_smmu_uc_cb_probe(struct device *dev) ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_UC] = (bypass != 0); ipa3_ctx->uc_pdev = dev; - + cb->done = true; return 0; } +static void ipa3_ap_iommu_unmap(struct ipa_smmu_cb_ctx *cb, const u32 *add_map, u32 add_map_size) { + + int i, res; + + /* iterate of each entry of the additional mapping array */ + for (i = 0; i < add_map_size / sizeof(u32); i += 3) { + u32 iova = be32_to_cpu(add_map[i]); + u32 pa = be32_to_cpu(add_map[i + 1]); + u32 size = be32_to_cpu(add_map[i + 2]); + unsigned long iova_p; + phys_addr_t pa_p; + u32 size_p; + + IPA_SMMU_ROUND_TO_PAGE(iova, pa, size, + iova_p, pa_p, size_p); + IPADBG_LOW("unmapping 0x%lx to 0x%pa size %d\n", + iova_p, &pa_p, size_p); + + res = iommu_unmap(cb->iommu_domain,iova_p, size_p); + if(res != size_p) { + pr_err("iommu unmap failed for AP cb\n"); + ipa_assert(); + } + } +} static int ipa_smmu_ap_cb_probe(struct device *dev) { struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP); @@ -9034,6 +9061,8 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) if (ret < 0 && ret != -EEXIST) { IPAERR("unable to allocate smem MODEM entry\n"); cb->valid = false; + if(add_map) + ipa3_ap_iommu_unmap(cb, add_map, add_map_size); return -EFAULT; } smem_addr = qcom_smem_get(SMEM_MODEM, @@ -9042,6 +9071,8 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) if (IS_ERR(smem_addr)) { IPAERR("unable to acquire smem MODEM entry\n"); cb->valid = false; + if(add_map) + ipa3_ap_iommu_unmap(cb, add_map, add_map_size); return -EFAULT; } if (smem_size != ipa_smem_size) @@ -9062,6 +9093,7 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) smmu_info.present[IPA_SMMU_CB_AP] = true; + cb->done = true; ipa3_ctx->pdev = dev; cb->next_addr = cb->va_end; @@ -9114,18 +9146,26 @@ static int ipa_smmu_11ad_cb_probe(struct device *dev) IPADBG("11AD using shared CB\n"); cb->shared = true; } - + cb->done = true; return 0; } static int ipa_smmu_cb_probe(struct device *dev, enum ipa_smmu_cb_type cb_type) { + struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(cb_type); + + if((cb != NULL) && (cb->done == true)) { + IPADBG("SMMU CB type %d already initialized\n", cb_type); + return 0; + } switch (cb_type) { case IPA_SMMU_CB_AP: + ipa3_ctx->pdev = &ipa3_ctx->master_pdev->dev; return ipa_smmu_ap_cb_probe(dev); case IPA_SMMU_CB_WLAN: return ipa_smmu_wlan_cb_probe(dev); case IPA_SMMU_CB_UC: + ipa3_ctx->uc_pdev = &ipa3_ctx->master_pdev->dev; return ipa_smmu_uc_cb_probe(dev); case IPA_SMMU_CB_11AD: return ipa_smmu_11ad_cb_probe(dev); @@ -9140,16 +9180,15 @@ static int ipa3_attach_to_smmu(void) struct ipa_smmu_cb_ctx *cb; int i, result; - ipa3_ctx->pdev = &ipa3_ctx->master_pdev->dev; - ipa3_ctx->uc_pdev = &ipa3_ctx->master_pdev->dev; - if (smmu_info.arm_smmu) { IPADBG("smmu is enabled\n"); for (i = 0; i < IPA_SMMU_CB_MAX; i++) { cb = ipa3_get_smmu_ctx(i); result = ipa_smmu_cb_probe(cb->dev, i); - if (result) + if (result) { IPAERR("probe failed for cb %d\n", i); + return result; + } } } else { IPADBG("smmu is disabled\n"); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index c4e9c7c78e40..ed025daa26ba 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -544,6 +544,7 @@ struct ipa_smmu_cb_ctx { u32 va_end; bool shared; bool is_cache_coherent; + bool done; }; /** From e091b01ac44e70d450a8d050855b5f3f0f510695 Mon Sep 17 00:00:00 2001 From: Cheng Zeng Date: Wed, 1 Dec 2021 14:52:56 +0800 Subject: [PATCH 17/33] 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 18/33] 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 19/33] 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 20/33] 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 */ From 0c348e3f8070593b38342ced045c5084315edbca Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Fri, 7 Jan 2022 00:54:28 +0530 Subject: [PATCH 21/33] msm: ipa3: Changes not allow ODL pipe setup during SSR When SSR in progress not allowing to setup ODL pipe. Change-Id: Ied44a7bafdf90cff2f3b7619da88fe3c31d18956 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_odl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c b/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c index 68fbabcdeb2d..0f3f4979e95b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c @@ -366,6 +366,11 @@ int ipa3_odl_pipe_open(void) return 0; } + if (atomic_read(&ipa3_ctx->is_ssr)) { + IPAERR("SSR in progress ODL pipe configuration not allowed\n"); + return 0; + } + memset(&holb_cfg, 0, sizeof(holb_cfg)); holb_cfg.tmr_val = 0; holb_cfg.en = 1; From 8918458fc79b14ab144924a48f2ec93a46ea470b Mon Sep 17 00:00:00 2001 From: Raghavendar rao l Date: Tue, 14 Dec 2021 15:28:22 +0530 Subject: [PATCH 22/33] msm: ipa3: enable ipa register save when device is about to crash Changes to save the IPA/GSI hardware contents onto ipa_reg_save structure before to crash from APPS side, This support is starting from IPA 4.5 version uptill 4.11. Signed-off-by: Raghavendar rao l Change-Id: I1680cf7bfab56d4a4888cf90874b92b999c3c9c9 --- config/dataipa.h | 10 ++- config/dataipa_GKI.conf | 4 ++ config/dataipa_QGKI.conf | 4 ++ .../ipa/ipa_v3/dump/ipa4.1/ipa_hw_common_ex.h | 64 ++++++++++++++++- .../ipa/ipa_v3/dump/ipa4.5/ipa_hw_common_ex.h | 68 +++++++++++++++++-- .../msm/ipa/ipa_v3/dump/ipa_reg_dump.c | 44 +++++++++--- .../msm/ipa/ipa_v3/dump/ipa_reg_dump.h | 26 ++++++- 7 files changed, 202 insertions(+), 18 deletions(-) diff --git a/config/dataipa.h b/config/dataipa.h index 567fa2e68b6a..4e4ec61081a6 100644 --- a/config/dataipa.h +++ b/config/dataipa.h @@ -1,10 +1,16 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* -* Copyright (c) 2020, The Linux Foundation. All rights reserved. -*/ + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ #define CONFIG_GSI 1 #define CONFIG_GSI_REGISTER_VERSION_2 1 #define CONFIG_RMNET_IPA3 1 #define CONFIG_RNDIS_IPA 1 #define CONFIG_IPA_WDI_UNIFIED_API 1 +#define CONFIG_IPA3_REGDUMP 1 +#define CONFIG_IPA3_APPS_REGDUMP 1 +#define CONFIG_IPA3_REGDUMP_IPA_4_5 1 +#define CONFIG_IPA3_4_5_RGSTR 0 +#define CONFIG_IPA3_REGDUMP_NUM_EXTRA_ENDP_REGS 0 diff --git a/config/dataipa_GKI.conf b/config/dataipa_GKI.conf index 1559ef90cdca..6103d50a41c7 100644 --- a/config/dataipa_GKI.conf +++ b/config/dataipa_GKI.conf @@ -4,3 +4,7 @@ export CONFIG_IPA_CLIENTS_MANAGER=m export CONFIG_IPA_WDI_UNIFIED_API=y export CONFIG_RMNET_IPA3=y export CONFIG_RNDIS_IPA=m +export CONFIG_IPA3_REGDUMP=y +export CONFIG_IPA3_APPS_REGDUMP=y +export CONFIG_IPA3_REGDUMP_IPA_4_5=y +export CONFIG_IPA3_4_5_RGSTR=n diff --git a/config/dataipa_QGKI.conf b/config/dataipa_QGKI.conf index 5c1f8d44c450..b311ca3f3989 100644 --- a/config/dataipa_QGKI.conf +++ b/config/dataipa_QGKI.conf @@ -4,3 +4,7 @@ export CONFIG_IPA_CLIENTS_MANAGER=y export CONFIG_IPA_WDI_UNIFIED_API=y export CONFIG_RMNET_IPA3=y export CONFIG_RNDIS_IPA=y +export CONFIG_IPA3_REGDUMP=y +export CONFIG_IPA3_APPS_REGDUMP=y +export CONFIG_IPA3_REGDUMP_IPA_4_5=y +export CONFIG_IPA3_4_5_RGSTR=n diff --git a/drivers/platform/msm/ipa/ipa_v3/dump/ipa4.1/ipa_hw_common_ex.h b/drivers/platform/msm/ipa/ipa_v3/dump/ipa4.1/ipa_hw_common_ex.h index 5012a32b2a5a..ed31c017fc6e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/dump/ipa4.1/ipa_hw_common_ex.h +++ b/drivers/platform/msm/ipa/ipa_v3/dump/ipa4.1/ipa_hw_common_ex.h @@ -1,4 +1,6 @@ /* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved. + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -412,6 +414,20 @@ enum ipa_hw_irq_srcs_e { */ #define IPA_HW_REG_SAVE_NUM_ACTIVE_PIPES 23 + +/* + * Total number of channel contexts that need to be saved for q6 + */ + +#define IPA_HW_REG_SAVE_GSI_NUM_CH_CNTXT_Q6 11 + +/* + * Total number of event ring contexts that need to be saved for Q6 + */ + +#define IPA_HW_REG_SAVE_GSI_NUM_EVT_CNTXT_Q6 11 + + /* * Macro to set the active flag for all active pipe indexed register */ @@ -511,7 +527,29 @@ enum ipa_hw_irq_srcs_e { { GEN_2xVECTOR_REG_OFST(reg_name, IPA_REG_SAVE_HWP_GSI_EE, 3), \ (u32 *)&ipa_reg_save.gsi.ch_cntxt.uc[3].var_name }, \ { GEN_2xVECTOR_REG_OFST(reg_name, IPA_REG_SAVE_HWP_GSI_EE, 4), \ - (u32 *)&ipa_reg_save.gsi.ch_cntxt.uc[4].var_name } + (u32 *)&ipa_reg_save.gsi.ch_cntxt.uc[4].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 0), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[0].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 1), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[1].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 2), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[2].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 3), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[3].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 4), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[4].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 5), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[5].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 6), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[6].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 7), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[7].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 8), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[8].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 9), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[9].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 10), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[10].var_name } #define IPA_REG_SAVE_CFG_ENTRY_GSI_EVT_CNTXT(reg_name, var_name) \ { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_A7_EE, 0), \ @@ -545,7 +583,29 @@ enum ipa_hw_irq_srcs_e { { GEN_2xVECTOR_REG_OFST(reg_name, IPA_REG_SAVE_HWP_GSI_EE, 2), \ (u32 *)&ipa_reg_save.gsi.evt_cntxt.uc[2].var_name }, \ { GEN_2xVECTOR_REG_OFST(reg_name, IPA_REG_SAVE_HWP_GSI_EE, 3), \ - (u32 *)&ipa_reg_save.gsi.evt_cntxt.uc[3].var_name } + (u32 *)&ipa_reg_save.gsi.evt_cntxt.uc[3].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 0), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[0].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 1), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[1].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 2), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[2].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 3), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[3].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 4), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[4].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 5), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[5].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 6), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[6].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 7), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[7].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 8), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[8].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 9), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[9].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 10), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[10].var_name } /* * Macro to define a particular register cfg entry for all pipe diff --git a/drivers/platform/msm/ipa/ipa_v3/dump/ipa4.5/ipa_hw_common_ex.h b/drivers/platform/msm/ipa/ipa_v3/dump/ipa4.5/ipa_hw_common_ex.h index dfd95f7c2d5b..96e99aee4430 100644 --- a/drivers/platform/msm/ipa/ipa_v3/dump/ipa4.5/ipa_hw_common_ex.h +++ b/drivers/platform/msm/ipa/ipa_v3/dump/ipa4.5/ipa_hw_common_ex.h @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * */ #if !defined(_IPA_HW_COMMON_EX_H_) #define _IPA_HW_COMMON_EX_H_ @@ -447,6 +449,11 @@ enum ipa_hw_irq_srcs_e { */ #define IPA_HW_REG_SAVE_GSI_NUM_CH_CNTXT_UC 2 +/* + * Total number of channel contexts that need to be saved for q6 + */ +#define IPA_HW_REG_SAVE_GSI_NUM_CH_CNTXT_Q6 11 + /* * Total number of event ring contexts that need to be saved for APPS */ @@ -456,6 +463,10 @@ enum ipa_hw_irq_srcs_e { * Total number of event ring contexts that need to be saved for UC */ #define IPA_HW_REG_SAVE_GSI_NUM_EVT_CNTXT_UC 1 +/* + * Total number of event ring contexts that need to be saved for Q6 + */ +#define IPA_HW_REG_SAVE_GSI_NUM_EVT_CNTXT_Q6 11 /* * Total number of endpoints for which ipa_reg_save.pipes[endp_number] @@ -562,7 +573,31 @@ enum ipa_hw_irq_srcs_e { { GEN_2xVECTOR_REG_OFST(reg_name, IPA_REG_SAVE_HWP_GSI_EE, 1), \ (u32 *)&ipa_reg_save.gsi.ch_cntxt.uc[0].var_name }, \ { GEN_2xVECTOR_REG_OFST(reg_name, IPA_REG_SAVE_HWP_GSI_EE, 3), \ - (u32 *)&ipa_reg_save.gsi.ch_cntxt.uc[1].var_name } + (u32 *)&ipa_reg_save.gsi.ch_cntxt.uc[1].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 0), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[0].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 1), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[1].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 2), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[2].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 3), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[3].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 4), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[4].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 5), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[5].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 6), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[6].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 7), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[7].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 8), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[8].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 9), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[9].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 10), \ + (u32 *)&ipa_reg_save.gsi.ch_cntxt.q6[10].var_name } + + #define IPA_REG_SAVE_CFG_ENTRY_GSI_EVT_CNTXT(reg_name, var_name) \ { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_A7_EE, 0), \ @@ -604,14 +639,39 @@ enum ipa_hw_irq_srcs_e { { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_A7_EE, 18), \ (u32 *)&ipa_reg_save.gsi.evt_cntxt.a7[18].var_name }, \ { GEN_2xVECTOR_REG_OFST(reg_name, IPA_REG_SAVE_HWP_GSI_EE, 1), \ - (u32 *)&ipa_reg_save.gsi.evt_cntxt.uc[0].var_name } + (u32 *)&ipa_reg_save.gsi.evt_cntxt.uc[0].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 0), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[0].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 1), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[1].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 2), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[2].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 3), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[3].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 4), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[4].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 5), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[5].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 6), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[6].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 7), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[7].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 8), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[8].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 9), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[9].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 10), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[10].var_name }, \ + { GEN_2xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE, 11), \ + (u32 *)&ipa_reg_save.gsi.evt_cntxt.q6[11].var_name } + /* * Macro to define a particular register cfg entry for all pipe * indexed register */ #define IPA_REG_SAVE_CFG_ENTRY_PIPE_ENDP(reg_name, var_name) \ - ({ GEN_1xVECTOR_REG_OFST(reg_name, 0), \ + { GEN_1xVECTOR_REG_OFST(reg_name, 0), \ (u32 *)&ipa_reg_save.ipa.pipes[0].endp.var_name }, \ { GEN_1xVECTOR_REG_OFST(reg_name, 1), \ (u32 *)&ipa_reg_save.ipa.pipes[1].endp.var_name }, \ @@ -672,7 +732,7 @@ enum ipa_hw_irq_srcs_e { { GEN_1xVECTOR_REG_OFST(reg_name, 29), \ (u32 *)&ipa_reg_save.ipa.pipes[29].endp.var_name }, \ { GEN_1xVECTOR_REG_OFST(reg_name, 30), \ - (u32 *)&ipa_reg_save.ipa.pipes[30].endp.var_name }) + (u32 *)&ipa_reg_save.ipa.pipes[30].endp.var_name } /* * Macro to define a particular register cfg entry for the remaining diff --git a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c index d531b024b83d..a81bfb204cc0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c +++ b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "ipa_reg_dump.h" #include "ipa_access_control.h" @@ -306,6 +307,8 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { * because the following registers are not scaler, rather * they are register arrays... */ + /* Below are accessable only by VMID0 domain. */ +#ifndef CONFIG_IPA3_APPS_REGDUMP IPA_REG_SAVE_CFG_ENTRY_GEN_EE(IPA_IRQ_STTS_EE_n, ipa_irq_stts_ee_n), IPA_REG_SAVE_CFG_ENTRY_GEN_EE(IPA_IRQ_EN_EE_n, @@ -322,6 +325,7 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { ipa_suspend_irq_info_ee_n), IPA_REG_SAVE_CFG_ENTRY_GEN_EE(IPA_SUSPEND_IRQ_EN_EE_n, ipa_suspend_irq_en_ee_n), +#endif /* CONFIG_IPA3_APPS_REGDUMP */ /* Pipe Endp Registers */ IPA_REG_SAVE_CFG_ENTRY_PIPE_ENDP(IPA_ENDP_INIT_CTRL_n, @@ -370,38 +374,45 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { ipa_src_rsrc_grp_01_rsrc_type_n), IPA_REG_SAVE_CFG_ENTRY_SRC_RSRC_GRP(IPA_SRC_RSRC_GRP_23_RSRC_TYPE_n, ipa_src_rsrc_grp_23_rsrc_type_n), +#ifdef CONFIG_IPA3_4_5_RGSTR #if defined(CONFIG_IPA3_REGDUMP_IPA_4_5) IPA_REG_SAVE_CFG_ENTRY_SRC_RSRC_GRP(IPA_SRC_RSRC_GRP_45_RSRC_TYPE_n, ipa_src_rsrc_grp_45_rsrc_type_n), -#endif - +#endif /* CONFIG_IPA3_REGDUMP_IPA_4_5 */ +#endif /* CONFIG_IPA3_4_5_RGSTR */ /* Destination Resource Group Config Registers */ IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_GRP(IPA_DST_RSRC_GRP_01_RSRC_TYPE_n, ipa_dst_rsrc_grp_01_rsrc_type_n), IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_GRP(IPA_DST_RSRC_GRP_23_RSRC_TYPE_n, ipa_dst_rsrc_grp_23_rsrc_type_n), +#ifdef CONFIG_IPA3_4_5_RGSTR #if defined(CONFIG_IPA3_REGDUMP_IPA_4_5) IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_GRP(IPA_DST_RSRC_GRP_45_RSRC_TYPE_n, ipa_dst_rsrc_grp_45_rsrc_type_n), -#endif +#endif /* CONFIG_IPA3_REGDUMP_IPA_4_5 */ +#endif /* CONFIG_IPA3_4_5_RGSTR */ /* Source Resource Group Count Registers */ IPA_REG_SAVE_CFG_ENTRY_SRC_RSRC_CNT_GRP( IPA_SRC_RSRC_GRP_0123_RSRC_TYPE_CNT_n, ipa_src_rsrc_grp_0123_rsrc_type_cnt_n), +#ifdef CONFIG_IPA3_4_5_RGSTR #if defined(CONFIG_IPA3_REGDUMP_IPA_4_5) IPA_REG_SAVE_CFG_ENTRY_SRC_RSRC_CNT_GRP( IPA_SRC_RSRC_GRP_4567_RSRC_TYPE_CNT_n, ipa_src_rsrc_grp_4567_rsrc_type_cnt_n), -#endif +#endif /* CONFIG_IPA3_REGDUMP_IPA_4_5 */ +#endif /* CONFIG_IPA3_4_5_RGSTR */ /* Destination Resource Group Count Registers */ IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_CNT_GRP( IPA_DST_RSRC_GRP_0123_RSRC_TYPE_CNT_n, ipa_dst_rsrc_grp_0123_rsrc_type_cnt_n), +#ifdef CONFIG_IPA3_4_5_RGSTR #if defined(CONFIG_IPA3_REGDUMP_IPA_4_5) IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_CNT_GRP( IPA_DST_RSRC_GRP_4567_RSRC_TYPE_CNT_n, ipa_dst_rsrc_grp_4567_rsrc_type_cnt_n), -#endif +#endif /* CONFIG_IPA3_REGDUMP_IPA_4_5 */ +#endif /* CONFIG_IPA3_4_5_RGSTR */ /* * ===================================================================== * GSI register definitions begin here... @@ -409,6 +420,9 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { */ /* GSI General Registers */ + /* Can access only through VMID_0 domain. */ + +#ifndef CONFIG_IPA3_APPS_REGDUMP GEN_SRC_DST_ADDR_MAP(GSI_CFG, gsi.gen, gsi_cfg), @@ -419,7 +433,9 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { IPA_GSI_TOP_GSI_INST_RAM_n, ipa_gsi_top_gsi_inst_ram_n), + /* GSI Debug Registers */ + /* can access only through VMID_0 domain. */ GEN_SRC_DST_ADDR_MAP(IPA_GSI_TOP_GSI_DEBUG_BUSY_REG, gsi.debug, ipa_gsi_top_gsi_debug_busy_reg), @@ -449,6 +465,8 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { GSI_DEBUG_QSB_LOG_LAST_MISC_IDn, qsb_log_last_misc), /* GSI IRAM pointers Registers */ + /* can access only through VMID_0 domain */ + GEN_SRC_DST_ADDR_MAP(IPA_GSI_TOP_GSI_IRAM_PTR_CH_CMD, gsi.debug.gsi_iram_ptrs, ipa_gsi_top_gsi_iram_ptr_ch_cmd), @@ -488,8 +506,10 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { GEN_SRC_DST_ADDR_MAP(IPA_GSI_TOP_GSI_IRAM_PTR_INT_MOD_STOPPED, gsi.debug.gsi_iram_ptrs, ipa_gsi_top_gsi_iram_ptr_int_mod_stopped), - /* GSI SHRAM pointers Registers */ + /* can access only through VMID_0 domain */ + + GEN_SRC_DST_ADDR_MAP(IPA_GSI_TOP_GSI_SHRAM_PTR_CH_CNTXT_BASE_ADDR, gsi.debug.gsi_shram_ptrs, ipa_gsi_top_gsi_shram_ptr_ch_cntxt_base_addr), @@ -508,7 +528,6 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { GEN_SRC_DST_ADDR_MAP(IPA_GSI_TOP_GSI_SHRAM_PTR_FUNC_STACK_BASE_ADDR, gsi.debug.gsi_shram_ptrs, ipa_gsi_top_gsi_shram_ptr_func_stack_base_addr), - /* * NOTE: That GEN_SRC_DST_ADDR_MAP() not used below. This is * because the following registers are not scaler, rather @@ -516,8 +535,12 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { */ /* GSI General EE Registers */ + /* can access only through VMID_0 domain */ + + IPA_REG_SAVE_CFG_ENTRY_GSI_GENERAL_EE(GSI_MANAGER_EE_QOS_n, gsi_manager_ee_qos_n), +#endif /* CONFIG_IPA3_APPS_REGDUMP */ IPA_REG_SAVE_CFG_ENTRY_GSI_GENERAL_EE(EE_n_GSI_STATUS, ee_n_gsi_status), IPA_REG_SAVE_CFG_ENTRY_GSI_GENERAL_EE(EE_n_CNTXT_TYPE_IRQ, @@ -659,12 +682,17 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { ipa_endp_init_rsrc_grp_n), IPA_REG_SAVE_CFG_ENTRY_PIPE_ENDP_EXTRA(IPA_ENDP_INIT_SEQ_n, ipa_endp_init_seq_n), + + /* can access only through VMID_0 domain */ +#ifndef CONFIG_IPA3_APPS_REGDUMP IPA_REG_SAVE_CFG_ENTRY_PIPE_ENDP_EXTRA(IPA_ENDP_GSI_CFG_TLV_n, ipa_endp_gsi_cfg_tlv_n), IPA_REG_SAVE_CFG_ENTRY_PIPE_ENDP_EXTRA(IPA_ENDP_GSI_CFG_AOS_n, ipa_endp_gsi_cfg_aos_n), IPA_REG_SAVE_CFG_ENTRY_PIPE_ENDP_EXTRA(IPA_ENDP_GSI_CFG1_n, ipa_endp_gsi_cfg1_n), +#endif /* CONFIG_IPA3_APPS_REGDUMP */ + IPA_REG_SAVE_CFG_ENTRY_PIPE_ENDP_EXTRA (IPA_ENDP_FILTER_ROUTER_HSH_CFG_n, ipa_endp_filter_router_hsh_cfg_n), @@ -1490,7 +1518,7 @@ int ipa_reg_save_init(u32 value) if (ipa3_ctx->do_testbus_collection_on_crash) { memset(ipa_testbus_mem, value, sizeof(ipa_testbus_mem)); ipa_reg_save.ipa.testbus = - (struct ipa_reg_save_ipa_testbus_s *) ipa_testbus_mem; + (struct ipa_reg_save_ipa_testbus_s *) ipa_testbus_mem; } /* setup access for register collection/dump on crash */ diff --git a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h index 377931ecf6f3..665999423f11 100644 --- a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h +++ b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #if !defined(_IPA_REG_DUMP_H_) #define _IPA_REG_DUMP_H_ @@ -242,18 +243,33 @@ struct map_src_dst_addr_s { #define IPA_REG_SAVE_GSI_VER(reg_name, var_name) \ { GEN_1xVECTOR_REG_OFST(reg_name, 0), \ (u32 *)&ipa_reg_save.gsi.gen.var_name } + + + /* * Macro to define a particular register cfg entry for all 3 EE * indexed register */ + + +#ifdef CONFIG_IPA3_APPS_REGDUMP + +#define IPA_REG_SAVE_CFG_ENTRY_GEN_EE(reg_name, var_name) \ + { GEN_1xVECTOR_REG_OFST(reg_name, IPA_HW_A7_EE), \ + (u32 *)&ipa_reg_save.ipa.gen_ee[IPA_HW_A7_EE].var_name } + +#else + #define IPA_REG_SAVE_CFG_ENTRY_GEN_EE(reg_name, var_name) \ - { GEN_1xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE), \ - (u32 *)&ipa_reg_save.ipa.gen_ee[IPA_HW_Q6_EE].var_name }, \ { GEN_1xVECTOR_REG_OFST(reg_name, IPA_HW_A7_EE), \ (u32 *)&ipa_reg_save.ipa.gen_ee[IPA_HW_A7_EE].var_name }, \ + { GEN_1xVECTOR_REG_OFST(reg_name, IPA_HW_Q6_EE), \ + (u32 *)&ipa_reg_save.ipa.gen_ee[IPA_HW_Q6_EE].var_name }, \ { GEN_1xVECTOR_REG_OFST(reg_name, IPA_HW_HWP_EE), \ (u32 *)&ipa_reg_save.ipa.gen_ee[IPA_HW_HWP_EE].var_name } +#endif /* CONFIG_IPA3_APPS_REGDUMP */ + #define IPA_REG_SAVE_CFG_ENTRY_GSI_FIFO(reg_name, var_name, index) \ { GEN_SCALER_REG_OFST(reg_name), \ (u32 *)&ipa_reg_save.ipa.gsi_fifo_status[index].var_name } @@ -1115,6 +1131,9 @@ struct ipa_reg_save_gsi_ch_cntxt_s { a7[IPA_HW_REG_SAVE_GSI_NUM_CH_CNTXT_A7]; struct ipa_reg_save_gsi_ch_cntxt_per_ep_s uc[IPA_HW_REG_SAVE_GSI_NUM_CH_CNTXT_UC]; + struct ipa_reg_save_gsi_ch_cntxt_per_ep_s + q6[IPA_HW_REG_SAVE_GSI_NUM_CH_CNTXT_Q6]; + }; /* GSI Event Context register save top level data struct */ @@ -1123,6 +1142,9 @@ struct ipa_reg_save_gsi_evt_cntxt_s { a7[IPA_HW_REG_SAVE_GSI_NUM_EVT_CNTXT_A7]; struct ipa_reg_save_gsi_evt_cntxt_per_ep_s uc[IPA_HW_REG_SAVE_GSI_NUM_EVT_CNTXT_UC]; + struct ipa_reg_save_gsi_evt_cntxt_per_ep_s + q6[IPA_HW_REG_SAVE_GSI_NUM_EVT_CNTXT_Q6]; + }; /* Top level IPA register save data struct */ From 2a2981c64345b48f00b3160d8bd99a6aae03bae4 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Thu, 23 Dec 2021 00:06:59 +0530 Subject: [PATCH 23/33] msm: ipa3: Deepsleep enable changes Adding support to deepsleep scenario. Change-Id: I2b388396cf9a7f26f77bbcd49c1014e16475a980 --- drivers/platform/msm/gsi/gsi.c | 3 +- drivers/platform/msm/ipa/ipa_v3/ipa.c | 134 +++++++++++++++++- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 7 + drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 4 +- drivers/platform/msm/ipa/ipa_v3/ipa_rt.c | 2 +- drivers/platform/msm/ipa/ipa_v3/ipa_uc.c | 11 ++ drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 18 +++ drivers/platform/msm/ipa/ipa_v3/teth_bridge.c | 5 + 8 files changed, 176 insertions(+), 8 deletions(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index b70eed7d647c..7d75084783e0 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -1482,8 +1482,7 @@ int gsi_deregister_device(unsigned long dev_hdl, bool force) devm_free_irq(gsi_ctx->dev, gsi_ctx->per.irq, gsi_ctx); gsi_unmap_base(); - memset(gsi_ctx, 0, sizeof(*gsi_ctx)); - + gsi_ctx->per_registered = false; return GSI_STATUS_SUCCESS; } EXPORT_SYMBOL(gsi_deregister_device); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 514ad94e3e5d..c075241f093a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef CONFIG_ARM64 @@ -124,6 +125,11 @@ static void ipa_gsi_notify_cb(struct gsi_per_notify *notify); static int ipa3_attach_to_smmu(void); static int ipa3_alloc_pkt_init(void); +#ifdef CONFIG_DEEPSLEEP +static void ipa3_deepsleep_resume(void); +static void ipa3_deepsleep_suspend(void); +#endif + static void ipa3_load_ipa_fw(struct work_struct *work); static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw); static DECLARE_DELAYED_WORK(ipa3_fw_load_failure_handle, ipa3_load_ipa_fw); @@ -438,6 +444,38 @@ int ipa_smmu_free_sgt(struct sg_table **out_sgt_ptr) } EXPORT_SYMBOL(ipa_smmu_free_sgt); +/** + * ipa_pm_notify() - PM notify to listen suspend events + * + * This callback will be invoked by the pm framework to suspend + * operation is invoked. + * + * Returns NOTIFY_DONE to pm framework completed operation. + */ + +static int ipa_pm_notify(struct notifier_block *b, unsigned long event, void *p) +{ + IPAERR("Entry\n"); + switch (event) { + case PM_POST_SUSPEND: +#ifdef CONFIG_DEEPSLEEP + if (mem_sleep_current == PM_SUSPEND_MEM) { + IPADBG("Enter deepsleep resume\n"); + ipa3_deepsleep_resume(); + IPADBG("Exit deepsleep resume\n"); + } +#endif + break; + } + IPAERR("Exit\n"); + return NOTIFY_DONE; +} + + +static struct notifier_block ipa_pm_notifier = { + .notifier_call = ipa_pm_notify, +}; + static const struct dev_pm_ops ipa_pm_ops = { .suspend_late = ipa3_ap_suspend, .resume_early = ipa3_ap_resume, @@ -5063,6 +5101,7 @@ static void ipa3_teardown_apps_pipes(void) __ipa3_del_rt_rule(ipa3_ctx->dflt_v4_rt_rule_hdl); __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl, false); ipa3_teardown_sys_pipe(ipa3_ctx->clnt_hdl_cmd); + ipa3_dealloc_common_event_ring(); } #ifdef CONFIG_COMPAT @@ -6317,6 +6356,12 @@ static inline void ipa3_enable_napi_lan_rx(void) napi_enable(&ipa3_ctx->napi_lan_rx); } +static inline void ipa3_disable_napi_lan_rx(void) +{ + if (ipa3_ctx->lan_rx_napi_enable) + napi_disable(&ipa3_ctx->napi_lan_rx); +} + static inline void ipa3_register_to_fmwk(void) { struct ipa_core_data data; @@ -6691,6 +6736,11 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p, IPADBG("register to fmwk\n"); ipa3_register_to_fmwk(); } + +#ifdef CONFIG_DEEPSLEEP + if (!ipa3_is_ready()) + ipa_fmwk_deepsleep_exit_ipa(); +#endif complete_all(&ipa3_ctx->init_completion_obj); ipa_ut_module_init(); @@ -6793,13 +6843,12 @@ static int ipa3_manual_load_ipa_fws(void) static int ipa3_pil_load_ipa_fws(const char *sub_sys) { - void *subsystem_get_retval = NULL; IPADBG("PIL FW loading process initiated sub_sys=%s\n", sub_sys); - subsystem_get_retval = subsystem_get(sub_sys); - if (IS_ERR_OR_NULL(subsystem_get_retval)) { + ipa3_ctx->subsystem_get_retval = subsystem_get(sub_sys); + if (IS_ERR_OR_NULL(ipa3_ctx->subsystem_get_retval)) { IPAERR("Unable to PIL load FW for sub_sys=%s\n", sub_sys); return -EINVAL; } @@ -6808,6 +6857,20 @@ static int ipa3_pil_load_ipa_fws(const char *sub_sys) return 0; } +#ifdef CONFIG_DEEPSLEEP +static int ipa3_pil_unload_ipa_fws(void) +{ + + IPADBG("PIL FW unloading process initiated sub_sys\n"); + + if (ipa3_ctx->subsystem_get_retval) + subsystem_put(ipa3_ctx->subsystem_get_retval); + + IPADBG("PIL FW unloading process is complete sub_sys\n"); + return 0; +} +#endif + static void ipa3_load_ipa_fw(struct work_struct *work) { int result; @@ -9513,7 +9576,8 @@ int ipa3_ap_suspend(struct device *dev) int i; IPADBG("Enter...\n"); - + if (!of_device_is_compatible(dev->of_node,"qcom,ipa")) + return 0; /* In case there is a tx/rx handler in polling mode fail to suspend */ for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++) { if (ipa3_ctx->ep[i].sys && @@ -9524,6 +9588,13 @@ int ipa3_ap_suspend(struct device *dev) } } +#ifdef CONFIG_DEEPSLEEP + if (mem_sleep_current == PM_SUSPEND_MEM) { + IPADBG("Enter deepsleep suspend\n"); + ipa3_deepsleep_suspend(); + IPADBG("Exit deepsleep suspend\n"); + } +#endif ipa_pm_deactivate_all_deferred(); IPADBG("Exit\n"); @@ -9556,6 +9627,58 @@ bool ipa3_get_lan_rx_napi(void) return ipa3_ctx->lan_rx_napi_enable; } + +#ifdef CONFIG_DEEPSLEEP +static void ipa3_deepsleep_suspend(void) +{ + IPADBG("Entry\n"); + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); + + /* To allow default routing table delection using this flag */ + ipa3_ctx->deepsleep = true; + /*Disabling the LAN NAPI*/ + ipa3_disable_napi_lan_rx(); + /*NOt allow uC related operations until uC load again*/ + ipa3_ctx->uc_ctx.uc_loaded = false; + /*Disconnecting LAN PROD/LAN CONS/CMD PROD apps pipes*/ + ipa3_teardown_apps_pipes(); + /*Deregistering the GSI driver*/ + gsi_deregister_device(ipa3_ctx->gsi_dev_hdl, false); + /*Destroying filter table ids*/ + ipa3_destroy_flt_tbl_idrs(); + /*Disabling IPA interrupt*/ + ipa3_remove_interrupt_handler(IPA_TX_SUSPEND_IRQ); + ipa3_interrupts_destroy(ipa3_res.ipa_irq, &ipa3_ctx->master_pdev->dev); + /*Destroy the NAT device*/ + ipa3_nat_ipv6ct_destroy_devices(); + /*Freeing memory allocated for coalesing and dma task*/ + ipa3_free_coal_close_frame(); + ipa3_free_dma_task_for_gsi(); + /*Destroying ipa hal module*/ + ipahal_destroy(); + ipa3_ctx->ipa_initialization_complete = false; + ipa3_debugfs_remove(); + /*Unloading IPA FW to allow FW load in resume*/ + ipa3_pil_unload_ipa_fws(); + /*Calling framework API to reset IPA ready flag to false*/ + ipa_fmwk_deepsleep_entry_ipa(); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + IPADBG("Exit\n"); +} + +static void ipa3_deepsleep_resume(void) +{ + + IPADBG("Entry\n"); + /*After deeplseep exit we shouldn't allow delete the default routing table*/ + ipa3_ctx->deepsleep = false; + /*Scheduling WQ to load IPA FW*/ + queue_work(ipa3_ctx->transport_power_mgmt_wq, + &ipa3_fw_loading_work); + IPADBG("Exit\n"); +} +#endif + static void ipa_gsi_notify_cb(struct gsi_per_notify *notify) { /* @@ -9985,6 +10108,8 @@ static int __init ipa_module_init(void) /* Register as a PCI device driver */ return pci_register_driver(&ipa_pci_driver); } + + register_pm_notifier(&ipa_pm_notifier); /* Register as a platform device driver */ return platform_driver_register(&ipa_plat_drv); } @@ -9995,6 +10120,7 @@ static void __exit ipa_module_exit(void) if (running_emulation) pci_unregister_driver(&ipa_pci_driver); platform_driver_unregister(&ipa_plat_drv); + unregister_pm_notifier(&ipa_pm_notifier); kfree(ipa3_ctx); ipa3_ctx = NULL; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 83e65d8799e0..b4a4c22b8abb 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -4741,6 +4741,13 @@ static void ipa_dma_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) } } +void ipa3_dealloc_common_event_ring(void) +{ + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); + gsi_dealloc_evt_ring(ipa3_ctx->gsi_evt_comm_hdl); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); +} + int ipa3_alloc_common_event_ring(void) { struct gsi_evt_ring_props gsi_evt_ring_props; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index ed025daa26ba..71d0822f25ea 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2125,6 +2125,8 @@ struct ipa3_context { bool (*get_teth_port_state[IPA_MAX_CLNT])(void); atomic_t is_ssr; + bool deepsleep; + void *subsystem_get_retval; struct IpaHwOffloadStatsAllocCmdData_t gsi_info[IPA_HW_PROTOCOL_MAX]; bool ipa_wan_skb_page; @@ -2506,7 +2508,6 @@ int ipa3_start_stop_client_prod_gsi_chnl(enum ipa_client_type client, bool start_chnl); void ipa3_client_prod_post_shutdown_cleanup(void); - int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset, u32 tmr_val, enum ipa_client_type client); @@ -3124,6 +3125,7 @@ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats); struct dentry *ipa_debugfs_get_root(void); void ipa3_enable_dcd(void); void ipa3_disable_prefetch(enum ipa_client_type client); +void ipa3_dealloc_common_event_ring(void); int ipa3_alloc_common_event_ring(void); int ipa3_allocate_dma_task_for_gsi(void); void ipa3_free_dma_task_for_gsi(void); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c index 81a4573b68f2..8c21090ffdab 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c @@ -1753,7 +1753,7 @@ int __ipa3_del_rt_rule(u32 rule_hdl) !strcmp(entry->tbl->name, IPA_DFLT_RT_TBL_NAME)) { IPADBG("Deleting rule from default rt table idx=%u\n", entry->tbl->idx); - if (entry->tbl->rule_cnt == 1) { + if (entry->tbl->rule_cnt == 1 && !ipa3_ctx->deepsleep) { IPAERR_RL("Default tbl last rule cannot be deleted\n"); return -EINVAL; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c index 4200d188284c..96a73878b3ba 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c @@ -1113,6 +1113,17 @@ remap_fail: return result; } +void ipa3_uc_interface_destroy(void) +{ + if(ipa3_ctx->uc_ctx.uc_inited) { + ipa3_remove_interrupt_handler(IPA_UC_IRQ_2); + ipa3_remove_interrupt_handler(IPA_UC_IRQ_1); + ipa3_remove_interrupt_handler(IPA_UC_IRQ_0); + iounmap(ipa3_ctx->uc_ctx.uc_sram_mmio); + ipa3_ctx->uc_ctx.uc_inited = false; + } +} + /** * ipa3_uc_send_cmd() - Send a command to the uC * diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index d14a04e22540..96623321bbe5 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -2991,6 +2991,13 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, break; #if IS_ENABLED(CONFIG_DEEPSLEEP) case SUBSYS_AFTER_DS_ENTRY: + IPAWANINFO("IPA Received AFTER DEEPSLEEP ENTRY\n"); + if (atomic_read(&rmnet_ipa3_ctx->is_ssr) && + ipa3_ctx_get_type(IPA_HW_TYPE) < IPA_HW_v4_0) + ipa3_q6_post_shutdown_cleanup(); + + IPAWANINFO("AFTER DEEPSLEEP ENTRY handling is complete\n"); + break; #endif case SUBSYS_AFTER_SHUTDOWN: IPAWANINFO("IPA Received MPSS AFTER_SHUTDOWN\n"); @@ -3005,6 +3012,17 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, break; #if IS_ENABLED(CONFIG_DEEPSLEEP) case SUBSYS_BEFORE_DS_EXIT: + IPAWANINFO("IPA received BEFORE DEEPSLEEP EXIT\n"); + if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) { + /* clean up cached QMI msg/handlers */ + ipa3_qmi_service_exit(); + ipa3_q6_pre_powerup_cleanup(); + } + /* hold a proxy vote for the modem. */ + ipa3_proxy_clk_vote(atomic_read(&rmnet_ipa3_ctx->is_ssr)); + ipa3_reset_freeze_vote(); + IPAWANINFO("BEFORE DEEPSLEEP EXIT handling is complete\n"); + break; #endif case SUBSYS_BEFORE_POWERUP: IPAWANINFO("IPA received MPSS BEFORE_POWERUP\n"); diff --git a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c index 24f24c908667..965609bb4c56 100644 --- a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c +++ b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c @@ -215,6 +215,11 @@ int ipa3_teth_bridge_driver_init(void) { int res; + if(ipa3_teth_ctx) { + TETH_DBG("Tethering bridge already initlized\n"); + return 0; + } + TETH_DBG("Tethering bridge driver init\n"); ipa3_teth_ctx = kzalloc(sizeof(*ipa3_teth_ctx), GFP_KERNEL); if (!ipa3_teth_ctx) From fd9b8800345c5b597af34e315cbf7abc9f437327 Mon Sep 17 00:00:00 2001 From: Srikanth Vakiti Date: Sat, 8 Jan 2022 17:37:04 +0530 Subject: [PATCH 24/33] msm: ipa3: Disable of ODL offload checksum ODL endpipe offload checksum disabled Change-Id: I889bdea3ff6287188292ca17aa3df9b579a4fa8e Signed-off-by: Vakiti Srikanth --- drivers/platform/msm/ipa/ipa_v3/ipa_odl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c b/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c index 0f3f4979e95b..ba2686809ebe 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_odl.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "ipa_i.h" @@ -284,7 +285,7 @@ int ipa_setup_odl_pipe(void) ipa_odl_ep_cfg = &ipa3_odl_ctx->odl_sys_param; IPADBG("Setting up the odl endpoint\n"); - ipa_odl_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en = IPA_ENABLE_CS_OFFLOAD_DL; + ipa_odl_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en = IPA_DISABLE_CS_OFFLOAD; ipa_odl_ep_cfg->ipa_ep_cfg.aggr.aggr_en = IPA_ENABLE_AGGR; ipa_odl_ep_cfg->ipa_ep_cfg.aggr.aggr_hard_byte_limit_en = 1; From 7705d29b41aff303e270caf1ece216c8dc20ede9 Mon Sep 17 00:00:00 2001 From: Raghavendar rao l Date: Mon, 24 Jan 2022 18:13:00 +0530 Subject: [PATCH 25/33] msm: ipa3: Fix to avoid the boot up crash in non smmu targets Updated change to perform ipa pre initialization even before attempting to load the ipa firmware along with pdev node initialization for non smmu target. Change-Id: I04421c1f11f0c7b4d7a0f30135741946b157aa2c Signed-off-by: Raghavendar rao l --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index c075241f093a..cdd6e54f4249 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -9538,7 +9538,17 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p) return -EOPNOTSUPP; } } + /* Below update of pre init for non smmu device, As + * existing flow initialzies only for smmu + * enabled node.*/ + + result = ipa3_pre_init(&ipa3_res, pdev_p); + if (result) { + IPAERR("ipa3_init failed\n"); + return result; + } ipa_fw_load_sm_handle_event(IPA_FW_LOAD_EVNT_SMMU_DONE); + goto skip_repeat_pre_init; } /* Proceed to real initialization */ @@ -9548,6 +9558,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p) return result; } +skip_repeat_pre_init: result = of_platform_populate(pdev_p->dev.of_node, ipa_plat_drv_match, NULL, &pdev_p->dev); if (result) { From fd9586ccafacce8b742e2114f21e5e07229190d5 Mon Sep 17 00:00:00 2001 From: Himansu Nayak Date: Mon, 31 Jan 2022 08:07:32 +0530 Subject: [PATCH 26/33] msm: ipa3: Fix to validate the NAT table entries during NAT table init During NAT table Initialization parameter pass from HLOS, if max/zero table entries passed it was leading to out of bound read. Adding checks to validate the table entries before passing to NAT table parameter. Signed-off-by: Himansu Nayak --- drivers/platform/msm/ipa/ipa_v3/ipa_nat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c index 8ced02501f84..3c24d13e7c76 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c @@ -1366,8 +1366,9 @@ int ipa3_nat_init_cmd( goto bail; } - if (init->table_entries == 0) { - IPAERR_RL("Table entries is zero\n"); + if (init->table_entries == 0 || + init->table_entries == U16_MAX) { + IPAERR_RL("Table entries is %d\n", init->table_entries); result = -EPERM; goto bail; } From dc1c1a22525b5296de774e460a33af83e79bae8b Mon Sep 17 00:00:00 2001 From: Jagadeesh Ponduru Date: Mon, 31 Jan 2022 12:26:57 +0530 Subject: [PATCH 27/33] msm: ipa3: Disable gsi fifo and test bus registers Update change to disable gsi fifo and gsi test bus registers as these cannot be accessed through IPA_AP. Change-Id: Icd7c85101a8997eff08acc98dbc1ead7b6067c81 Signed-off-by: Jagadeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c index a81bfb204cc0..78aab2747854 100644 --- a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c +++ b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c @@ -735,7 +735,9 @@ static struct map_src_dst_addr_s ipa_uc_regs_to_save_array[] = { }; static void ipa_hal_save_regs_save_ipa_testbus(void); +#ifndef CONFIG_IPA3_APPS_REGDUMP static void ipa_reg_save_gsi_fifo_status(void); +#endif /* CONFIG_IPA3_APPS_REGDUMP */ static void ipa_reg_save_rsrc_cnts(void); static void ipa_hal_save_regs_ipa_cmdq(void); static void ipa_hal_save_regs_rsrc_db(void); @@ -865,9 +867,10 @@ void ipa_save_registers(void) num_regs += (CONFIG_IPA3_REGDUMP_NUM_EXTRA_ENDP_REGS * IPA_REG_SAVE_NUM_EXTRA_ENDP_REGS); +#ifndef CONFIG_IPA3_APPS_REGDUMP /* Saving GSI FIFO Status registers */ ipa_reg_save_gsi_fifo_status(); - +#endif /* CONFIG_IPA3_APPS_REGDUMP */ /* * On targets that support SSR, we generally want to disable * the following reg save functionality as it may cause stalls @@ -896,6 +899,7 @@ void ipa_save_registers(void) } /* GSI test bus */ +#ifndef CONFIG_IPA3_APPS_REGDUMP for (i = 0; i < ARRAY_SIZE(ipa_reg_save_gsi_ch_test_bus_selector_array); i++) { @@ -911,6 +915,7 @@ void ipa_save_registers(void) i].gsi_testbus_reg = (u32) IPA_READ_SCALER_REG(GSI_TEST_BUS_REG); } +#endif /* CONFIG_IPA3_APPS_REGDUMP */ ipa_reg_save_rsrc_cnts(); @@ -1067,6 +1072,7 @@ void ipa_save_registers(void) * * @return */ +#ifndef CONFIG_IPA3_APPS_REGDUMP static void ipa_reg_save_gsi_fifo_status(void) { union ipa_hwio_def_ipa_gsi_fifo_status_ctrl_u gsi_fifo_status_ctrl; @@ -1089,7 +1095,7 @@ static void ipa_reg_save_gsi_fifo_status(void) IPA_READ_SCALER_REG(IPA_GSI_AOS_FIFO_STATUS); } } - +#endif /* CONFIG_IPA3_APPS_REGDUMP */ /* * FUNCTION: ipa_reg_save_rsrc_cnts * From 3b56c6e41a16243d59228b7e3fcf8876daa0a5cc Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Thu, 3 Feb 2022 21:47:05 +0530 Subject: [PATCH 28/33] msm: ipa3: Changes to resume only suspend operation complete In suspend abort scenario before receving suspend callback and resume it again causing issues. To avoid this scenario only if suspend completed doing resume operation. Change-Id: I0cf08b4e9ab4f74c44d4bcb14f9472b8332b5f7b --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index cdd6e54f4249..a0ca7bd1697f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -459,7 +459,7 @@ static int ipa_pm_notify(struct notifier_block *b, unsigned long event, void *p) switch (event) { case PM_POST_SUSPEND: #ifdef CONFIG_DEEPSLEEP - if (mem_sleep_current == PM_SUSPEND_MEM) { + if (mem_sleep_current == PM_SUSPEND_MEM && ipa3_ctx->deepsleep) { IPADBG("Enter deepsleep resume\n"); ipa3_deepsleep_resume(); IPADBG("Exit deepsleep resume\n"); From 1024d06f3ff5c305c5ad81af899681c5cdba29c7 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Thu, 17 Mar 2022 18:43:30 +0530 Subject: [PATCH 29/33] msm: ipa3: In deep sleep scenario destroy/ reinitialize uC interrupts In deep sleep suspend/resume scenario destroy the uC interrupts in suspend and reinitialize the interrupts in resume Change-Id: Ib3631cef8e1e78651b6b79aef7f3d65dae0411c2 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 1 + drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 1 + drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index a0ca7bd1697f..b95f98e5da48 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -9660,6 +9660,7 @@ static void ipa3_deepsleep_suspend(void) /*Disabling IPA interrupt*/ ipa3_remove_interrupt_handler(IPA_TX_SUSPEND_IRQ); ipa3_interrupts_destroy(ipa3_res.ipa_irq, &ipa3_ctx->master_pdev->dev); + ipa3_uc_interface_destroy(); /*Destroy the NAT device*/ ipa3_nat_ipv6ct_destroy_devices(); /*Freeing memory allocated for coalesing and dma task*/ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 4267d36c54f2..10a4650c7335 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2978,6 +2978,7 @@ int ipa3_uc_send_cmd(u32 cmd, u32 opcode, u32 expected_status, void ipa3_uc_register_handlers(enum ipa3_hw_features feature, struct ipa3_uc_hdlrs *hdlrs); int ipa3_uc_notify_clk_state(bool enabled); +void ipa3_uc_interface_destroy(void); int ipa3_dma_setup(void); void ipa3_dma_shutdown(void); void ipa3_dma_async_memcpy_notify_cb(void *priv, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c b/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c index d52a80003b2d..a51c34fb27cd 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c @@ -454,7 +454,9 @@ int ipa3_remove_interrupt_handler(enum ipa_irq_type interrupt) return -EFAULT; } - kfree(ipa_interrupt_to_cb[irq_num].private_data); + /*If free ipa3_ctx pointer causing device crash during remove interrupt*/ + if(ipa_interrupt_to_cb[irq_num].private_data != ipa3_ctx) + kfree(ipa_interrupt_to_cb[irq_num].private_data); ipa_interrupt_to_cb[irq_num].deferred_flag = false; ipa_interrupt_to_cb[irq_num].handler = NULL; ipa_interrupt_to_cb[irq_num].private_data = NULL; From 8aa0d102d81fb2632ce988fcc8d816e7fed7b5b1 Mon Sep 17 00:00:00 2001 From: Cheng Zeng Date: Thu, 24 Mar 2022 16:09:28 +0800 Subject: [PATCH 30/33] msm: gsi: Fix the incorrect evt ring pointer The pointer should be event ring pointer, not transfer ring pointer, it has chance to get wrong upper 32 bits when smmu is disabled. Signed-off-by: Cheng Zeng --- drivers/platform/msm/gsi/gsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 7d75084783e0..2ae33a7bbb2a 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -4057,7 +4057,7 @@ int gsi_poll_n_channel(unsigned long chan_hdl, /* update rp to see of we have anything new to process */ rp = ctx->evtr->props.gsi_read_event_ring_rp( &ctx->evtr->props, ctx->evtr->id, ee); - rp |= ctx->ring.rp & 0xFFFFFFFF00000000ULL; + rp |= ctx->evtr->ring.rp & 0xFFFFFFFF00000000ULL; ctx->evtr->ring.rp = rp; /* read gsi event ring rp again if last read is empty */ @@ -4069,7 +4069,7 @@ int gsi_poll_n_channel(unsigned long chan_hdl, __iowmb(); rp = ctx->evtr->props.gsi_read_event_ring_rp( &ctx->evtr->props, ctx->evtr->id, ee); - rp |= ctx->ring.rp & 0xFFFFFFFF00000000ULL; + rp |= ctx->evtr->ring.rp & 0xFFFFFFFF00000000ULL; ctx->evtr->ring.rp = rp; if (rp == ctx->evtr->ring.rp_local) { spin_unlock_irqrestore( From c36b185506b020fde547a7998990a923af132c4f Mon Sep 17 00:00:00 2001 From: Vinayaka B M Date: Fri, 22 Apr 2022 08:02:54 +0530 Subject: [PATCH 31/33] msm: ipa: Set the logbuf NULL after destroy Set the ipa3_ctx->logbuf NULL after destroy,or IPAERR will use the ipa3_ctx->logbuf after free it, that can make crash Change-Id: I470c4a043d426d7620c01fadac1f1cd12ad54b08 --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index b95f98e5da48..c0d813316098 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -7947,8 +7947,10 @@ fail_mem_ctrl: kfree(ipa3_ctx->ipa_tz_unlock_reg); ipa3_ctx->ipa_tz_unlock_reg = NULL; fail_tz_unlock_reg: - if (ipa3_ctx->logbuf) + if (ipa3_ctx->logbuf) { ipc_log_context_destroy(ipa3_ctx->logbuf); + ipa3_ctx->logbuf = NULL; + } fail_uc_file_alloc: kfree(ipa3_ctx->gsi_fw_file_name); ipa3_ctx->gsi_fw_file_name = NULL; From 9c3cb3f994df6753804a868739fda1eb51417658 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Fri, 15 Apr 2022 11:46:09 +0530 Subject: [PATCH 32/33] msm: ipa3: Reduce the QMI timeout value to avoid race condition In SSR scenario if QMI response delayed SSR events getting timeout, To avoid this issue reduce the QMI timeout value from 60sec to 10sec. Change-Id: Ib0113a91f9bd60b3ea0e374bf249d4859a22a040 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index ae02f21d11de..1ae4f5699f29 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -27,7 +27,7 @@ #define IPA_Q6_SERVICE_INS_ID 2 #define QMI_SEND_STATS_REQ_TIMEOUT_MS 5000 -#define QMI_SEND_REQ_TIMEOUT_MS 60000 +#define QMI_SEND_REQ_TIMEOUT_MS 10000 #define QMI_MHI_SEND_REQ_TIMEOUT_MS 1000 #define QMI_IPA_FORCE_CLEAR_DATAPATH_TIMEOUT_MS 1000 From 1a79536d0ec22a533b8fcb99dd53e9cc32d0cd1f Mon Sep 17 00:00:00 2001 From: Raghavendar rao l Date: Mon, 14 Mar 2022 20:19:10 +0530 Subject: [PATCH 33/33] msm: ipa3: Handle race condition to avoid NULL access Updated change to avoid race condition and NULL pointer access, In case of SSR and ioctl call while performing QMI transaction. Change-Id: I09dbf33d76a3a0d9e4917e62aaf1257a1abe2db9 Signed-off-by: Raghavendar rao l --- .../platform/msm/ipa/ipa_v3/ipa_qmi_service.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index ae02f21d11de..df60c8e59f12 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -467,14 +467,22 @@ static int ipa3_qmi_send_req_wait(struct qmi_handle *client_handle, struct qmi_txn txn; int ret; + mutex_lock(&ipa3_qmi_lock); + + if (!client_handle) { + + mutex_unlock(&ipa3_qmi_lock); + return -EINVAL; + } + ret = qmi_txn_init(client_handle, &txn, resp_desc->ei_array, resp); if (ret < 0) { IPAWANERR("QMI txn init failed, ret= %d\n", ret); + mutex_unlock(&ipa3_qmi_lock); return ret; } - mutex_lock(&ipa3_qmi_lock); ret = qmi_send_request(client_handle, &ipa3_qmi_ctx->server_sq, &txn, @@ -483,19 +491,16 @@ static int ipa3_qmi_send_req_wait(struct qmi_handle *client_handle, req_desc->ei_array, req); - if (unlikely(!ipa_q6_clnt)) { - mutex_unlock(&ipa3_qmi_lock); - return -EINVAL; - } - mutex_unlock(&ipa3_qmi_lock); if (ret < 0) { qmi_txn_cancel(&txn); + mutex_unlock(&ipa3_qmi_lock); return ret; } - ret = qmi_txn_wait(&txn, msecs_to_jiffies(timeout_ms)); + ret = qmi_txn_wait(&txn, msecs_to_jiffies(timeout_ms)); + mutex_unlock(&ipa3_qmi_lock); return ret; }