Merge 9c90eafb19 on remote branch

Change-Id: Iee486b1c93bc29d3ed1fbd303e43895ab8ee1c10
This commit is contained in:
Linux Build Service Account 2022-02-11 01:27:15 -08:00
commit 39d40ad45e
19 changed files with 466 additions and 49 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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),
@ -707,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);
@ -837,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
@ -868,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++) {
@ -883,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();
@ -1039,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;
@ -1061,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
*
@ -1490,7 +1524,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 */

View file

@ -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 */

View file

@ -41,6 +41,7 @@
#include <linux/jiffies.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/suspend.h>
#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;
@ -9475,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 */
@ -9485,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) {
@ -9513,7 +9587,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 +9599,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 +9638,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 +10119,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 +10131,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;
}

View file

@ -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;

View file

@ -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;
@ -4741,6 +4765,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;

View file

@ -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,

View file

@ -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 */
@ -2125,6 +2128,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 +2511,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 +3128,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);

View file

@ -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;
}

View file

@ -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;
@ -366,6 +367,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;

View file

@ -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;
}

View file

@ -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
*

View file

@ -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");

View file

@ -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)