summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSkylar Chang <chiaweic@codeaurora.org>2017-02-10 11:40:30 -0800
committerSkylar Chang <chiaweic@codeaurora.org>2017-02-10 11:40:30 -0800
commit038d0bef5f2b9b2ac5daa716131b1b8b928cc541 (patch)
tree53cadba2d836342ea1cdc76d7bf9fdebb1bb9303 /drivers
parent2aa89ab3ff59a788321bc6af782d639cfc8dab1f (diff)
msm: ipa3: fix race condition in SSR
On pipe setup, enable data path should happen for after all pipe resources are allocated. This change prevents a race condition where the pipe is enabled before RX buffers are submitted to IPA. Then, when buffers are submitted to IPA there is a race between submitting the buffers and getting RX packets. CRs-Fixed: 1096357 Change-Id: Ic32924b6893bb8c7813b1b8e68e03b5e09560b69 Acked-by: Ady Abraham <adya@qti.qualcomm.com> Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_client.c30
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_dp.c16
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h1
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_utils.c11
4 files changed, 33 insertions, 25 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
index 00bfbf84c75a..e3dfe8927682 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -46,6 +46,20 @@ int ipa3_enable_data_path(u32 clnt_hdl)
int res = 0;
struct ipahal_reg_endp_init_rsrc_grp rsrc_grp;
+ /* Assign the resource group for pipe */
+ memset(&rsrc_grp, 0, sizeof(rsrc_grp));
+ rsrc_grp.rsrc_grp = ipa_get_ep_group(ep->client);
+ if (rsrc_grp.rsrc_grp == -1) {
+ IPAERR("invalid group for client %d\n", ep->client);
+ WARN_ON(1);
+ return -EFAULT;
+ }
+
+ IPADBG("Setting group %d for pipe %d\n",
+ rsrc_grp.rsrc_grp, clnt_hdl);
+ ipahal_write_reg_n_fields(IPA_ENDP_INIT_RSRC_GRP_n, clnt_hdl,
+ &rsrc_grp);
+
IPADBG("Enabling data path\n");
if (IPA_CLIENT_IS_CONS(ep->client)) {
memset(&holb_cfg, 0 , sizeof(holb_cfg));
@@ -64,20 +78,6 @@ int ipa3_enable_data_path(u32 clnt_hdl)
res = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl);
}
- /* Assign the resource group for pipe */
- memset(&rsrc_grp, 0, sizeof(rsrc_grp));
- rsrc_grp.rsrc_grp = ipa_get_ep_group(ep->client);
- if (rsrc_grp.rsrc_grp == -1) {
- IPAERR("invalid group for client %d\n", ep->client);
- WARN_ON(1);
- return -EFAULT;
- }
-
- IPADBG("Setting group %d for pipe %d\n",
- rsrc_grp.rsrc_grp, clnt_hdl);
- ipahal_write_reg_n_fields(IPA_ENDP_INIT_RSRC_GRP_n, clnt_hdl,
- &rsrc_grp);
-
return res;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index be2946c873b3..c2c017ac172c 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1360,13 +1360,6 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
}
}
- result = ipa3_enable_data_path(ipa_ep_idx);
- if (result) {
- IPAERR("enable data path failed res=%d clnt=%d.\n", result,
- ipa_ep_idx);
- goto fail_gen2;
- }
-
if (!ep->skip_ep_cfg) {
if (ipa3_cfg_ep(ipa_ep_idx, &sys_in->ipa_ep_cfg)) {
IPAERR("fail to configure EP.\n");
@@ -1498,6 +1491,13 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
ipa3_install_dflt_flt_rules(ipa_ep_idx);
}
+ result = ipa3_enable_data_path(ipa_ep_idx);
+ if (result) {
+ IPAERR("enable data path failed res=%d ep=%d.\n", result,
+ ipa_ep_idx);
+ goto fail_gen2;
+ }
+
if (!ep->keep_ipa_awake)
IPA_ACTIVE_CLIENTS_DEC_EP(sys_in->client);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 7feb1c1ce178..ec26eea1e033 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -42,6 +42,7 @@
#define IPA_COOKIE 0x57831603
#define MTU_BYTE 1500
+#define IPA_EP_NOT_ALLOCATED (-1)
#define IPA3_MAX_NUM_PIPES 31
#define IPA_SYS_DESC_FIFO_SZ 0x800
#define IPA_SYS_TX_DATA_DESC_FIFO_SZ 0x1000
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 3b909acdd823..944c40eb03d8 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -95,7 +95,8 @@
#define QMB_MASTER_SELECT_PCIE (1)
#define IPA_CLIENT_NOT_USED \
- {-1, -1, false, IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR}
+ {IPA_EP_NOT_ALLOCATED, IPA_EP_NOT_ALLOCATED, false, \
+ IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR}
/* Resource Group index*/
#define IPA_GROUP_UL (0)
@@ -919,12 +920,18 @@ u8 ipa3_get_hw_type_index(void)
*/
int ipa3_get_ep_mapping(enum ipa_client_type client)
{
+ int ipa_ep_idx;
+
if (client >= IPA_CLIENT_MAX || client < 0) {
IPAERR("Bad client number! client =%d\n", client);
return -EINVAL;
}
- return ipa3_ep_mapping[ipa3_get_hw_type_index()][client].pipe_num;
+ ipa_ep_idx = ipa3_ep_mapping[ipa3_get_hw_type_index()][client].pipe_num;
+ if (ipa_ep_idx < 0 || ipa_ep_idx >= IPA3_MAX_NUM_PIPES)
+ return IPA_EP_NOT_ALLOCATED;
+
+ return ipa_ep_idx;
}
/**