Merge "msm: ipa3: Add resource index for second pine instance."
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 389fc10..a8ed84a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -307,19 +307,30 @@
 	NUM_SMEM_SUBSYSTEMS,
 };
 
-#define IPA_WDI_RX_RING_RES			0
-#define IPA_WDI_RX_RING_RP_RES		1
-#define IPA_WDI_RX_COMP_RING_RES	2
-#define IPA_WDI_RX_COMP_RING_WP_RES	3
-#define IPA_WDI_TX_RING_RES			4
-#define IPA_WDI_CE_RING_RES			5
-#define IPA_WDI_CE_DB_RES			6
-#define IPA_WDI_TX_DB_RES			7
-#define IPA_WDI_TX1_RING_RES		8
-#define IPA_WDI_CE1_RING_RES		9
-#define IPA_WDI_CE1_DB_RES			10
-#define IPA_WDI_TX1_DB_RES			11
-#define IPA_WDI_MAX_RES				12
+#define IPA_WDI_RX_RING_RES            0
+#define IPA_WDI_RX_RING_RP_RES         1
+#define IPA_WDI_RX_COMP_RING_RES       2
+#define IPA_WDI_RX_COMP_RING_WP_RES    3
+#define IPA_WDI_RX2_RING_RES           4
+#define IPA_WDI_RX2_RING_RP_RES        5
+#define IPA_WDI_RX2_COMP_RING_RES      6
+#define IPA_WDI_RX2_COMP_RING_WP_RES   7
+#define IPA_WDI_TX_RING_RES            8
+#define IPA_WDI_CE_RING_RES            9
+#define IPA_WDI_CE_DB_RES              10
+#define IPA_WDI_TX_DB_RES              11
+#define IPA_WDI_TX1_RING_RES           12
+#define IPA_WDI_CE1_RING_RES           13
+#define IPA_WDI_CE1_DB_RES             14
+#define IPA_WDI_TX1_DB_RES             15
+#define IPA_WDI_TX2_RING_RES           16
+#define IPA_WDI_CE2_RING_RES           17
+#define IPA_WDI_CE2_DB_RES             18
+#define IPA_WDI_TX2_DB_RES             19
+#define IPA_WDI_MAX_RES                20
+
+#define IPA_WDI3_TX2_DIR 4
+#define IPA_WDI3_RX2_DIR 5
 
 /* use QMAP header reserved bit to identify tethered traffic */
 #define IPA_QMAP_TETH_BIT (1 << 30)
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 583e751..52b96d5 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
@@ -940,9 +940,15 @@
 				IPA_WDI_TX1_RING_RES;
 		end = (dir == IPA_WDI3_TX_DIR) ?
 				IPA_WDI_TX_DB_RES : IPA_WDI_TX1_DB_RES;
-	} else {
+	} else if (dir == IPA_WDI3_TX2_DIR) {
+		start = IPA_WDI_TX2_RING_RES;
+		end = IPA_WDI_TX2_DB_RES;
+	} else if (dir == IPA_WDI3_RX_DIR) {
 		start = IPA_WDI_RX_RING_RES;
-		end = IPA_WDI_RX_COMP_RING_WP_RES;
+                end = IPA_WDI_RX_COMP_RING_WP_RES;
+	} else {
+		 start = IPA_WDI_RX2_RING_RES;
+                end = IPA_WDI_RX2_COMP_RING_WP_RES;
 	}
 
 	for (i = start; i <= end; i++) {
@@ -1000,9 +1006,14 @@
 		case IPA_WDI_TX_DB_RES:
 		case IPA_WDI_CE1_DB_RES:
 		case IPA_WDI_TX1_DB_RES:
+		case IPA_WDI_RX2_RING_RP_RES:
+		case IPA_WDI_RX2_COMP_RING_WP_RES:
+		case IPA_WDI_CE2_DB_RES:
+		case IPA_WDI_TX2_DB_RES:
 
 			if (ipa_create_ap_smmu_mapping_pa(pa, len,
-				(res_idx == IPA_WDI_CE_DB_RES) ? true : false,
+				((res_idx == IPA_WDI_CE_DB_RES) ||
+				(res_idx == IPA_WDI_CE2_DB_RES)) ? true : false,
 						iova)) {
 				IPAERR("Fail to create mapping res %d\n",
 						res_idx);
@@ -1016,6 +1027,11 @@
 		case IPA_WDI_CE_RING_RES:
 		case IPA_WDI_TX1_RING_RES:
 		case IPA_WDI_CE1_RING_RES:
+		case IPA_WDI_RX2_RING_RES:
+		case IPA_WDI_RX2_COMP_RING_RES:
+		case IPA_WDI_TX2_RING_RES:
+		case IPA_WDI_CE2_RING_RES:
+
 			if (ipa_create_ap_smmu_mapping_sgt(sgt, iova)) {
 				IPAERR("Fail to create mapping res %d\n",
 						res_idx);
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 d636d3e..e97a7b4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c
@@ -86,14 +86,16 @@
 	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) */
-		if ((dir == IPA_WDI3_TX_DIR) || (dir == IPA_WDI3_TX1_DIR))
+		if ((dir == IPA_WDI3_TX_DIR) || (dir == IPA_WDI3_TX1_DIR) ||
+			(dir == IPA_WDI3_TX2_DIR))
 			gsi_evt_ring_props.re_size = GSI_EVT_RING_RE_SIZE_32B;
 		else
 			gsi_evt_ring_props.re_size = GSI_EVT_RING_RE_SIZE_8B;
 	} else {
 		gsi_evt_ring_props.intr = GSI_INTR_IRQ;
 		/* 16 (for Tx) and 8 (for Rx) */
-		if ((dir == IPA_WDI3_TX_DIR) || (dir == IPA_WDI3_TX1_DIR))
+		if ((dir == IPA_WDI3_TX_DIR) || (dir == IPA_WDI3_TX1_DIR) ||
+			(dir == IPA_WDI3_TX2_DIR))
 			gsi_evt_ring_props.re_size = GSI_EVT_RING_RE_SIZE_16B;
 		else
 			gsi_evt_ring_props.re_size = GSI_EVT_RING_RE_SIZE_8B;
@@ -114,7 +116,16 @@
 				IPAERR("failed to get smmu mapping\n");
 				return -EFAULT;
 			}
-		} else {
+		} else if (dir == IPA_WDI3_TX2_DIR) {
+                        if (ipa_create_gsi_smmu_mapping(
+                                IPA_WDI_CE2_RING_RES,
+                                true, info->event_ring_base_pa,
+                                &info_smmu->event_ring_base, len,
+                                false, &va)) {
+                                IPAERR("failed to get smmu mapping\n");
+                                return -EFAULT;
+                        }
+                } else if (dir == IPA_WDI3_RX_DIR) {
 			if (ipa_create_gsi_smmu_mapping(
 				IPA_WDI_RX_COMP_RING_RES, true,
 				info->event_ring_base_pa,
@@ -123,7 +134,16 @@
 				IPAERR("failed to get smmu mapping\n");
 				return -EFAULT;
 			}
-		}
+		} else {
+			if (ipa_create_gsi_smmu_mapping(
+                                IPA_WDI_RX2_COMP_RING_RES, true,
+                                info->event_ring_base_pa,
+                                &info_smmu->event_ring_base, len,
+                                false, &va)) {
+                                IPAERR("failed to get smmu mapping\n");
+                                return -EFAULT;
+                        }
+                }
 		gsi_evt_ring_props.ring_len = len;
 		gsi_evt_ring_props.ring_base_addr = (u64)va;
 	}
@@ -148,7 +168,8 @@
 	/* 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))
+	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;
 	else
 		gsi_channel_props.dir = GSI_CHAN_DIR_TO_GSI;
@@ -166,7 +187,8 @@
 	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))
+		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;
@@ -199,7 +221,17 @@
 				result = -EFAULT;
 				goto fail_get_gsi_ep_info;
 			}
-		} else {
+		} else if (dir == IPA_WDI3_TX2_DIR) {
+                        if (ipa_create_gsi_smmu_mapping(
+                                IPA_WDI_TX2_RING_RES,
+                                true, info->transfer_ring_base_pa,
+                                &info_smmu->transfer_ring_base, len,
+                                false, &va)) {
+                                IPAERR("failed to get smmu mapping\n");
+                                result = -EFAULT;
+                                goto fail_get_gsi_ep_info;
+                        }
+                } else if (dir == IPA_WDI3_RX_DIR) {
 			if (ipa_create_gsi_smmu_mapping(
 				IPA_WDI_RX_RING_RES, true,
 				info->transfer_ring_base_pa,
@@ -209,6 +241,16 @@
 				result = -EFAULT;
 				goto fail_get_gsi_ep_info;
 			}
+		} else {
+			if (ipa_create_gsi_smmu_mapping(
+                                IPA_WDI_RX2_RING_RES, true,
+                                info->transfer_ring_base_pa,
+                                &info_smmu->transfer_ring_base, len,
+                                false, &va)) {
+                                IPAERR("failed to get smmu mapping\n");
+                                result = -EFAULT;
+                                goto fail_get_gsi_ep_info;
+                        }
 		}
 		gsi_channel_props.ring_len = len;
 		gsi_channel_props.ring_base_addr = (u64)va;
@@ -269,7 +311,16 @@
 				result = -EFAULT;
 				goto fail_write_scratch;
 			}
-		} else {
+		} else if (dir == IPA_WDI3_TX2_DIR) {
+                        if (ipa_create_gsi_smmu_mapping(
+                                IPA_WDI_CE2_DB_RES,
+                                true, info_smmu->event_ring_doorbell_pa,
+                                NULL, 4, true, &va)) {
+                                IPAERR("failed to get smmu mapping\n");
+                                result = -EFAULT;
+                                goto fail_write_scratch;
+                        }
+                } else if (dir == IPA_WDI3_RX_DIR) {
 			if (ipa_create_gsi_smmu_mapping(
 				IPA_WDI_RX_COMP_RING_WP_RES,
 				true, info_smmu->event_ring_doorbell_pa,
@@ -278,6 +329,15 @@
 				result = -EFAULT;
 				goto fail_write_scratch;
 			}
+		} else {
+			if (ipa_create_gsi_smmu_mapping(
+                                IPA_WDI_RX2_COMP_RING_WP_RES,
+                                true, info_smmu->event_ring_doorbell_pa,
+                                NULL, 4, true, &va)) {
+                                IPAERR("failed to get smmu mapping\n");
+                                result = -EFAULT;
+                                goto fail_write_scratch;
+                        }
 		}
 		addr_low = (u32)va;
 		addr_high = (u32)((u64)va >> 32);
@@ -328,7 +388,7 @@
 	memset(&ch_scratch, 0, sizeof(ch_scratch));
 	ch_scratch.wdi3.update_rp_moderation_threshold =
 		UPDATE_RP_MODERATION_THRESHOLD;
-	if (dir == IPA_WDI3_RX_DIR) {
+	if ((dir == IPA_WDI3_RX_DIR) || (dir == IPA_WDI3_RX2_DIR)) {
 		if (!is_smmu_enabled)
 			ch_scratch.wdi3.rx_pkt_offset = info->pkt_offset;
 		else
@@ -380,7 +440,19 @@
 			ch_scratch.wdi3.wifi_rp_address_low = (u32)va;
 			ch_scratch.wdi3.wifi_rp_address_high =
 				(u32)((u64)va >> 32);
-		} else {
+		} else if (dir == IPA_WDI3_TX2_DIR) {
+                        if (ipa_create_gsi_smmu_mapping(
+                                IPA_WDI_TX2_DB_RES,
+                                true, info_smmu->transfer_ring_doorbell_pa,
+                                NULL, 4, true, &va)) {
+                                IPAERR("failed to get smmu mapping\n");
+                                result = -EFAULT;
+                                goto fail_write_scratch;
+                        }
+                        ch_scratch.wdi3.wifi_rp_address_low = (u32)va;
+                        ch_scratch.wdi3.wifi_rp_address_high =
+                                (u32)((u64)va >> 32);
+                } else if (dir == IPA_WDI3_RX_DIR){
 			if (ipa_create_gsi_smmu_mapping(IPA_WDI_RX_RING_RP_RES,
 				true, info_smmu->transfer_ring_doorbell_pa,
 				NULL, 4, true, &va)) {
@@ -391,6 +463,17 @@
 			ch_scratch.wdi3.wifi_rp_address_low = (u32)va;
 			ch_scratch.wdi3.wifi_rp_address_high =
 				(u32)((u64)va >> 32);
+		} else {
+			if (ipa_create_gsi_smmu_mapping(IPA_WDI_RX2_RING_RP_RES,
+                                true, info_smmu->transfer_ring_doorbell_pa,
+                                NULL, 4, true, &va)) {
+                                IPAERR("failed to get smmu mapping\n");
+                                result = -EFAULT;
+                                goto fail_write_scratch;
+                        }
+                        ch_scratch.wdi3.wifi_rp_address_low = (u32)va;
+                        ch_scratch.wdi3.wifi_rp_address_high =
+                                (u32)((u64)va >> 32);
 		}
 	}
 
@@ -471,6 +554,7 @@
 	u32 gsi_db_addr_low, gsi_db_addr_high;
 	void __iomem *db_addr;
 	u32 evt_ring_db_addr_low, evt_ring_db_addr_high, db_val = 0;
+	u8 rx_dir, tx_dir;
 
 	/* wdi3 only support over gsi */
 	if (ipa_get_wdi_version() != IPA_WDI_3) {
@@ -573,8 +657,11 @@
 	}
 
 	/* setup RX gsi channel */
+	rx_dir = (rx_client == IPA_CLIENT_WLAN2_PROD) ?
+			IPA_WDI3_RX_DIR : IPA_WDI3_RX2_DIR;
+
 	if (ipa3_setup_wdi3_gsi_channel(in->is_smmu_enabled,
-		&in->u_rx.rx, &in->u_rx.rx_smmu, IPA_WDI3_RX_DIR,
+		&in->u_rx.rx, &in->u_rx.rx_smmu, rx_dir,
 		ep_rx)) {
 		IPAERR("fail to setup wdi3 gsi rx channel\n");
 		result = -EFAULT;
@@ -624,8 +711,11 @@
 	}
 
 	/* setup TX gsi channel */
+	tx_dir = (tx_client == IPA_CLIENT_WLAN2_CONS) ?
+                        IPA_WDI3_TX_DIR : IPA_WDI3_TX2_DIR;
+
 	if (ipa3_setup_wdi3_gsi_channel(in->is_smmu_enabled,
-		&in->u_tx.tx, &in->u_tx.tx_smmu, IPA_WDI3_TX_DIR,
+		&in->u_tx.tx, &in->u_tx.tx_smmu, tx_dir,
 		ep_tx)) {
 		IPAERR("fail to setup wdi3 gsi tx channel\n");
 		result = -EFAULT;
@@ -781,6 +871,8 @@
 {
 	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;
 
 	/* wdi3 only support over gsi */
 	if (ipa_get_wdi_version() != IPA_WDI_3) {
@@ -802,7 +894,8 @@
 
 	ep_tx = &ipa3_ctx->ep[ipa_ep_idx_tx];
 	ep_rx = &ipa3_ctx->ep[ipa_ep_idx_rx];
-
+	rx_client = ipa3_get_client_mapping(ipa_ep_idx_rx);
+	tx_client = ipa3_get_client_mapping(ipa_ep_idx_tx);
 	IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx));
 	/* tear down tx1 pipe */
 	if (ipa_ep_idx_tx1 >= 0) {
@@ -844,7 +937,10 @@
 		IPAERR("failed to release gsi channel: %d\n", result);
 		goto exit;
 	}
-	ipa3_release_wdi3_gsi_smmu_mappings(IPA_WDI3_TX_DIR);
+	if (tx_client == IPA_CLIENT_WLAN2_CONS)
+		ipa3_release_wdi3_gsi_smmu_mappings(IPA_WDI3_TX_DIR);
+	else
+		ipa3_release_wdi3_gsi_smmu_mappings(IPA_WDI3_TX2_DIR);
 
 	memset(ep_tx, 0, sizeof(struct ipa3_ep_context));
 	IPADBG("tx client (ep: %d) disconnected\n", ipa_ep_idx_tx);
@@ -865,7 +961,10 @@
 		IPAERR("failed to release gsi channel: %d\n", result);
 		goto exit;
 	}
-	ipa3_release_wdi3_gsi_smmu_mappings(IPA_WDI3_RX_DIR);
+	if (rx_client == IPA_CLIENT_WLAN2_PROD)
+		ipa3_release_wdi3_gsi_smmu_mappings(IPA_WDI3_RX_DIR);
+	else
+		ipa3_release_wdi3_gsi_smmu_mappings(IPA_WDI3_RX2_DIR);
 
 	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5)
 		ipa3_uc_debug_stats_dealloc(IPA_HW_PROTOCOL_WDI3);