diff options
author | Skylar Chang <chiaweic@codeaurora.org> | 2017-02-10 11:40:30 -0800 |
---|---|---|
committer | Skylar Chang <chiaweic@codeaurora.org> | 2017-02-10 11:40:30 -0800 |
commit | 038d0bef5f2b9b2ac5daa716131b1b8b928cc541 (patch) | |
tree | 53cadba2d836342ea1cdc76d7bf9fdebb1bb9303 /drivers | |
parent | 2aa89ab3ff59a788321bc6af782d639cfc8dab1f (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.c | 30 | ||||
-rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 16 | ||||
-rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 1 | ||||
-rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 11 |
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; } /** |