Browse Source

msm: ipa: ipa5.5 updates

ipa5.5 register updates and resource/ep configuration.

Change-Id: I5bd1aad67f481d36f4942e215f422edd7073d06e
Signed-off-by: Chaitanya Pratapa <[email protected]>
(cherry picked from commit 7ba64dfbbd3bcbab52f17a470fa7f2ffbe29b02c)
Chaitanya Pratapa 3 years ago
parent
commit
d7819fa285

+ 0 - 1
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

+ 0 - 1
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

+ 1 - 1
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

+ 1 - 1
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

+ 10 - 0
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

+ 8 - 40
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();

+ 63 - 8
drivers/platform/msm/ipa/ipa_v3/ipa.c

@@ -27,7 +27,6 @@
 #include <linux/hashtable.h>
 #include <linux/jhash.h>
 #include <linux/pci.h>
-#include <soc/qcom/subsystem_restart.h>
 #include <linux/soc/qcom/smem.h>
 #include <linux/qcom_scm.h>
 #include <asm/cacheflush.h>
@@ -37,6 +36,12 @@
 #include <linux/of_address.h>
 #include <linux/qcom_scm.h>
 #include <linux/soc/qcom/mdt_loader.h>
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0))
+#include <linux/panic_notifier.h>
+#else
+#include <soc/qcom/subsystem_restart.h>
+#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);
 

+ 10 - 0
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_ */

+ 3 - 0
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)
 {

+ 2 - 0
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,

+ 4 - 0
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);
 		/*

+ 0 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c

@@ -10,7 +10,6 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/uaccess.h>
-#include <soc/qcom/subsystem_restart.h>
 #include <linux/ipa.h>
 #include <linux/vmalloc.h>
 

+ 601 - 3
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

+ 295 - 4
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,14 +573,73 @@ int ipa_imm_cmd_modify_ip_packet_init_ex(
 	return 0;
 }
 
-inline void ipa_imm_cmd_modify_ip_packet_init_ex_dest_pipe(
+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 *)cmd_data)->rt_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)
+{
+	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(
 	enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
 {
@@ -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

+ 46 - 3
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;
 };
 
 /*

+ 692 - 30
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, &params->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(
+			&params->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,
+			&params->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,40 +2497,158 @@ fail_extra_alloc:
 	return rc;
 }
 
-
-/**
- * ipa_fltrt_calc_extra_wrd_bytes()- Calculate the number of extra words for eq
- * @attrib: equation attribute
+/*
+ * 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 value: 0 on success, negative otherwise
+ * Return codes:
+ * 0: success
+ * -EPERM: wrong input
  */
-static int ipa_fltrt_calc_extra_wrd_bytes(
-	const struct ipa_ipfltri_rule_eq *attrib)
+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 num = 0;
-
-	/*
-	 * 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)
-		num++;
-	if (attrib->protocol_eq_present)
-		num++;
-	if (attrib->tc_eq_present)
-		num++;
-	num += attrib->num_offset_meq_128;
-	num += attrib->num_offset_meq_32;
-	num += attrib->num_ihl_offset_meq_32;
-	num += attrib->num_ihl_offset_range_16;
-	if (attrib->ihl_offset_eq_32_present)
-		num++;
-	if (attrib->ihl_offset_eq_16_present)
-		num++;
+	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;
 
-	IPAHAL_DBG_LOW("extra bytes number %d\n", num);
+	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
+ * @attrib: equation attribute
+ *
+ * Return value: 0 on success, negative otherwise
+ */
+static int ipa_fltrt_calc_extra_wrd_bytes(
+	const struct ipa_ipfltri_rule_eq *attrib)
+{
+	int num = 0;
+
+	/*
+	 * 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)
+		num++;
+	if (attrib->protocol_eq_present)
+		num++;
+	if (attrib->tc_eq_present)
+		num++;
+	num += attrib->num_offset_meq_128;
+	num += attrib->num_offset_meq_32;
+	num += attrib->num_ihl_offset_meq_32;
+	num += attrib->num_ihl_offset_range_16;
+	if (attrib->ihl_offset_eq_32_present)
+		num++;
+	if (attrib->ihl_offset_eq_16_present)
+		num++;
+
+	IPAHAL_DBG_LOW("extra bytes number %d\n", num);
 
 	return num;
 }
@@ -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

+ 6 - 0
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;
 };

+ 123 - 0
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);
 

+ 228 - 0
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
 

+ 510 - 1
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 =

+ 22 - 1
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;
 };
 
 /*

+ 43 - 1
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_ */

+ 11 - 0
drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c

@@ -22,8 +22,10 @@
 #include <linux/workqueue.h>
 #include <linux/debugfs.h>
 #include <net/pkt_sched.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0))
 #include <soc/qcom/subsystem_restart.h>
 #include <soc/qcom/subsystem_notif.h>
+#endif
 #include <linux/remoteproc/qcom_rproc.h>
 #include "ipa_qmi_service.h"
 #include <linux/rmnet_ipa_fd_ioctl.h>
@@ -31,7 +33,11 @@
 #include <uapi/linux/ip.h>
 #include <uapi/linux/msm_rmnet.h>
 #include <net/ipv6.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0))
+#include <linux/if_rmnet.h>
+#else
 #include <net/rmnet_config.h>
+#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

+ 1 - 0
drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c

@@ -10,6 +10,7 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/compat.h>
 #include <linux/rmnet_ipa_fd_ioctl.h>
 #include "ipa_qmi_service.h"
 #include "ipa_i.h"