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>
This commit is contained in:
parent
2aa89ab3ff
commit
038d0bef5f
4 changed files with 33 additions and 25 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue