Merge "msm: ipa3: Changes to add dual pass support for GSB pipe"
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c
index 728c283..2145042 100644
--- a/drivers/platform/msm/gsi/gsi.c
+++ b/drivers/platform/msm/gsi/gsi.c
@@ -1865,8 +1865,8 @@
 	struct gsihal_reg_ev_ch_k_cntxt_3 ev_ch_k_cntxt_3;
 	struct gsihal_reg_ev_ch_k_cntxt_8 ev_ch_k_cntxt_8;
 	struct gsihal_reg_ev_ch_k_cntxt_9 ev_ch_k_cntxt_9;
-	struct gsihal_reg_ev_ch_k_cntxt_10 ev_ch_k_cntxt_10;
-	struct gsihal_reg_ev_ch_k_cntxt_11 ev_ch_k_cntxt_11;
+	union gsihal_reg_ev_ch_k_cntxt_10 ev_ch_k_cntxt_10;
+	union gsihal_reg_ev_ch_k_cntxt_11 ev_ch_k_cntxt_11;
 	struct gsihal_reg_ev_ch_k_cntxt_12 ev_ch_k_cntxt_12;
 	struct gsihal_reg_ev_ch_k_cntxt_13 ev_ch_k_cntxt_13;
 
@@ -1904,25 +1904,41 @@
 		ee, evt_id,
 		&ev_ch_k_cntxt_9);
 
-	ev_ch_k_cntxt_10.msi_addr_lsb = GSI_LSB(props->msi_addr);
-	gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_10,
-		ee, evt_id,
-		&ev_ch_k_cntxt_10);
+	if(props->intf != GSI_EVT_CHTYPE_WDI3_V2_EV) {
+		ev_ch_k_cntxt_10.msi_addr_lsb = GSI_LSB(props->msi_addr);
+		gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_10,
+			ee, evt_id,
+			&ev_ch_k_cntxt_10);
 
-	ev_ch_k_cntxt_11.msi_addr_msb = GSI_MSB(props->msi_addr);
-	gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_11,
-		ee, evt_id,
-		&ev_ch_k_cntxt_11);
+		ev_ch_k_cntxt_11.msi_addr_msb = GSI_MSB(props->msi_addr);
+		gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_11,
+			ee, evt_id,
+			&ev_ch_k_cntxt_11);
 
-	ev_ch_k_cntxt_12.rp_update_addr_lsb = GSI_LSB(props->rp_update_addr);
-	gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_12,
-		ee, evt_id,
-		&ev_ch_k_cntxt_12);
 
-	ev_ch_k_cntxt_13.rp_update_addr_msb = GSI_MSB(props->rp_update_addr);
-	gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_13,
-		ee, evt_id,
-		&ev_ch_k_cntxt_13);
+		ev_ch_k_cntxt_12.rp_update_addr_lsb = GSI_LSB(props->rp_update_addr);
+		gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_12,
+			ee, evt_id,
+			&ev_ch_k_cntxt_12);
+
+		ev_ch_k_cntxt_13.rp_update_addr_msb = GSI_MSB(props->rp_update_addr);
+		gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_13,
+			ee, evt_id,
+			&ev_ch_k_cntxt_13);
+	}
+	else {
+		ev_ch_k_cntxt_10.rp_addr_lsb = GSI_LSB(props->rp_update_addr);
+		gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_10,
+			ee, evt_id,
+			&ev_ch_k_cntxt_10);
+
+		ev_ch_k_cntxt_11.rp_addr_msb = GSI_MSB(props->rp_update_addr);
+		gsihal_write_reg_nk_fields(GSI_EE_n_EV_CH_k_CNTXT_11,
+			ee, evt_id,
+			&ev_ch_k_cntxt_11);
+	}
+
+
 }
 
 static void gsi_init_evt_ring(struct gsi_evt_ring_props *props,
@@ -2721,6 +2737,7 @@
 	case GSI_CHAN_PROT_WDI3:
 	case GSI_CHAN_PROT_GCI:
 	case GSI_CHAN_PROT_MHIP:
+	case GSI_CHAN_PROT_WDI3_V2:
 		ch_k_cntxt_0.chtype_protocol_msb = 0;
 		break;
 	case GSI_CHAN_PROT_AQC:
diff --git a/drivers/platform/msm/gsi/gsi.h b/drivers/platform/msm/gsi/gsi.h
index bae59d2..f0b5814 100644
--- a/drivers/platform/msm/gsi/gsi.h
+++ b/drivers/platform/msm/gsi/gsi.h
@@ -115,6 +115,7 @@
 	GSI_VER_2_11 = 9,
 	GSI_VER_3_0 = 10,
 	GSI_VER_5_5 = 11,
+	GSI_VER_6_0 = 12,
 	GSI_VER_MAX,
 };
 
@@ -174,6 +175,7 @@
 	GSI_EVT_CHTYPE_11AD_EV = 0x9,
 	GSI_EVT_CHTYPE_RTK_EV = 0xC,
 	GSI_EVT_CHTYPE_NTN_EV = 0xD,
+	GSI_EVT_CHTYPE_WDI3_V2_EV = 0XF,
 };
 
 enum gsi_evt_ring_elem_size {
@@ -263,6 +265,7 @@
 	GSI_CHAN_PROT_QDSS = 0xB,
 	GSI_CHAN_PROT_RTK = 0xC,
 	GSI_CHAN_PROT_NTN = 0xD,
+	GSI_CHAN_PROT_WDI3_V2 = 0XF,
 };
 
 enum gsi_max_prefetch {
@@ -954,6 +957,35 @@
 	uint32_t fixed_data_buffer_size_pow_2:16;
 	uint32_t resv2:8;
 };
+/**
+ * gsi_wdi3_hamilton_channel_scratch - WDI 3 protocol, hamilton chipset
+ * SW config area of channel scratch
+ *
+ * @wifi_rx_ri_addr_low: Low 32 bits of Transfer ring Read Index address.
+ * @wifi_rx_ri_addr_high: High 32 bits of Transer ring Read Index address.
+ * @update_ri_moderation_threshold: Threshold N for Transfer ring Read Index
+				    N is the number of packets that IPA will
+				    process before wifi transfer ring Ri will
+				    be updated.
+ * @endp_metadata_reg_offset: Rx only, the offset of IPA_ENDP_INIT_HDR_METADATA_n
+			      of the corresponding endpoint in 4B words from IPA
+			      base address.
+ * @qmap_id: Rx only, used for setting metadata register in IPA, Read only field
+	     for MCS, Write for SW
+ */
+
+struct __packed gsi_wdi3_v2_channel_scratch {
+	uint32_t wifi_rp_address_low;
+	uint32_t wifi_rp_address_high;
+	uint32_t update_rp_moderation_threshold : 5;
+	uint32_t qmap_id : 8;
+	uint32_t reserved1 : 3;
+	uint32_t endp_metadata_reg_offset : 16;
+	uint32_t rx_pkt_offset : 16;
+	uint32_t reserved2 : 6;
+	uint32_t bank_id : 6;
+	uint32_t reserved3: 4;
+};
 
 /**
  * gsi_wdi3_channel_scratch - WDI protocol 3 SW config area of
@@ -1125,6 +1157,7 @@
 	struct __packed gsi_11ad_rx_channel_scratch rx_11ad;
 	struct __packed gsi_11ad_tx_channel_scratch tx_11ad;
 	struct __packed gsi_wdi3_channel_scratch wdi3;
+	struct __packed gsi_wdi3_v2_channel_scratch wdi3_v2;
 	struct __packed gsi_mhip_channel_scratch mhip;
 	struct __packed gsi_wdi2_channel_scratch_new wdi2_new;
 	struct __packed gsi_aqc_channel_scratch aqc;
diff --git a/drivers/platform/msm/gsi/gsihal/gsihal_reg.c b/drivers/platform/msm/gsi/gsihal/gsihal_reg.c
index 803d215..613cfbc 100644
--- a/drivers/platform/msm/gsi/gsihal/gsihal_reg.c
+++ b/drivers/platform/msm/gsi/gsihal/gsihal_reg.c
@@ -746,23 +746,23 @@
 static void gsireg_construct_ev_ch_k_cntxt_10(enum gsihal_reg_name reg,
 	const void *fields, u32 *val)
 {
-	struct gsihal_reg_ev_ch_k_cntxt_10 *ctxt =
-		(struct gsihal_reg_ev_ch_k_cntxt_10 *)fields;
+	union gsihal_reg_ev_ch_k_cntxt_10 *ctxt =
+		(union gsihal_reg_ev_ch_k_cntxt_10 *)fields;
 
 	GSI_SETFIELD_IN_REG(*val, ctxt->msi_addr_lsb,
-		GSI_EE_n_EV_CH_k_CNTXT_10_MSI_ADDR_LSB_SHFT,
-		GSI_EE_n_EV_CH_k_CNTXT_10_MSI_ADDR_LSB_BMSK);
+		GSI_EE_n_EV_CH_k_CNTXT_10_ADDR_LSB_SHFT,
+		GSI_EE_n_EV_CH_k_CNTXT_10_ADDR_LSB_BMSK);
 }
 
 static void gsireg_construct_ev_ch_k_cntxt_11(enum gsihal_reg_name reg,
 	const void *fields, u32 *val)
 {
-	struct gsihal_reg_ev_ch_k_cntxt_11 *ctxt =
-		(struct gsihal_reg_ev_ch_k_cntxt_11 *)fields;
+	union gsihal_reg_ev_ch_k_cntxt_11 *ctxt =
+		(union gsihal_reg_ev_ch_k_cntxt_11 *)fields;
 
 	GSI_SETFIELD_IN_REG(*val, ctxt->msi_addr_msb,
-		GSI_EE_n_EV_CH_k_CNTXT_11_MSI_ADDR_MSB_SHFT,
-		GSI_EE_n_EV_CH_k_CNTXT_11_MSI_ADDR_MSB_BMSK);
+		GSI_EE_n_EV_CH_k_CNTXT_11_ADDR_MSB_SHFT,
+		GSI_EE_n_EV_CH_k_CNTXT_11_ADDR_MSB_BMSK);
 }
 
 static void gsireg_construct_ev_ch_k_cntxt_12(enum gsihal_reg_name reg,
diff --git a/drivers/platform/msm/gsi/gsihal/gsihal_reg.h b/drivers/platform/msm/gsi/gsihal/gsihal_reg.h
index 667762a..bd02a28 100644
--- a/drivers/platform/msm/gsi/gsihal/gsihal_reg.h
+++ b/drivers/platform/msm/gsi/gsihal/gsihal_reg.h
@@ -264,12 +264,14 @@
 	uint32_t intvec;
 };
 
-struct gsihal_reg_ev_ch_k_cntxt_10 {
+union gsihal_reg_ev_ch_k_cntxt_10 {
 	uint32_t msi_addr_lsb;
+	uint32_t rp_addr_lsb;
 };
 
-struct gsihal_reg_ev_ch_k_cntxt_11 {
+union gsihal_reg_ev_ch_k_cntxt_11 {
 	uint32_t msi_addr_msb;
+	uint32_t rp_addr_msb;
 };
 
 struct gsihal_reg_ev_ch_k_cntxt_12 {
diff --git a/drivers/platform/msm/gsi/gsihal/gsihal_reg_i.h b/drivers/platform/msm/gsi/gsihal/gsihal_reg_i.h
index 5e16c25..37bde4d 100644
--- a/drivers/platform/msm/gsi/gsihal/gsihal_reg_i.h
+++ b/drivers/platform/msm/gsi/gsihal/gsihal_reg_i.h
@@ -237,12 +237,12 @@
 #define GSI_EE_n_EV_CH_k_CNTXT_9_INTVEC_SHFT 0x0
 
 /* GSI_EE_n_EV_CH_k_CNTXT_10 */
-#define GSI_EE_n_EV_CH_k_CNTXT_10_MSI_ADDR_LSB_BMSK 0xffffffff
-#define GSI_EE_n_EV_CH_k_CNTXT_10_MSI_ADDR_LSB_SHFT 0x0
+#define GSI_EE_n_EV_CH_k_CNTXT_10_ADDR_LSB_BMSK 0xffffffff
+#define GSI_EE_n_EV_CH_k_CNTXT_10_ADDR_LSB_SHFT 0x0
 
 /* GSI_EE_n_EV_CH_k_CNTXT_11 */
-#define GSI_EE_n_EV_CH_k_CNTXT_11_MSI_ADDR_MSB_BMSK 0xffffffff
-#define GSI_EE_n_EV_CH_k_CNTXT_11_MSI_ADDR_MSB_SHFT 0x0
+#define GSI_EE_n_EV_CH_k_CNTXT_11_ADDR_MSB_BMSK 0xffffffff
+#define GSI_EE_n_EV_CH_k_CNTXT_11_ADDR_MSB_SHFT 0x0
 
 /* GSI_EE_n_EV_CH_k_CNTXT_12 */
 #define GSI_EE_n_EV_CH_k_CNTXT_12_RP_UPDATE_ADDR_LSB_BMSK 0xffffffff
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c b/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c
index d12bbd0..15f26b3 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c
@@ -208,7 +208,7 @@
 		return -EINVAL;
 	}
 
-	if (in->wdi_version > IPA_WDI_3 || in->wdi_version < IPA_WDI_1) {
+	if (in->wdi_version > IPA_WDI_3_V2 || in->wdi_version < IPA_WDI_1) {
 		IPA_WDI_ERR("wrong wdi version: %d\n", in->wdi_version);
 		return -EFAULT;
 	}
@@ -255,7 +255,7 @@
 
 	ipa_wdi_ctx_list[hdl]->is_smmu_enabled = out->is_smmu_enabled;
 
-	if (IPA_WDI2_OVER_GSI() || (in->wdi_version == IPA_WDI_3))
+	if (IPA_WDI2_OVER_GSI() || (in->wdi_version >= IPA_WDI_3))
 		out->is_over_gsi = true;
 	else
 		out->is_over_gsi = false;
@@ -400,7 +400,7 @@
 	rx.prop = rx_prop;
 	memset(rx_prop, 0, sizeof(rx_prop));
 	rx_prop[0].ip = IPA_IP_v4;
-	if (ipa_wdi_ctx_list[in->hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[in->hdl]->wdi_version >= IPA_WDI_3) {
 		if (IPA_CLIENT_IS_WLAN0_INSTANCE(ipa_wdi_ctx_list[in->hdl]->inst_id))
 			rx_prop[0].src_pipe = IPA_CLIENT_WLAN2_PROD;
 		else
@@ -416,7 +416,7 @@
 	}
 
 	rx_prop[1].ip = IPA_IP_v6;
-	if (ipa_wdi_ctx_list[in->hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[in->hdl]->wdi_version >= IPA_WDI_3) {
 		if (IPA_CLIENT_IS_WLAN0_INSTANCE(ipa_wdi_ctx_list[in->hdl]->inst_id))
 			rx_prop[1].src_pipe = IPA_CLIENT_WLAN2_PROD;
 		else
@@ -537,7 +537,7 @@
 		goto fail_setup_sys_pipe;
 	}
 	IPA_WDI_DBG("PM handle Registered\n");
-	if (ipa_wdi_ctx_list[in->hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[in->hdl]->wdi_version >= IPA_WDI_3) {
 		if (ipa3_conn_wdi3_pipes(in, out, ipa_wdi_ctx_list[in->hdl]->wdi_notify)) {
 			IPA_WDI_ERR("fail to setup wdi pipes\n");
 			ret = -EFAULT;
@@ -725,7 +725,7 @@
 		return -EPERM;
 	}
 
-	if (ipa_wdi_ctx_list[hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_3) {
 		if (IPA_CLIENT_IS_WLAN0_INSTANCE(ipa_wdi_ctx_list[hdl]->inst_id)) {
 			ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_PROD);
 			ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_CONS);
@@ -749,7 +749,7 @@
 		return -EFAULT;
 	}
 	IPA_WDI_DBG("Enable WDI pipes\n");
-	if (ipa_wdi_ctx_list[hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_3) {
 		if (ipa3_enable_wdi3_pipes(
 			ipa_ep_idx_tx, ipa_ep_idx_rx, ipa_ep_idx_tx1)) {
 			IPA_WDI_ERR("fail to enable wdi pipes\n");
@@ -1092,7 +1092,7 @@
 		}
 	}
 
-	if (ipa_wdi_ctx_list[hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_3) {
 		if (IPA_CLIENT_IS_WLAN0_INSTANCE(ipa_wdi_ctx_list[hdl]->inst_id)) {
 			ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_PROD);
 			ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_CONS);
@@ -1109,7 +1109,7 @@
 		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
 	}
 
-	if (ipa_wdi_ctx_list[hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_3) {
 		if (ipa3_disconn_wdi3_pipes(
 			ipa_ep_idx_tx, ipa_ep_idx_rx, ipa_ep_idx_tx1)) {
 			IPA_WDI_ERR("fail to tear down wdi pipes\n");
@@ -1167,7 +1167,7 @@
 		return -EPERM;
 	}
 
-	if (ipa_wdi_ctx_list[hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_3) {
 		if (IPA_CLIENT_IS_WLAN0_INSTANCE(ipa_wdi_ctx_list[hdl]->inst_id)) {
 			ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_PROD);
 			ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_CONS);
@@ -1184,7 +1184,7 @@
 		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
 	}
 
-	if (ipa_wdi_ctx_list[hdl]->wdi_version == IPA_WDI_3) {
+	if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_3) {
 		if (ipa3_disable_wdi3_pipes(
 			ipa_ep_idx_tx, ipa_ep_idx_rx, ipa_ep_idx_tx1)) {
 			IPA_WDI_ERR("fail to disable wdi pipes\n");
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 2019767..24f1923 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -12036,7 +12036,7 @@
 
 	switch (in->smmu_client) {
 	case IPA_SMMU_WLAN_CLIENT:
-		if (ipa_get_wdi_version() == IPA_WDI_3 ||
+		if (ipa_get_wdi_version() >= IPA_WDI_3 ||
 			IPA_WDI2_OVER_GSI())
 			is_smmu_enable =
 				!(ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP] ||
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
index 52b96d5..1762de6 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
@@ -740,14 +740,14 @@
 
 	if (IPA_CLIENT_IS_CONS(client)) {
 		start = IPA_WDI_TX_RING_RES;
-		if (ipa_get_wdi_version() == IPA_WDI_3)
+		if (ipa_get_wdi_version() >= IPA_WDI_3)
 			end = IPA_WDI_TX_DB_RES;
 		else
 			end = IPA_WDI_CE_DB_RES;
 	} else {
 		start = IPA_WDI_RX_RING_RES;
 		if (ipa3_ctx->ipa_wdi2 ||
-			(ipa_get_wdi_version() == IPA_WDI_3))
+			(ipa_get_wdi_version() >= IPA_WDI_3))
 			end = IPA_WDI_RX_COMP_RING_WP_RES;
 		else
 			end = IPA_WDI_RX_RING_RP_RES;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c
index e97a7b4..89ade11 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c
@@ -13,6 +13,7 @@
 #define IPA_WLAN_AGGR_BYTE_LIMIT 2 /*2 Kbytes Agger hard byte limit*/
 
 #define IPA_WDI3_GSI_EVT_RING_INT_MODT 32
+#define IPA_WDI3_MAX_VALUE_OF_BANK_ID 63
 
 static void ipa3_wdi3_gsi_evt_ring_err_cb(struct gsi_evt_err_notify *notify)
 {
@@ -80,9 +81,20 @@
 		IPAERR("invalid input\n");
 		return -EINVAL;
 	}
-	/* setup event ring */
 	memset(&gsi_evt_ring_props, 0, sizeof(gsi_evt_ring_props));
-	gsi_evt_ring_props.intf = GSI_EVT_CHTYPE_WDI3_EV;
+	memset(&gsi_channel_props, 0, sizeof(gsi_channel_props));
+
+	if(ipa_get_wdi_version() == IPA_WDI_3_V2) {
+		gsi_channel_props.prot = GSI_CHAN_PROT_WDI3_V2;
+		gsi_evt_ring_props.intf = GSI_EVT_CHTYPE_WDI3_V2_EV;
+	}
+	else {
+		gsi_channel_props.prot = GSI_CHAN_PROT_WDI3;
+		gsi_evt_ring_props.intf = GSI_EVT_CHTYPE_WDI3_EV;
+	}
+
+	/* setup event ring */
+
 	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_9) {
 		gsi_evt_ring_props.intr = GSI_INTR_MSI;
 		/* 32 (for Tx) and 8 (for Rx) */
@@ -166,8 +178,6 @@
 		gsi_evt_ring_props.ring_base_addr;
 
 	/* setup channel ring */
-	memset(&gsi_channel_props, 0, sizeof(gsi_channel_props));
-	gsi_channel_props.prot = GSI_CHAN_PROT_WDI3;
 	if ((dir == IPA_WDI3_TX_DIR) || (dir == IPA_WDI3_TX1_DIR) ||
 		(dir == IPA_WDI3_TX2_DIR))
 		gsi_channel_props.dir = GSI_CHAN_DIR_FROM_GSI;
@@ -185,13 +195,19 @@
 
 	gsi_channel_props.db_in_bytes = 0;
 	gsi_channel_props.evt_ring_hdl = ep->gsi_evt_ring_hdl;
+
 	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_9) {
 		/* 32 (for Tx) and 64 (for Rx) */
 		if ((dir == IPA_WDI3_TX_DIR) || (dir == IPA_WDI3_TX1_DIR) ||
 			(dir == IPA_WDI3_TX2_DIR))
 			gsi_channel_props.re_size = GSI_CHAN_RE_SIZE_32B;
-		else
-			gsi_channel_props.re_size = GSI_CHAN_RE_SIZE_64B;
+		else {
+			if (gsi_channel_props.prot == GSI_CHAN_PROT_WDI3_V2)
+				gsi_channel_props.re_size = GSI_CHAN_RE_SIZE_32B;
+			else 
+				gsi_channel_props.re_size = GSI_CHAN_RE_SIZE_64B;
+		}
+
 	} else
 		gsi_channel_props.re_size = GSI_CHAN_RE_SIZE_16B;
 
@@ -519,6 +535,48 @@
 			(1 << 8));
 	}
 
+	if(ipa_get_wdi_version() == IPA_WDI_3_V2) {
+
+		ch_scratch.wdi3_v2.wifi_rp_address_high =
+			ch_scratch.wdi3.wifi_rp_address_high;
+
+		ch_scratch.wdi3_v2.wifi_rp_address_low =
+			ch_scratch.wdi3.wifi_rp_address_low;
+
+		ch_scratch.wdi3_v2.update_rp_moderation_threshold =
+			ch_scratch.wdi3.update_rp_moderation_threshold;
+
+
+		if ( dir == IPA_WDI3_RX_DIR) {
+
+			ch_scratch.wdi3_v2.rx_pkt_offset = ch_scratch.wdi3.rx_pkt_offset;
+			ch_scratch.wdi3_v2.endp_metadata_reg_offset =
+						ch_scratch.wdi3.endp_metadata_reg_offset;
+		} else {
+
+
+				if(is_smmu_enabled) {
+					if(info_smmu->rx_bank_id > IPA_WDI3_MAX_VALUE_OF_BANK_ID) {
+						IPAERR("Incorrect bank id value %d Exceeding the 6bit range\n", info_smmu->rx_bank_id);
+						goto fail_write_scratch;
+					}
+					ch_scratch.wdi3_v2.bank_id = info_smmu->rx_bank_id;
+				}
+				else {
+					if(info->rx_bank_id > IPA_WDI3_MAX_VALUE_OF_BANK_ID) {
+						IPAERR("Incorrect bank id value %d Exceeding the 6bit range\n", info->rx_bank_id);
+						goto fail_write_scratch;
+					}
+
+					ch_scratch.wdi3_v2.bank_id = info->rx_bank_id;
+				}
+		}
+
+		ch_scratch.wdi3_v2.qmap_id = 0;
+		ch_scratch.wdi3_v2.reserved1 = 0;
+		ch_scratch.wdi3_v2.reserved2 = 0;
+	}
+
 	result = gsi_write_channel_scratch(ep->gsi_chan_hdl, ch_scratch);
 	if (result != GSI_STATUS_SUCCESS) {
 		IPAERR("failed to write evt ring scratch\n");
@@ -557,7 +615,7 @@
 	u8 rx_dir, tx_dir;
 
 	/* wdi3 only support over gsi */
-	if (ipa_get_wdi_version() != IPA_WDI_3) {
+	if (ipa_get_wdi_version() < IPA_WDI_3) {
 		IPAERR("wdi3 over uc offload not supported");
 		WARN_ON(1);
 		return -EFAULT;
@@ -870,12 +928,12 @@
 	int ipa_ep_idx_tx1)
 {
 	struct ipa3_ep_context *ep_tx, *ep_rx, *ep_tx1;
-	int result = 0;
 	enum ipa_client_type rx_client;
 	enum ipa_client_type tx_client;
+	int result = 0;
 
 	/* wdi3 only support over gsi */
-	if (ipa_get_wdi_version() != IPA_WDI_3) {
+	if (ipa_get_wdi_version() < IPA_WDI_3) {
 		IPAERR("wdi3 over uc offload not supported");
 		WARN_ON(1);
 		return -EFAULT;
@@ -988,7 +1046,7 @@
 	u32 holb_max_cnt = ipa3_ctx->uc_ctx.holb_monitor.max_cnt_wlan;
 
 	/* wdi3 only support over gsi */
-	if (ipa_get_wdi_version() != IPA_WDI_3) {
+	if (ipa_get_wdi_version() < IPA_WDI_3) {
 		IPAERR("wdi3 over uc offload not supported");
 		WARN_ON(1);
 		return -EFAULT;
@@ -1133,7 +1191,7 @@
 	struct ipahal_ep_cfg_ctrl_scnd ep_ctrl_scnd = { 0 };
 
 	/* wdi3 only support over gsi */
-	if (ipa_get_wdi_version() != IPA_WDI_3) {
+	if (ipa_get_wdi_version() < IPA_WDI_3) {
 		IPAERR("wdi3 over uc offload not supported");
 		WARN_ON(1);
 		return -EFAULT;