diff --git a/config/dataipa_GKI.conf b/config/dataipa_GKI.conf index 516dcf224b..a6ec1bd618 100644 --- a/config/dataipa_GKI.conf +++ b/config/dataipa_GKI.conf @@ -2,7 +2,6 @@ export CONFIG_GSI=m export CONFIG_IPA_CLIENTS_MANAGER=m export CONFIG_IPA_WDI_UNIFIED_API=y export CONFIG_RMNET_IPA3=y -export CONFIG_IPA3_MHI_PRIME_MANAGER=y export CONFIG_RNDIS_IPA=m export CONFIG_IPA3_REGDUMP=y export CONFIG_IPA3_REGDUMP_IPA_5_0=y diff --git a/config/dataipa_vendor.h b/config/dataipa_vendor.h index ef6bfe02a6..f711c22d9a 100644 --- a/config/dataipa_vendor.h +++ b/config/dataipa_vendor.h @@ -8,6 +8,5 @@ #define CONFIG_RNDIS_IPA 1 #define CONFIG_IPA_WDI_UNIFIED_API 1 #define CONFIG_IPA_VENDOR_DLKM 1 -#define CONFIG_IPA3_MHI_PRIME_MANAGER 1 #define CONFIG_IPA3_REGDUMP 1 #define CONFIG_IPA3_REGDUMP_IPA_5_0 1 diff --git a/dataipa_dlkm_vendor_board.mk b/dataipa_dlkm_vendor_board.mk index 2efe659ce1..98c510bae3 100644 --- a/dataipa_dlkm_vendor_board.mk +++ b/dataipa_dlkm_vendor_board.mk @@ -1,5 +1,5 @@ #Build ipa -DATA_DLKM_BOARD_PLATFORMS_LIST := taro +DATA_DLKM_BOARD_PLATFORMS_LIST := taro kalama ifneq ($(TARGET_BOARD_AUTO),true) ifeq ($(call is-board-platform-in-list,$(DATA_DLKM_BOARD_PLATFORMS_LIST)),true) BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/gsim.ko diff --git a/drivers/platform/msm/Android.mk b/drivers/platform/msm/Android.mk index 35bb08c30c..5f6450548e 100644 --- a/drivers/platform/msm/Android.mk +++ b/drivers/platform/msm/Android.mk @@ -1,5 +1,5 @@ ifneq ($(TARGET_BOARD_PLATFORM),qssi) -GSI_DLKM_PLATFORMS_LIST := taro +GSI_DLKM_PLATFORMS_LIST := taro kalama ifeq ($(call is-board-platform-in-list, $(GSI_DLKM_PLATFORMS_LIST)),true) #Make file to create GSI DLKM diff --git a/drivers/platform/msm/Kbuild b/drivers/platform/msm/Kbuild index 7814f8298a..e8e1b70fa9 100644 --- a/drivers/platform/msm/Kbuild +++ b/drivers/platform/msm/Kbuild @@ -26,6 +26,16 @@ LINUXINCLUDE += -include $(srctree)/../../vendor/qcom/opensource/dataipa/conf endif endif +ifeq ($(CONFIG_ARCH_KALAMA), y) +DATAIPADRVTOP = $(srctree)/../../vendor/qcom/opensource/dataipa/drivers/platform/msm +LINUXINCLUDE += -include $(srctree)/../../vendor/qcom/opensource/dataipa/config/dataipa_vendor.h +include $(srctree)/../../vendor/qcom/opensource/dataipa/config/dataipa_GKI.conf +ifeq ($(CONFIG_LOCALVERSION), "-gki-consolidate") +include $(srctree)/../../vendor/qcom/opensource/dataipa/config/dataipa_debug.conf +LINUXINCLUDE += -include $(srctree)/../../vendor/qcom/opensource/dataipa/config/dataipa_debug.h +endif +endif + #MDMs ifeq ($(CONFIG_ARCH_SDXLEMUR), y) LINUXINCLUDE += -include $(srctree)/techpack/dataipa/config/dataipa.h diff --git a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c index c546573726..ef1d9531b0 100644 --- a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c +++ b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c @@ -2357,29 +2357,17 @@ static void rndis_ipa_debugfs_init(struct rndis_ipa_dev *rndis_ipa_ctx) goto fail_directory; } - file = debugfs_create_bool + debugfs_create_bool ("tx_filter", flags_read_write, rndis_ipa_ctx->directory, &rndis_ipa_ctx->tx_filter); - if (!file) { - RNDIS_IPA_ERROR("could not create debugfs tx_filter file\n"); - goto fail_file; - } - file = debugfs_create_bool + debugfs_create_bool ("rx_filter", flags_read_write, rndis_ipa_ctx->directory, &rndis_ipa_ctx->rx_filter); - if (!file) { - RNDIS_IPA_ERROR("could not create debugfs rx_filter file\n"); - goto fail_file; - } - file = debugfs_create_bool + debugfs_create_bool ("icmp_filter", flags_read_write, rndis_ipa_ctx->directory, &rndis_ipa_ctx->icmp_filter); - if (!file) { - RNDIS_IPA_ERROR("could not create debugfs icmp_filter file\n"); - goto fail_file; - } debugfs_create_u32 ("outstanding_high", flags_read_write, @@ -2452,54 +2440,34 @@ static void rndis_ipa_debugfs_init(struct rndis_ipa_dev *rndis_ipa_ctx) aggr_directory, &ipa_to_usb_ep_cfg.aggr.aggr_pkt_limit); - file = debugfs_create_bool + debugfs_create_bool ("tx_dump_enable", flags_read_write, rndis_ipa_ctx->directory, &rndis_ipa_ctx->tx_dump_enable); - if (!file) { - RNDIS_IPA_ERROR("fail to create tx_dump_enable file\n"); - goto fail_file; - } - file = debugfs_create_bool + debugfs_create_bool ("rx_dump_enable", flags_read_write, rndis_ipa_ctx->directory, &rndis_ipa_ctx->rx_dump_enable); - if (!file) { - RNDIS_IPA_ERROR("fail to create rx_dump_enable file\n"); - goto fail_file; - } - file = debugfs_create_bool + debugfs_create_bool ("deaggregation_enable", flags_read_write, rndis_ipa_ctx->directory, &rndis_ipa_ctx->deaggregation_enable); - if (!file) { - RNDIS_IPA_ERROR("fail to create deaggregation_enable file\n"); - goto fail_file; - } debugfs_create_u32 ("error_msec_sleep_time", flags_read_write, rndis_ipa_ctx->directory, &rndis_ipa_ctx->error_msec_sleep_time); - file = debugfs_create_bool + debugfs_create_bool ("during_xmit_error", flags_read_only, rndis_ipa_ctx->directory, &rndis_ipa_ctx->during_xmit_error); - if (!file) { - RNDIS_IPA_ERROR("fail to create during_xmit_error file\n"); - goto fail_file; - } - file = debugfs_create_bool("is_vlan_mode", flags_read_only, + debugfs_create_bool("is_vlan_mode", flags_read_only, rndis_ipa_ctx->directory, &rndis_ipa_ctx->is_vlan_mode); - if (!file) { - RNDIS_IPA_ERROR("fail to create is_vlan_mode file\n"); - goto fail_file; - } RNDIS_IPA_DEBUG("debugfs entries were created\n"); RNDIS_IPA_LOG_EXIT(); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index e87e423526..9a56c1feed 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,12 @@ #include #include #include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)) +#include +#else +#include +#endif #include "gsi.h" #include "ipa_stats.h" @@ -7146,6 +7151,9 @@ static enum gsi_ver ipa3_get_gsi_ver(enum ipa_hw_type ipa_hw_type) case IPA_HW_v5_1: gsi_ver = GSI_VER_3_0; break; + case IPA_HW_v5_5: + gsi_ver = GSI_VER_5_5; + break; default: IPAERR("No GSI version for ipa type %d\n", ipa_hw_type); WARN_ON(1); @@ -8667,7 +8675,8 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, strlen(resource_p->uc_fw_file_name)); } - if (ipa3_ctx->secure_debug_check_action == USE_SCM) { + if (IPA_IS_REGULAR_CLK_MODE(ipa3_ctx->ipa3_hw_mode) && + ipa3_ctx->secure_debug_check_action == USE_SCM) { if (ipa_is_mem_dump_allowed()) ipa3_ctx->sd_state = SD_ENABLED; else @@ -10212,9 +10221,21 @@ static int ipa_smmu_perph_cb_probe(struct device *dev, * checks to see if they've been set in dtsi. If so, the logic * further below acts accordingly... */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)) + int mapping_config; + + mapping_config = qcom_iommu_get_mappings_configuration(cb->iommu_domain); + + if (mapping_config < 0) { + IPAERR("No Mapping configuration found for CB %d\n", cb_type); + } else { + bypass = (mapping_config & QCOM_IOMMU_MAPPING_CONF_S1_BYPASS) ? 1 : 0; + fast = (mapping_config & QCOM_IOMMU_MAPPING_CONF_FAST) ? 1 : 0; + } +#else iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_S1_BYPASS, &bypass); iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_FAST, &fast); - +#endif IPADBG( "CB %d PROBE dev=%pK DOMAIN ATTRS bypass=%d fast=%d\n", cb_type, dev, bypass, fast); @@ -10326,9 +10347,21 @@ static int ipa_smmu_uc_cb_probe(struct device *dev) * checks to see if they've been set in dtsi. If so, the logic * further below acts accordingly... */ - iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_S1_BYPASS, &bypass); - iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_FAST, &fast); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)) + int mapping_config; + mapping_config = qcom_iommu_get_mappings_configuration(cb->iommu_domain); + + if (mapping_config < 0) { + IPAERR("No Mapping configuration found for UC CB\n"); + } else { + bypass = (mapping_config & QCOM_IOMMU_MAPPING_CONF_S1_BYPASS) ? 1 : 0; + fast = (mapping_config & QCOM_IOMMU_MAPPING_CONF_FAST) ? 1 : 0; + } +#else + iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_S1_BYPASS, &bypass); + iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_FAST, &fast); +#endif IPADBG("UC CB PROBE dev=%pK DOMAIN ATTRS bypass=%d fast=%d\n", dev, bypass, fast); @@ -10418,9 +10451,21 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) * checks to see if they've been set in dtsi. If so, the logic * further below acts accordingly... */ - iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_S1_BYPASS, &bypass); - iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_FAST, &fast); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)) + int mapping_config; + mapping_config = qcom_iommu_get_mappings_configuration(cb->iommu_domain); + + if (mapping_config < 0) { + IPAERR("No Mapping configuration found for AP CB\n"); + } else { + bypass = (mapping_config & QCOM_IOMMU_MAPPING_CONF_S1_BYPASS) ? 1 : 0; + fast = (mapping_config & QCOM_IOMMU_MAPPING_CONF_FAST) ? 1 : 0; + } +#else + iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_S1_BYPASS, &bypass); + iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_FAST, &fast); +#endif IPADBG("AP CB PROBE dev=%pK DOMAIN ATTRS bypass=%d fast=%d\n", dev, bypass, fast); @@ -10541,9 +10586,19 @@ static int ipa_smmu_11ad_cb_probe(struct device *dev) IPADBG("11AD CB PROBE dev=%pK va_start=0x%x va_size=0x%x\n", dev, cb->va_start, cb->va_size); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)) + int mapping_config; - iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_S1_BYPASS, &bypass); + mapping_config = qcom_iommu_get_mappings_configuration(cb->iommu_domain); + if (mapping_config < 0) { + IPAERR("No Mapping configuration found for 11AD CB\n"); + } else { + bypass = (mapping_config & QCOM_IOMMU_MAPPING_CONF_S1_BYPASS) ? 1 : 0; + } +#else + iommu_domain_get_attr(cb->iommu_domain, DOMAIN_ATTR_S1_BYPASS, &bypass); +#endif IPADBG("11AD CB PROBE dev=%pK DOMAIN ATTRS bypass=%d\n", dev, bypass); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_defs.h b/drivers/platform/msm/ipa/ipa_v3/ipa_defs.h index 1c5476b784..09ecf4e078 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_defs.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_defs.h @@ -30,6 +30,9 @@ * will be assigned by ipa driver. * @close_aggr_irq_mod: close aggregation/coalescing and close GSI * interrupt moderation + * @ttl_update: bool to indicate whether TTL update is needed or not. + * @qos_class: QOS classification value. + * @skip_ingress: bool to skip ingress policing. */ struct ipa_rt_rule_i { enum ipa_client_type dst; @@ -43,6 +46,9 @@ struct ipa_rt_rule_i { u8 enable_stats; u8 cnt_idx; u8 close_aggr_irq_mod; + u8 ttl_update; + u8 qos_class; + u8 skip_ingress; }; /** @@ -77,6 +83,8 @@ struct ipa_rt_rule_i { * will be assigned by ipa driver. * @close_aggr_irq_mod: close aggregation/coalescing and close GSI * interrupt moderation + * @ttl_update: bool to indicate whether TTL update is needed or not. + * @qos_class: QOS classification value. */ struct ipa_flt_rule_i { u8 retain_hdr; @@ -95,6 +103,8 @@ struct ipa_flt_rule_i { u8 enable_stats; u8 cnt_idx; u8 close_aggr_irq_mod; + u8 ttl_update; + u8 qos_class; }; #endif /* _IPA_DEFS_H_ */ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 00ae2c522e..8c10157ca2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -4921,6 +4921,7 @@ fail_and_disable_clocks: fail_gen: return result; } +EXPORT_SYMBOL(ipa3_sys_setup); int ipa3_sys_teardown(u32 clnt_hdl) { @@ -4946,6 +4947,7 @@ int ipa3_sys_teardown(u32 clnt_hdl) return 0; } +EXPORT_SYMBOL(ipa3_sys_teardown); int ipa3_sys_update_gsi_hdls(u32 clnt_hdl, unsigned long gsi_ch_hdl, unsigned long gsi_ev_hdl) @@ -4965,6 +4967,7 @@ int ipa3_sys_update_gsi_hdls(u32 clnt_hdl, unsigned long gsi_ch_hdl, return 0; } +EXPORT_SYMBOL(ipa3_sys_update_gsi_hdls); static void ipa_gsi_evt_ring_err_cb(struct gsi_evt_err_notify *notify) { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 676095c813..1409c9eb54 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2776,6 +2776,8 @@ void ipa3_cal_ep_holb_scale_base_val(u32 tmr_val, int ipa3_cfg_ep_cfg(u32 clnt_hdl, const struct ipa_ep_cfg_cfg *ipa_ep_cfg); +int ipa3_cfg_ep_prod_cfg(u32 clnt_hdl, const struct ipa_ep_cfg_prod_cfg *prod_cfg); + int ipa3_force_cfg_ep_holb(u32 clnt_hdl, struct ipa_ep_cfg_holb *ipa_ep_cfg); int ipa3_cfg_ep_metadata_mask(u32 clnt_hdl, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 7bfbc8c488..2ab18fc168 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -2385,7 +2385,11 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, } } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) + ret = mhi_prepare_for_transfer(ipa_mpm_ctx->md[probe_id].mhi_dev, 0); +#else ret = mhi_prepare_for_transfer(ipa_mpm_ctx->md[probe_id].mhi_dev); +#endif if (ret) { IPA_MPM_ERR("mhi_prepare_for_transfer failed %d\n", ret); /* 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 a96f8f653c..ed4d768f07 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index cc3bc0857a..ec639ce062 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -203,7 +203,19 @@ #define IPA_v5_0_DST_GROUP_MAX (7) #define IPA_v5_0_GROUP_MAX (7) -#define IPA_GROUP_MAX IPA_v5_0_GROUP_MAX +#define IPA_v5_5_GROUP_UL (0) +#define IPA_v5_5_GROUP_DL (1) +#define IPA_v5_5_GROUP_DMA (2) +#define IPA_v5_5_GROUP_QDSS (3) +#define IPA_v5_5_GROUP_URLLC (4) +#define IPA_v5_5_GROUP_CV2X (4) +#define IPA_v5_5_GROUP_UC (5) +#define IPA_v5_5_GROUP_DRB_IP (6) +#define IPA_v5_5_SRC_GROUP_MAX (6) +#define IPA_v5_5_DST_GROUP_MAX (7) +#define IPA_v5_5_GROUP_MAX (7) + +#define IPA_GROUP_MAX IPA_v5_5_GROUP_MAX enum ipa_rsrc_grp_type_src { IPA_v3_0_RSRC_GRP_TYPE_SRC_PKT_CONTEXTS, @@ -309,6 +321,7 @@ enum ipa_ver { IPA_5_0_MHI, IPA_5_1, IPA_5_1_APQ, + IPA_5_5, IPA_VER_MAX, }; @@ -584,6 +597,19 @@ static const struct rsrc_min_max ipa3_rsrc_src_grp_config {22, 22}, {16, 16}, {0, 0}, {0, 0}, {16, 16}, {0, 0}, {0, 0}, }, }, + [IPA_5_5] = { + /* UL DL unused unused URLLC UC_RX_Q N/A */ + [IPA_v5_0_RSRC_GRP_TYPE_SRC_PKT_CONTEXTS] = { + {3, 9}, {4, 10}, {0, 0}, {0, 0}, {1, 63}, {0, 63}, {0, 0}, }, + [IPA_v5_0_RSRC_GRP_TYPE_SRC_DESCRIPTOR_LISTS] = { + {9, 9}, {12, 12}, {0, 0}, {0, 0}, {10, 10}, {0, 0}, {0, 0}, }, + [IPA_v5_0_RSRC_GRP_TYPE_SRC_DESCRIPTOR_BUFF] = { + {9, 9}, {24, 24}, {0, 0}, {0, 0}, {20, 20}, {0, 0}, {0, 0}, }, + [IPA_v5_0_RSRC_GRP_TYPE_SRC_HPS_DMARS] = { + {0, 63}, {0, 63}, {0, 63}, {0, 63}, {1, 63}, {0, 63}, {0, 0}, }, + [IPA_v5_0_RSRC_GRP_TYPE_SRC_ACK_ENTRIES] = { + {22, 22}, {16, 16}, {0, 0}, {0, 0}, {16, 16}, {0, 0}, {0, 0}, }, + }, }; static const struct rsrc_min_max ipa3_rsrc_dst_grp_config @@ -737,6 +763,15 @@ static const struct rsrc_min_max ipa3_rsrc_dst_grp_config {0, 3}, {0, 3}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, }, }, + [IPA_5_5] = { + /* UL DL unused unused unused UC_RX_Q DRBIP N/A */ + [IPA_v5_0_RSRC_GRP_TYPE_DST_DATA_SECTORS] = { + {6, 6}, {5, 5}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {39, 39}, }, + [IPA_v5_0_RSRC_GRP_TYPE_DST_DPS_DMARS] = { + {0, 3}, {0, 3}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, }, + [IPA_v5_0_RSRC_GRP_TYPE_DST_ULSO_SEGMENTS] = { + {0, 0x3f}, {0, 0x3f}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, }, + }, }; static const struct rsrc_min_max ipa3_rsrc_rx_grp_config @@ -844,6 +879,11 @@ static const struct rsrc_min_max ipa3_rsrc_rx_grp_config {3, 3}, {3, 3}, {0, 0}, {0, 0}, {3, 3}, {0, 0} }, }, + [IPA_5_5] = { + /* UL DL unused unused URLLC UC_RX_Q */ + [IPA_RSRC_GRP_TYPE_RX_HPS_CMDQ] = { + {3, 3}, {3, 3}, {0, 0}, {0, 0}, {3, 3}, {0, 0} }, + }, }; static const u32 ipa3_rsrc_rx_grp_hps_weight_config @@ -5074,6 +5114,335 @@ static const struct ipa_ep_configuration ipa3_ep_mapping IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, { 36, 36, 8, 8, IPA_EE_AP }, IPA_TX_INSTANCE_NA }, + /* IPA_5_5 */ + [IPA_5_5][IPA_CLIENT_USB_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 1, 0, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_APPS_WAN_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 2, 11, 25, 32, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_APPS_WAN_LOW_LAT_PROD] = { + true, IPA_v5_5_GROUP_URLLC, + false, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 4, 9, 8, 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_WLAN2_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 6, 16, 8, 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 2 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_WIGIG_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 7, 17, 8, 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 2 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_APPS_LAN_PROD] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 9, 19, 26, 32, IPA_EE_AP, GSI_SMART_PRE_FETCH, 4 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_APPS_WAN_LOW_LAT_DATA_PROD] = { + true, IPA_v5_5_GROUP_URLLC, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 10, 5, 10, 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_APPS_CMD_PROD] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 14, 12, 20, 24, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_Q6_WAN_PROD] = { + true, IPA_v5_5_GROUP_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 12, 0, 16, 28, IPA_EE_Q6, GSI_SMART_PRE_FETCH, 2 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_Q6_CMD_PROD] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 13, 1, 20, 24, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_Q6_DL_NLO_DATA_PROD] = { + true, IPA_v5_5_GROUP_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 15, 2, 28, 32, IPA_EE_Q6, GSI_FREE_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_Q6_DL_NLO_LL_DATA_PROD] = { + true, IPA_v5_5_GROUP_URLLC, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 5, 8, 28, 32, IPA_EE_Q6, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_APPS_LAN_COAL_CONS] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 16, 13, 8, 23, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_UL }, + + [IPA_5_5][IPA_CLIENT_APPS_LAN_CONS] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 17, 14, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_UL }, + + [IPA_5_5][IPA_CLIENT_APPS_WAN_COAL_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 23, 4, 8, 23, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_APPS_WAN_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 24, 1, 9, 9, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_USB_DPL_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 25, 20, 5, 5, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_ODL_DPL_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 26, 2, 5, 5, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_WIGIG1_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 27, 21, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_WLAN2_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 28, 3, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_WLAN2_CONS1] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 29, 22, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_USB_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 30, 23, 9, 9, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_APPS_WAN_LOW_LAT_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 32, 8, 9, 9, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_APPS_WAN_LOW_LAT_DATA_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 33, 10, 9, 9, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_WIGIG2_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 34, 6, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_WIGIG3_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 35, 25, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_Q6_LAN_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 18, 3, 9, 9, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_Q6_QBAP_STATUS_CONS] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 19, 4, 9, 9, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_UL }, + + [IPA_5_5][IPA_CLIENT_Q6_UL_NLO_DATA_CONS] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 20, 5, 5, 5, IPA_EE_Q6, GSI_SMART_PRE_FETCH, 2 }, + IPA_TX_INSTANCE_UL }, + + [IPA_5_5][IPA_CLIENT_Q6_UL_NLO_ACK_CONS] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 21, 6, 5, 5, IPA_EE_Q6, GSI_SMART_PRE_FETCH, 2 }, + IPA_TX_INSTANCE_UL }, + + [IPA_5_5][IPA_CLIENT_Q6_WAN_CONS] = { + true, IPA_v5_5_GROUP_UL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 22, 7, 9, 9, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_UL }, + + /*For test purposes only*/ + [IPA_5_5][IPA_CLIENT_TEST_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_NO_UCP, + QMB_MASTER_SELECT_DDR, + { 0, 15, 8, 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_TEST1_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 3, 7, 8, 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_TEST2_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 1, 0, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_TEST3_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 11, 9, 8, 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_TEST4_PROD] = { + true, IPA_v5_5_GROUP_UL, + true, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 7, 17, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY, 0 }, + IPA_TX_INSTANCE_NA }, + + [IPA_5_5][IPA_CLIENT_TEST_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 32, 8, 9, 9, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_TEST1_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 34, 6, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_TEST2_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 33, 10, 9, 9, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_TEST3_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 30, 23, 9, 9, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, + + [IPA_5_5][IPA_CLIENT_TEST4_CONS] = { + true, IPA_v5_5_GROUP_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 35, 25, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 }, + IPA_TX_INSTANCE_DL }, }; static struct ipa3_mem_partition ipa_3_0_mem_part = { @@ -5937,6 +6306,103 @@ static struct ipa3_mem_partition ipa_5_1_mem_part = { .end_ofst = 0x4fe8, }; +static struct ipa3_mem_partition ipa_5_5_mem_part = { + .uc_descriptor_ram_ofst = 0x0, + .uc_descriptor_ram_size = 0x1000, + .uc_ofst = 0x1000, + .uc_size = 0x80, + .uc_info_ofst = 0x1080, + .uc_info_size = 0x200, + .ofst_start = 0x1280, + .v4_flt_hash_ofst = 0x1288, + .v4_flt_hash_size = 0x78, + .v4_flt_hash_size_ddr = 0x4000, + .v4_flt_nhash_ofst = 0x1308, + .v4_flt_nhash_size = 0x78, + .v4_flt_nhash_size_ddr = 0x4000, + .v6_flt_hash_ofst = 0x1388, + .v6_flt_hash_size = 0x78, + .v6_flt_hash_size_ddr = 0x4000, + .v6_flt_nhash_ofst = 0x1408, + .v6_flt_nhash_size = 0x78, + .v6_flt_nhash_size_ddr = 0x4000, + .v4_rt_num_index = 0x13, + .v4_modem_rt_index_lo = 0x0, + .v4_modem_rt_index_hi = 0xa, + .v4_apps_rt_index_lo = 0xb, + .v4_apps_rt_index_hi = 0x12, + .v4_rt_hash_ofst = 0x1488, + .v4_rt_hash_size = 0x98, + .v4_rt_hash_size_ddr = 0x4000, + .v4_rt_nhash_ofst = 0x1528, + .v4_rt_nhash_size = 0x98, + .v4_rt_nhash_size_ddr = 0x4000, + .v6_rt_num_index = 0x13, + .v6_modem_rt_index_lo = 0x0, + .v6_modem_rt_index_hi = 0xa, + .v6_apps_rt_index_lo = 0xb, + .v6_apps_rt_index_hi = 0x12, + .v6_rt_hash_ofst = 0x15c8, + .v6_rt_hash_size = 0x98, + .v6_rt_hash_size_ddr = 0x4000, + .v6_rt_nhash_ofst = 0x1668, + .v6_rt_nhash_size = 0x098, + .v6_rt_nhash_size_ddr = 0x4000, + .modem_hdr_ofst = 0x1708, + .modem_hdr_size = 0x240, + .apps_hdr_ofst = 0x1948, + .apps_hdr_size = 0x1e0, + .apps_hdr_size_ddr = 0x800, + .modem_hdr_proc_ctx_ofst = 0x1b40, + .modem_hdr_proc_ctx_size = 0xb20, + .apps_hdr_proc_ctx_ofst = 0x2660, + .apps_hdr_proc_ctx_size = 0x200, + .apps_hdr_proc_ctx_size_ddr = 0x0, + .stats_quota_q6_ofst = 0x2868, + .stats_quota_q6_size = 0x48, + .stats_quota_ap_ofst = 0x28B0, + .stats_quota_ap_size = 0x60, + .stats_tethering_ofst = 0x2910, + .stats_tethering_size = 0x3c0, + .stats_flt_v4_ofst = 0, + .stats_flt_v4_size = 0, + .stats_flt_v6_ofst = 0, + .stats_flt_v6_size = 0, + .stats_rt_v4_ofst = 0, + .stats_rt_v4_size = 0, + .stats_rt_v6_ofst = 0, + .stats_rt_v6_size = 0, + .stats_fnr_ofst = 0x2cd0, + .stats_fnr_size = 0xba0, + .stats_drop_ofst = 0x3870, + .stats_drop_size = 0x20, + .modem_comp_decomp_ofst = 0x0, + .modem_comp_decomp_size = 0x0, + .modem_ofst = 0x3898, + .modem_size = 0xd48, + .nat_tbl_ofst = 0x45e0, + .nat_tbl_size = 0x900, + .apps_v4_flt_hash_ofst = 0x2718, + .apps_v4_flt_hash_size = 0x0, + .apps_v4_flt_nhash_ofst = 0x2718, + .apps_v4_flt_nhash_size = 0x0, + .apps_v6_flt_hash_ofst = 0x2718, + .apps_v6_flt_hash_size = 0x0, + .apps_v6_flt_nhash_ofst = 0x2718, + .apps_v6_flt_nhash_size = 0x0, + .apps_v4_rt_hash_ofst = 0x2718, + .apps_v4_rt_hash_size = 0x0, + .apps_v4_rt_nhash_ofst = 0x2718, + .apps_v4_rt_nhash_size = 0x0, + .apps_v6_rt_hash_ofst = 0x2718, + .apps_v6_rt_hash_size = 0x0, + .apps_v6_rt_nhash_ofst = 0x2718, + .apps_v6_rt_nhash_size = 0x0, + .pdn_config_ofst = 0x4ee8, + .pdn_config_size = 0x100, + .end_ofst = 0x4fe8, +}; + const char *ipa_clients_strings[IPA_CLIENT_MAX] = { __stringify(IPA_CLIENT_HSIC1_PROD), __stringify(IPA_CLIENT_HSIC1_CONS), @@ -6580,6 +7046,9 @@ u8 ipa3_get_hw_type_index(void) if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ) hw_type_index = IPA_5_1_APQ; break; + case IPA_HW_v5_5: + hw_type_index = IPA_5_5; + break; default: IPAERR("Incorrect IPA version %d\n", ipa3_ctx->ipa_hw_type); hw_type_index = IPA_3_0; @@ -7484,6 +7953,12 @@ int ipa3_cfg_ep(u32 clnt_hdl, const struct ipa_ep_cfg *ipa_ep_cfg) &ipa_ep_cfg->metadata_mask); if (result) return result; + + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v5_5) { + result = ipa3_cfg_ep_prod_cfg(clnt_hdl, &ipa_ep_cfg->prod_cfg); + if (result) + return result; + } } return 0; @@ -7540,10 +8015,11 @@ int ipa3_cfg_ep_nat(u32 clnt_hdl, const struct ipa_ep_cfg_nat *ep_nat) return -EINVAL; } - IPADBG("pipe=%d, nat_en=%d(%s)\n", + IPADBG("pipe=%d, nat_en=%d(%s), nat_exc_suppress=%d\n", clnt_hdl, ep_nat->nat_en, - ipa3_get_nat_en_str(ep_nat->nat_en)); + ipa3_get_nat_en_str(ep_nat->nat_en), + ep_nat->nat_exc_suppress); /* copy over EP cfg */ ipa3_ctx->ep[clnt_hdl].cfg.nat = *ep_nat; @@ -7552,6 +8028,11 @@ int ipa3_cfg_ep_nat(u32 clnt_hdl, const struct ipa_ep_cfg_nat *ep_nat) ipahal_write_reg_n_fields(IPA_ENDP_INIT_NAT_n, clnt_hdl, ep_nat); + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v5_5) { + ipahal_write_reg_n_fields(IPA_ENDP_INIT_NAT_EXC_SUPPRESS_n, + clnt_hdl, ep_nat); + } + IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl)); return 0; @@ -7699,6 +8180,53 @@ int ipa3_cfg_ep_cfg(u32 clnt_hdl, const struct ipa_ep_cfg_cfg *cfg) return 0; } +/** + * ipa3_cfg_ep_prod_cfg() - IPA Producer end-point configuration + * @clnt_hdl: [in] opaque client handle assigned by IPA to client + * @prod_cfg: [in] Producer specific configuration + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa3_cfg_ep_prod_cfg(u32 clnt_hdl, const struct ipa_ep_cfg_prod_cfg *prod_cfg) +{ + u8 tx_instance; + + if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || + ipa3_ctx->ep[clnt_hdl].valid == 0 || + IPA_CLIENT_IS_PROD(ipa3_ctx->ep[clnt_hdl].client) || + prod_cfg == NULL) { + IPAERR("bad parm, clnt_hdl = %d , ep_valid = %d\n", + clnt_hdl, + ipa3_ctx->ep[clnt_hdl].valid); + return -EINVAL; + } + + /* copy over EP cfg */ + ipa3_ctx->ep[clnt_hdl].cfg.prod_cfg = *prod_cfg; + + tx_instance = ipa3_get_tx_instance(ipa3_ctx->ep[clnt_hdl].client); + if (tx_instance == -EINVAL) { + IPAERR("bad parm, clnt_hdl = %d , ep_valid = %d\n", + clnt_hdl, + ipa3_ctx->ep[clnt_hdl].valid); + return -EINVAL; + } + ipa3_ctx->ep[clnt_hdl].cfg.cfg.tx_instance = tx_instance; + ipa3_ctx->ep[clnt_hdl].cfg.prod_cfg.tx_instance = tx_instance; + + IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl)); + + ipahal_write_reg_n_fields(IPA_ENDP_INIT_PROD_CFG_n, clnt_hdl, + &ipa3_ctx->ep[clnt_hdl].cfg.prod_cfg); + + IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl)); + + return 0; +} + + /** * ipa3_cfg_ep_metadata_mask() - IPA end-point meta-data mask configuration * @clnt_hdl: [in] opaque client handle assigned by IPA to client @@ -8856,6 +9384,9 @@ int ipa3_init_mem_partition(enum ipa_hw_type type) case IPA_HW_v5_1: ipa3_ctx->ctrl->mem_partition = &ipa_5_1_mem_part; break; + case IPA_HW_v5_5: + ipa3_ctx->ctrl->mem_partition = &ipa_5_5_mem_part; + break; case IPA_HW_None: case IPA_HW_v1_0: case IPA_HW_v1_1: @@ -10661,6 +11192,66 @@ static void ipa3_write_rsrc_grp_type_reg(int group_index, } break; + case IPA_5_5: + if (src) { + switch (group_index) { + case IPA_v5_5_GROUP_UL: + case IPA_v5_5_GROUP_DL: + ipahal_write_reg_n_fields( + IPA_SRC_RSRC_GRP_01_RSRC_TYPE_n, + n, val); + break; + case IPA_v5_5_GROUP_DMA: + case IPA_v5_5_GROUP_QDSS: + ipahal_write_reg_n_fields( + IPA_SRC_RSRC_GRP_23_RSRC_TYPE_n, + n, val); + break; + case IPA_v5_5_GROUP_URLLC: + case IPA_v5_5_GROUP_UC: + ipahal_write_reg_n_fields( + IPA_SRC_RSRC_GRP_45_RSRC_TYPE_n, + n, val); + break; + default: + IPAERR( + " Invalid source resource group,index #%d\n", + group_index); + break; + } + } else { + switch (group_index) { + case IPA_v5_5_GROUP_UL: + case IPA_v5_5_GROUP_DL: + ipahal_write_reg_n_fields( + IPA_DST_RSRC_GRP_01_RSRC_TYPE_n, + n, val); + break; + case IPA_v5_5_GROUP_DMA: + case IPA_v5_5_GROUP_QDSS: + ipahal_write_reg_n_fields( + IPA_DST_RSRC_GRP_23_RSRC_TYPE_n, + n, val); + break; + case IPA_v5_5_GROUP_URLLC: + case IPA_v5_5_GROUP_UC: + ipahal_write_reg_n_fields( + IPA_DST_RSRC_GRP_45_RSRC_TYPE_n, + n, val); + break; + case IPA_v5_5_GROUP_DRB_IP: + ipahal_write_reg_n_fields( + IPA_DST_RSRC_GRP_67_RSRC_TYPE_n, + n, val); + break; + default: + IPAERR( + " Invalid destination resource group,index #%d\n", + group_index); + break; + } + } + break; default: IPAERR("invalid hw type\n"); @@ -10848,6 +11439,12 @@ void ipa3_set_resorce_groups_min_max_limits(void) src_grp_idx_max = IPA_v5_0_SRC_GROUP_MAX; dst_grp_idx_max = IPA_v5_0_DST_GROUP_MAX; break; + case IPA_5_5: + src_rsrc_type_max = IPA_v5_0_RSRC_GRP_TYPE_SRC_MAX; + dst_rsrc_type_max = IPA_v5_0_RSRC_GRP_TYPE_DST_MAX; + src_grp_idx_max = IPA_v5_5_SRC_GROUP_MAX; + dst_grp_idx_max = IPA_v5_5_DST_GROUP_MAX; + break; default: IPAERR("invalid hw type index\n"); WARN_ON(1); @@ -12092,6 +12689,7 @@ struct device *ipa3_get_pdev(void) return ipa3_ctx->pdev; } +EXPORT_SYMBOL(ipa3_get_pdev); /** * ipa3_enable_dcd() - enable dynamic clock division on IPA diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c index 37118f0e1e..13f1460f3f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c @@ -472,6 +472,67 @@ static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_ip_packet_init_ex( return pyld; } +static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_ip_packet_init_ex_v5_5( + enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx) +{ + struct ipahal_imm_cmd_pyld *pyld; + struct ipa_imm_cmd_hw_ip_packet_init_ex_v5_5 *data; + struct ipahal_imm_cmd_ip_packet_init_ex *packet_init_ex_params = + (struct ipahal_imm_cmd_ip_packet_init_ex *)params; + + pyld = IPAHAL_MEM_ALLOC(sizeof(*pyld) + sizeof(*data), is_atomic_ctx); + if (unlikely(!pyld)) { + IPAHAL_ERR("kzalloc err\n"); + return pyld; + } + pyld->opcode = ipahal_imm_cmd_get_opcode(cmd); + pyld->len = sizeof(*data); + data = (struct ipa_imm_cmd_hw_ip_packet_init_ex_v5_5 *)pyld->data; + + data->frag_disable = packet_init_ex_params->frag_disable; + data->filter_disable = packet_init_ex_params->filter_disable; + data->nat_disable = packet_init_ex_params->nat_disable; + data->route_disable = packet_init_ex_params->route_disable; + data->hdr_removal_insertion_disable = + packet_init_ex_params->hdr_removal_insertion_disable; + data->cs_disable = packet_init_ex_params->cs_disable; + data->quota_tethering_stats_disable = + packet_init_ex_params->quota_tethering_stats_disable; + data->dpl_disable = packet_init_ex_params->dpl_disable; + data->flt_rt_tbl_idx = packet_init_ex_params->flt_rt_tbl_idx; + data->flt_stats_cnt_idx = packet_init_ex_params->flt_stats_cnt_idx; + data->flt_priority = packet_init_ex_params->flt_priority; + data->flt_ext_hdr = packet_init_ex_params->flt_ext_hdr; + data->flt_close_aggr_irq_mod = + packet_init_ex_params->flt_close_aggr_irq_mod; + /* rule id value of 0x3FF is required */ + /* (if not set correctly, filtering stats may be updated) */ + data->flt_rule_id = 0x3FF; + data->flt_action = packet_init_ex_params->flt_action; + data->flt_pdn_idx = packet_init_ex_params->flt_pdn_idx; + data->flt_set_metadata = packet_init_ex_params->flt_set_metadata; + data->flt_retain_hdr = packet_init_ex_params->flt_retain_hdr; + data->flt_ttl = packet_init_ex_params->flt_ttl; + data->flt_qos_class = packet_init_ex_params->flt_qos_class; + data->rt_pipe_dest_idx = packet_init_ex_params->rt_pipe_dest_idx; + data->rt_stats_cnt_idx = packet_init_ex_params->rt_stats_cnt_idx; + data->rt_priority = packet_init_ex_params->rt_priority; + data->rt_ext_hdr = packet_init_ex_params->rt_ext_hdr; + data->rt_close_aggr_irq_mod = + packet_init_ex_params->rt_close_aggr_irq_mod; + /* rule id value of 0x3FF is required */ + /* (if not set correctly, filtering stats may be updated) */ + data->rt_rule_id = 0x3FF; + data->rt_hdr_offset = packet_init_ex_params->rt_hdr_offset; + data->rt_proc_ctx = packet_init_ex_params->rt_proc_ctx; + data->rt_retain_hdr = packet_init_ex_params->rt_retain_hdr; + data->rt_system = packet_init_ex_params->rt_system; + data->rt_ttl = packet_init_ex_params->rt_ttl; + data->rt_qos_class = packet_init_ex_params->rt_qos_class; + data->rt_skip_ingress = packet_init_ex_params->rt_skip_ingress; + return pyld; +} + int ipa_imm_cmd_modify_ip_packet_init_ex( enum ipahal_imm_cmd_name cmd, const void *cmd_data, @@ -512,12 +573,71 @@ int ipa_imm_cmd_modify_ip_packet_init_ex( return 0; } +static int ipa_imm_cmd_modify_ip_packet_init_ex_v5_5( + enum ipahal_imm_cmd_name cmd, + const void *cmd_data, + const void *params, + const void *params_mask) +{ + struct ipa_imm_cmd_hw_ip_packet_init_ex_v5_5 *data = + (struct ipa_imm_cmd_hw_ip_packet_init_ex_v5_5 *)cmd_data; + struct ipahal_imm_cmd_ip_packet_init_ex *mask = + (struct ipahal_imm_cmd_ip_packet_init_ex *)params_mask; + struct ipahal_imm_cmd_ip_packet_init_ex *prms = + (struct ipahal_imm_cmd_ip_packet_init_ex *)params; + + CHECK_SET_PARAM(frag_disable, data, prms, mask); + CHECK_SET_PARAM(filter_disable, data, prms, mask); + CHECK_SET_PARAM(nat_disable, data, prms, mask); + CHECK_SET_PARAM(route_disable, data, prms, mask); + CHECK_SET_PARAM(hdr_removal_insertion_disable, data, prms, mask); + CHECK_SET_PARAM(cs_disable, data, prms, mask); + CHECK_SET_PARAM(quota_tethering_stats_disable, data, prms, mask); + CHECK_SET_PARAM(dpl_disable, data, prms, mask); + CHECK_SET_PARAM(flt_rt_tbl_idx, data, prms, mask); + CHECK_SET_PARAM(flt_stats_cnt_idx, data, prms, mask); + CHECK_SET_PARAM(flt_priority, data, prms, mask); + CHECK_SET_PARAM(flt_close_aggr_irq_mod, data, prms, mask); + CHECK_SET_PARAM(flt_action, data, prms, mask); + CHECK_SET_PARAM(flt_pdn_idx, data, prms, mask); + CHECK_SET_PARAM(flt_set_metadata, data, prms, mask); + CHECK_SET_PARAM(flt_retain_hdr, data, prms, mask); + CHECK_SET_PARAM(rt_pipe_dest_idx, data, prms, mask); + CHECK_SET_PARAM(rt_stats_cnt_idx, data, prms, mask); + CHECK_SET_PARAM(rt_priority, data, prms, mask); + CHECK_SET_PARAM(rt_close_aggr_irq_mod, data, prms, mask); + CHECK_SET_PARAM(rt_hdr_offset, data, prms, mask); + CHECK_SET_PARAM(rt_proc_ctx, data, prms, mask); + CHECK_SET_PARAM(rt_retain_hdr, data, prms, mask); + CHECK_SET_PARAM(rt_system, data, prms, mask); + CHECK_SET_PARAM(flt_ext_hdr, data, prms, mask); + CHECK_SET_PARAM(flt_ttl, data, prms, mask); + CHECK_SET_PARAM(flt_qos_class, data, prms, mask); + CHECK_SET_PARAM(rt_ext_hdr, data, prms, mask); + CHECK_SET_PARAM(rt_ttl, data, prms, mask); + CHECK_SET_PARAM(rt_qos_class, data, prms, mask); + CHECK_SET_PARAM(rt_skip_ingress, data, prms, mask); + return 0; +} + +inline void ipa_imm_cmd_modify_ip_packet_init_ex_dest_pipe_v5_5( + const void *cmd_data, + u64 pipe_dest_idx) +{ + ((struct ipa_imm_cmd_hw_ip_packet_init_ex_v5_5 *)cmd_data)->rt_pipe_dest_idx + = pipe_dest_idx; +} + inline void ipa_imm_cmd_modify_ip_packet_init_ex_dest_pipe( const void *cmd_data, u64 pipe_dest_idx) { - ((struct ipa_imm_cmd_hw_ip_packet_init_ex *)cmd_data)->rt_pipe_dest_idx - = pipe_dest_idx; + if (ipahal_ctx->hw_type >= IPA_HW_v5_5) + return ipa_imm_cmd_modify_ip_packet_init_ex_dest_pipe_v5_5(cmd_data, + pipe_dest_idx); + else + ((struct ipa_imm_cmd_hw_ip_packet_init_ex *)cmd_data)->rt_pipe_dest_idx + = pipe_dest_idx; } static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_nat_dma( @@ -942,6 +1062,11 @@ static struct ipahal_imm_cmd_obj ipa_imm_cmd_construct_register_read, ipa_imm_cmd_modify_dummy, 13}, + /* IPAv5_5 */ + [IPA_HW_v5_5][IPA_IMM_CMD_IP_PACKET_INIT_EX] = { + ipa_imm_cmd_construct_ip_packet_init_ex_v5_5, + ipa_imm_cmd_modify_ip_packet_init_ex_v5_5, + 18}, }; /* @@ -1151,6 +1276,9 @@ static enum ipahal_pkt_status_exception pkt_status_parse_exception( case 8: exception_type = IPAHAL_PKT_STATUS_EXCEPTION_PACKET_LENGTH; break; + case 10: + exception_type = IPAHAL_PKT_STATUS_EXCEPTION_TTL; + break; case 16: exception_type = IPAHAL_PKT_STATUS_EXCEPTION_FRAG_RULE_MISS; break; @@ -1164,8 +1292,11 @@ static enum ipahal_pkt_status_exception pkt_status_parse_exception( exception_type = IPAHAL_PKT_STATUS_EXCEPTION_NAT; break; case 128: - exception_type = IPAHAL_PKT_STATUS_EXCEPTION_UCP; - break; + exception_type = IPAHAL_PKT_STATUS_EXCEPTION_UCP; + break; + case 131: + exception_type = IPAHAL_PKT_STATUS_EXCEPTION_RQOS; + break; case 229: exception_type = IPAHAL_PKT_STATUS_EXCEPTION_CSUM; break; @@ -1308,16 +1439,97 @@ static void __ipa_parse_frag_pkt_v5_0(struct ipahal_pkt_status *status, status->nat_type = hw_status->frag_pkt.nat_type; } +static void __ipa_parse_gen_pkt_v5_5(struct ipahal_pkt_status *status, + const void *unparsed_status) +{ + bool is_ipv6; + union ipa_pkt_status_hw_v5_5 *hw_status = + (union ipa_pkt_status_hw_v5_5 *)unparsed_status; + + is_ipv6 = (hw_status->ipa_pkt.status_mask & 0x80) ? false : true; + status->pkt_len = hw_status->ipa_pkt.pkt_len; + status->endp_src_idx = hw_status->ipa_pkt.endp_src_idx; + status->endp_dest_idx = hw_status->ipa_pkt.endp_dest_idx; + status->metadata = hw_status->ipa_pkt.metadata; + status->flt_local = hw_status->ipa_pkt.flt_local; + status->flt_hash = hw_status->ipa_pkt.flt_hash; + status->flt_global = hw_status->ipa_pkt.flt_hash; + status->flt_ret_hdr = hw_status->ipa_pkt.flt_ret_hdr; + status->flt_miss = (hw_status->ipa_pkt.rt_rule_id == + IPAHAL_PKT_STATUS_FLTRT_RULE_MISS_ID); + status->flt_rule_id = hw_status->ipa_pkt.flt_rule_id; + status->rt_local = hw_status->ipa_pkt.rt_local; + status->rt_hash = hw_status->ipa_pkt.rt_hash; + status->ucp = hw_status->ipa_pkt.ucp; + status->rt_tbl_idx = hw_status->ipa_pkt.rt_tbl_idx; + status->rt_miss = (hw_status->ipa_pkt.rt_rule_id == + IPAHAL_PKT_STATUS_FLTRT_RULE_MISS_ID); + status->rt_rule_id = hw_status->ipa_pkt.rt_rule_id; + status->nat_hit = hw_status->ipa_pkt.nat_hit; + status->nat_entry_idx = hw_status->ipa_pkt.nat_entry_idx; + status->tag_info = hw_status->ipa_pkt.tag_info; + status->egress_tc = hw_status->ipa_pkt.egress_tc; + status->ingress_tc = hw_status->ipa_pkt.ingress_tc; + status->seq_num = hw_status->ipa_pkt.seq_num; + status->time_of_day_ctr = hw_status->ipa_pkt.time_of_day_ctr; + status->hdr_local = hw_status->ipa_pkt.hdr_local; + status->hdr_offset = hw_status->ipa_pkt.hdr_offset; + status->frag_hit = hw_status->ipa_pkt.frag_hit; + status->frag_rule = hw_status->ipa_pkt.frag_rule; + status->nat_type = hw_status->ipa_pkt.nat_type; + status->nat_exc_suppress = hw_status->ipa_pkt.nat_exc_suppress; + status->tsp = hw_status->ipa_pkt.tsp; + status->ttl_dec = hw_status->ipa_pkt.ttl_dec; + + status->exception = pkt_status_parse_exception(is_ipv6, + hw_status->ipa_pkt.exception); +} + + +static void __ipa_parse_frag_pkt_v5_5(struct ipahal_pkt_status *status, + const void *unparsed_status) +{ + union ipa_pkt_status_hw_v5_5 *hw_status = + (union ipa_pkt_status_hw_v5_5 *)unparsed_status; + + status->frag_rule_idx = hw_status->frag_pkt.frag_rule_idx; + status->tbl_idx = hw_status->frag_pkt.tbl_idx; + status->src_ip_addr = hw_status->frag_pkt.src_ip_addr; + status->dest_ip_addr = hw_status->frag_pkt.dest_ip_addr; + status->protocol = hw_status->frag_pkt.protocol; + status->ip_id = hw_status->frag_pkt.ip_id; + status->tlated_ip_addr = hw_status->frag_pkt.tlated_ip_addr; + status->ip_cksum_diff = hw_status->frag_pkt.ip_cksum_diff; + status->endp_src_idx = hw_status->frag_pkt.endp_src_idx; + status->endp_dest_idx = hw_status->frag_pkt.endp_dest_idx; + status->metadata = hw_status->frag_pkt.metadata; + status->seq_num = hw_status->frag_pkt.seq_num; + status->hdr_local = hw_status->frag_pkt.hdr_local; + status->hdr_offset = hw_status->frag_pkt.hdr_offset; + status->exception = hw_status->frag_pkt.exception; + status->nat_type = hw_status->frag_pkt.nat_type; + status->hdr_ret = hw_status->frag_pkt.ret; + status->ll = hw_status->frag_pkt.ll; + status->ingress_tc = hw_status->frag_pkt.ingress_tc; + status->egress_tc = hw_status->frag_pkt.egress_tc; + status->pd = hw_status->frag_pkt.pd; +} + + static void ipa_pkt_status_parse( const void *unparsed_status, struct ipahal_pkt_status *status); static void ipa_pkt_status_parse_thin(const void *unparsed_status, struct ipahal_pkt_status_thin *status); static void ipa_pkt_status_parse_thin_v5_0(const void *unparsed_status, struct ipahal_pkt_status_thin *status); +static void ipa_pkt_status_parse_thin_v5_5(const void *unparsed_status, + struct ipahal_pkt_status_thin *status); static void ipa_pkt_status_parse( const void *unparsed_status, struct ipahal_pkt_status *status); static void ipa_pkt_status_parse_v5_0( const void *unparsed_status, struct ipahal_pkt_status *status); +static void ipa_pkt_status_parse_v5_5( + const void *unparsed_status, struct ipahal_pkt_status *status); /* * struct ipahal_pkt_status_obj - Pakcet Status H/W information for * specific IPA version @@ -1363,6 +1575,14 @@ static struct ipahal_pkt_status_obj ipahal_pkt_status_objs[IPA_HW_MAX] = { __ipa_parse_gen_pkt_v5_0, __ipa_parse_frag_pkt_v5_0, }, + /* IPAv5.5 */ + [IPA_HW_v5_5] = { + IPA3_0_PKT_STATUS_SIZE, + ipa_pkt_status_parse_v5_5, + ipa_pkt_status_parse_thin_v5_5, + __ipa_parse_gen_pkt_v5_5, + __ipa_parse_frag_pkt_v5_5, + }, }; static inline enum ipahal_pkt_status_opcode ipa_hw_opcode_to_opcode( @@ -1446,6 +1666,32 @@ static inline void ipa_set_pkt_status_mask(const u16 hw_status_mask, status->status_mask &= 0xFFFF; } +static inline void ipa_set_pkt_status_mask_v5_5(const u16 hw_status_mask, + struct ipahal_pkt_status *status) +{ + IPA_PKT_STATUS_SET_MSK(0x1, IPAHAL_PKT_STATUS_MASK_FRAG_PROCESS_SHFT); + IPA_PKT_STATUS_SET_MSK(0x2, IPAHAL_PKT_STATUS_MASK_FILT_PROCESS_SHFT); + IPA_PKT_STATUS_SET_MSK(0x4, IPAHAL_PKT_STATUS_MASK_NAT_PROCESS_SHFT); + IPA_PKT_STATUS_SET_MSK(0x8, IPAHAL_PKT_STATUS_MASK_ROUTE_PROCESS_SHFT); + IPA_PKT_STATUS_SET_MSK(0x10, IPAHAL_PKT_STATUS_MASK_TAG_VALID_SHFT); + IPA_PKT_STATUS_SET_MSK(0x20, IPAHAL_PKT_STATUS_MASK_FRAGMENT_SHFT); + IPA_PKT_STATUS_SET_MSK(0x40, + IPAHAL_PKT_STATUS_MASK_FIRST_FRAGMENT_SHFT); + IPA_PKT_STATUS_SET_MSK(0x80, IPAHAL_PKT_STATUS_MASK_V4_SHFT); + IPA_PKT_STATUS_SET_MSK(0x100, + IPAHAL_PKT_STATUS_MASK_CKSUM_PROCESS_SHFT); + IPA_PKT_STATUS_SET_MSK(0x200, IPAHAL_PKT_STATUS_MASK_AGGR_PROCESS_SHFT); + IPA_PKT_STATUS_SET_MSK(0x400, IPAHAL_PKT_STATUS_MASK_OPENED_FRAME_SHFT); + IPA_PKT_STATUS_SET_MSK(0x800, + IPAHAL_PKT_STATUS_MASK_DEAGGR_PROCESS_SHFT); + IPA_PKT_STATUS_SET_MSK(0x1000, IPAHAL_PKT_STATUS_MASK_DEAGG_FIRST_SHFT); + IPA_PKT_STATUS_SET_MSK(0x2000, IPAHAL_PKT_STATUS_MASK_SRC_EOT_SHFT); + IPA_PKT_STATUS_SET_MSK(0x4000, IPAHAL_PKT_STATUS_MASK_RQOS_NAS_SHFT); + IPA_PKT_STATUS_SET_MSK(0x8000, IPAHAL_PKT_STATUS_MASK_RQOS_AS_SHFT); + status->status_mask &= 0xFFFF; +} + + static void ipa_pkt_status_parse( const void *unparsed_status, struct ipahal_pkt_status *status) { @@ -1488,6 +1734,27 @@ static void ipa_pkt_status_parse_v5_0( ipa_set_pkt_status_mask((u16)(hw_status->ipa_pkt.status_mask), status); } +static void ipa_pkt_status_parse_v5_5( + const void *unparsed_status, struct ipahal_pkt_status *status) +{ + union ipa_pkt_status_hw_v5_5 *hw_status = + (union ipa_pkt_status_hw_v5_5 *)unparsed_status; + + status->status_opcode = + ipa_hw_opcode_to_opcode(hw_status->ipa_pkt.status_opcode); + + if (status->status_opcode == IPAHAL_PKT_STATUS_OPCODE_NEW_FRAG_RULE) + ipahal_pkt_status_objs[ipahal_ctx->hw_type].\ + __parse_frag_pkt(status, unparsed_status); + else + ipahal_pkt_status_objs[ipahal_ctx->hw_type].\ + __parse_gen_pkt(status, unparsed_status); + + status->nat_type = ipa_hw_nat_type_to_nat_type(status->nat_type); + + ipa_set_pkt_status_mask_v5_5((u16)(hw_status->ipa_pkt.status_mask), status); +} + /* * ipa_pkt_status_parse_thin() - Parse some of the packet status fields * for specific usage in the LAN rx data path where parsing needs to be done @@ -1535,6 +1802,30 @@ static void ipa_pkt_status_parse_thin_v5_0(const void *unparsed_status, hw_status->ipa_pkt.exception); } +/* + * ipa_pkt_status_parse_thin_v5_5() - Parse some of the v5.5 packet status + * fields for specific usage in the LAN rx data path where parsing needs + * to be done but only for specific fields. + * @unparsed_status: Pointer to H/W format of the packet status as read from HW + * @status: Pointer to pre-allocated buffer where the parsed info will be + * stored + */ +static void ipa_pkt_status_parse_thin_v5_5(const void *unparsed_status, + struct ipahal_pkt_status_thin *status) +{ + union ipa_pkt_status_hw_v5_5 *hw_status = + (union ipa_pkt_status_hw_v5_5 *)unparsed_status; + bool is_ipv6 = + (hw_status->ipa_pkt.status_mask & 0x80) ? false : true; + + IPAHAL_DBG_LOW("Parse Thin Status Packet\n"); + status->metadata = hw_status->ipa_pkt.metadata; + status->endp_src_idx = hw_status->ipa_pkt.endp_src_idx; + status->ucp = hw_status->ipa_pkt.ucp; + status->exception = pkt_status_parse_exception(is_ipv6, + hw_status->ipa_pkt.exception); +} + /* * ipahal_pkt_status_init() - Build the packet status information array * for the different IPA versions diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h index 92747a6704..b23fac0caa 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h @@ -241,9 +241,18 @@ struct ipahal_imm_cmd_ip_packet_init { * @cs_disable: true - disabled, false - enabled * @quota_tethering_stats_disable: true - disabled, false - enabled * fields @flt_rt_tbl_idx - @flt_retain_hdr are a logical software translation - * of ipa5_0_flt_rule_hw_hdr. + * of ipa5_0_flt_rule_hw_hdr/ipa5_5_flt_rule_hw_hdr * fields @rt_pipe_dest_idx - @rt_system are a logical software translation - * ipa5_0_rt_rule_hw_hdr + * ipa5_0_rt_rule_hw_hdr/ipa5_5_flt_rule_hw_hdr + * @dpl_disable: true - disabled, false - enabled, valid from IPAv5_5. + * @flt_ext_hdr: true - flt ext_hdr enabled, false - disabled. Note all fields of + * ext header are valid in immediate command irrespective of this flag. + * fields @flt_ttl - @flt_qos_class are a logical software translation + * of ipa5_5_flt_rule_hw_hdr_ext. + * @rt_ext_hdr: true - rt ext_hdr enabled, false - disabled. Note all fields of + * ext header are valid in immediate command irrespective of this flag. + * fields @rt_ttl - @rt_skip_ingress are a logical software translation + * ipa5_5_rt_rule_hw_hdr_ext */ struct ipahal_imm_cmd_ip_packet_init_ex { bool frag_disable; @@ -269,6 +278,14 @@ struct ipahal_imm_cmd_ip_packet_init_ex { bool rt_proc_ctx; bool rt_retain_hdr; bool rt_system; + bool dpl_disable; + bool flt_ext_hdr; + bool flt_ttl; + u8 flt_qos_class; + bool rt_ext_hdr; + bool rt_ttl; + u8 rt_qos_class; + bool rt_skip_ingress; }; /* @@ -513,6 +530,7 @@ enum ipahal_pkt_status_exception { IPAHAL_PKT_STATUS_EXCEPTION_IPTYPE, IPAHAL_PKT_STATUS_EXCEPTION_PACKET_LENGTH, IPAHAL_PKT_STATUS_EXCEPTION_PACKET_THRESHOLD, + IPAHAL_PKT_STATUS_EXCEPTION_TTL, IPAHAL_PKT_STATUS_EXCEPTION_FRAG_RULE_MISS, IPAHAL_PKT_STATUS_EXCEPTION_SW_FILT, /* @@ -522,6 +540,7 @@ enum ipahal_pkt_status_exception { IPAHAL_PKT_STATUS_EXCEPTION_NAT, IPAHAL_PKT_STATUS_EXCEPTION_IPV6CT, IPAHAL_PKT_STATUS_EXCEPTION_UCP, + IPAHAL_PKT_STATUS_EXCEPTION_RQOS, IPAHAL_PKT_STATUS_EXCEPTION_CSUM, IPAHAL_PKT_STATUS_EXCEPTION_MAX, }; @@ -567,11 +586,17 @@ enum ipahal_pkt_status_mask { IPAHAL_PKT_STATUS_MASK_CKSUM_PROCESS_SHFT, IPAHAL_PKT_STATUS_MASK_AGGR_PROCESS_SHFT, IPAHAL_PKT_STATUS_MASK_DEST_EOT_SHFT, + IPAHAL_PKT_STATUS_MASK_OPENED_FRAME_SHFT = + IPAHAL_PKT_STATUS_MASK_DEST_EOT_SHFT, IPAHAL_PKT_STATUS_MASK_DEAGGR_PROCESS_SHFT, IPAHAL_PKT_STATUS_MASK_DEAGG_FIRST_SHFT, IPAHAL_PKT_STATUS_MASK_SRC_EOT_SHFT, IPAHAL_PKT_STATUS_MASK_PREV_EOT_SHFT, + IPAHAL_PKT_STATUS_MASK_RQOS_NAS_SHFT = + IPAHAL_PKT_STATUS_MASK_PREV_EOT_SHFT, IPAHAL_PKT_STATUS_MASK_BYTE_LIMIT_SHFT, + IPAHAL_PKT_STATUS_MASK_RQOS_AS_SHFT = + IPAHAL_PKT_STATUS_MASK_BYTE_LIMIT_SHFT, }; /* @@ -648,6 +673,17 @@ enum ipahal_pkt_status_nat_type { * @ip_id: IP packet IP ID number. * @tlated_ip_addr: IP address. * @ip_cksum_diff: IP packet checksum difference. + * @hdr_ret: l2 header retained flag, indicates whether l2 header is retained + * or not. + * @ll: low latency indication. + * @tsp: Traffic shaping policing flag, indicates traffic class info + * overwrites tag info. + * @ttl_dec: ttl update flag, indicates whether ttl is updated. + * @nat_exc_suppress: nat exception supress flag, indicates whether + * nat exception is suppressed. + * @ingress_tc: Ingress traffic class index. + * @egress_tc: Egress traffic class index. + * @pd: router disabled ingress policer. */ struct ipahal_pkt_status { u64 tag_info; @@ -687,7 +723,14 @@ struct ipahal_pkt_status { u16 ip_id; u32 tlated_ip_addr; u16 ip_cksum_diff; - + bool hdr_ret; + bool ll; + bool tsp; + bool ttl_dec; + bool nat_exc_suppress; + u8 ingress_tc; + u8 egress_tc; + bool pd; }; /* diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c index 55b6dca181..ade9f43ef5 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c @@ -97,8 +97,12 @@ static const int ipa3_0_ihl_ofst_meq32[] = { IPA_IHL_OFFSET_MEQ32_0, static int ipa_fltrt_generate_hw_rule_bdy(enum ipa_ip_type ipt, const struct ipa_rule_attrib *attrib, u8 **buf, u16 *en_rule); +static int ipa_fltrt_generate_hw_rule_bdy_5_5(enum ipa_ip_type ipt, + const struct ipa_rule_attrib *attrib, u8 **buf, u16 *en_rule, bool ext_hdr); static int ipa_fltrt_generate_hw_rule_bdy_from_eq( const struct ipa_ipfltri_rule_eq *attrib, u8 **buf); +static int ipa_fltrt_generate_hw_rule_bdy_from_eq_5_5( + const struct ipa_ipfltri_rule_eq *attrib, u8 **buf, bool ext_hdr); static int ipa_flt_generate_eq_ip4(enum ipa_ip_type ip, const struct ipa_rule_attrib *attrib, struct ipa_ipfltri_rule_eq *eq_atrb); @@ -114,6 +118,8 @@ static int ipa_rt_parse_hw_rule_ipav4_5(u8 *addr, struct ipahal_rt_rule_entry *rule); static int ipa_rt_parse_hw_rule_ipav5_0(u8 *addr, struct ipahal_rt_rule_entry *rule); +static int ipa_rt_parse_hw_rule_ipav5_5(u8 *addr, + struct ipahal_rt_rule_entry *rule); static int ipa_flt_parse_hw_rule(u8 *addr, struct ipahal_flt_rule_entry *rule); static int ipa_flt_parse_hw_rule_ipav4(u8 *addr, @@ -122,6 +128,8 @@ static int ipa_flt_parse_hw_rule_ipav4_5(u8 *addr, struct ipahal_flt_rule_entry *rule); static int ipa_flt_parse_hw_rule_ipav5_0(u8 *addr, struct ipahal_flt_rule_entry *rule); + static int ipa_flt_parse_hw_rule_ipav5_5(u8 *addr, + struct ipahal_flt_rule_entry *rule); #define IPA_IS_RAN_OUT_OF_EQ(__eq_array, __eq_index) \ (ARRAY_SIZE(__eq_array) <= (__eq_index)) @@ -368,6 +376,88 @@ static int ipa_rt_gen_hw_rule_ipav5_0(struct ipahal_rt_rule_gen_params *params, return 0; } +static int ipa_rt_gen_hw_rule_ipav5_5(struct ipahal_rt_rule_gen_params *params, + u32 *hw_len, u8 *buf) +{ + struct ipa5_5_rt_rule_hw_hdr *rule_hdr; + struct ipa5_5_rt_rule_hw_hdr_ext *ext_hdr; + u8 *start; + u16 en_rule = 0; + + start = buf; + rule_hdr = (struct ipa5_5_rt_rule_hw_hdr *)buf; + + ipa_assert_on(params->dst_pipe_idx & ~0xFF); + rule_hdr->u.hdr.pipe_dest_idx = params->dst_pipe_idx; + switch (params->hdr_type) { + case IPAHAL_RT_RULE_HDR_PROC_CTX: + rule_hdr->u.hdr.system = !params->hdr_lcl; + rule_hdr->u.hdr.proc_ctx = 1; + ipa_assert_on(params->hdr_ofst & 31); + rule_hdr->u.hdr.hdr_offset = (params->hdr_ofst) >> 5; + break; + case IPAHAL_RT_RULE_HDR_RAW: + rule_hdr->u.hdr.system = !params->hdr_lcl; + rule_hdr->u.hdr.proc_ctx = 0; + ipa_assert_on(params->hdr_ofst & 3); + rule_hdr->u.hdr.hdr_offset = (params->hdr_ofst) >> 2; + break; + case IPAHAL_RT_RULE_HDR_NONE: + rule_hdr->u.hdr.system = !params->hdr_lcl; + rule_hdr->u.hdr.proc_ctx = 0; + rule_hdr->u.hdr.hdr_offset = 0; + break; + default: + IPAHAL_ERR("Invalid HDR type %d\n", params->hdr_type); + WARN_ON_RATELIMIT_IPA(1); + return -EINVAL; + } + + ipa_assert_on(params->priority & ~0xFF); + rule_hdr->u.hdr.priority = params->priority; + rule_hdr->u.hdr.retain_hdr = params->rule->retain_hdr ? 0x1 : 0x0; + ipa_assert_on(params->id & ~((1 << IPA3_0_RULE_ID_BIT_LEN) - 1)); + ipa_assert_on(params->id == ((1 << IPA3_0_RULE_ID_BIT_LEN) - 1)); + rule_hdr->u.hdr.rule_id = params->id; + rule_hdr->u.hdr.stats_cnt_idx = params->cnt_idx; + rule_hdr->u.hdr.close_aggr_irq_mod = + params->rule->close_aggr_irq_mod ? 0x1 : 0x0; + + buf += sizeof(struct ipa5_5_rt_rule_hw_hdr); + + if (params->rule->ttl_update || params->rule->qos_class || + params->rule->skip_ingress) { + ext_hdr = (struct ipa5_5_rt_rule_hw_hdr_ext *)buf; + rule_hdr->u.hdr.ext_hdr = 1; + ext_hdr->u.hdr.ttl = params->rule->ttl_update ? 0x1 : 0x0; + ext_hdr->u.hdr.qos_class = params->rule->qos_class; + ext_hdr->u.hdr.skip_ingress = params->rule->skip_ingress ? 0x1 : 0x0; + buf += sizeof(struct ipa5_5_rt_rule_hw_hdr_ext); + } else { + rule_hdr->u.hdr.ext_hdr = 0; + } + + if (ipa_fltrt_generate_hw_rule_bdy_5_5(params->ipt, ¶ms->rule->attrib, + &buf, &en_rule, rule_hdr->u.hdr.ext_hdr)) { + IPAHAL_ERR("fail to generate hw rule\n"); + return -EPERM; + } + rule_hdr->u.hdr.en_rule = en_rule; + + IPAHAL_DBG_LOW("en_rule 0x%x\n", en_rule); + ipa_write_64(rule_hdr->u.word, (u8 *)rule_hdr); + + if (*hw_len == 0) { + *hw_len = buf - start; + } else if (*hw_len != (buf - start)) { + IPAHAL_ERR("hw_len differs b/w passed=0x%x calc=%td\n", + *hw_len, (buf - start)); + return -EPERM; + } + + return 0; +} + static int ipa_flt_gen_hw_rule(struct ipahal_flt_rule_gen_params *params, u32 *hw_len, u8 *buf) { @@ -733,6 +823,125 @@ static int ipa_flt_gen_hw_rule_ipav5_0( return 0; } +static int ipa_flt_gen_hw_rule_ipav5_5( + struct ipahal_flt_rule_gen_params *params, + u32 *hw_len, u8 *buf) +{ + struct ipa5_5_flt_rule_hw_hdr *rule_hdr; + struct ipa5_5_flt_rule_hw_hdr_ext *ext_hdr; + u8 *start; + u16 en_rule = 0; + + start = buf; + rule_hdr = (struct ipa5_5_flt_rule_hw_hdr *)buf; + + switch (params->rule->action) { + case IPA_PASS_TO_ROUTING: + rule_hdr->u.hdr.action = 0x0; + break; + case IPA_PASS_TO_SRC_NAT: + rule_hdr->u.hdr.action = 0x1; + break; + case IPA_PASS_TO_DST_NAT: + rule_hdr->u.hdr.action = 0x2; + break; + case IPA_PASS_TO_EXCEPTION: + rule_hdr->u.hdr.action = 0x3; + break; + default: + IPAHAL_ERR_RL("Invalid Rule Action %d\n", params->rule->action); + WARN_ON_RATELIMIT_IPA(1); + return -EINVAL; + } + + if (params->rt_tbl_idx & ~0xFF) { + IPAHAL_ERR_RL("Invalid RT table idx 0x%X\n", + params->rt_tbl_idx); + WARN_ON_RATELIMIT_IPA(1); + return -EINVAL; + } + rule_hdr->u.hdr.rt_tbl_idx = params->rt_tbl_idx; + rule_hdr->u.hdr.retain_hdr = params->rule->retain_hdr ? 0x1 : 0x0; + + if (params->rule->pdn_idx & ~0xF) { + IPAHAL_ERR_RL("Invalid PDN idx 0x%X\n", params->rule->pdn_idx); + WARN_ON_RATELIMIT_IPA(1); + return -EINVAL; + } + rule_hdr->u.hdr.pdn_idx = params->rule->pdn_idx; + rule_hdr->u.hdr.set_metadata = params->rule->set_metadata ? 0x1 : 0x0; + rule_hdr->u.hdr.rsvd = 0; + + if (params->priority & ~0xFF) { + IPAHAL_ERR_RL("Invalid priority 0x%X\n", params->priority); + WARN_ON_RATELIMIT_IPA(1); + return -EINVAL; + } + rule_hdr->u.hdr.priority = params->priority; + if ((params->id & ~((1 << IPA3_0_RULE_ID_BIT_LEN) - 1)) || + (params->id == ((1 << IPA3_0_RULE_ID_BIT_LEN) - 1))) { + IPAHAL_ERR_RL("Invalid id 0x%X\n", params->id); + WARN_ON_RATELIMIT_IPA(1); + return -EINVAL; + } + rule_hdr->u.hdr.rule_id = params->id; + rule_hdr->u.hdr.stats_cnt_idx = params->cnt_idx; + rule_hdr->u.hdr.close_aggr_irq_mod = + params->rule->close_aggr_irq_mod ? 0x1 : 0x0; + + buf += sizeof(struct ipa5_5_flt_rule_hw_hdr); + + if (params->rule->ttl_update || params->rule->qos_class) { + ext_hdr = (struct ipa5_5_flt_rule_hw_hdr_ext *)buf; + rule_hdr->u.hdr.ext_hdr = 1; + ext_hdr->u.hdr.ttl = params->rule->ttl_update ? 0x1 : 0x0; + ext_hdr->u.hdr.qos_class = params->rule->qos_class; + buf += sizeof(struct ipa5_5_flt_rule_hw_hdr_ext); + } else { + rule_hdr->u.hdr.ext_hdr = 0; + } + + if (params->rule->eq_attrib_type) { + if (ipa_fltrt_generate_hw_rule_bdy_from_eq_5_5( + ¶ms->rule->eq_attrib, &buf, rule_hdr->u.hdr.ext_hdr)) { + IPAHAL_ERR("fail to generate hw rule from eq\n"); + return -EPERM; + } + en_rule = params->rule->eq_attrib.rule_eq_bitmap; + } else { + if (ipa_fltrt_generate_hw_rule_bdy_5_5(params->ipt, + ¶ms->rule->attrib, &buf, &en_rule, rule_hdr->u.hdr.ext_hdr)) { + IPAHAL_ERR("fail to generate hw rule\n"); + return -EPERM; + } + } + rule_hdr->u.hdr.en_rule = en_rule; + + IPAHAL_DBG_LOW("en_rule=0x%x, action=%d, rt_idx=%d, retain_hdr=%d\n", + en_rule, + rule_hdr->u.hdr.action, + rule_hdr->u.hdr.rt_tbl_idx, + rule_hdr->u.hdr.retain_hdr); + IPAHAL_DBG_LOW("priority=%d, rule_id=%d, pdn=%d, set_metadata=%d\n", + rule_hdr->u.hdr.priority, + rule_hdr->u.hdr.rule_id, + rule_hdr->u.hdr.pdn_idx, + rule_hdr->u.hdr.set_metadata); + + ipa_write_64(rule_hdr->u.word, (u8 *)rule_hdr); + + if (*hw_len == 0) { + *hw_len = buf - start; + } else if (*hw_len != (buf - start)) { + IPAHAL_ERR("hw_len differs b/w passed=0x%x calc=%td\n", + *hw_len, (buf - start)); + return -EPERM; + } + + return 0; +} + + /* * struct ipahal_fltrt_obj - Flt/Rt H/W information for specific IPA version * @support_hash: Is hashable tables supported @@ -1023,6 +1232,52 @@ static struct ipahal_fltrt_obj ipahal_fltrt_objs[IPA_HW_MAX] = { [IPA_IS_PURE_ACK] = 0, }, }, + + /* IPAv5.5 */ + [IPA_HW_v5_5] = { + true, + IPA3_0_HW_TBL_WIDTH, + IPA3_0_HW_TBL_SYSADDR_ALIGNMENT, + IPA3_0_HW_TBL_LCLADDR_ALIGNMENT, + IPA3_0_HW_TBL_BLK_SIZE_ALIGNMENT, + IPA3_0_HW_RULE_START_ALIGNMENT, + IPA3_0_HW_TBL_HDR_WIDTH, + IPA3_0_HW_TBL_ADDR_MASK, + IPA5_0_RULE_MAX_PRIORITY, + IPA5_0_RULE_MIN_PRIORITY, + IPA3_0_LOW_RULE_ID, + IPA3_0_RULE_ID_BIT_LEN, + IPA3_0_HW_RULE_BUF_SIZE, + ipa_write_64, + ipa_fltrt_create_flt_bitmap_v5_0, + ipa_fltrt_create_tbl_addr, + ipa_fltrt_parse_tbl_addr, + ipa_rt_gen_hw_rule_ipav5_5, + ipa_flt_gen_hw_rule_ipav5_5, + ipa_flt_generate_eq, + ipa_rt_parse_hw_rule_ipav5_5, + ipa_flt_parse_hw_rule_ipav5_5, + { + [IPA_TOS_EQ] = 0xFF, + [IPA_PROTOCOL_EQ] = 1, + [IPA_TC_EQ] = 2, + [IPA_OFFSET_MEQ128_0] = 3, + [IPA_OFFSET_MEQ128_1] = 4, + [IPA_OFFSET_MEQ32_0] = 5, + [IPA_OFFSET_MEQ32_1] = 6, + [IPA_IHL_OFFSET_MEQ32_0] = 7, + [IPA_IHL_OFFSET_MEQ32_1] = 8, + [IPA_METADATA_COMPARE] = 9, + [IPA_IHL_OFFSET_RANGE16_0] = 10, + [IPA_IHL_OFFSET_RANGE16_1] = 11, + [IPA_IHL_OFFSET_EQ_32] = 12, + [IPA_IHL_OFFSET_EQ_16] = 13, + [IPA_FL_EQ] = 14, + [IPA_IS_FRAG] = 15, + [IPA_IS_PURE_ACK] = 0, + }, + }, + }; static int ipa_flt_generate_eq(enum ipa_ip_type ipt, @@ -2242,6 +2497,124 @@ fail_extra_alloc: return rc; } +/* + * ipa_fltrt_generate_hw_rule_bdy_5_5() - generate HW rule body (w/o header) for 5.5 + * @ip: IP address type + * @attrib: IPA rule attribute + * @buf: output buffer. Advance it after building the rule + * @en_rule: enable rule + * + * Return codes: + * 0: success + * -EPERM: wrong input + */ +static int ipa_fltrt_generate_hw_rule_bdy_5_5(enum ipa_ip_type ipt, + const struct ipa_rule_attrib *attrib, u8 **buf, u16 *en_rule, bool ext_hdr) +{ + int sz; + int rc = 0; + u8 *extra_wrd_buf; + u8 *rest_wrd_buf; + u8 *extra_wrd_start; + u8 *rest_wrd_start; + u8 *extra_wrd_i; + u8 *rest_wrd_i; + + sz = IPA3_0_HW_TBL_WIDTH * 2 + IPA3_0_HW_RULE_START_ALIGNMENT; + extra_wrd_buf = kzalloc(sz, GFP_KERNEL); + if (!extra_wrd_buf) { + rc = -ENOMEM; + goto fail_extra_alloc; + } + + sz = IPA3_0_HW_RULE_BUF_SIZE + IPA3_0_HW_RULE_START_ALIGNMENT; + rest_wrd_buf = kzalloc(sz, GFP_KERNEL); + if (!rest_wrd_buf) { + rc = -ENOMEM; + goto fail_rest_alloc; + } + + extra_wrd_start = extra_wrd_buf + IPA3_0_HW_RULE_START_ALIGNMENT; + extra_wrd_start = (u8 *)((long)extra_wrd_start & + ~IPA3_0_HW_RULE_START_ALIGNMENT); + + rest_wrd_start = rest_wrd_buf + IPA3_0_HW_RULE_START_ALIGNMENT; + rest_wrd_start = (u8 *)((long)rest_wrd_start & + ~IPA3_0_HW_RULE_START_ALIGNMENT); + + extra_wrd_i = extra_wrd_start; + rest_wrd_i = rest_wrd_start; + + rc = ipa_fltrt_rule_generation_err_check(ipt, attrib); + if (rc) { + IPAHAL_ERR_RL("rule generation err check failed\n"); + goto fail_err_check; + } + + if (ipt == IPA_IP_v4) { + if (ipa_fltrt_generate_hw_rule_bdy_ip4(en_rule, attrib, + &extra_wrd_i, &rest_wrd_i)) { + IPAHAL_ERR_RL("failed to build ipv4 hw rule\n"); + rc = -EPERM; + goto fail_err_check; + } + + } else if (ipt == IPA_IP_v6) { + if (ipa_fltrt_generate_hw_rule_bdy_ip6(en_rule, attrib, + &extra_wrd_i, &rest_wrd_i)) { + IPAHAL_ERR_RL("failed to build ipv6 hw rule\n"); + rc = -EPERM; + goto fail_err_check; + } + } else { + IPAHAL_ERR_RL("unsupported ip %d\n", ipt); + goto fail_err_check; + } + + /* + * default "rule" means no attributes set -> map to + * OFFSET_MEQ32_0 with mask of 0 and val of 0 and offset 0 + */ + if (attrib->attrib_mask == 0) { + IPAHAL_DBG_LOW("building default rule\n"); + *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(ipa3_0_ofst_meq32[0]); + extra_wrd_i = ipa_write_8(0, extra_wrd_i); /* offset */ + rest_wrd_i = ipa_write_32(0, rest_wrd_i); /* mask */ + rest_wrd_i = ipa_write_32(0, rest_wrd_i); /* val */ + } + + IPAHAL_DBG("extra_word_1 0x%llx\n", *(u64 *)extra_wrd_start); + IPAHAL_DBG("extra_word_2 0x%llx\n", + *(u64 *)(extra_wrd_start + IPA3_0_HW_TBL_WIDTH)); + + if (ext_hdr) { + sz = extra_wrd_i - extra_wrd_start; + IPAHAL_DBG("extra words params sz %d, buf: 0x%llx, \n", sz, *buf); + *buf = ipa_fltrt_copy_mem(extra_wrd_start, *buf, sz); + IPAHAL_DBG("After extra copy *buf 0x%llx\n", *buf); + *buf = ipa_pad_to_64(*buf); + } else { + extra_wrd_i = ipa_pad_to_64(extra_wrd_i); + sz = extra_wrd_i - extra_wrd_start; + IPAHAL_DBG("extra words params sz %d, buf: 0x%llx, \n", sz, *buf); + *buf = ipa_fltrt_copy_mem(extra_wrd_start, *buf, sz); + } + IPAHAL_DBG("Updated *buf 0x%llx\n", *buf); + + rest_wrd_i = ipa_pad_to_64(rest_wrd_i); + sz = rest_wrd_i - rest_wrd_start; + IPAHAL_DBG("non extra words params sz %d\n", sz); + *buf = ipa_fltrt_copy_mem(rest_wrd_start, *buf, sz); + IPAHAL_DBG("After rest copy *buf 0x%llx\n", *buf); + +fail_err_check: + kfree(rest_wrd_buf); +fail_rest_alloc: + kfree(extra_wrd_buf); +fail_extra_alloc: + return rc; +} + /** * ipa_fltrt_calc_extra_wrd_bytes()- Calculate the number of extra words for eq @@ -2451,6 +2824,182 @@ static int ipa_fltrt_generate_hw_rule_bdy_from_eq( return 0; } +static int ipa_fltrt_generate_hw_rule_bdy_from_eq_5_5( + const struct ipa_ipfltri_rule_eq *attrib, u8 **buf, bool ext_hdr) +{ + uint8_t num_offset_meq_32 = attrib->num_offset_meq_32; + uint8_t num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16; + uint8_t num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32; + uint8_t num_offset_meq_128 = attrib->num_offset_meq_128; + int i; + int extra_bytes; + u8 *extra; + u8 *rest; + + extra_bytes = ipa_fltrt_calc_extra_wrd_bytes(attrib); + /* only 3 eq does not have extra word param, 13 out of 16 is the number + * of equations that needs extra word param + */ + if (extra_bytes > 13) { + IPAHAL_ERR_RL("too much extra bytes\n"); + return -EPERM; + } else if (extra_bytes > IPA3_0_HW_TBL_HDR_WIDTH) { + /* two extra words */ + extra = *buf; + rest = *buf + IPA3_0_HW_TBL_HDR_WIDTH * 2; + } else if (extra_bytes > 0) { + /* single exra word */ + extra = *buf; + /* With ext_hdr, 2 bytes are already occupied. */ + if (ext_hdr && extra_bytes > (IPA3_0_HW_TBL_HDR_WIDTH - 2)) + rest = *buf + IPA3_0_HW_TBL_HDR_WIDTH * 2; + else + rest = *buf + IPA3_0_HW_TBL_HDR_WIDTH; + } else { + /* no extra words */ + extra = NULL; + rest = *buf; + } + + /* + * tos_eq_present field has two meanings: + * tos equation for IPA ver < 4.5 (as the field name reveals) + * pure_ack equation for IPA ver >= 4.5 + * In both cases it needs one extra word. + */ + if (attrib->tos_eq_present) { + if (IPA_IS_RULE_EQ_VALID(IPA_IS_PURE_ACK)) { + extra = ipa_write_8(0, extra); + } else if (IPA_IS_RULE_EQ_VALID(IPA_TOS_EQ)) { + extra = ipa_write_8(attrib->tos_eq, extra); + } else { + IPAHAL_ERR("no support for pure_ack and tos eqs\n"); + return -EPERM; + } + } + + if (attrib->protocol_eq_present) + extra = ipa_write_8(attrib->protocol_eq, extra); + + if (attrib->tc_eq_present) + extra = ipa_write_8(attrib->tc_eq, extra); + + if (num_offset_meq_128) { + extra = ipa_write_8(attrib->offset_meq_128[0].offset, extra); + for (i = 0; i < 8; i++) + rest = ipa_write_8(attrib->offset_meq_128[0].mask[i], + rest); + for (i = 0; i < 8; i++) + rest = ipa_write_8(attrib->offset_meq_128[0].value[i], + rest); + for (i = 8; i < 16; i++) + rest = ipa_write_8(attrib->offset_meq_128[0].mask[i], + rest); + for (i = 8; i < 16; i++) + rest = ipa_write_8(attrib->offset_meq_128[0].value[i], + rest); + num_offset_meq_128--; + } + + if (num_offset_meq_128) { + extra = ipa_write_8(attrib->offset_meq_128[1].offset, extra); + for (i = 0; i < 8; i++) + rest = ipa_write_8(attrib->offset_meq_128[1].mask[i], + rest); + for (i = 0; i < 8; i++) + rest = ipa_write_8(attrib->offset_meq_128[1].value[i], + rest); + for (i = 8; i < 16; i++) + rest = ipa_write_8(attrib->offset_meq_128[1].mask[i], + rest); + for (i = 8; i < 16; i++) + rest = ipa_write_8(attrib->offset_meq_128[1].value[i], + rest); + num_offset_meq_128--; + } + + if (num_offset_meq_32) { + extra = ipa_write_8(attrib->offset_meq_32[0].offset, extra); + rest = ipa_write_32(attrib->offset_meq_32[0].mask, rest); + rest = ipa_write_32(attrib->offset_meq_32[0].value, rest); + num_offset_meq_32--; + } + + if (num_offset_meq_32) { + extra = ipa_write_8(attrib->offset_meq_32[1].offset, extra); + rest = ipa_write_32(attrib->offset_meq_32[1].mask, rest); + rest = ipa_write_32(attrib->offset_meq_32[1].value, rest); + num_offset_meq_32--; + } + + if (num_ihl_offset_meq_32) { + extra = ipa_write_8(attrib->ihl_offset_meq_32[0].offset, + extra); + + rest = ipa_write_32(attrib->ihl_offset_meq_32[0].mask, rest); + rest = ipa_write_32(attrib->ihl_offset_meq_32[0].value, rest); + num_ihl_offset_meq_32--; + } + + if (num_ihl_offset_meq_32) { + extra = ipa_write_8(attrib->ihl_offset_meq_32[1].offset, + extra); + + rest = ipa_write_32(attrib->ihl_offset_meq_32[1].mask, rest); + rest = ipa_write_32(attrib->ihl_offset_meq_32[1].value, rest); + num_ihl_offset_meq_32--; + } + + if (attrib->metadata_meq32_present) { + rest = ipa_write_32(attrib->metadata_meq32.mask, rest); + rest = ipa_write_32(attrib->metadata_meq32.value, rest); + } + + if (num_ihl_offset_range_16) { + extra = ipa_write_8(attrib->ihl_offset_range_16[0].offset, + extra); + + rest = ipa_write_16(attrib->ihl_offset_range_16[0].range_high, + rest); + rest = ipa_write_16(attrib->ihl_offset_range_16[0].range_low, + rest); + num_ihl_offset_range_16--; + } + + if (num_ihl_offset_range_16) { + extra = ipa_write_8(attrib->ihl_offset_range_16[1].offset, + extra); + + rest = ipa_write_16(attrib->ihl_offset_range_16[1].range_high, + rest); + rest = ipa_write_16(attrib->ihl_offset_range_16[1].range_low, + rest); + num_ihl_offset_range_16--; + } + + if (attrib->ihl_offset_eq_32_present) { + extra = ipa_write_8(attrib->ihl_offset_eq_32.offset, extra); + rest = ipa_write_32(attrib->ihl_offset_eq_32.value, rest); + } + + if (attrib->ihl_offset_eq_16_present) { + extra = ipa_write_8(attrib->ihl_offset_eq_16.offset, extra); + rest = ipa_write_16(attrib->ihl_offset_eq_16.value, rest); + rest = ipa_write_16(0, rest); + } + + if (attrib->fl_eq_present) + rest = ipa_write_32(attrib->fl_eq & 0xFFFFF, rest); + + if (extra) + extra = ipa_pad_to_64(extra); + rest = ipa_pad_to_64(rest); + *buf = rest; + + return 0; +} + + static void ipa_flt_generate_mac_addr_eq(struct ipa_ipfltri_rule_eq *eq_atrb, u8 hdr_mac_addr_offset, const uint8_t mac_addr_mask[ETH_ALEN], const uint8_t mac_addr[ETH_ALEN], u8 ofst_meq128) @@ -3693,6 +4242,58 @@ static int ipa_rt_parse_hw_rule_ipav5_0(u8 *addr, atrb, &rule->rule_size); } +static int ipa_rt_parse_hw_rule_ipav5_5(u8 *addr, + struct ipahal_rt_rule_entry *rule) +{ + struct ipa5_5_rt_rule_hw_hdr *rule_hdr; + struct ipa5_5_rt_rule_hw_hdr_ext *ext_hdr; + struct ipa_ipfltri_rule_eq *atrb; + u32 ext_hdr_sz = 0; + + IPAHAL_DBG_LOW("Entry\n"); + + rule_hdr = (struct ipa5_5_rt_rule_hw_hdr *)addr; + atrb = &rule->eq_attrib; + + IPAHAL_DBG_LOW("read hdr 0x%llx\n", rule_hdr->u.word); + + if (rule_hdr->u.word == 0) { + /* table terminator - empty table */ + rule->rule_size = 0; + return 0; + } + + rule->dst_pipe_idx = rule_hdr->u.hdr.pipe_dest_idx; + if (rule_hdr->u.hdr.proc_ctx) { + rule->hdr_type = IPAHAL_RT_RULE_HDR_PROC_CTX; + rule->hdr_ofst = (rule_hdr->u.hdr.hdr_offset) << 5; + } else { + rule->hdr_type = IPAHAL_RT_RULE_HDR_RAW; + rule->hdr_ofst = (rule_hdr->u.hdr.hdr_offset) << 2; + } + rule->hdr_lcl = !rule_hdr->u.hdr.system; + + rule->priority = rule_hdr->u.hdr.priority; + rule->retain_hdr = rule_hdr->u.hdr.retain_hdr; + rule->cnt_idx = rule_hdr->u.hdr.stats_cnt_idx; + rule->id = rule_hdr->u.hdr.rule_id; + rule->close_aggr_irq_mod = rule_hdr->u.hdr.close_aggr_irq_mod; + + atrb->rule_eq_bitmap = rule_hdr->u.hdr.en_rule; + + if (rule_hdr->u.hdr.ext_hdr) { + ext_hdr = + (struct ipa5_5_rt_rule_hw_hdr_ext *)(addr + sizeof(*rule_hdr)); + rule->ttl_update = ext_hdr->u.hdr.ttl; + rule->qos_class = ext_hdr->u.hdr.qos_class; + rule->skip_ingress = ext_hdr->u.hdr.skip_ingress; + ext_hdr_sz = sizeof(*ext_hdr); + } + + return ipa_fltrt_parse_hw_rule_eq(addr, sizeof(*rule_hdr) + ext_hdr_sz, + atrb, &rule->rule_size); +} + static int ipa_flt_parse_hw_rule(u8 *addr, struct ipahal_flt_rule_entry *rule) { struct ipa3_0_flt_rule_hw_hdr *rule_hdr; @@ -3890,6 +4491,67 @@ static int ipa_flt_parse_hw_rule_ipav5_0(u8 *addr, atrb, &rule->rule_size); } +static int ipa_flt_parse_hw_rule_ipav5_5(u8 *addr, + struct ipahal_flt_rule_entry *rule) +{ + struct ipa5_5_flt_rule_hw_hdr *rule_hdr; + struct ipa5_5_flt_rule_hw_hdr_ext *ext_hdr; + struct ipa_ipfltri_rule_eq *atrb; + u32 ext_hdr_sz = 0; + + IPAHAL_DBG_LOW("Entry\n"); + + rule_hdr = (struct ipa5_5_flt_rule_hw_hdr *)addr; + atrb = &rule->rule.eq_attrib; + + if (rule_hdr->u.word == 0) { + /* table terminator - empty table */ + rule->rule_size = 0; + return 0; + } + + switch (rule_hdr->u.hdr.action) { + case 0x0: + rule->rule.action = IPA_PASS_TO_ROUTING; + break; + case 0x1: + rule->rule.action = IPA_PASS_TO_SRC_NAT; + break; + case 0x2: + rule->rule.action = IPA_PASS_TO_DST_NAT; + break; + case 0x3: + rule->rule.action = IPA_PASS_TO_EXCEPTION; + break; + default: + IPAHAL_ERR("Invalid Rule Action %d\n", rule_hdr->u.hdr.action); + WARN_ON_RATELIMIT_IPA(1); + rule->rule.action = rule_hdr->u.hdr.action; + } + + rule->rule.rt_tbl_idx = rule_hdr->u.hdr.rt_tbl_idx; + rule->rule.retain_hdr = rule_hdr->u.hdr.retain_hdr; + rule->priority = rule_hdr->u.hdr.priority; + rule->id = rule_hdr->u.hdr.rule_id; + rule->rule.pdn_idx = rule_hdr->u.hdr.pdn_idx; + rule->rule.set_metadata = rule_hdr->u.hdr.set_metadata; + rule->cnt_idx = rule_hdr->u.hdr.stats_cnt_idx; + rule->rule.close_aggr_irq_mod = rule_hdr->u.hdr.close_aggr_irq_mod; + + atrb->rule_eq_bitmap = rule_hdr->u.hdr.en_rule; + rule->rule.eq_attrib_type = 1; + if (rule_hdr->u.hdr.ext_hdr) { + ext_hdr = + (struct ipa5_5_flt_rule_hw_hdr_ext *)(addr + sizeof(*rule_hdr)); + rule->rule.ttl_update = ext_hdr->u.hdr.ttl; + rule->rule.qos_class = ext_hdr->u.hdr.qos_class; + ext_hdr_sz = sizeof(*ext_hdr); + } + return ipa_fltrt_parse_hw_rule_eq(addr, sizeof(*rule_hdr) + ext_hdr_sz, + atrb, &rule->rule_size); +} + + /* * ipahal_fltrt_init() - Build the FLT/RT information table * See ipahal_fltrt_objs[] comments diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.h index e0f887fad0..9744fb6736 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.h @@ -83,6 +83,9 @@ struct ipahal_rt_rule_gen_params { * @cnt_idx: stats counter index * @close_aggr_irq_mod: close aggregation/coalescing and close GSI * interrupt moderation + * @ttl_update: bool to indicate whether TTL update is needed or not. + * @qos_class: QOS classification value. + * @skip_ingress: bool to skip ingress policing. * @eq_attrib: Equations and their params in the rule * @rule_size: Rule size in memory */ @@ -96,6 +99,9 @@ struct ipahal_rt_rule_entry { u32 id; u8 cnt_idx; u8 close_aggr_irq_mod; + u8 ttl_update; + u8 qos_class; + u8 skip_ingress; struct ipa_ipfltri_rule_eq eq_attrib; u32 rule_size; }; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt_i.h index 59b2bb40a6..13bbe2f6cd 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt_i.h @@ -184,6 +184,68 @@ struct ipa5_0_rt_rule_hw_hdr { } u; }; +/** + * struct ipa5_5_rt_rule_hw_hdr - HW header of IPA routing rule + * @word: routing rule header properties + * @en_rule: enable rule - Equation bit fields + * @pipe_dest_idx: destination pipe index + * @stats_cnt_idx_lsb: stats cnt index + * @priority: Rule priority. Added to distinguish rules order + * at the integrated table consisting from hashable and + * non-hashable parts + * @ext_hdr: indicates whethere extention header is present or not. + * @close_aggr_irq_mod: close aggregation/coalescing and close GSI + * interrupt moderation + * @rule_id: rule ID that will be returned in the packet status + * @hdr_offset: header offset + * @proc_ctx: whether hdr_offset points to header table or to + * header processing context table + * @retain_hdr: added to add back to the packet the header removed + * as part of header removal. This will be done as part of + * header insertion block. + * @system: Is referenced header is lcl or sys memory + */ +struct ipa5_5_rt_rule_hw_hdr { + union { + u64 word; + struct { + u64 en_rule : 16; + u64 pipe_dest_idx : 8; + u64 stats_cnt_idx : 8; + u64 priority : 8; + u64 ext_hdr : 1; + u64 close_aggr_irq_mod : 1; + u64 rule_id : 10; + u64 hdr_offset : 9; + u64 proc_ctx : 1; + u64 retain_hdr : 1; + u64 system : 1; + } hdr; + } u; +}; + +/** + * struct ipa5_5_rt_rule_hw_hdr_ext - HW header of IPA routing rule + * extention + * @word: routing rule extention header properties + * @ttl: enable ttl decrement. + * @qos_class: qos classification value. + * @skip_ingress: Skip ingress policing. + * @rsvd: Reserved bits + */ +struct ipa5_5_rt_rule_hw_hdr_ext { + union { + u16 word; + struct { + u16 ttl : 1; + u16 qos_class : 6; + u16 skip_ingress : 1; + u16 rsvd : 8; + } hdr; + } u; +}; + + /** * struct ipa3_0_flt_rule_hw_hdr - HW header of IPA filter rule * @word: filtering rule properties @@ -335,6 +397,67 @@ struct ipa5_0_flt_rule_hw_hdr { } u; }; +/** + * struct ipa5_5_flt_rule_hw_hdr - HW header of IPA filter rule + * @word: filtering rule properties + * @en_rule: enable rule + * @rt_tbl_idx: index in routing table + * @stats_cnt_idx: stats cnt index + * @priority: Rule priority. Added to distinguish rules order + * at the integrated table consisting from hashable and + * non-hashable parts + * @ext_hdr: indicates whethere extention header is present or not. + * @close_aggr_irq_mod: close aggregation/coalescing and close GSI + * interrupt moderation + * @rule_id: rule ID that will be returned in the packet status + * @action: post filtering action + * @pdn_idx: in case of go to src nat action possible to input the pdn index to + * the NAT block + * @set_metadata: enable metadata replacement in the NAT block + * @retain_hdr: added to add back to the packet the header removed + * as part of header removal. This will be done as part of + * header insertion block. + * @rsvd: reserved bits + */ +struct ipa5_5_flt_rule_hw_hdr { + union { + u64 word; + struct { + u64 en_rule : 16; + u64 rt_tbl_idx : 8; + u64 stats_cnt_idx : 8; + u64 priority : 8; + u64 ext_hdr : 1; + u64 close_aggr_irq_mod : 1; + u64 rule_id : 10; + u64 action : 5; + u64 pdn_idx : 4; + u64 set_metadata : 1; + u64 retain_hdr : 1; + u64 rsvd : 1; + } hdr; + } u; +}; + +/** + * struct ipa5_5_flt_rule_hw_hdr_ext - HW header of IPA filter rule + * extention + * @word: filtering rule extention header properties + * @ttl: enable ttl decrement. + * @qos_class: qos classification value. + * @rsvd: Reserved bits + */ +struct ipa5_5_flt_rule_hw_hdr_ext { + union { + u16 word; + struct { + u16 ttl : 1; + u16 qos_class : 6; + u16 rsvd : 9; + } hdr; + } u; +}; + int ipahal_fltrt_init(enum ipa_hw_type ipa_hw_type); void ipahal_fltrt_destroy(void); 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 c951b8752b..2019472461 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h @@ -413,6 +413,61 @@ struct ipa_imm_cmd_hw_ip_packet_init_ex { u64 rt_system : 1; } __packed; +/* + * struct ipa_imm_cmd_hw_ip_packet_init_ex_v5_5 - IP_PACKET_INIT_EX command payload + * in H/W format for IPA v5_5. + * @frag_disable: 1 - disabled. overrides IPA_ENDP_CONFIG_n:FRAG_OFFLOAD_EN + * @filter_disable: 1 - disabled, 0 enabled + * @nat_disable: 1 - disabled, 0 enabled + * @route_disable: 1 - disabled, 0 enabled + * @hdr_removal_insertion_disable: 1 - disabled, 0 enabled + * @cs_disable: 1 - disabled, 0 enabled + * @quota_tethering_stats_disable: 1 - disabled, 0 enabled + * @dpl_disable: 1 - disabled, 0 enabled + * fields @flt_rt_tbl_idx - @rsvd4 are a copy of ipa5_5_flt_rule_hw_hdr + * fields @rt_pipe_dest_idx - @rsvd5 are a copy of ipa5_5_rt_rule_hw_hdr + */ +struct ipa_imm_cmd_hw_ip_packet_init_ex_v5_5 { + u64 rsvd1 : 16; + u64 frag_disable : 1; + u64 filter_disable : 1; + u64 nat_disable : 1; + u64 route_disable : 1; + u64 hdr_removal_insertion_disable : 1; + u64 cs_disable : 1; + u64 quota_tethering_stats_disable : 1; + u64 dpl_disable : 1; + u64 rsvd2 : 40; + u64 flt_rt_tbl_idx : 8; + u64 flt_stats_cnt_idx : 8; + u64 flt_priority : 8; + u64 flt_ext_hdr : 1; + u64 flt_close_aggr_irq_mod : 1; + u64 flt_rule_id : 10; + u64 flt_action : 5; + u64 flt_pdn_idx : 4; + u64 flt_set_metadata : 1; + u64 flt_retain_hdr : 1; + u64 rsvd3 : 1; + u64 flt_ttl : 1; + u64 flt_qos_class : 6; + u64 rsvd4 : 9; + u64 rt_pipe_dest_idx : 8; + u64 rt_stats_cnt_idx : 8; + u64 rt_priority : 8; + u64 rt_ext_hdr : 1; + u64 rt_close_aggr_irq_mod : 1; + u64 rt_rule_id : 10; + u64 rt_hdr_offset : 9; + u64 rt_proc_ctx : 1; + u64 rt_retain_hdr : 1; + u64 rt_system : 1; + u64 rt_ttl : 1; + u64 rt_qos_class : 6; + u64 rt_skip_ingress : 1; + u64 rsvd5 : 8; +} __packed; + /* * struct ipa_imm_cmd_hw_register_write - REGISTER_WRITE command payload * in H/W format. @@ -882,6 +937,174 @@ struct ipa_frag_pkt_status_hw_v5_0 { u64 reserved_5:8; } __packed; +/* + * struct ipa_status_pkt_hw_v5_5 - IPA v5.5 status packet payload in H/W format. + * This structure describes the status packet H/W structure for the + * following statuses: IPA_STATUS_PACKET, IPA_STATUS_DROPPED_PACKET, + * IPA_STATUS_SUSPENDED_PACKET. + * Other statuses types has different status packet structure. + * @status_opcode: The Type of the status (Opcode). + * @exception: (not bitmask) - the first exception that took place. + * In case of exception, src endp and pkt len are always valid. + * @status_mask: Bit mask specifying on which H/W blocks the pkt was processed. + * @pkt_len: Pkt pyld len including hdr, include retained hdr if used. Does + * not include padding or checksum trailer len. + * @endp_src_idx: Source end point index. + * @reserved_1: reserved + * @rt_local: Route table location flag: Does matching rt rule belongs to + * rt tbl that resides in lcl memory? (if not, then system mem) + * @rt_hash: Route hash hit flag: Does matching rt rule was in hash tbl? + * Not valid in case of exception + * @reserved_2: reserved + * @metadata: meta data value used by packet + * @flt_local: Filter table location flag: Does matching flt rule belongs to + * flt tbl that resides in lcl memory? (if not, then system mem) + * @flt_hash: Filter hash hit flag: Does matching flt rule was in hash tbl? + * @flt_global: Global filter rule flag: Does matching flt rule belongs to + * the global flt tbl? (if not, then the per endp tables) + * @flt_ret_hdr: Retain header in filter rule flag: Does matching flt rule + * specifies to retain header? + * Starting IPA4.5, this will be true only if packet has L2 header. + * @flt_rule_id: The ID of the matching filter rule. This info can be combined + * with endp_src_idx to locate the exact rule. ID=0x3FF reserved to specify + * flt miss. In case of miss, all flt info to be ignored + * @rt_tbl_idx: Index of rt tbl that contains the rule on which was a match + * @rt_rule_id: The ID of the matching rt rule. This info can be combined + * with rt_tbl_idx to locate the exact rule. ID=0x3FF reserved to specify + * rt miss. In case of miss, all rt info to be ignored + * @nat_hit: NAT hit flag: Was their NAT hit? + * @nat_entry_idx: Index of the NAT entry used of NAT processing + * @nat_type: Defines the type of the NAT operation: + * 00: No NAT + * 01: Source NAT + * 10: Destination NAT + * 11: Reserved + * @tag_info: S/W defined value provided via immediate command + * @egress_tc: Egress traffic class index. + * @ingress_tc: Ingress traffic class index. + * @seq_num: Per source endp unique packet sequence number + * @time_of_day_ctr: running counter from IPA clock + * @hdr_local: Header table location flag: In header insertion, was the header + * taken from the table resides in local memory? (If no, then system mem) + * @hdr_offset: Offset of used header in the header table + * @frag_hit: Frag hit flag: Was their frag rule hit in H/W frag table? + * @frag_rule: Frag rule index in H/W frag table in case of frag hit + * @endp_dest_idx: Destination end point index. + * @hw_specific: H/W specific reserved value + * @ucp: UC Processing flag. + * @nat_exc_suppress: nat exception supress flag, indicates whether + * nat exception is suppressed. + * @tsp: Traffic shaping policing flag, indicates traffic class info + * overwrites tag info. + * @ttl_dec: ttl update flag, indicates whether ttl is updated. + */ +struct ipa_gen_pkt_status_hw_v5_5 { + u64 status_opcode:8; + u64 exception:8; + u64 status_mask:16; + u64 pkt_len:16; + u64 endp_src_idx:8; + u64 reserved_1:3; + u64 rt_local:1; + u64 rt_hash:1; + u64 reserved_2:3; + u64 metadata:32; + u64 flt_local:1; + u64 flt_hash:1; + u64 flt_global:1; + u64 flt_ret_hdr:1; + u64 flt_rule_id:10; + u64 rt_tbl_idx:8; + u64 rt_rule_id:10; + u64 nat_hit:1; + u64 nat_entry_idx:13; + u64 nat_type:2; + u64 tag_info:36; + u64 egress_tc:6; + u64 ingress_tc:6; + u64 seq_num:8; + u64 time_of_day_ctr:24; + u64 hdr_local:1; + u64 hdr_offset:10; + u64 frag_hit:1; + u64 frag_rule:4; + u64 endp_dest_idx:8; + u64 hw_specific:4; + u64 nat_exc_suppress:1; + u64 tsp:1; + u64 ttl_dec:1; + u64 ucp:1; +} __packed; + +/* + * struct ipa_frag_pkt_status_hw_v5_5 - + * IPA v5.5 status packet payload in H/W format. + * This structure describes the frag status packet H/W structure for the + * following statuses: IPA_NEW_FRAG_RULE. + * @status_opcode: The Type of the status (Opcode). + * @frag_rule_idx: Frag rule index value. + * @reserved_1: reserved + * @exception: (not bitmask) - the first exception that took place. + * @tbl_idx: Table index valid or not. + * @endp_src_idx: Source end point index. + * In case of exception, src endp and pkt len are always valid. + * @seq_num: Packet sequence number. + * @src_ip_addr: Source packet IP address. + * @dest_ip_addr: Destination packet IP address. + * @ret: l2 header retained flag, indicates whether l2 header is retained + * or not. + * @ll: low latency indication. + * @ttl_dec: ttl update indication. + * @reserved_2: reserved + * @nat_type: Defines the type of the NAT operation: + * 00: No NAT + * 01: Source NAT + * 10: Destination NAT + * 11: Reserved + * @protocol: Protocal number. + * @ip_id: IP packet IP ID number. + * @tlated_ip_addr: IP address. + * @hdr_offset: Offset of used header in the header table + * @ingress_tc: ingress traffic class index + * @ip_cksum_diff: IP packet checksum difference. + * @metadata: meta data value used by packet + * @reserved_4: reserved + * @endp_dest_idx: Destination end point index. + * @egress_tc: egress traffic class index + * @pd: router disabled ingress policer. + * @hdr_local: Header table location flag: In header insertion, was the header + * taken from the table resides in local memory? (If no, then system mem) + */ +struct ipa_frag_pkt_status_hw_v5_5 { + u64 status_opcode:8; + u64 frag_rule_idx:4; + u64 reserved_1:2; + u64 exception:1; + u64 tbl_idx:1; + u64 endp_src_idx:8; + u64 seq_num:8; + u64 src_ip_addr:32; + u64 dest_ip_addr:32; + u64 ret:1; + u64 ll:1; + u64 ttl_dec:1; + u64 reserved_2:3; + u64 nat_type:2; + u64 protocol:8; + u64 ip_id:16; + u64 tlated_ip_addr:32; + u64 hdr_offset:10; + u64 ingress_tc:6; + u64 ip_cksum_diff:16; + u64 metadata:32; + u64 reserved_4:16; + u64 endp_dest_idx:8; + u64 egress_tc:6; + u64 pd:1; + u64 hdr_local:1; +} __packed; + + union ipa_pkt_status_hw { struct ipa_gen_pkt_status_hw ipa_pkt; struct ipa_frag_pkt_status_hw frag_pkt; @@ -892,6 +1115,11 @@ union ipa_pkt_status_hw_v5_0 { struct ipa_frag_pkt_status_hw_v5_0 frag_pkt; } __packed; +union ipa_pkt_status_hw_v5_5 { + struct ipa_gen_pkt_status_hw_v5_5 ipa_pkt; + struct ipa_frag_pkt_status_hw_v5_5 frag_pkt; +} __packed; + /* Size of H/W Packet Status */ #define IPA3_0_PKT_STATUS_SIZE 32 diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c index 9575e9425f..26bf512253 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c @@ -1004,6 +1004,22 @@ static void ipareg_construct_qtime_timestamp_cfg( IPA_QTIME_TIMESTAMP_CFG_NAT_TIMESTAMP_LSB_BMSK); } +static void ipareg_construct_qtime_timestamp_cfg_v5_5( + enum ipahal_reg_name reg, const void *fields, u32 *val) +{ + const struct ipahal_reg_qtime_timestamp_cfg *ts_cfg = + (const struct ipahal_reg_qtime_timestamp_cfg *)fields; + + IPA_SETFIELD_IN_REG(*val, + ts_cfg->tag_timestamp_lsb, + IPA_QTIME_TIMESTAMP_CFG_TAG_TIMESTAMP_LSB_SHFT, + IPA_QTIME_TIMESTAMP_CFG_TAG_TIMESTAMP_LSB_BMSK); + IPA_SETFIELD_IN_REG(*val, + ts_cfg->nat_timestamp_lsb, + IPA_QTIME_TIMESTAMP_CFG_NAT_TIMESTAMP_LSB_SHFT, + IPA_QTIME_TIMESTAMP_CFG_NAT_TIMESTAMP_LSB_BMSK); +} + static u8 ipareg_timers_pulse_gran_code( enum ipa_timers_time_gran_type gran) { @@ -1970,9 +1986,42 @@ static void ipareg_construct_endp_init_cfg_n( IPA_SETFIELD_IN_REG(*val, cfg->gen_qmb_master_sel, IPA_ENDP_INIT_CFG_n_CS_GEN_QMB_MASTER_SEL_SHFT, IPA_ENDP_INIT_CFG_n_CS_GEN_QMB_MASTER_SEL_BMSK); - + if (ipahal_ctx->hw_type >= IPA_HW_v5_5) + IPA_SETFIELD_IN_REG(*val, cfg->pipe_replicate_en, + IPA_ENDP_INIT_CFG_n_PIPE_REPLICATE_EN_SEL_SHFT_V5_5, + IPA_ENDP_INIT_CFG_n_PIPE_REPLICATE_EN_SEL_BMSK_V5_5); } +static void ipareg_construct_endp_init_prod_cfg_n_v5_5( + enum ipahal_reg_name reg, const void *fields, u32 *val) +{ + struct ipa_ep_cfg_prod_cfg *cfg = + (struct ipa_ep_cfg_prod_cfg *)fields; + + IPA_SETFIELD_IN_REG(*val, cfg->tx_instance ? 1 : 0, + IPA_ENDP_INIT_PROD_CFG_n_TX_SEL_SHIFT, + IPA_ENDP_INIT_PROD_CFG_n_TX_SEL_BMASK); + IPA_SETFIELD_IN_REG(*val, cfg->tsp_enable ? 1 : 0, + IPA_ENDP_INIT_PROD_CFG_n_TSP_ENABLE_SHIFT, + IPA_ENDP_INIT_PROD_CFG_n_TSP_ENABLE_BMASK); + IPA_SETFIELD_IN_REG(*val, cfg->max_output_size_drop_enable ? 1 : 0, + IPA_ENDP_INIT_PROD_CFG_n_MAX_OUTPUT_SIZE_DROP_ENABLE_SHIFT, + IPA_ENDP_INIT_PROD_CFG_n_MAX_OUTPUT_SIZE_DROP_ENABLE_BMASK); + IPA_SETFIELD_IN_REG(*val, cfg->tsp_idx, + IPA_ENDP_INIT_PROD_CFG_n_TSP_INDEX_SHIFT, + IPA_ENDP_INIT_PROD_CFG_n_TSP_INDEX_BMASK); + IPA_SETFIELD_IN_REG(*val, cfg->max_output_size, + IPA_ENDP_INIT_PROD_CFG_n_MAX_OUTPUT_SIZE_SHIFT, + IPA_ENDP_INIT_PROD_CFG_n_MAX_OUTPUT_SIZE_BMASK); + IPA_SETFIELD_IN_REG(*val, cfg->egress_tc_lowest, + IPA_ENDP_INIT_PROD_CFG_n_EGRESS_TC_LOWEST_SHIFT, + IPA_ENDP_INIT_PROD_CFG_n_EGRESS_TC_LOWEST_BMASK); + IPA_SETFIELD_IN_REG(*val, cfg->egress_tc_highest, + IPA_ENDP_INIT_PROD_CFG_n_EGRESS_TC_HIGHEST_SHIFT, + IPA_ENDP_INIT_PROD_CFG_n_EGRESS_TC_HIGHEST_BMASK); +} + + static void ipareg_construct_endp_init_deaggr_n( enum ipahal_reg_name reg, const void *fields, u32 *val) { @@ -2165,6 +2214,20 @@ static void ipareg_construct_endp_init_nat_n(enum ipahal_reg_name reg, IPA_ENDP_INIT_NAT_n_NAT_EN_BMSK); } +static void ipareg_construct_endp_init_nat_exc_suppress_n +( + enum ipahal_reg_name reg, + const void *fields, u32 *val +) +{ + struct ipa_ep_cfg_nat *ep_nat = + (struct ipa_ep_cfg_nat *)fields; + + IPA_SETFIELD_IN_REG(*val, ep_nat->nat_exc_suppress ? 1 : 0, + IPA_ENDP_INIT_NAT_EXC_SUPPRESS_n_EN_SHFT, + IPA_ENDP_INIT_NAT_EXC_SUPPRESS_n_EN_BMSK); +} + static void ipareg_construct_endp_init_conn_track_n(enum ipahal_reg_name reg, const void *fields, u32 *val) { @@ -2302,6 +2365,11 @@ static void ipareg_parse_endp_init_aggr_n_v4_5(enum ipahal_reg_name reg, ep_aggr->pulse_generator = ((val & IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_BMSK_V4_5) >> IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_SHFT_V4_5); + + if (ipahal_ctx->hw_type >= IPA_HW_v5_5) + ep_aggr->aggr_coal_l2 = + ((val & IPA_ENDP_INIT_AGGR_n_AGGR_COAL_L2_BMSK_V5_5) >> + IPA_ENDP_INIT_AGGR_n_AGGR_COAL_L2_SHFT_V5_5); } static void ipareg_construct_endp_init_aggr_n(enum ipahal_reg_name reg, @@ -2406,6 +2474,11 @@ static void ipareg_construct_endp_init_aggr_n_v4_5(enum ipahal_reg_name reg, IPA_SETFIELD_IN_REG(*val, ep_aggr->pulse_generator, IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_SHFT_V4_5, IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_BMSK_V4_5); + + if (ipahal_ctx->hw_type >= IPA_HW_v5_5) + IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_coal_l2, + IPA_ENDP_INIT_AGGR_n_AGGR_COAL_L2_SHFT_V5_5, + IPA_ENDP_INIT_AGGR_n_AGGR_COAL_L2_BMSK_V5_5); } static void ipareg_construct_endp_init_hdr_ext_n_common( @@ -3109,6 +3182,41 @@ static void ipareg_construct_coal_evict_lru(enum ipahal_reg_name reg, IPA_COAL_EVICTION_EN_SHFT, IPA_COAL_EVICTION_EN_BMSK); } +static void ipareg_construct_coal_evict_lru_v5_5(enum ipahal_reg_name reg, + const void *fields, u32 *val) +{ + struct ipahal_reg_coal_evict_lru *evict_lru = + (struct ipahal_reg_coal_evict_lru *)fields; + + IPA_SETFIELD_IN_REG(*val, evict_lru->coal_eviction_en, + IPA_COAL_EVICTION_EN_SHFT_v5_5, + IPA_COAL_EVICTION_EN_BMSK_v5_5); + + IPA_SETFIELD_IN_REG(*val, evict_lru->coal_vp_lru_gran_sel, + IPA_COAL_VP_LRU_GRAN_SEL_SHFT_v5_5, + IPA_COAL_VP_LRU_GRAN_SEL_BMSK_v5_5); + + IPA_SETFIELD_IN_REG(*val, evict_lru->coal_vp_lru_udp_thrshld, + IPA_COAL_VP_LRU_UDP_THRSHLD_SHFT_v5_5, + IPA_COAL_VP_LRU_UDP_THRSHLD_BMSK_v5_5); + + IPA_SETFIELD_IN_REG(*val, evict_lru->coal_vp_lru_tcp_thrshld, + IPA_COAL_VP_LRU_TCP_THRSHLD_SHFT_v5_5, + IPA_COAL_VP_LRU_TCP_THRSHLD_BMSK_v5_5); + + IPA_SETFIELD_IN_REG(*val, evict_lru->coal_vp_lru_udp_thrshld_en, + IPA_COAL_VP_LRU_UDP_THRSHLD_EN_SHFT_v5_5, + IPA_COAL_VP_LRU_UDP_THRSHLD_EN_BMSK_v5_5); + + IPA_SETFIELD_IN_REG(*val, evict_lru->coal_vp_lru_tcp_thrshld_en, + IPA_COAL_VP_LRU_TCP_THRSHLD_EN_SHFT_v5_5, + IPA_COAL_VP_LRU_TCP_THRSHLD_EN_BMSK_v5_5); + + IPA_SETFIELD_IN_REG(*val, evict_lru->coal_vp_lru_tcp_num, + IPA_COAL_VP_LRU_TCP_NUM_SHFT_v5_5, + IPA_COAL_VP_LRU_TCP_NUM_BMSK_v5_5); +} + static void ipareg_parse_coal_evict_lru(enum ipahal_reg_name reg, void *fields, u32 val) { @@ -3124,6 +3232,43 @@ static void ipareg_parse_coal_evict_lru(enum ipahal_reg_name reg, IPA_COAL_EVICTION_EN_SHFT, IPA_COAL_EVICTION_EN_BMSK); } +static void ipareg_parse_coal_evict_lru_v5_5(enum ipahal_reg_name reg, + void *fields, u32 val) +{ + struct ipahal_reg_coal_evict_lru *evict_lru = + (struct ipahal_reg_coal_evict_lru *)fields; + + memset(evict_lru, 0, sizeof(*evict_lru)); + + evict_lru->coal_eviction_en = IPA_GETFIELD_FROM_REG(val, + IPA_COAL_EVICTION_EN_SHFT_v5_5, + IPA_COAL_EVICTION_EN_BMSK_v5_5); + + evict_lru->coal_vp_lru_gran_sel = IPA_GETFIELD_FROM_REG(val, + IPA_COAL_VP_LRU_GRAN_SEL_SHFT_v5_5, + IPA_COAL_VP_LRU_GRAN_SEL_BMSK_v5_5); + + evict_lru->coal_vp_lru_udp_thrshld = IPA_GETFIELD_FROM_REG(val, + IPA_COAL_VP_LRU_UDP_THRSHLD_SHFT_v5_5, + IPA_COAL_VP_LRU_UDP_THRSHLD_BMSK_v5_5); + + evict_lru->coal_vp_lru_tcp_thrshld = IPA_GETFIELD_FROM_REG(val, + IPA_COAL_VP_LRU_TCP_THRSHLD_SHFT_v5_5, + IPA_COAL_VP_LRU_TCP_THRSHLD_BMSK_v5_5); + + evict_lru->coal_vp_lru_udp_thrshld_en = IPA_GETFIELD_FROM_REG(val, + IPA_COAL_VP_LRU_UDP_THRSHLD_EN_SHFT_v5_5, + IPA_COAL_VP_LRU_UDP_THRSHLD_EN_BMSK_v5_5); + + evict_lru->coal_vp_lru_tcp_thrshld_en = IPA_GETFIELD_FROM_REG(val, + IPA_COAL_VP_LRU_TCP_THRSHLD_EN_SHFT_v5_5, + IPA_COAL_VP_LRU_TCP_THRSHLD_EN_BMSK_v5_5); + + evict_lru->coal_vp_lru_tcp_num = IPA_GETFIELD_FROM_REG(val, + IPA_COAL_VP_LRU_TCP_NUM_SHFT_v5_5, + IPA_COAL_VP_LRU_TCP_NUM_BMSK_v5_5); +} + static void ipareg_construct_coal_qmap_cfg(enum ipahal_reg_name reg, const void *fields, u32 *val) { @@ -4630,6 +4775,370 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = { [IPA_HW_v5_0][IPA_FEC_ATTR_EE_n] = { ipareg_construct_dummy, ipareg_parse_dummy, 0x0000C028, 0x1000, 0, 0, 1, 0}, + + /* IPA_CFG */ + [IPA_HW_v5_5][IPA_COMP_HW_VERSION] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000040, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_VERSION] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000044, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_FLAVOR_0] = { + ipareg_construct_dummy, ipareg_parse_ipa_flavor_0, + 0x00000000, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_ENABLED_PIPES] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_COMP_CFG] = { + ipareg_construct_comp_cfg_v5_0, ipareg_parse_comp_cfg_v5_0, + 0x00000048, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_CLKON_CFG] = { + ipareg_construct_clkon_cfg_v4_5, ipareg_parse_clkon_cfg_v4_5, + 0x00000050, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_ROUTE] = { + ipareg_construct_route_v5_0, ipareg_parse_dummy, + 0x00000054, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SHARED_MEM_SIZE] = { + ipareg_construct_dummy, ipareg_parse_shared_mem_size, + 0x0000005C, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_NAT_TIMER] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000060, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_TAG_TIMER] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000064, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_QSB_MAX_WRITES] = { + ipareg_construct_qsb_max_writes, ipareg_parse_qsb_max_writes, + 0x00000070, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_QSB_MAX_READS] = { + ipareg_construct_qsb_max_reads_v4_0, ipareg_parse_qsb_max_reads, + 0x00000074, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STATE_TX1] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_FETCHER] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000000C4, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_FETCHER_MASK_0] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000000C8, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_DFETCHER] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000000CC, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_ACL] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000000D0, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000000D4, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_RX_ACTIVE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_TX0] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_AGGR_ACTIVE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_AGGR_ACTIVE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000120, 0x4, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_GSI_TLV] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_GSI_AOS] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000000D8, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_GENERIC_RAM_ARBITER_PRIORITY] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000004DC, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STATE_COAL_MASTER_1] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000000FC, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_FILT_ROUT_HASH_EN] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_FILT_ROUT_HASH_FLUSH] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_FILT_ROUT_CACHE_FLUSH] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000404, 0, 0, 0, 0, 0 }, + [IPA_HW_v5_5][IPA_SYS_PKT_PROC_CNTXT_BASE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000470, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_LOCAL_PKT_PROC_CNTXT_BASE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000478, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_TX_CFG] = { + ipareg_construct_tx_cfg_v5_0, ipareg_parse_tx_cfg_v5_0, + 0x00000488, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_IDLE_INDICATION_CFG] = { + ipareg_construct_idle_indication_cfg, ipareg_parse_dummy, + 0x000004A8, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_QTIME_TIMESTAMP_CFG] = { + ipareg_construct_qtime_timestamp_cfg_v5_5, ipareg_parse_dummy, + 0x0000004Ac, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_TIMERS_XO_CLK_DIV_CFG] = { + ipareg_construct_timers_xo_clk_div_cfg, + ipareg_parse_timers_xo_clk_div_cfg, + 0x0000004B0, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_TIMERS_PULSE_GRAN_CFG] = { + ipareg_construct_timers_pulse_gran_cfg_v5_0, + ipareg_parse_timers_pulse_gran_cfg_v5_0, + 0x0000004B4, 0, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_SRC_RSRC_GRP_01_RSRC_TYPE_n] = { + ipareg_construct_rsrg_grp_xy_v5_0, ipareg_parse_dummy, + 0x00000500, 0x20, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SRC_RSRC_GRP_23_RSRC_TYPE_n] = { + ipareg_construct_rsrg_grp_xy_v5_0, ipareg_parse_dummy, + 0x00000504, 0x20, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_DST_RSRC_GRP_01_RSRC_TYPE_n] = { + ipareg_construct_rsrg_grp_xy_v5_0, ipareg_parse_dummy, + 0x00000600, 0x20, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_DST_RSRC_GRP_23_RSRC_TYPE_n] = { + ipareg_construct_rsrg_grp_xy_v5_0, ipareg_parse_dummy, + 0x00000604, 0x20, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SRC_RSRC_GRP_45_RSRC_TYPE_n] = { + ipareg_construct_rsrg_grp_xy_v5_0, ipareg_parse_dummy, + 0x00000508, 0x20, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SRC_RSRC_GRP_67_RSRC_TYPE_n] = { + ipareg_construct_rsrg_grp_xy_v5_0, ipareg_parse_dummy, + 0x0000050C, 0x20, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_DST_RSRC_GRP_45_RSRC_TYPE_n] = { + ipareg_construct_rsrg_grp_xy_v5_0, ipareg_parse_dummy, + 0x00000608, 0x20, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_DST_RSRC_GRP_67_RSRC_TYPE_n] = { + ipareg_construct_rsrg_grp_xy_v5_0, ipareg_parse_dummy, + 0x0000060C, 0x20, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_AGGR_FORCE_CLOSE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_AGGR_FORCE_CLOSE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000006B0, 0x4, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_QUOTA_BASE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000006D0, 0x4, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_QUOTA_MASK_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x4, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_QUOTA_MASK_EE_n_REG_k] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000710, 0x4, 0, 0, 0, 0x8}, + [IPA_HW_v5_5][IPA_STAT_TETHERING_BASE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000006E0, 0x4, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_TETHERING_MASK_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x4, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_TETHERING_MASK_EE_n_REG_k] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000750, 0x4, 0, 0, 0, 0x8}, + [IPA_HW_v5_5][IPA_STAT_FILTER_IPV4_BASE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000700, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_FILTER_IPV6_BASE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000704, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_ROUTER_IPV4_BASE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000708, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_ROUTER_IPV6_BASE] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000070C, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_STAT_DROP_CNT_BASE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000006F0, 0x4, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STAT_DROP_CNT_MASK_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x4, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_STAT_DROP_CNT_MASK_EE_n_REG_k] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000790 , 0x4, 0, 0, 1, 0x8}, + [IPA_HW_v5_5][IPA_ENDP_INIT_CTRL_n] = { + ipareg_construct_endp_init_ctrl_n_v4_0, ipareg_parse_dummy, + 0x00001000, 0x80, 0, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_CTRL_SCND_n] = { + ipareg_construct_endp_init_ctrl_scnd_n, ipareg_parse_dummy, + 0x00001004, 0x80, 0, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_CFG_n] = { + ipareg_construct_endp_init_cfg_n, ipareg_parse_dummy, + 0x00001008, 0x80, 0, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_NAT_n] = { + ipareg_construct_endp_init_nat_n, ipareg_parse_dummy, + 0x0000100C, 0x80, 0, 10, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_HDR_n] = { + ipareg_construct_endp_init_hdr_n_v4_9, ipareg_parse_dummy, + 0x00001010, 0x80, 0, 30, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_HDR_EXT_n] = { + ipareg_construct_endp_init_hdr_ext_n_v5_0, ipareg_parse_dummy, + 0x00001014, 0x80, 0, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_HDR_METADATA_n] = { + ipareg_construct_endp_init_hdr_metadata_n, + ipareg_parse_dummy, + 0x0000101c, 0x80, 0, 10, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_MODE_n] = { + ipareg_construct_endp_init_mode_n_v5_0, ipareg_parse_dummy, + 0x00001020, 0x80, 0, 10, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_AGGR_n] = { + ipareg_construct_endp_init_aggr_n_v4_5, + ipareg_parse_endp_init_aggr_n_v4_5, + 0x00001024, 0x80, 0, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_DEAGGR_n] = { + ipareg_construct_endp_init_deaggr_n_v4_5, + ipareg_parse_dummy, + 0x00001034, 0x80, 0, 10, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_RSRC_GRP_n] = { + ipareg_construct_endp_init_rsrc_grp_n_v5_0, + ipareg_parse_dummy, + 0x00001038, 0x80, 0, 30, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_SEQ_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000103C, 0x80, 0, 10, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_STATUS_n] = { + ipareg_construct_endp_status_n_v5_0, ipareg_parse_dummy, + 0x00001040, 0x80, 0, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_CONN_TRACK_n] = { + ipareg_construct_endp_init_conn_track_n, + ipareg_parse_dummy, + 0x00001050, 0x80, 0, 10, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_FILTER_ROUTER_HSH_CFG_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x70, 0, 31, 1, 0}, + [IPA_HW_v5_5][IPA_FILTER_CACHE_CFG_n] = { + ipareg_construct_cache_cfg_n, ipareg_parse_cache_cfg_n, + 0x0000105C , 0x80, 0, 31, 1, 0}, + [IPA_HW_v5_5][IPA_ROUTER_CACHE_CFG_n] = { + ipareg_construct_cache_cfg_n, ipareg_parse_cache_cfg_n, + 0x00001070 , 0x80, 0, 31, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_CTRL_STATUS_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00001068, 0x80, 0, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_HDR_METADATA_MASK_n] = { + ipareg_construct_endp_init_hdr_metadata_mask_n, + ipareg_parse_dummy, + 0x00001018, 0x80, 13, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_HOL_BLOCK_EN_n] = { + ipareg_construct_endp_init_hol_block_en_n, + ipareg_parse_dummy, + 0x0000102c, 0x80, 13, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_HOL_BLOCK_TIMER_n] = { + ipareg_construct_endp_init_hol_block_timer_n_v5_0, + ipareg_parse_dummy, + 0x00001030, 0x80, 13, 30, 1, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_PROD_CFG_n] = { + ipareg_construct_endp_init_prod_cfg_n_v5_5, ipareg_parse_dummy, + 0x0000106C, 0x80, 13, 30, 1, 0}, + [IPA_HW_v5_5][IPA_COAL_EVICT_LRU] = { + ipareg_construct_coal_evict_lru_v5_5, ipareg_parse_coal_evict_lru_v5_5, + 0x00000918, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_COAL_QMAP_CFG] = { + ipareg_construct_coal_qmap_cfg, ipareg_parse_coal_qmap_cfg, + 0x0000091c, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_ULSO_CFG_IP_ID_MIN_VALUE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000934, 0x4, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_ULSO_CFG_IP_ID_MAX_VALUE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00000924, 0x4, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_ULSO_CFG_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00001070, 0x80, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_INIT_NAT_EXC_SUPPRESS_n] = { + ipareg_construct_endp_init_nat_exc_suppress_n, ipareg_parse_dummy, + 0x00001078, 0x80, 0, 0, 0, 0}, + + /* IPA_DEBUG */ + [IPA_HW_v5_5][IPA_RX_HPS_CLIENTS_MIN_DEPTH_1] = { //TODO contstruct not matching previous version + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000082C8, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_RX_HPS_CLIENTS_MAX_DEPTH_1] = { //TODO contstruct not matching previous version + ipareg_construct_dummy, ipareg_parse_dummy, + 0x000082D0, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_RX_HPS_CLIENTS_MIN_DEPTH_0] = { + ipareg_construct_rx_hps_clients_depth0_v4_5, + ipareg_parse_dummy, + 0x000082c4, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_RX_HPS_CLIENTS_MAX_DEPTH_0] = { + ipareg_construct_rx_hps_clients_depth0_v4_5, + ipareg_parse_dummy, + 0x000082CC, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_DPS_SEQUENCER_FIRST] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00008584, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_DPS_SEQUENCER_LAST] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00008588, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_HPS_SEQUENCER_FIRST] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000858C, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_HPS_SEQUENCER_LAST] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00008590, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_GSI_CFG1_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00008800, 0x4, 0, 30, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_GSI_CFG_TLV_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00009000, 0x4, 0, 30, 0, 0}, + [IPA_HW_v5_5][IPA_ENDP_GSI_CFG_AOS_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x00009400, 0x4, 0, 30, 0, 0}, + + /* IPA_EE */ + [IPA_HW_v5_5][IPA_IRQ_STTS_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000C008, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_IRQ_EN_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000C00c, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_IRQ_CLR_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000C010, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SNOC_FEC_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000C018, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SUSPEND_IRQ_INFO_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SUSPEND_IRQ_INFO_EE_n_REG_k] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000C030, 0x1000, 0, 0, 0, 0x4}, + [IPA_HW_v5_5][IPA_SUSPEND_IRQ_EN_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SUSPEND_IRQ_EN_EE_n_REG_k] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000C050, 0x1000, 0, 0, 0, 0x4}, + [IPA_HW_v5_5][IPA_SUSPEND_IRQ_CLR_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_SUSPEND_IRQ_CLR_EE_n_REG_k] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000C070, 0x1000, 0, 0, 0, 0x4}, + [IPA_HW_v5_5][IPA_HOLB_DROP_IRQ_INFO_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_HOLB_DROP_IRQ_EN_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_HOLB_DROP_IRQ_CLR_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0x1000, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_IRQ_EE_UC_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + 0x0000C01c, 0x1000, 0, 0, 1, 0}, + [IPA_HW_v5_5][IPA_FEC_ADDR_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_FEC_ADDR_MSB_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 0, 0}, + [IPA_HW_v5_5][IPA_FEC_ATTR_EE_n] = { + ipareg_construct_dummy, ipareg_parse_dummy, + -1, 0, 0, 0, 0, 0}, + }; /* @@ -5078,7 +5587,7 @@ void ipahal_get_aggr_force_close_valmask(int ep_idx, IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_SHFT_V4_9; bmsk = IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_BMSK_V4_9; - } else if (ipahal_ctx->hw_type <= IPA_HW_v5_1) { + } else if (ipahal_ctx->hw_type <= IPA_HW_v5_5) { u8 reg_idx; shft = diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h index 2bce6f535f..5d96c09249 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h @@ -165,6 +165,7 @@ enum ipahal_reg_name { IPA_ULSO_CFG_IP_ID_MIN_VALUE_n, IPA_ULSO_CFG_IP_ID_MAX_VALUE_n, IPA_ENDP_INIT_ULSO_CFG_n, + IPA_ENDP_INIT_NAT_EXC_SUPPRESS_n, IPA_REG_MAX, }; @@ -752,12 +753,32 @@ struct ipahal_reg_state_coal_master { /* * struct ipahal_reg_coal_evict_lru - IPA_COAL_EVICT_LRU register * @coal_vp_lru_thrshld: Connection that is opened below this val - * will not get evicted + * will not get evicted. valid till v5_2. * @coal_eviction_en: Enable eviction + * @coal_vp_lru_gran_sel: select the appropiate granularity out of 4 options + * Valid from v5_5. + * @coal_vp_lru_udp_thrshld: Coalescing eviction threshold. LRU VP + * stickness/inactivity defined by this threshold fot UDP connectiom. + * 0 mean all UDP's non sticky. Valid from v5_5. + * @coal_vp_lru_tcp_thrshld: Coalescing eviction threshold. LRU VP + * stickness/inactivity defined by this threshold fot TCP connection. + * 0 mean all TCP's non sticky. Valid from v5_5. + * @coal_vp_lru_udp_thrshld_en: Coalescing eviction enable for UDP connections + * when UDP pacjet arrived. 0-disable these evictions. Valid from v5_5. + * @coal_vp_lru_tcp_thrshld_en: Coalescing eviction enable for TCP connections + * when TCP pacjet arrived. 0-disable these evictions. Valid from v5_5. + * @coal_vp_lru_tcp_num: configured TCP NUM value , SW define when TCP/UDP will + * treat as exceed during eviction process. Valid from v5_5. */ struct ipahal_reg_coal_evict_lru { u32 coal_vp_lru_thrshld; bool coal_eviction_en; + u8 coal_vp_lru_gran_sel; + u8 coal_vp_lru_udp_thrshld; + u8 coal_vp_lru_tcp_thrshld; + bool coal_vp_lru_udp_thrshld_en; + bool coal_vp_lru_tcp_thrshld_en; + bool coal_vp_lru_tcp_num; }; /* diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h index efc60a6ee0..9e267b84db 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h @@ -126,6 +126,8 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type); #define IPA_ENDP_INIT_AGGR_n_AGGR_EN_BMSK 0x3 #define IPA_ENDP_INIT_AGGR_n_AGGR_EN_SHFT 0x0 +#define IPA_ENDP_INIT_AGGR_n_AGGR_COAL_L2_BMSK_V5_5 0x10000000 +#define IPA_ENDP_INIT_AGGR_n_AGGR_COAL_L2_SHFT_V5_5 28 #define IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_BMSK_V4_5 0x8000000 #define IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_SHFT_V4_5 27 #define IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_BMSK_V4_5 0x4000000 @@ -271,6 +273,8 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type); #define IPA_DEBUG_CNT_REG_N_DBG_CNT_REG_SHFT 0x0 /* IPA_ENDP_INIT_CFG_n register */ +#define IPA_ENDP_INIT_CFG_n_PIPE_REPLICATE_EN_SEL_BMSK_V5_5 0x200 +#define IPA_ENDP_INIT_CFG_n_PIPE_REPLICATE_EN_SEL_SHFT_V5_5 0x9 #define IPA_ENDP_INIT_CFG_n_CS_GEN_QMB_MASTER_SEL_BMSK 0x100 #define IPA_ENDP_INIT_CFG_n_CS_GEN_QMB_MASTER_SEL_SHFT 0x8 #define IPA_ENDP_INIT_CFG_n_CS_METADATA_HDR_OFFSET_BMSK 0x78 @@ -280,6 +284,23 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type); #define IPA_ENDP_INIT_CFG_n_FRAG_OFFLOAD_EN_BMSK 0x1 #define IPA_ENDP_INIT_CFG_n_FRAG_OFFLOAD_EN_SHFT 0x0 +/* IPA_ENDP_INIT_PROD_CFG_n register */ +#define IPA_ENDP_INIT_PROD_CFG_n_EGRESS_TC_HIGHEST_BMASK 0xFF000000 +#define IPA_ENDP_INIT_PROD_CFG_n_EGRESS_TC_HIGHEST_SHIFT 0x18 +#define IPA_ENDP_INIT_PROD_CFG_n_EGRESS_TC_LOWEST_BMASK 0xFF0000 +#define IPA_ENDP_INIT_PROD_CFG_n_EGRESS_TC_LOWEST_SHIFT 0x10 +#define IPA_ENDP_INIT_PROD_CFG_n_MAX_OUTPUT_SIZE_BMASK 0xFF00 +#define IPA_ENDP_INIT_PROD_CFG_n_MAX_OUTPUT_SIZE_SHIFT 0x8 +#define IPA_ENDP_INIT_PROD_CFG_n_TSP_INDEX_BMASK 0xF0 +#define IPA_ENDP_INIT_PROD_CFG_n_TSP_INDEX_SHIFT 0x3 +#define IPA_ENDP_INIT_PROD_CFG_n_MAX_OUTPUT_SIZE_DROP_ENABLE_BMASK 0x4 +#define IPA_ENDP_INIT_PROD_CFG_n_MAX_OUTPUT_SIZE_DROP_ENABLE_SHIFT 0x2 +#define IPA_ENDP_INIT_PROD_CFG_n_TSP_ENABLE_BMASK 0x2 +#define IPA_ENDP_INIT_PROD_CFG_n_TSP_ENABLE_SHIFT 0x1 +#define IPA_ENDP_INIT_PROD_CFG_n_TX_SEL_BMASK 0x1 +#define IPA_ENDP_INIT_PROD_CFG_n_TX_SEL_SHIFT 0x0 + + /* IPA_ENDP_INIT_HDR_METADATA_MASK_n register */ #define IPA_ENDP_INIT_HDR_METADATA_MASK_n_METADATA_MASK_BMSK 0xffffffff #define IPA_ENDP_INIT_HDR_METADATA_MASK_n_METADATA_MASK_SHFT 0x0 @@ -710,7 +731,7 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type); #define IPA_COAL_VP_LRU_THRSHLD_SHFT 1 #define IPA_COAL_EVICTION_EN_BMSK 0x1 #define IPA_COAL_EVICTION_EN_SHFT 0 -#define IPA_COAL_QMAP_CFG_BMSK 0x1 +#define IPA_COAL_QMAP_CFG_BMSK 0x3 #define IPA_COAL_QMAP_CFG_SHFT 0 #define IPA_NAT_UC_EXTERNAL_CFG_BMSK 0xFFFFFFFF #define IPA_NAT_UC_EXTERNAL_CFG_SHFT 0 @@ -838,4 +859,25 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type); #define IPA_ENDP_INIT_ULSO_CFG_n_IPV4_ID_MIN_MAX_VAL_INDEX_BMSK 0x3 #define IPA_ENDP_INIT_ULSO_CFG_n_IPV4_ID_MIN_MAX_VAL_INDEX_SHFT 0 +/* IPA 5.5 */ +/* IPA_COAL registers*/ +#define IPA_COAL_VP_LRU_TCP_NUM_BMSK_v5_5 0xF8000 +#define IPA_COAL_VP_LRU_TCP_NUM_SHFT_v5_5 15 +#define IPA_COAL_VP_LRU_TCP_THRSHLD_EN_BMSK_v5_5 0x4000 +#define IPA_COAL_VP_LRU_TCP_THRSHLD_EN_SHFT_v5_5 14 +#define IPA_COAL_VP_LRU_UDP_THRSHLD_EN_BMSK_v5_5 0x2000 +#define IPA_COAL_VP_LRU_UDP_THRSHLD_EN_SHFT_v5_5 13 +#define IPA_COAL_VP_LRU_TCP_THRSHLD_BMSK_v5_5 0x1F00 +#define IPA_COAL_VP_LRU_TCP_THRSHLD_SHFT_v5_5 8 +#define IPA_COAL_VP_LRU_UDP_THRSHLD_BMSK_v5_5 0xF8 +#define IPA_COAL_VP_LRU_UDP_THRSHLD_SHFT_v5_5 3 +#define IPA_COAL_VP_LRU_GRAN_SEL_BMSK_v5_5 0x6 +#define IPA_COAL_VP_LRU_GRAN_SEL_SHFT_v5_5 1 +#define IPA_COAL_EVICTION_EN_BMSK_v5_5 0x1 +#define IPA_COAL_EVICTION_EN_SHFT_v5_5 0 + +/* IPA_ENDP_INIT_NAT_EXC_SUPPRESS_n register */ +#define IPA_ENDP_INIT_NAT_EXC_SUPPRESS_n_EN_BMSK 0x1 +#define IPA_ENDP_INIT_NAT_EXC_SUPPRESS_n_EN_SHFT 0x0 + #endif /* _IPAHAL_REG_I_H_ */ diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 1c6e8e9056..8dc042250b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -22,8 +22,10 @@ #include #include #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) #include #include +#endif #include #include "ipa_qmi_service.h" #include @@ -31,7 +33,11 @@ #include #include #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)) +#include +#else #include +#endif #include "ipa_mhi_proxy.h" #include "ipa_trace.h" @@ -1439,7 +1445,12 @@ static netdev_tx_t ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) qmap_check = RMNET_MAP_GET_CD_BIT(skb); +#else + qmap_check = (((struct rmnet_map_header *)(void *)(skb->data))->flags & MAP_CMD_FLAG) ? + true : false; +#endif spin_lock_irqsave(&wwan_ptr->lock, flags); /* There can be a race between enabling the wake queue and * suspend in progress. Check if suspend is pending and 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 807c6bc7d2..60f9ad9ae0 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 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "ipa_qmi_service.h" #include "ipa_i.h"