diff --git a/config/dataipa_gsi_V1.h b/config/dataipa_gsi_V1.h new file mode 100644 index 000000000000..883e6b8c6e9c --- /dev/null +++ b/config/dataipa_gsi_V1.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Copyright (c) 2020, The Linux Foundation. All rights reserved. +*/ + +#define CONFIG_GSI 1 +#define CONFIG_RMNET_IPA3 1 +#define CONFIG_RNDIS_IPA 1 +#define CONFIG_IPA_WDI_UNIFIED_API 1 diff --git a/config/dataipa_gsi_V1_GKI.conf b/config/dataipa_gsi_V1_GKI.conf new file mode 100644 index 000000000000..075a7198f28b --- /dev/null +++ b/config/dataipa_gsi_V1_GKI.conf @@ -0,0 +1,5 @@ +export CONFIG_GSI=m +export CONFIG_IPA_CLIENTS_MANAGER=m +export CONFIG_IPA_WDI_UNIFIED_API=y +export CONFIG_RMNET_IPA3=y +export CONFIG_RNDIS_IPA=m diff --git a/config/dataipa_gsi_V1_QGKI.conf b/config/dataipa_gsi_V1_QGKI.conf new file mode 100644 index 000000000000..14c5fa85fb3f --- /dev/null +++ b/config/dataipa_gsi_V1_QGKI.conf @@ -0,0 +1,5 @@ +export CONFIG_GSI=y +export CONFIG_IPA_CLIENTS_MANAGER=y +export CONFIG_IPA_WDI_UNIFIED_API=y +export CONFIG_RMNET_IPA3=y +export CONFIG_RNDIS_IPA=y diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile index dff2077aacc2..378e128dfd55 100644 --- a/drivers/platform/msm/Makefile +++ b/drivers/platform/msm/Makefile @@ -26,6 +26,19 @@ include $(srctree)/techpack/dataipa/config/dataipa_GKI.conf endif endif +ifeq ($(CONFIG_QTI_QUIN_GVM),y) +LINUXINCLUDE += -include $(srctree)/techpack/dataipa/config/dataipa_gsi_V1.h +ifeq ($(CONFIG_QGKI),y) +include $(srctree)/techpack/dataipa/config/dataipa_gsi_V1_QGKI.conf +ifeq ($(CONFIG_LOCALVERSION), "-qgki-debug") +include $(srctree)/techpack/dataipa/config/dataipa_debug.conf +LINUXINCLUDE += -include $(srctree)/techpack/dataipa/config/dataipa_debug.h +endif +else +include $(srctree)/techpack/dataipa/config/dataipa_gsi_V1_GKI.conf +endif +endif + DATAIPADRVTOP = $(srctree)/techpack/dataipa/drivers/platform/msm ifneq (,$(filter $(CONFIG_IPA3),y m)) diff --git a/drivers/platform/msm/gsi/gsi_reg_v1.h b/drivers/platform/msm/gsi/gsi_reg_v1.h index 680a2c1490d3..af3bc598ad7d 100644 --- a/drivers/platform/msm/gsi/gsi_reg_v1.h +++ b/drivers/platform/msm/gsi/gsi_reg_v1.h @@ -442,6 +442,8 @@ #define GSI_V2_2_GSI_INST_RAM_n_MAXn 4095 #define GSI_V2_5_GSI_INST_RAM_n_MAXn 8191 #define GSI_V2_7_GSI_INST_RAM_n_MAXn 5119 +#define GSI_V2_9_GSI_INST_RAM_n_MAXn 6143 +#define GSI_V2_11_GSI_INST_RAM_n_MAXn 5119 #define GSI_GSI_INST_RAM_n_INST_BYTE_3_BMSK 0xff000000 #define GSI_GSI_INST_RAM_n_INST_BYTE_3_SHFT 0x18 @@ -476,6 +478,11 @@ #define GSI_EE_n_GSI_CH_k_CNTXT_1_R_LENGTH_BMSK 0xffff #define GSI_EE_n_GSI_CH_k_CNTXT_1_R_LENGTH_SHFT 0x0 +#define GSI_V2_9_EE_n_GSI_CH_k_CNTXT_1_OFFS(k, n) \ + (GSI_GSI_REG_BASE_OFFS + 0x0000f004 + 0x4000 * (n) + 0x80 * (k)) +#define GSI_V2_9_EE_n_GSI_CH_k_CNTXT_1_R_LENGTH_BMSK 0xfffff +#define GSI_V2_9_EE_n_GSI_CH_k_CNTXT_1_R_LENGTH_SHFT 0x0 + #define GSI_EE_n_GSI_CH_k_CNTXT_2_OFFS(k, n) \ (GSI_GSI_REG_BASE_OFFS + 0x0001c008 + 0x4000 * (n) + 0x80 * (k)) #define GSI_EE_n_GSI_CH_k_CNTXT_2_R_BASE_ADDR_LSBS_BMSK 0xffffffff @@ -549,6 +556,20 @@ #define GSI_V2_5_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_BMSK 0xf #define GSI_V2_5_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_SHFT 0x0 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_OFFS(k, n) \ + (GSI_GSI_REG_BASE_OFFS + 0x0000f05c + 0x4000 * (n) + 0x80 * (k)) +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_DB_IN_BYTES_BMSK 0x1000000 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_DB_IN_BYTES_SHFT 0x18 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_EMPTY_LVL_THRSHOLD_BMSK 0xff0000 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_EMPTY_LVL_THRSHOLD_SHFT 0x10 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_PREFETCH_MODE_BMSK 0x3c00 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_PREFETCH_MODE_SHFT 0xa +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_USE_DB_ENG_BMSK 0x200 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_USE_DB_ENG_SHFT 0x9 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_BMSK 0x100 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_SHFT 0x8 +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_BMSK 0xf +#define GSI_V2_9_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_SHFT 0x0 #define GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(k, n) \ (GSI_GSI_REG_BASE_OFFS + 0x0001c060 + 0x4000 * (n) + 0x80 * (k)) @@ -590,6 +611,11 @@ #define GSI_EE_n_EV_CH_k_CNTXT_1_R_LENGTH_BMSK 0xffff #define GSI_EE_n_EV_CH_k_CNTXT_1_R_LENGTH_SHFT 0x0 +#define GSI_V2_9_EE_n_EV_CH_k_CNTXT_1_OFFS(k, n) \ + (GSI_GSI_REG_BASE_OFFS + 0x00010004 + 0x4000 * (n) + 0x80 * (k)) +#define GSI_V2_9_EE_n_EV_CH_k_CNTXT_1_R_LENGTH_BMSK 0xfffff +#define GSI_V2_9_EE_n_EV_CH_k_CNTXT_1_R_LENGTH_SHFT 0x0 + #define GSI_EE_n_EV_CH_k_CNTXT_2_OFFS(k, n) \ (GSI_GSI_REG_BASE_OFFS + 0x0001d008 + 0x4000 * (n) + 0x80 * (k)) #define GSI_EE_n_EV_CH_k_CNTXT_2_R_BASE_ADDR_LSBS_BMSK 0xffffffff @@ -850,6 +876,110 @@ #define GSI_V2_5_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_THREE_N_HALF_KB_FVAL 0x4 #define GSI_V2_5_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_FOUR_KB_FVAL 0x5 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_OFFS(n) \ + (GSI_GSI_REG_BASE_OFFS + 0x00012040 + 0x4000 * (n)) +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_USE_INTER_EE_BMSK 0x8000 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_USE_INTER_EE_SHFT 0xf +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_USE_RD_WR_ENG_BMSK 0x4000 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_USE_RD_WR_ENG_SHFT 0xE +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_RMSK 0x7fff +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_MAXn 2 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_IOVEC_BMSK 0x38000000 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_IOVEC_SHFT 0x1b +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_SDMA_MAX_BURST_BMSK 0x7F80000 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_SDMA_MAX_BURST_SHFT 0x13 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_INT_BMSK 0x70000 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_INT_SHFT 0x10 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_USE_SDMA_BMSK 0x8000 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_USE_SDMA_SHFT 0xf +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_CH_FULL_LOGIC_BMSK 0x4000 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_CH_FULL_LOGIC_SHFT 0xe +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_CH_PEND_TRANSLATE_BMSK 0x2000 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_CH_PEND_TRANSLATE_SHFT 0xd +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_NUM_EV_PER_EE_BMSK 0x1f00 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_NUM_EV_PER_EE_SHFT 0x8 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_NUM_CH_PER_EE_BMSK 0xf8 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_NUM_CH_PER_EE_SHFT 0x3 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_BMSK 0x7 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_SHFT 0x0 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_ONE_KB_FVAL 0x0 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_TWO_KB_FVAL 0x1 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_TWO_N_HALF_KB_FVAL 0x2 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_THREE_KB_FVAL 0x3 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_THREE_N_HALF_KB_FVAL 0x4 +#define GSI_V2_7_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_FOUR_KB_FVAL 0x5 + +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_OFFS(n) \ + (GSI_GSI_REG_BASE_OFFS + 0x00012040 + 0x4000 * (n)) +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_RMSK 0xffffffff +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_MAXn 2 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_INI(n) \ + in_dword_masked(GSI_V2_9_EE_n_GSI_HW_PARAM_2_OFFS(n), \ + GSI_V2_9_EE_n_GSI_HW_PARAM_2_RMSK) +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_INMI(n, mask) \ + in_dword_masked(GSI_V2_9_EE_n_GSI_HW_PARAM_2_OFFS(n), \ + mask) +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_USE_INTER_EE_BMSK 0x80000000 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_USE_INTER_EE_SHFT 0x1f +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_USE_RD_WR_ENG_BMSK 0x40000000 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_USE_RD_WR_ENG_SHFT 0x1e +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_IOVEC_BMSK 0x38000000 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_IOVEC_SHFT 0x1b +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_SDMA_MAX_BURST_BMSK 0x7f80000 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_SDMA_MAX_BURST_SHFT 0x13 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_INT_BMSK 0x70000 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_INT_SHFT 0x10 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_USE_SDMA_BMSK 0x8000 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_USE_SDMA_SHFT 0xf +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_CH_FULL_LOGIC_BMSK 0x4000 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_CH_FULL_LOGIC_SHFT 0xe +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_CH_PEND_TRANSLATE_BMSK 0x2000 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_CH_PEND_TRANSLATE_SHFT 0xd +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_NUM_EV_PER_EE_BMSK 0x1f00 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_NUM_EV_PER_EE_SHFT 0x8 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_NUM_CH_PER_EE_BMSK 0xf8 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_NUM_CH_PER_EE_SHFT 0x3 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_BMSK 0x7 +#define GSI_V2_9_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_SHFT 0x0 + +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_OFFS(n) \ + (GSI_GSI_REG_BASE_OFFS + 0x00012040 + 0x4000 * (n)) +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_USE_INTER_EE_BMSK 0x80000000 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_USE_INTER_EE_SHFT 0x1f +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_USE_RD_WR_ENG_BMSK 0x40000000 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_USE_RD_WR_ENG_SHFT 0x1e +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_RMSK 0xffffffff +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_MAXn 2 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_IOVEC_BMSK 0x38000000 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_IOVEC_SHFT 0x1b +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_SDMA_MAX_BURST_BMSK 0x7F80000 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_SDMA_MAX_BURST_SHFT 0x13 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_INT_BMSK 0x70000 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_SDMA_N_INT_SHFT 0x10 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_USE_SDMA_BMSK 0x8000 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_USE_SDMA_SHFT 0xf +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_CH_FULL_LOGIC_BMSK 0x4000 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_CH_FULL_LOGIC_SHFT 0xe +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_CH_PEND_TRANSLATE_BMSK 0x2000 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_CH_PEND_TRANSLATE_SHFT 0xd +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_NUM_EV_PER_EE_BMSK 0x1f00 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_NUM_EV_PER_EE_SHFT 0x8 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_NUM_CH_PER_EE_BMSK 0xf8 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_NUM_CH_PER_EE_SHFT 0x3 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_BMSK 0x7 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_SHFT 0x0 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_ONE_KB_FVAL 0x0 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_TWO_KB_FVAL 0x1 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_TWO_N_HALF_KB_FVAL 0x2 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_THREE_KB_FVAL 0x3 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_THREE_N_HALF_KB_FVAL 0x4 +#define GSI_V2_11_EE_n_GSI_HW_PARAM_2_GSI_IRAM_SIZE_FOUR_KB_FVAL 0x5 +#define GSI_GSI_IRAM_PTR_MSI_DB_OFFS \ + (GSI_GSI_REG_BASE_OFFS + 0x00000414) +#define GSI_GSI_IRAM_PTR_MSI_DB_FULL_RMSK 0xfff +#define GSI_GSI_IRAM_PTR_MSI_DB_FULL_IRAM_PTR_BMSK 0xfff +#define GSI_GSI_IRAM_PTR_MSI_DB_FULL_IRAM_PTR_SHFT 0x0 + #define GSI_EE_n_GSI_SW_VERSION_OFFS(n) \ (GSI_GSI_REG_BASE_OFFS + 0x0001f044 + 0x4000 * (n)) #define GSI_EE_n_GSI_SW_VERSION_MAJOR_BMSK 0xf0000000 diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c b/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c index b96745830666..0a64d77cca27 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c @@ -126,6 +126,8 @@ static int ipa_wdi_cleanup_internal(void) struct ipa_wdi_intf_info *entry; struct ipa_wdi_intf_info *next; + ipa3_uc_dereg_rdyCB(); + /* clear interface list */ list_for_each_entry_safe(entry, next, &ipa_wdi_ctx->head_intf_list, link) { @@ -635,6 +637,12 @@ static int ipa_wdi_enable_pipes_internal(void) if (ipa_ep_idx_tx <= 0 || ipa_ep_idx_rx <= 0) return -EFAULT; + ret = ipa_pm_activate_sync(ipa_wdi_ctx->ipa_pm_hdl); + if (ret) { + IPA_WDI_ERR("fail to activate ipa pm\n"); + return -EFAULT; + } + if (ipa_wdi_ctx->wdi_version == IPA_WDI_3) { if (ipa3_enable_wdi3_pipes(ipa_ep_idx_tx, ipa_ep_idx_rx)) { IPA_WDI_ERR("fail to enable wdi pipes\n"); @@ -666,12 +674,6 @@ static int ipa_wdi_enable_pipes_internal(void) } } - ret = ipa_pm_activate_sync(ipa_wdi_ctx->ipa_pm_hdl); - if (ret) { - IPA_WDI_ERR("fail to activate ipa pm\n"); - return -EFAULT; - } - return 0; } diff --git a/drivers/platform/msm/ipa/ipa_common_i.h b/drivers/platform/msm/ipa/ipa_common_i.h index 96baecb8c50c..24b5260b4efc 100644 --- a/drivers/platform/msm/ipa/ipa_common_i.h +++ b/drivers/platform/msm/ipa/ipa_common_i.h @@ -469,10 +469,6 @@ int ipa3_connect_mhi_pipe(struct ipa_mhi_connect_params_internal *in, u32 *clnt_hdl); int ipa3_disconnect_mhi_pipe(u32 clnt_hdl); bool ipa3_mhi_stop_gsi_channel(enum ipa_client_type client); -int ipa3_qmi_enable_force_clear_datapath_send( - struct ipa_enable_force_clear_datapath_req_msg_v01 *req); -int ipa3_qmi_disable_force_clear_datapath_send( - struct ipa_disable_force_clear_datapath_req_msg_v01 *req); int ipa3_generate_tag_process(void); int ipa3_disable_sps_pipe(enum ipa_client_type client); int ipa3_mhi_reset_channel_internal(enum ipa_client_type client); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 9632851a331e..15b06c6c6af2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -35,6 +35,12 @@ #include #include #include "gsi.h" +#include +#include +#include +#include +#include +#include #ifdef CONFIG_ARM64 @@ -1866,7 +1872,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (!ipa3_is_ready()) { IPAERR("IPA not ready, waiting for init completion\n"); - wait_for_completion(&ipa3_ctx->init_completion_obj); + if (ipa3_ctx->manual_fw_load) { + if (!wait_for_completion_timeout( + &ipa3_ctx->init_completion_obj, + msecs_to_jiffies(1000))) { + IPAERR("IPA not ready, return\n"); + return -ETIME; + } + } else { + wait_for_completion(&ipa3_ctx->init_completion_obj); + } } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); @@ -5285,13 +5300,14 @@ static void ipa3_active_clients_log_mod( } if (id->type != SIMPLE) { - t = local_clock(); + t = sched_clock(); nanosec_rem = do_div(t, 1000000000) / 1000; snprintf(temp_str, IPA3_ACTIVE_CLIENTS_LOG_LINE_LEN, - inc ? "[%5lu.%06lu] ^ %s, %s: %d" : - "[%5lu.%06lu] v %s, %s: %d", + inc ? "[%5lu.%06lu] ^ %s, %s: %d cnt = %d" : + "[%5lu.%06lu] v %s, %s: %d cnt = %d", (unsigned long)t, nanosec_rem, - id->id_string, id->file, id->line); + id->id_string, id->file, id->line, + atomic_read(&ipa3_ctx->ipa3_active_clients.cnt)); ipa3_active_clients_log_insert(temp_str); } spin_unlock_irqrestore(&ipa3_ctx->ipa3_active_clients_logging.lock, @@ -7034,6 +7050,9 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, ipa3_ctx->tx_wrapper_cache_max_size = get_tx_wrapper_cache_size( resource_p->tx_wrapper_cache_max_size); ipa3_ctx->gsi_wdi_db_polling = resource_p->gsi_wdi_db_polling; + ipa3_ctx->ipa_config_is_auto = resource_p->ipa_config_is_auto; + ipa3_ctx->manual_fw_load = resource_p->manual_fw_load; + ipa3_ctx->max_num_smmu_cb = resource_p->max_num_smmu_cb; if (resource_p->gsi_fw_file_name) { ipa3_ctx->gsi_fw_file_name = @@ -7499,20 +7518,21 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, /* Create the dummy netdev for LAN RX NAPI*/ ipa3_enable_napi_netdev(); - result = ipa3_wwan_init(); - if (result) { - IPAERR(":ipa3_wwan_init err=%d\n", -result); - result = -ENODEV; - goto fail_wwan_init; - } + if (ipa3_ctx->platform_type != IPA_PLAT_TYPE_APQ) { + result = ipa3_wwan_init(); + if (result) { + IPAERR(":ipa3_wwan_init err=%d\n", -result); + result = -ENODEV; + goto fail_wwan_init; + } - result = ipa3_rmnet_ctl_init(); - if (result) { - IPAERR(":ipa3_rmnet_ctl_init err=%d\n", -result); - result = -ENODEV; - goto fail_rmnet_ctl_init; + result = ipa3_rmnet_ctl_init(); + if (result) { + IPAERR(":ipa3_rmnet_ctl_init err=%d\n", -result); + result = -ENODEV; + goto fail_rmnet_ctl_init; + } } - mutex_init(&ipa3_ctx->app_clock_vote.mutex); return 0; @@ -7828,6 +7848,10 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, ipa_drv_res->skip_ieob_mask_wa = false; ipa_drv_res->ipa_gpi_event_rp_ddr = false; ipa_drv_res->gsi_wdi_db_polling = false; + ipa_drv_res->ipa_config_is_auto = false; + ipa_drv_res->manual_fw_load = false; + ipa_drv_res->max_num_smmu_cb = IPA_SMMU_CB_MAX; + /* Get IPA HW Version */ result = of_property_read_u32(pdev->dev.of_node, "qcom,ipa-hw-ver", &ipa_drv_res->ipa_hw_type); @@ -7933,6 +7957,13 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, ipa_drv_res->ipa_wdi2 ? "True" : "False"); + ipa_drv_res->ipa_config_is_auto = + of_property_read_bool(pdev->dev.of_node, + "qcom,ipa-config-is-auto"); + IPADBG(": ipa-config-is-auto = %s\n", + ipa_drv_res->ipa_config_is_auto + ? "True" : "False"); + ipa_drv_res->ipa_wan_skb_page = of_property_read_bool(pdev->dev.of_node, "qcom,wan-use-skb-page"); @@ -8357,6 +8388,22 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, get_dts_tx_wrapper_cache_size(pdev, ipa_drv_res); + ipa_drv_res->manual_fw_load = + of_property_read_bool(pdev->dev.of_node, + "qcom,manual-fw-load"); + IPADBG(": manual-fw-load (%s)\n", + ipa_drv_res->manual_fw_load? "True" : "False"); + + result = of_property_read_u32(pdev->dev.of_node, + "qcom,max_num_smmu_cb", + &ipa_drv_res->max_num_smmu_cb); + if (result) + IPADBG(": using default max number of cb = %d\n", + ipa_drv_res->max_num_smmu_cb); + else + IPADBG(": found ipa_drv_res->max_num_smmu_cb = %d\n", + ipa_drv_res->max_num_smmu_cb); + return 0; } @@ -8862,7 +8909,8 @@ static void ipa_smmu_update_fw_loader(void) break; } } - if (i == IPA_SMMU_CB_MAX) { + if (i == IPA_SMMU_CB_MAX || + ipa3_ctx->num_smmu_cb_probed == ipa3_ctx->max_num_smmu_cb) { IPADBG("All %d CBs probed\n", IPA_SMMU_CB_MAX); ipa_fw_load_sm_handle_event(IPA_FW_LOAD_EVNT_SMMU_DONE); } @@ -8922,6 +8970,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p) cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP); cb->dev = dev; smmu_info.present[IPA_SMMU_CB_AP] = true; + ipa3_ctx->num_smmu_cb_probed++; ipa_smmu_update_fw_loader(); return 0; @@ -8935,6 +8984,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p) cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN); cb->dev = dev; smmu_info.present[IPA_SMMU_CB_WLAN] = true; + ipa3_ctx->num_smmu_cb_probed++; ipa_smmu_update_fw_loader(); return 0; @@ -8948,6 +8998,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p) cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC); cb->dev = dev; smmu_info.present[IPA_SMMU_CB_UC] = true; + ipa3_ctx->num_smmu_cb_probed++; ipa_smmu_update_fw_loader(); return 0; @@ -8961,6 +9012,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p) cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_11AD); cb->dev = dev; smmu_info.present[IPA_SMMU_CB_11AD] = true; + ipa3_ctx->num_smmu_cb_probed++; ipa_smmu_update_fw_loader(); return 0; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index df9f377adcac..4d86f9795948 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -454,6 +454,51 @@ int ipa3_smmu_map_peer_buff(u64 iova, u32 size, bool map, struct sg_table *sgt, } EXPORT_SYMBOL(ipa3_smmu_map_peer_buff); +int ipa3_smmu_map_ctg(u64 iova, u32 size, bool map, phys_addr_t pa, + enum ipa_smmu_cb_type cb_type) +{ + struct iommu_domain *smmu_domain; + int res; + phys_addr_t phys; + unsigned long va; + size_t len; + + if (cb_type >= IPA_SMMU_CB_MAX) { + IPAERR("invalid cb_type\n"); + return -EINVAL; + } + + if (ipa3_ctx->s1_bypass_arr[cb_type]) { + IPADBG("CB# %d is set to s1 bypass\n", cb_type); + return 0; + } + + smmu_domain = ipa3_get_smmu_domain_by_type(cb_type); + if (!smmu_domain) { + IPAERR("invalid smmu domain\n"); + return -EINVAL; + } + + if (map) { + va = rounddown(iova, PAGE_SIZE); + phys = rounddown(pa, PAGE_SIZE); + len = size + ((iova - va > pa - phys) ? + (iova-va) : (pa - phys)); + res = ipa3_iommu_map(smmu_domain, va, phys, + roundup(len, PAGE_SIZE), + IOMMU_READ | IOMMU_WRITE); + } else { + va = rounddown(iova, PAGE_SIZE); + phys = rounddown(pa, PAGE_SIZE); + len = size + ((iova - va > pa - phys) ? + (iova-va) : (pa - phys)); + res = iommu_unmap(smmu_domain, va, + roundup(len, PAGE_SIZE)); + } + IPADBG("ctg %s 0x%llx to 0x%llx\n", map ? "map" : "unmap", pa, iova); + return 0; +} + static enum ipa_client_cb_type ipa_get_client_cb_type( enum ipa_client_type client_type) { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index c635d1cc5b15..4cae77a34cb5 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -75,6 +75,7 @@ const char *ipa3_event_name[IPA_EVENT_MAX_NUM] = { __stringify(IPA_GSB_DISCONNECT), __stringify(IPA_COALESCE_ENABLE), __stringify(IPA_COALESCE_DISABLE), + __stringify(IPA_SET_MTU), __stringify_1(WIGIG_CLIENT_CONNECT), __stringify_1(WIGIG_FST_SWITCH), }; @@ -95,6 +96,7 @@ const char *ipa3_hdr_proc_type_name[] = { __stringify(IPA_HDR_PROC_L2TP_HEADER_ADD), __stringify(IPA_HDR_PROC_L2TP_HEADER_REMOVE), __stringify(IPA_HDR_PROC_ETHII_TO_ETHII_EX), + __stringify(IPA_HDR_PROC_SET_DSCP), }; static struct dentry *dent; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index fcd0160ed462..6e1addd91aa4 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1762,6 +1762,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, goto fail_pipe_not_valid; } + trace_ipa3_tx_dp(skb,sys->ep->client); num_frags = skb_shinfo(skb)->nr_frags; /* * make sure TLV FIFO supports the needed frags. @@ -1914,6 +1915,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, IPA_STATS_INC_CNT(ipa3_ctx->stats.tx_hw_pkts); } + trace_ipa3_tx_done(sys->ep->client); if (num_frags) { kfree(desc); IPA_STATS_INC_CNT(ipa3_ctx->stats.tx_non_linear); @@ -4606,6 +4608,7 @@ void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys) */ clk_off = ipa_pm_activate(sys->pm_hdl); if (!clk_off && sys->napi_obj) { + trace_ipa3_napi_schedule(sys->ep->client); napi_schedule(sys->napi_obj); IPA_STATS_INC_CNT(sys->napi_sch_cnt); } else if (!clk_off && @@ -5285,6 +5288,9 @@ int ipa3_rx_poll(u32 clnt_hdl, int weight) IPAERR("Invalid client.\n"); return cnt; } + ep = &ipa3_ctx->ep[clnt_hdl]; + + trace_ipa3_napi_poll_entry(ep->client); wan_def_sys = ipa3_ctx->ep[ipa_ep_idx].sys; remain_aggr_weight = weight / ipa3_ctx->ipa_wan_aggr_pkt_cnt; @@ -5295,7 +5301,6 @@ int ipa3_rx_poll(u32 clnt_hdl, int weight) return -EINVAL; } - ep = &ipa3_ctx->ep[clnt_hdl]; start_poll: while (remain_aggr_weight > 0 && atomic_read(&ep->sys->curr_polling_state)) { @@ -5341,6 +5346,7 @@ start_poll: IPADBG_LOW("Client = %d not replenished free descripotrs\n", ep->client); } + trace_ipa3_napi_poll_exit(ep->client); return cnt; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index e0b43c7d6236..17ca594be236 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1793,9 +1793,9 @@ enum ipa_client_cb_type { */ struct ipa_flt_rt_counter { struct idr hdl; + spinlock_t hdl_lock; bool used_hw[IPA_FLT_RT_HW_COUNTER]; bool used_sw[IPA_FLT_RT_SW_COUNTER]; - spinlock_t hdl_lock; }; /** @@ -1946,6 +1946,9 @@ struct ipa3_app_clock_vote { * @rmnet_ctl_enable: enable pipe support fow low latency data * @gsi_fw_file_name: GSI IPA fw file name * @uc_fw_file_name: uC IPA fw file name + * @manual_fw_load: bool,if fw load is done manually + * @max_num_smmu_cb: number of smmu s1 cb supported + * @ipa_config_is_auto: flag to indicate auto config */ struct ipa3_context { struct ipa3_char_device_context cdev; @@ -2024,6 +2027,7 @@ struct ipa3_context { enum gsi_ver gsi_ver; enum ipa3_platform_type platform_type; bool ipa_config_is_mhi; + bool ipa_config_is_auto; bool use_ipa_teth_bridge; bool modem_cfg_emb_pipe_flt; bool ipa_wdi2; @@ -2137,6 +2141,9 @@ struct ipa3_context { char *uc_fw_file_name; bool gsi_wdi_db_polling; u32 ipa_wan_aggr_pkt_cnt; + bool manual_fw_load; + u32 num_smmu_cb_probed; + u32 max_num_smmu_cb; }; struct ipa3_plat_drv_res { @@ -2202,6 +2209,9 @@ struct ipa3_plat_drv_res { u32 tx_wrapper_cache_max_size; bool gsi_wdi_db_polling; u32 ipa_wan_aggr_pkt_cnt; + bool manual_fw_load; + bool ipa_config_is_auto; + u32 max_num_smmu_cb; }; /** @@ -3084,6 +3094,8 @@ int ipa3_smmu_map_peer_reg(phys_addr_t phys_addr, bool map, enum ipa_smmu_cb_type cb_type); int ipa3_smmu_map_peer_buff(u64 iova, u32 size, bool map, struct sg_table *sgt, enum ipa_smmu_cb_type cb_type); +int ipa3_smmu_map_ctg(u64 iova, u32 size, bool map, phys_addr_t pa, + enum ipa_smmu_cb_type cb_type); void ipa3_reset_freeze_vote(void); int ipa3_ntn_init(void); int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats); 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 e9d1c84f968b..51b229a99fd1 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -1512,11 +1512,14 @@ static void ipa3_q6_clnt_svc_arrive(struct work_struct *work) IPAWANERR( "ipa3_qmi_init_modem_send_sync_msg failed due to SSR!\n"); /* Cleanup when ipa3_wwan_remove is called */ - mutex_lock(&ipa3_qmi_lock); - qmi_handle_release(ipa_q6_clnt); - vfree(ipa_q6_clnt); - ipa_q6_clnt = NULL; - mutex_unlock(&ipa3_qmi_lock); + if (ipa_q6_clnt != NULL) { + mutex_lock(&ipa3_qmi_lock); + qmi_handle_release(ipa_q6_clnt); + vfree(ipa_q6_clnt); + ipa_q6_clnt = NULL; + mutex_unlock(&ipa3_qmi_lock); + } + IPAWANERR("Exit from service arrive fun\n"); return; } @@ -2143,6 +2146,8 @@ int ipa3_qmi_enable_per_client_stats( IPAWANDBG("Sending QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01\n"); + if (unlikely(!ipa_q6_clnt)) + return -ETIMEDOUT; rc = ipa3_qmi_send_req_wait(ipa_q6_clnt, &req_desc, req, &resp_desc, resp, @@ -2180,6 +2185,8 @@ int ipa3_qmi_get_per_client_packet_stats( IPAWANDBG("Sending QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01\n"); + if (unlikely(!ipa_q6_clnt)) + return -ETIMEDOUT; rc = ipa3_qmi_send_req_wait(ipa_q6_clnt, &req_desc, req, &resp_desc, resp, @@ -2237,6 +2244,8 @@ int ipa3_qmi_send_mhi_cleanup_request(struct ipa_mhi_cleanup_req_msg_v01 *req) resp_desc.msg_id = QMI_IPA_MHI_CLEANUP_RESP_V01; resp_desc.ei_array = ipa_mhi_cleanup_resp_msg_v01_ei; + if (unlikely(!ipa_q6_clnt)) + return -ETIMEDOUT; rc = ipa3_qmi_send_req_wait(ipa_q6_clnt, &req_desc, req, &resp_desc, &resp, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h index 46538945007a..ac3eec0ff7f0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h @@ -121,6 +121,8 @@ struct ipa3_rmnet_mux_val { bool ul_flt_reg; bool mux_hdr_set; uint32_t hdr_hdl; + uint16_t mtu_v4; + uint16_t mtu_v6; }; extern struct qmi_elem_info @@ -305,6 +307,9 @@ int rmnet_ipa3_enable_per_client_stats(bool *data); int rmnet_ipa3_query_per_client_stats( struct wan_ioctl_query_per_client_stats *data); +int rmnet_ipa3_get_wan_mtu( + struct ipa_mtu_info *data); + int ipa3_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req, struct ipa_get_data_stats_resp_msg_v01 *resp); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_trace.h b/drivers/platform/msm/ipa/ipa_v3/ipa_trace.h index af59a3c90d09..e83e48251981 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_trace.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_trace.h @@ -123,19 +123,35 @@ TRACE_EVENT( TRACE_EVENT( rmnet_ipa_netif_rcv_skb3, - TP_PROTO(unsigned long rx_pkt_cnt), + TP_PROTO(const struct sk_buff *skb, unsigned long rx_pkt_cnt), - TP_ARGS(rx_pkt_cnt), + TP_ARGS(skb, rx_pkt_cnt), TP_STRUCT__entry( + __string(name, skb->dev->name) + __field(const void *, skbaddr) + __field(u16, protocol) + __field(unsigned int, len) + __field(unsigned int, data_len) __field(unsigned long, rx_pkt_cnt) ), TP_fast_assign( + __assign_str(name, skb->dev->name); + __entry->skbaddr = skb; + __entry->protocol = ntohs(skb->protocol); + __entry->len = skb->len; + __entry->data_len = skb->data_len; __entry->rx_pkt_cnt = rx_pkt_cnt; ), - TP_printk("rx_pkt_cnt=%lu", __entry->rx_pkt_cnt) + TP_printk("dev=%s skbaddr=%p protocol=0x%04x len=%u data_len=%u rx_pkt_cnt=%lu", + __get_str(name), + __entry->skbaddr, + __entry->protocol, + __entry->len, + __entry->data_len, + __entry->rx_pkt_cnt) ); TRACE_EVENT( @@ -174,6 +190,112 @@ TRACE_EVENT( TP_printk("napi_overall_poll_pkt_cnt=%d", __entry->poll_num) ); +TRACE_EVENT( + ipa3_napi_schedule, + + TP_PROTO(unsigned long client), + + TP_ARGS(client), + + TP_STRUCT__entry( + __field(unsigned long, client) + ), + + TP_fast_assign( + __entry->client = client; + ), + + TP_printk("client=%lu", __entry->client) +); + +TRACE_EVENT( + ipa3_napi_poll_entry, + + TP_PROTO(unsigned long client), + + TP_ARGS(client), + + TP_STRUCT__entry( + __field(unsigned long, client) + ), + + TP_fast_assign( + __entry->client = client; + ), + + TP_printk("client=%lu", __entry->client) +); + + +TRACE_EVENT( + ipa3_napi_poll_exit, + + TP_PROTO(unsigned long client), + + TP_ARGS(client), + + TP_STRUCT__entry( + __field(unsigned long, client) + ), + + TP_fast_assign( + __entry->client = client; + ), + + TP_printk("client=%lu", __entry->client) +); + +TRACE_EVENT( + ipa3_tx_dp, + + TP_PROTO(const struct sk_buff *skb, unsigned long client), + + TP_ARGS(skb, client), + + TP_STRUCT__entry( + __string(name, skb->dev->name) + __field(const void *, skbaddr) + __field(u16, protocol) + __field(unsigned int, len) + __field(unsigned int, data_len) + __field(unsigned long, client) + ), + + TP_fast_assign( + __assign_str(name, skb->dev->name); + __entry->skbaddr = skb; + __entry->protocol = ntohs(skb->protocol); + __entry->len = skb->len; + __entry->data_len = skb->data_len; + __entry->client = client; + ), + + TP_printk("dev=%s skbaddr=%p protocol=0x%04x len=%u data_len=%u client=%lu", + __get_str(name), + __entry->skbaddr, + __entry->protocol, + __entry->len, + __entry->data_len, + __entry->client) +); + +TRACE_EVENT( + ipa3_tx_done, + + TP_PROTO(unsigned long client), + + TP_ARGS(client), + + TP_STRUCT__entry( + __field(unsigned long, client) + ), + + TP_fast_assign( + __entry->client = client; + ), + + TP_printk("client=%lu", __entry->client) +); #endif /* _IPA_TRACE_H */ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c index 85a26d32c888..526f5246ffd8 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c @@ -7,6 +7,7 @@ #define IPA_UC_NTN_DB_PA_TX 0x79620DC #define IPA_UC_NTN_DB_PA_RX 0x79620D8 +#define IPA_UC_RING_ELEM_SZ 16 static void ipa3_uc_ntn_event_log_info_handler( struct IpaHwEventLogInfoData_t *uc_event_top_mmio) @@ -287,13 +288,31 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, } if (params->smmu_enabled) { IPADBG("smmu is enabled on EMAC\n"); - result = ipa3_smmu_map_peer_buff((u64)params->ring_base_iova, - params->ntn_ring_size, map, params->ring_base_sgt, - IPA_SMMU_CB_UC); - if (result) { - IPAERR("failed to %s ntn ring %d\n", - map ? "map" : "unmap", result); - goto fail_map_ring; + if (params->ring_base_sgt) { + result = ipa3_smmu_map_peer_buff( + (u64)params->ring_base_iova, + params->ntn_ring_size, map, + params->ring_base_sgt, + IPA_SMMU_CB_UC); + if (result) { + IPAERR("failed to %s ntn ring %d\n", + map ? "map" : "unmap", result); + goto fail_map_ring; + } + } else { + /* Eth driver passes # of elements instead of sz + * Calc & pass the ring size to map contigous mem + */ + result = ipa3_smmu_map_ctg( + (u64)params->ring_base_iova, + params->ntn_ring_size*IPA_UC_RING_ELEM_SZ, + map, params->ring_base_pa, + IPA_SMMU_CB_UC); + if (result) { + IPAERR("failed to %s ntn ring %d\n", + map ? "map" : "unmap", result); + goto fail_map_ring; + } } result = ipa3_smmu_map_peer_buff( (u64)params->buff_pool_base_iova, @@ -367,9 +386,15 @@ fail_map_data_buff_smmu_disabled: params->num_buffers * 4, !map, NULL, IPA_SMMU_CB_UC); goto fail_map_buffer_smmu_disabled; fail_map_buffer_smmu_enabled: - ipa3_smmu_map_peer_buff((u64)params->ring_base_iova, - params->ntn_ring_size, !map, params->ring_base_sgt, - IPA_SMMU_CB_UC); + if (params->ring_base_sgt) { + ipa3_smmu_map_peer_buff((u64)params->ring_base_iova, + params->ntn_ring_size, !map, params->ring_base_sgt, + IPA_SMMU_CB_UC); + } else { + ipa3_smmu_map_ctg((u64)params->ring_base_iova, + params->ntn_ring_size*IPA_UC_RING_ELEM_SZ, !map, + params->ring_base_pa, IPA_SMMU_CB_UC); + } goto fail_map_ring; fail_map_buffer_smmu_disabled: ipa3_smmu_map_peer_buff((u64)params->ring_base_pa, @@ -475,6 +500,8 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, /* setup dl ep cfg */ ep_dl->valid = 1; ep_dl->client = in->dl.client; + ep_dl->client_notify = notify; + ep_dl->priv = priv; memset(&ep_dl->cfg, 0, sizeof(ep_ul->cfg)); ep_dl->cfg.nat.nat_en = IPA_BYPASS_NAT; ep_dl->cfg.hdr.hdr_len = hdr_len; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c index d948dd3eb425..fbf8d06061a3 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c @@ -3001,7 +3001,7 @@ int ipa3_uc_dereg_rdyCB(void) return 0; } - +EXPORT_SYMBOL(ipa3_uc_dereg_rdyCB); /** * ipa3_uc_wdi_get_dbpa() - To retrieve diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 3baff1ed2c5c..109ebb0065ba 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -263,6 +263,7 @@ enum ipa_ver { IPA_4_0_MHI, IPA_4_1, IPA_4_1_APQ, + IPA_4_1_APQ_AUTO, IPA_4_2, IPA_4_5, IPA_4_5_MHI, @@ -374,6 +375,19 @@ static const struct rsrc_min_max ipa3_rsrc_src_grp_config [IPA_v4_0_RSRC_GRP_TYPE_SRC_ACK_ENTRIES] = { {14, 14}, {20, 20}, {0, 0}, {14, 14}, {0, 0}, {0, 0} }, }, + [IPA_4_1_APQ_AUTO] = { + /* LWA_DL UL_DL unused UC_RX_Q, other are invalid */ + [IPA_v4_0_RSRC_GRP_TYPE_SRC_PKT_CONTEXTS] = { + {1, 63}, {1, 63}, {0, 0}, {1, 63}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_DESCRIPTOR_LISTS] = { + {10, 10}, {10, 10}, {0, 0}, {8, 8}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_DESCRIPTOR_BUFF] = { + {12, 12}, {14, 14}, {0, 0}, {8, 8}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_HPS_DMARS] = { + {0, 63}, {0, 63}, {0, 63}, {0, 63}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_ACK_ENTRIES] = { + {14, 14}, {20, 20}, {0, 0}, {14, 14}, {0, 0}, {0, 0} }, + }, [IPA_4_2] = { /* UL_DL other are invalid */ [IPA_v4_0_RSRC_GRP_TYPE_SRC_PKT_CONTEXTS] = { @@ -521,6 +535,13 @@ static const struct rsrc_min_max ipa3_rsrc_dst_grp_config [IPA_v4_0_RSRC_GRP_TYPE_DST_DPS_DMARS] = { {2, 63}, {1, 63}, {1, 2}, {0, 2}, {0, 0}, {0, 0} }, }, + [IPA_4_1_APQ_AUTO] = { + /* LWA_DL UL/DL/DPL uC, other are invalid */ + [IPA_v4_0_RSRC_GRP_TYPE_DST_DATA_SECTORS] = { + {4, 4}, {4, 4}, {3, 3}, {2, 2}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_DST_DPS_DMARS] = { + {2, 63}, {1, 63}, {1, 2}, {0, 2}, {0, 0}, {0, 0} }, + }, [IPA_4_2] = { /* UL/DL/DPL, other are invalid */ [IPA_v4_0_RSRC_GRP_TYPE_DST_DATA_SECTORS] = { @@ -610,6 +631,11 @@ static const struct rsrc_min_max ipa3_rsrc_rx_grp_config [IPA_RSRC_GRP_TYPE_RX_HPS_CMDQ] = { {3, 3}, {7, 7}, {0, 0}, {2, 2}, {0, 0}, {0, 0} }, }, + [IPA_4_1_APQ_AUTO] = { + /* LWA_DL UL_DL unused UC_RX_Q, other are invalid */ + [IPA_RSRC_GRP_TYPE_RX_HPS_CMDQ] = { + {3, 3}, {7, 7}, {0, 0}, {2, 2}, {0, 0}, {0, 0} }, + }, [IPA_4_2] = { /* UL_DL, other are invalid */ [IPA_RSRC_GRP_TYPE_RX_HPS_CMDQ] = { @@ -713,6 +739,8 @@ static const struct ipa_qmb_outstanding ipa3_qmb_outstanding [IPA_4_0_MHI][IPA_QMB_INSTANCE_PCIE] = {12, 4, 0}, [IPA_4_1][IPA_QMB_INSTANCE_DDR] = {12, 8, 120}, [IPA_4_1][IPA_QMB_INSTANCE_PCIE] = {12, 4, 0}, + [IPA_4_1_APQ_AUTO][IPA_QMB_INSTANCE_DDR] = {12, 8, 120}, + [IPA_4_1_APQ_AUTO][IPA_QMB_INSTANCE_PCIE] = {12, 4, 0}, [IPA_4_2][IPA_QMB_INSTANCE_DDR] = {12, 8, 0}, [IPA_4_5][IPA_QMB_INSTANCE_DDR] = {16, 8, 120}, [IPA_4_5][IPA_QMB_INSTANCE_PCIE] = {12, 8, 0}, @@ -2033,6 +2061,126 @@ static const struct ipa_ep_configuration ipa3_ep_mapping QMB_MASTER_SELECT_DDR, { 17, 14, 9, 9, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_WLAN2_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 6, 11, 8, 16, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_USB_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 0, 8, 8, 16, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_APPS_LAN_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 8, 10, 8, 16, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_APPS_CMD_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 5, 4, 20, 24, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_ETHERNET_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 9, 0, 8, 16, IPA_EE_UC } }, + /* Only for test purpose */ + [IPA_4_1_APQ_AUTO][IPA_CLIENT_TEST_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + {0, 8, 8, 16, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_TEST1_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 0, 8, 8, 16, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_TEST2_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 6, 2, 8, 16, IPA_EE_AP } }, + + [IPA_4_1_APQ_AUTO][IPA_CLIENT_WLAN2_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 18, 15, 8, 13, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_USB_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 19, 12, 9, 9, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_USB_DPL_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 15, 7, 5, 5, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_APPS_LAN_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 10, 5, 9, 9, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_ODL_DPL_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 12, 2, 9, 9, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_ETHERNET_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 22, 1, 9, 9, IPA_EE_UC } }, + /* Only for test purpose */ + /* MBIM aggregation test pipes should have the same QMB as USB_CONS */ + [IPA_4_1_APQ_AUTO][IPA_CLIENT_TEST_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 19, 12, 9, 9, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_TEST1_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 19, 12, 9, 9, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_TEST2_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 18, 3, 9, 9, IPA_EE_AP } }, + [IPA_4_1_APQ_AUTO][IPA_CLIENT_TEST3_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 15, 7, 5, 5, IPA_EE_AP } }, + /* Dummy consumer (pipe 31) is used in L2TP rt rule */ + [IPA_4_1_APQ_AUTO][IPA_CLIENT_DUMMY_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 31, 31, 8, 8, IPA_EE_AP } }, + /* IPA_4_2 */ [IPA_4_2][IPA_CLIENT_WLAN1_PROD] = { true, IPA_v4_2_GROUP_UL_DL, @@ -4459,6 +4607,12 @@ u8 ipa3_get_hw_type_index(void) break; case IPA_HW_v4_1: hw_type_index = IPA_4_1; + if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ) { + hw_type_index = IPA_4_1_APQ; + if (ipa3_ctx->ipa_config_is_auto) { + hw_type_index = IPA_4_1_APQ_AUTO; + } + } break; case IPA_HW_v4_2: hw_type_index = IPA_4_2; @@ -7888,6 +8042,8 @@ static void ipa3_write_rsrc_grp_type_reg(int group_index, case IPA_4_0: case IPA_4_0_MHI: case IPA_4_1: + case IPA_4_1_APQ: + case IPA_4_1_APQ_AUTO: if (src) { switch (group_index) { case IPA_v4_0_GROUP_LWA_DL: @@ -8253,6 +8409,8 @@ void ipa3_set_resorce_groups_min_max_limits(void) case IPA_4_0: case IPA_4_0_MHI: case IPA_4_1: + case IPA_4_1_APQ: + case IPA_4_1_APQ_AUTO: src_rsrc_type_max = IPA_v4_0_RSRC_GRP_TYPE_SRC_MAX; dst_rsrc_type_max = IPA_v4_0_RSRC_GRP_TYPE_DST_MAX; src_grp_idx_max = IPA_v4_0_SRC_GROUP_MAX; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c index 4a6d3b533ffe..4fdd04437455 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c @@ -1477,6 +1477,9 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, case IPA_HDR_PROC_802_3_TO_802_3: ctx->cmd.value = IPA_HDR_UCP_802_3_TO_802_3; break; + case IPA_HDR_PROC_SET_DSCP: + ctx->cmd.value = IPA_HDR_UCP_SET_DSCP; + break; default: IPAHAL_ERR("unknown ipa_hdr_proc_type %d", type); WARN_ON(1); @@ -1522,6 +1525,9 @@ static int ipahal_get_proc_ctx_needed_len_v3(enum ipa_hdr_proc_type type) case IPA_HDR_PROC_ETHII_TO_ETHII_EX: ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq_ex); break; + case IPA_HDR_PROC_SET_DSCP: + ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq); + break; default: /* invalid value to make sure failure */ IPAHAL_ERR_RL("invalid ipa_hdr_proc_type %d\n", type); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h index 4702b2b70d68..c298e1749272 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h @@ -675,6 +675,7 @@ union ipa_pkt_status_hw { #define IPA_HDR_UCP_L2TP_UDP_HEADER_ADD 12 #define IPA_HDR_UCP_L2TP_UDP_HEADER_REMOVE 13 #define IPA_HDR_UCP_ETHII_TO_ETHII_EX 14 +#define IPA_HDR_UCP_SET_DSCP 16 /* Processing context TLV type */ #define IPA_PROC_CTX_TLV_TYPE_END 0 diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 69d9656eb3a5..8262525f642b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -90,6 +90,10 @@ static DECLARE_DELAYED_WORK(ipa_tether_stats_poll_wakequeue_work, static int rmnet_ipa_send_coalesce_notification(uint8_t qmap_id, bool enable, bool tcp, bool udp); +static int rmnet_ipa_send_set_mtu_notification(char *if_name, + uint16_t mtu_v4, uint16_t mtu_v6, enum ipa_ip_type ip); + + enum ipa3_wwan_device_status { WWAN_DEVICE_INACTIVE = 0, WWAN_DEVICE_ACTIVE = 1 @@ -1395,7 +1399,7 @@ static void apps_ipa_packet_receive_notify(void *priv, skb_set_mac_header(skb, 0); if (ipa3_rmnet_res.ipa_napi_enable) { - trace_rmnet_ipa_netif_rcv_skb3(dev->stats.rx_packets); + trace_rmnet_ipa_netif_rcv_skb3(skb, dev->stats.rx_packets); result = netif_receive_skb(skb); } else { if (dev->stats.rx_packets % IPA_WWAN_RX_SOFTIRQ_THRESH @@ -1756,6 +1760,8 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct mutex *mux_mutex_ptr; int wan_ep; bool tcp_en = false, udp_en = false; + bool mtu_v4_set = false, mtu_v6_set = false; + enum ipa_ip_type iptype; IPAWANDBG("rmnet_ipa got ioctl number 0x%08x", cmd); switch (cmd) { @@ -2086,6 +2092,65 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } mutex_unlock(&rmnet_ipa3_ctx->clock_vote.mutex); break; + /* Get MTU */ + case RMNET_IOCTL_GET_MTU: + mux_channel = rmnet_ipa3_ctx->mux_channel; + rmnet_index = + find_vchannel_name_index(ext_ioctl_data.u.mtu_params.if_name); + + if (rmnet_index == MAX_NUM_OF_MUX_CHANNEL) { + IPAWANERR("%s is an invalid iface name\n", + ext_ioctl_data.u.mtu_params.if_name); + return -ENODEV; + } + + IPAWANDBG("getting v4 MTU = %d\n", mux_channel[rmnet_index].mtu_v4); + ext_ioctl_data.u.mtu_params.mtu_v4 = + mux_channel[rmnet_index].mtu_v4; + + IPAWANDBG("getting v6 MTU = %d\n", mux_channel[rmnet_index].mtu_v6); + ext_ioctl_data.u.mtu_params.mtu_v6 = + mux_channel[rmnet_index].mtu_v6; + break; + /* Set MTU */ + case RMNET_IOCTL_SET_MTU: + mux_channel = rmnet_ipa3_ctx->mux_channel; + rmnet_index = + find_vchannel_name_index(ext_ioctl_data.u.mtu_params.if_name); + + if (rmnet_index == MAX_NUM_OF_MUX_CHANNEL) { + IPAWANERR("%s is an invalid iface name\n", + ext_ioctl_data.u.mtu_params.if_name); + return -ENODEV; + } + + /* V4 case */ + if (ext_ioctl_data.u.mtu_params.mtu_v4 > 0) { + mux_channel[rmnet_index].mtu_v4 = + ext_ioctl_data.u.mtu_params.mtu_v4; + mtu_v4_set = true; + IPAWANDBG("Set v4 MTU = %d\n", mux_channel[rmnet_index].mtu_v4); + iptype = IPA_IP_v4; + } + /* V6 case */ + if (ext_ioctl_data.u.mtu_params.mtu_v6 > 0) { + mux_channel[rmnet_index].mtu_v6 = + ext_ioctl_data.u.mtu_params.mtu_v6; + mtu_v6_set = true; + IPAWANDBG("Set v6 MTU = %d\n", mux_channel[rmnet_index].mtu_v6); + iptype = IPA_IP_v6; + } + + if (mtu_v4_set && mtu_v6_set) + iptype = IPA_IP_MAX; + + rc = rmnet_ipa_send_set_mtu_notification( + ext_ioctl_data.u.mtu_params.if_name, + mux_channel[rmnet_index].mtu_v4, + mux_channel[rmnet_index].mtu_v6, + iptype); + + break; default: IPAWANERR("[%s] unsupported extended cmd[%d]", dev->name, @@ -2179,6 +2244,37 @@ static int rmnet_ipa_send_coalesce_notification(uint8_t qmap_id, return 0; } +static int rmnet_ipa_send_set_mtu_notification(char *if_name, + uint16_t mtu_v4, uint16_t mtu_v6, enum ipa_ip_type ip) +{ + struct ipa_msg_meta msg_meta; + struct ipa_mtu_info *mtu_info; + int rc; + + memset(&msg_meta, 0, sizeof(struct ipa_msg_meta)); + mtu_info = kzalloc(sizeof(*mtu_info), GFP_KERNEL); + if (!mtu_info) + return -ENOMEM; + + strlcpy(mtu_info->if_name, if_name, IPA_RESOURCE_NAME_MAX); + mtu_info->mtu_v4 = mtu_v4; + mtu_info->mtu_v6 = mtu_v6; + mtu_info->ip_type = ip; + msg_meta.msg_type = IPA_SET_MTU; + msg_meta.msg_len = sizeof(struct ipa_mtu_info); + + rc = ipa_send_msg(&msg_meta, mtu_info, ipa3_wwan_msg_free_cb); + if (rc) { + IPAWANERR("ipa_send_msg failed: %d\n", rc); + return -EFAULT; + } + IPAWANDBG( + "sent new mtu_v4(%d)/mtu_v6(%d) with iptype(%d) for iface(%s) to IPACM", + mtu_v4, mtu_v6, ip, if_name); + + return 0; +} + int ipa3_wwan_set_modem_state(struct wan_ioctl_notify_wan_state *state) { uint32_t bw_mbps = 0; @@ -4785,13 +4881,118 @@ int rmnet_ipa3_query_per_client_stats( return 0; } +/* rmnet_ipa3_get_wan_mtu() - + * @data - IOCTL data + * + * This function handles WAN_IOC_GET_WAN_MTU. + * It is used to send WAN MTU information to IPACM. + * + * Return codes: + * 0: Success + * -EINVAL: Invalid args provided + */ +int rmnet_ipa3_get_wan_mtu( + struct ipa_mtu_info *data) +{ + struct ipa3_rmnet_mux_val *mux_channel; + int rmnet_index; + + mux_channel = rmnet_ipa3_ctx->mux_channel; + rmnet_index = + find_vchannel_name_index(data->if_name); + + if (rmnet_index == MAX_NUM_OF_MUX_CHANNEL) { + IPAWANERR("%s is an invalid iface name\n", + data->if_name); + return -ENODEV; + } + + IPAWANDBG("getting v4 MTU = %d\n", mux_channel[rmnet_index].mtu_v4); + data->mtu_v4 = + mux_channel[rmnet_index].mtu_v4; + + IPAWANDBG("getting v6 MTU = %d\n", mux_channel[rmnet_index].mtu_v6); + data->mtu_v6 = + mux_channel[rmnet_index].mtu_v6; + + return 0; +} #ifdef CONFIG_DEBUG_FS +static char dbg_buff[4096]; + +static ssize_t rmnet_ipa_set_mtu(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + __s8 if_name[IFNAMSIZ]; + uint16_t mtu_v4 = 0, mtu_v6 = 0; + unsigned long missing; + char *sptr, *token; + + if (count >= sizeof(dbg_buff)) + return -EFAULT; + + missing = copy_from_user(dbg_buff, buf, count); + if (missing) + return -EFAULT; + + dbg_buff[count] = '\0'; + + sptr = dbg_buff; + + memset(if_name, 0, IFNAMSIZ); + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + strlcpy(if_name, token, IFNAMSIZ); + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou16(token, 0, &mtu_v4)) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou16(token, 0, &mtu_v6)) + return -EINVAL; + + rmnet_ipa_send_set_mtu_notification( + if_name, + mtu_v4, + mtu_v6, IPA_IP_MAX); + + return count; +} + + +#define RMNET_IPA_WRITE_ONLY_MODE 0220 + +struct rmnet_ipa_debugfs_file { + const char *name; + umode_t mode; + void *data; + const struct file_operations fops; +}; + +static const struct rmnet_ipa_debugfs_file debugfs_files[] = { + { + "mtu", RMNET_IPA_WRITE_ONLY_MODE, NULL, { + .write = rmnet_ipa_set_mtu, + } + }, +}; + static void rmnet_ipa_debugfs_init(void) { const mode_t read_write_mode = 0664; + int i = 0; + struct dentry *file; struct rmnet_ipa_debugfs *dbgfs = &rmnet_ipa3_ctx->dbgfs; + const size_t debugfs_files_num = + sizeof(debugfs_files) / sizeof(struct rmnet_ipa_debugfs_file); dbgfs->dent = debugfs_create_dir("rmnet_ipa", 0); @@ -4800,6 +5001,18 @@ static void rmnet_ipa_debugfs_init(void) return; } + for (i = 0; i < debugfs_files_num; ++i) { + const struct rmnet_ipa_debugfs_file *curr = &debugfs_files[i]; + + file = debugfs_create_file(curr->name, curr->mode, dbgfs->dent, + curr->data, &curr->fops); + if (!file || IS_ERR(file)) { + IPAERR("fail to create file for debug_fs %s\n", + curr->name); + goto fail; + } + } + dbgfs->dfile_outstanding_high = debugfs_create_u32("outstanding_high", read_write_mode, dbgfs->dent, &rmnet_ipa3_ctx->outstanding_high); diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c index 7c3f05135fb1..6a839241cd1c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c @@ -475,6 +475,28 @@ static long ipa3_wan_ioctl(struct file *filp, } break; + case WAN_IOC_GET_WAN_MTU: + IPAWANDBG_LOW("got WAN_IOC_GET_WAN_MTU :>>>\n"); + pyld_sz = sizeof(struct ipa_mtu_info); + param = memdup_user((const void __user *)arg, pyld_sz); + if (IS_ERR(param)) { + retval = PTR_ERR(param); + break; + } + if (rmnet_ipa3_get_wan_mtu( + (struct ipa_mtu_info *) + param)) { + IPAWANERR("WAN_IOC_GET_WAN_MTU failed\n"); + retval = -EFAULT; + break; + } + + if (copy_to_user((void __user *)arg, param, pyld_sz)) { + retval = -EFAULT; + break; + } + break; + default: retval = -ENOTTY; }