Merge 9899d28499 on remote branch

Change-Id: Ibb39146ab2bc330fcfb6ae4625e865339ef2e7dd
This commit is contained in:
Linux Build Service Account 2020-10-22 10:01:25 -07:00
commit bbf898e76b
10 changed files with 172 additions and 92 deletions

View file

@ -659,13 +659,21 @@ static void ecm_ipa_packet_receive_notify
packet_len = skb->len;
ECM_IPA_DEBUG("packet RX, len=%d\n", skb->len);
if (unlikely(ecm_ipa_ctx == NULL)) {
ECM_IPA_DEBUG("Private context is NULL. Drop SKB.\n");
dev_kfree_skb_any(skb);
return;
}
if (unlikely(ecm_ipa_ctx->state != ECM_IPA_CONNECTED_AND_UP)) {
ECM_IPA_DEBUG("Missing pipe connected and/or iface up\n");
dev_kfree_skb_any(skb);
return;
}
if (unlikely(evt != IPA_RECEIVE)) {
ECM_IPA_ERROR("A none IPA_RECEIVE event in ecm_ipa_receive\n");
dev_kfree_skb_any(skb);
return;
}

View file

@ -467,6 +467,10 @@ static int ipa_uc_offload_conn_pipes_internal(struct ipa_uc_offload_conn_in_para
return -EPERM;
}
/*Store the connection info, required during disconnect pipe */
memcpy(&offload_ctx->conn, &inp->u.ntn,
sizeof(struct ipa_ntn_conn_in_params));
switch (offload_ctx->proto) {
case IPA_UC_NTN:
ret = ipa_uc_ntn_conn_pipes(&inp->u.ntn, &outp->u.ntn,

View file

@ -1135,6 +1135,12 @@ static void rndis_ipa_packet_receive_notify(
("packet Rx, len=%d\n",
skb->len);
if (unlikely(rndis_ipa_ctx == NULL)) {
RNDIS_IPA_DEBUG("Private context is NULL. Drop SKB.\n");
dev_kfree_skb_any(skb);
return;
}
if (unlikely(rndis_ipa_ctx->rx_dump_enable))
rndis_ipa_dump_skb(skb);
@ -1142,11 +1148,15 @@ static void rndis_ipa_packet_receive_notify(
RNDIS_IPA_DEBUG("use connect()/up() before receive()\n");
RNDIS_IPA_DEBUG("packet dropped (length=%d)\n",
skb->len);
rndis_ipa_ctx->rx_dropped++;
dev_kfree_skb_any(skb);
return;
}
if (evt != IPA_RECEIVE) {
RNDIS_IPA_ERROR_RL("a none IPA_RECEIVE event in driver RX\n");
rndis_ipa_ctx->rx_dropped++;
dev_kfree_skb_any(skb);
return;
}

View file

@ -384,6 +384,8 @@ int ipa_smmu_store_sgt(struct sg_table **out_ch_ptr,
struct sg_table *in_sgt_ptr)
{
unsigned int nents;
int i;
struct scatterlist *in_sg, *out_sg;
if (in_sgt_ptr != NULL) {
*out_ch_ptr = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
@ -401,8 +403,12 @@ int ipa_smmu_store_sgt(struct sg_table **out_ch_ptr,
return -ENOMEM;
}
memcpy((*out_ch_ptr)->sgl, in_sgt_ptr->sgl,
nents*sizeof((*out_ch_ptr)->sgl));
out_sg = (*out_ch_ptr)->sgl;
for_each_sg(in_sgt_ptr->sgl, in_sg, in_sgt_ptr->nents, i) {
memcpy(out_sg, in_sg, sizeof(struct scatterlist));
out_sg++;
}
(*out_ch_ptr)->nents = nents;
(*out_ch_ptr)->orig_nents = in_sgt_ptr->orig_nents;
}

View file

@ -420,14 +420,33 @@ int ipa3_smmu_map_peer_buff(u64 iova, u32 size, bool map, struct sg_table *sgt,
}
}
} else {
res = iommu_unmap(smmu_domain,
rounddown(iova, PAGE_SIZE),
roundup(size + iova - rounddown(iova, PAGE_SIZE),
PAGE_SIZE));
if (res != roundup(size + iova - rounddown(iova, PAGE_SIZE),
PAGE_SIZE)) {
IPAERR("Fail to unmap 0x%llx\n", iova);
return -EINVAL;
if (sgt != NULL) {
va = rounddown(iova, PAGE_SIZE);
len = 0;
for_each_sg(sgt->sgl, sg, sgt->nents, i) {
len = PAGE_ALIGN(sg->offset + sg->length);
res = iommu_unmap(smmu_domain, va,
roundup(len, PAGE_SIZE));
if (res !=
roundup(len, PAGE_SIZE)) {
IPAERR("Fail to unmap iova=%llx\n",
iova);
return -EINVAL;
}
va += len;
count++;
}
} else {
res = iommu_unmap(smmu_domain,
rounddown(iova, PAGE_SIZE),
roundup(size + iova -
rounddown(iova, PAGE_SIZE),
PAGE_SIZE));
if (res != roundup(size + iova -
rounddown(iova, PAGE_SIZE), PAGE_SIZE)) {
IPAERR("Fail to unmap 0x%llx\n", iova);
return -EINVAL;
}
}
}
IPADBG("Peer buff %s 0x%llx\n", map ? "map" : "unmap", iova);
@ -1523,6 +1542,12 @@ int ipa3_release_gsi_channel(u32 clnt_hdl)
if (!ep->keep_ipa_awake)
IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl));
/* Set the disconnect in progress flag to avoid calling cb.*/
spin_lock(&ipa3_ctx->disconnect_lock);
atomic_set(&ep->disconnect_in_progress, 1);
spin_unlock(&ipa3_ctx->disconnect_lock);
gsi_res = gsi_dealloc_channel(ep->gsi_chan_hdl);
if (gsi_res != GSI_STATUS_SUCCESS) {
IPAERR("Error deallocating channel: %d\n", gsi_res);
@ -1541,7 +1566,9 @@ int ipa3_release_gsi_channel(u32 clnt_hdl)
if (!ep->keep_ipa_awake)
IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl));
spin_lock(&ipa3_ctx->disconnect_lock);
memset(&ipa3_ctx->ep[clnt_hdl], 0, sizeof(struct ipa3_ep_context));
spin_unlock(&ipa3_ctx->disconnect_lock);
IPADBG("exit\n");
return 0;

View file

@ -1202,7 +1202,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
if (ipa3_assign_policy(sys_in, ep->sys)) {
IPAERR("failed to sys ctx for client %d\n", sys_in->client);
result = -ENOMEM;
goto fail_gen2;
goto fail_napi;
}
ep->valid = 1;
@ -1219,17 +1219,17 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
ep->sys->status_stat =
kzalloc(sizeof(struct ipa3_status_stats), GFP_KERNEL);
if (!ep->sys->status_stat)
goto fail_gen2;
goto fail_napi;
}
if (!ep->skip_ep_cfg) {
if (ipa3_cfg_ep(ipa_ep_idx, &sys_in->ipa_ep_cfg)) {
IPAERR("fail to configure EP.\n");
goto fail_gen2;
goto fail_napi;
}
if (ipa3_cfg_ep_status(ipa_ep_idx, &ep->status)) {
IPAERR("fail to configure status of EP.\n");
goto fail_gen2;
goto fail_napi;
}
IPADBG("ep %d configuration successful\n", ipa_ep_idx);
} else {
@ -1239,7 +1239,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
result = ipa_gsi_setup_channel(sys_in, ep);
if (result) {
IPAERR("Failed to setup GSI channel\n");
goto fail_gen2;
goto fail_napi;
}
*clnt_hdl = ipa_ep_idx;
@ -1250,7 +1250,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
IPAERR("failed to alloc repl for client %d\n",
sys_in->client);
result = -ENOMEM;
goto fail_gen2;
goto fail_napi;
}
atomic_set(&ep->sys->repl->pending, 0);
ep->sys->repl->capacity = ep->sys->rx_pool_sz + 1;
@ -1275,7 +1275,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
IPAERR("failed to alloc repl for client %d\n",
sys_in->client);
result = -ENOMEM;
goto fail_gen2;
goto fail_napi;
}
atomic_set(&ep->sys->page_recycle_repl->pending, 0);
ep->sys->page_recycle_repl->capacity =
@ -1380,6 +1380,11 @@ fail_page_recycle_repl:
ep->sys->page_recycle_repl->capacity = 0;
kfree(ep->sys->page_recycle_repl);
}
fail_napi:
/* Delete NAPI TX object. */
if (ipa3_ctx->tx_napi_enable &&
(IPA_CLIENT_IS_PROD(sys_in->client)))
netif_napi_del(&ep->sys->napi_tx);
fail_gen2:
ipa_pm_deregister(ep->sys->pm_hdl);
fail_pm:
@ -3402,14 +3407,18 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
unsigned int src_pipe;
u32 metadata;
u8 ucp;
void (*client_notify)(void *client_priv, enum ipa_dp_evt_type evt,
unsigned long data);
void *client_priv;
ipahal_pkt_status_parse_thin(rx_skb->data, &status);
src_pipe = status.endp_src_idx;
metadata = status.metadata;
ucp = status.ucp;
ep = &ipa3_ctx->ep[src_pipe];
if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes)) {
IPAERR_RL("drop pipe=%d\n", src_pipe);
if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes) ||
unlikely(atomic_read(&ep->disconnect_in_progress))) {
IPAERR("drop pipe=%d\n", src_pipe);
dev_kfree_skb_any(rx_skb);
return;
}
@ -3431,12 +3440,19 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
metadata, *(u32 *)rx_skb->cb);
IPADBG_LOW("ucp: %d\n", *(u8 *)(rx_skb->cb + 4));
spin_lock(&ipa3_ctx->disconnect_lock);
if (likely((!atomic_read(&ep->disconnect_in_progress)) &&
ep->valid && ep->client_notify))
ep->client_notify(ep->priv, IPA_RECEIVE,
ep->valid && ep->client_notify)) {
client_notify = ep->client_notify;
client_priv = ep->priv;
spin_unlock(&ipa3_ctx->disconnect_lock);
client_notify(client_priv, IPA_RECEIVE,
(unsigned long)(rx_skb));
else
} else {
spin_unlock(&ipa3_ctx->disconnect_lock);
dev_kfree_skb_any(rx_skb);
}
}
static void ipa3_recycle_rx_wrapper(struct ipa3_rx_pkt_wrapper *rx_pkt)

View file

@ -259,7 +259,7 @@ static int ipa3_uc_send_ntn_setup_pipe_cmd(
}
static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params,
bool map)
bool map, bool map_unmap_once)
{
struct iommu_domain *smmu_domain;
int result;
@ -275,14 +275,16 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params,
return -EINVAL;
}
result = ipa3_smmu_map_peer_reg(rounddown(params->ntn_reg_base_ptr_pa,
PAGE_SIZE), map, IPA_SMMU_CB_UC);
if (result) {
IPAERR("failed to %s uC regs %d\n",
map ? "map" : "unmap", result);
goto fail;
if (map_unmap_once) {
result = ipa3_smmu_map_peer_reg(rounddown(
params->ntn_reg_base_ptr_pa, PAGE_SIZE),
map, IPA_SMMU_CB_UC);
if (result) {
IPAERR("failed to %s uC regs %d\n",
map ? "map" : "unmap", result);
goto fail;
}
}
if (params->smmu_enabled) {
IPADBG("smmu is enabled on EMAC\n");
result = ipa3_smmu_map_peer_buff((u64)params->ring_base_iova,
@ -345,14 +347,13 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params,
IPAERR("Fail to map 0x%llx\n", iova);
} else {
result = iommu_unmap(smmu_domain, iova_p, size_p);
if (result != params->data_buff_size)
if (result != size_p) {
IPAERR("Fail to unmap 0x%llx\n", iova);
}
if (result) {
if (params->smmu_enabled)
goto fail_map_data_buff_smmu_enabled;
else
goto fail_map_data_buff_smmu_disabled;
if (params->smmu_enabled)
goto fail_map_data_buff_smmu_enabled;
else
goto fail_map_data_buff_smmu_disabled;
}
}
}
return 0;
@ -392,6 +393,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in,
int ipa_ep_idx_ul;
int ipa_ep_idx_dl;
int result = 0;
bool unmapped = false;
if (in == NULL) {
IPAERR("invalid input\n");
@ -445,7 +447,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in,
goto fail;
}
result = ipa3_smmu_map_uc_ntn_pipes(&in->ul, true);
result = ipa3_smmu_map_uc_ntn_pipes(&in->ul, true, true);
if (result) {
IPAERR("failed to map SMMU for UL %d\n", result);
goto fail;
@ -484,7 +486,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in,
goto fail_disable_dp_ul;
}
result = ipa3_smmu_map_uc_ntn_pipes(&in->dl, true);
result = ipa3_smmu_map_uc_ntn_pipes(&in->dl, true, false);
if (result) {
IPAERR("failed to map SMMU for DL %d\n", result);
goto fail_disable_dp_ul;
@ -515,11 +517,12 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in,
fail_disable_dp_dl:
ipa3_disable_data_path(ipa_ep_idx_dl);
fail_smmu_unmap_dl:
ipa3_smmu_map_uc_ntn_pipes(&in->dl, false);
ipa3_smmu_map_uc_ntn_pipes(&in->dl, false, true);
unmapped = true;
fail_disable_dp_ul:
ipa3_disable_data_path(ipa_ep_idx_ul);
fail_smmu_unmap_ul:
ipa3_smmu_map_uc_ntn_pipes(&in->ul, false);
ipa3_smmu_map_uc_ntn_pipes(&in->ul, false, !unmapped);
fail:
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
return result;
@ -600,7 +603,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul,
}
/* unmap the DL pipe */
result = ipa3_smmu_map_uc_ntn_pipes(&params->dl, false);
result = ipa3_smmu_map_uc_ntn_pipes(&params->dl, false, false);
if (result) {
IPAERR("failed to unmap SMMU for DL %d\n", result);
goto fail;
@ -621,7 +624,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul,
}
/* unmap the UL pipe */
result = ipa3_smmu_map_uc_ntn_pipes(&params->ul, false);
result = ipa3_smmu_map_uc_ntn_pipes(&params->ul, false, true);
if (result) {
IPAERR("failed to unmap SMMU for UL %d\n", result);
goto fail;

View file

@ -2636,23 +2636,25 @@ int ipa3_suspend_gsi_wdi_pipe(u32 clnt_hdl)
}
if (ep->valid) {
IPADBG("suspended pipe %d\n", ipa_ep_idx);
source_pipe_bitmask = 1 <<
ipa3_get_ep_mapping(ep->client);
res = ipa3_enable_force_clear(clnt_hdl,
false, source_pipe_bitmask);
if (res) {
/*
* assuming here modem SSR, AP can remove
* the delay in this case
*/
IPAERR("failed to force clear %d\n", res);
IPAERR("remove delay from SCND reg\n");
ep_ctrl_scnd.endp_delay = false;
ipahal_write_reg_n_fields(
IPA_ENDP_INIT_CTRL_SCND_n, clnt_hdl,
&ep_ctrl_scnd);
} else {
disable_force_clear = true;
if (IPA_CLIENT_IS_PROD(ep->client)) {
source_pipe_bitmask = 1 <<
ipa3_get_ep_mapping(ep->client);
res = ipa3_enable_force_clear(clnt_hdl,
false, source_pipe_bitmask);
if (res) {
/*
* assuming here modem SSR, AP can remove
* the delay in this case
*/
IPAERR("failed to force clear %d\n", res);
IPAERR("remove delay from SCND reg\n");
ep_ctrl_scnd.endp_delay = false;
ipahal_write_reg_n_fields(
IPA_ENDP_INIT_CTRL_SCND_n, clnt_hdl,
&ep_ctrl_scnd);
} else {
disable_force_clear = true;
}
}
retry_gsi_stop:
res = ipa3_stop_gsi_channel(ipa_ep_idx);

View file

@ -962,23 +962,25 @@ int ipa3_disable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx)
* as IPA uC will fail to suspend the pipe otherwise.
*/
ep = &ipa3_ctx->ep[ipa_ep_idx_rx];
source_pipe_bitmask = 1 <<
if (IPA_CLIENT_IS_PROD(ep->client)) {
source_pipe_bitmask = 1 <<
ipa3_get_ep_mapping(ep->client);
result = ipa3_enable_force_clear(ipa_ep_idx_rx,
false, source_pipe_bitmask);
if (result) {
/*
* assuming here modem SSR, AP can remove
* the delay in this case
*/
IPAERR("failed to force clear %d\n", result);
IPAERR("remove delay from SCND reg\n");
ep_ctrl_scnd.endp_delay = false;
ipahal_write_reg_n_fields(
IPA_ENDP_INIT_CTRL_SCND_n, ipa_ep_idx_rx,
&ep_ctrl_scnd);
} else {
disable_force_clear = true;
result = ipa3_enable_force_clear(ipa_ep_idx_rx,
false, source_pipe_bitmask);
if (result) {
/*
* assuming here modem SSR, AP can remove
* the delay in this case
*/
IPAERR("failed to force clear %d\n", result);
IPAERR("remove delay from SCND reg\n");
ep_ctrl_scnd.endp_delay = false;
ipahal_write_reg_n_fields(
IPA_ENDP_INIT_CTRL_SCND_n, ipa_ep_idx_rx,
&ep_ctrl_scnd);
} else {
disable_force_clear = true;
}
}
/* stop gsi rx channel */

View file

@ -1809,22 +1809,24 @@ int ipa3_disable_wigig_pipe_i(enum ipa_client_type client)
}
IPADBG("pipe %d\n", ipa_ep_idx);
source_pipe_bitmask = 1 << ipa_ep_idx;
res = ipa3_enable_force_clear(ipa_ep_idx,
false, source_pipe_bitmask);
if (res) {
/*
* assuming here modem SSR, AP can remove
* the delay in this case
*/
IPAERR("failed to force clear %d\n", res);
IPAERR("remove delay from SCND reg\n");
ep_ctrl_scnd.endp_delay = false;
ipahal_write_reg_n_fields(
IPA_ENDP_INIT_CTRL_SCND_n, ipa_ep_idx,
&ep_ctrl_scnd);
} else {
disable_force_clear = true;
if (IPA_CLIENT_IS_PROD(ep->client)) {
source_pipe_bitmask = 1 << ipa_ep_idx;
res = ipa3_enable_force_clear(ipa_ep_idx,
false, source_pipe_bitmask);
if (res) {
/*
* assuming here modem SSR, AP can remove
* the delay in this case
*/
IPAERR("failed to force clear %d\n", res);
IPAERR("remove delay from SCND reg\n");
ep_ctrl_scnd.endp_delay = false;
ipahal_write_reg_n_fields(
IPA_ENDP_INIT_CTRL_SCND_n, ipa_ep_idx,
&ep_ctrl_scnd);
} else {
disable_force_clear = true;
}
}
retry_gsi_stop:
res = ipa3_stop_gsi_channel(ipa_ep_idx);