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);