diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 07c2d2f61964..7d6b5802dfb0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6025,6 +6025,13 @@ static int ipa3_panic_notifier(struct notifier_block *this, int res; struct ipa_active_client_logging_info log_info; + if (ipa3_ctx != NULL) + { + if (ipa3_ctx->is_device_crashed) + return NOTIFY_DONE; + ipa3_ctx->is_device_crashed = true; + } + ipa3_freeze_clock_vote_and_notify_modem(); IPADBG("Calling uC panic handler\n"); @@ -7126,6 +7133,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, ipa3_ctx->gsi_ch20_wa = resource_p->gsi_ch20_wa; ipa3_ctx->wdi_over_pcie = resource_p->wdi_over_pcie; ipa3_ctx->ipa3_active_clients_logging.log_rdy = false; + ipa3_ctx->is_device_crashed = false; ipa3_ctx->mhi_evid_limits[0] = resource_p->mhi_evid_limits[0]; ipa3_ctx->mhi_evid_limits[1] = resource_p->mhi_evid_limits[1]; ipa3_ctx->entire_ipa_block_size = resource_p->entire_ipa_block_size; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 99fbd68e0e51..8a396a023703 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -89,6 +89,8 @@ #define IPA_QMAP_ID_BYTE 0 +#define IPA_MEM_ALLOC_RETRY 5 + static struct sk_buff *ipa3_get_skb_ipa_rx(unsigned int len, gfp_t flags); static void ipa3_replenish_wlan_rx_cache(struct ipa3_sys_context *sys); static void ipa3_replenish_rx_cache(struct ipa3_sys_context *sys); @@ -3922,7 +3924,9 @@ static void ipa3_set_aggr_limit(struct ipa_sys_connect_params *in, sys->ep->status.status_en = false; sys->rx_buff_sz = IPA_GENERIC_RX_BUFF_SZ(adjusted_sz); - if (in->client == IPA_CLIENT_APPS_WAN_COAL_CONS) + if (in->client == IPA_CLIENT_APPS_WAN_COAL_CONS || + (in->client == IPA_CLIENT_APPS_WAN_CONS && + ipa3_ctx->ipa_hw_type <= IPA_HW_v4_2)) in->ipa_ep_cfg.aggr.aggr_hard_byte_limit_en = 1; *aggr_byte_limit = sys->rx_buff_sz < *aggr_byte_limit ? @@ -4876,6 +4880,33 @@ fail_setup_event_ring: return result; } +static void *ipa3_ring_alloc(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp) +{ + void *va_addr; + int retry_cnt = 0; + +alloc: + va_addr = dma_alloc_coherent(dev, size, dma_handle, gfp); + if (!va_addr) { + if (retry_cnt < IPA_MEM_ALLOC_RETRY) { + IPADBG("Fail to dma alloc retry cnt = %d\n", + retry_cnt); + retry_cnt++; + goto alloc; + } + + if (gfp == GFP_ATOMIC) { + gfp = GFP_KERNEL; + goto alloc; + } + IPAERR("fail to dma alloc %u bytes\n", size); + ipa_assert(); + } + + return va_addr; +} + static int ipa_gsi_setup_event_ring(struct ipa3_ep_context *ep, u32 ring_size, gfp_t mem_flag) { @@ -4892,13 +4923,8 @@ static int ipa_gsi_setup_event_ring(struct ipa3_ep_context *ep, gsi_evt_ring_props.re_size = GSI_EVT_RING_RE_SIZE_16B; gsi_evt_ring_props.ring_len = ring_size; gsi_evt_ring_props.ring_base_vaddr = - dma_alloc_coherent(ipa3_ctx->pdev, gsi_evt_ring_props.ring_len, + ipa3_ring_alloc(ipa3_ctx->pdev, gsi_evt_ring_props.ring_len, &evt_dma_addr, mem_flag); - if (!gsi_evt_ring_props.ring_base_vaddr) { - IPAERR("fail to dma alloc %u bytes\n", - gsi_evt_ring_props.ring_len); - return -ENOMEM; - } gsi_evt_ring_props.ring_base_addr = evt_dma_addr; /* copy mem info */ @@ -5006,14 +5032,8 @@ static int ipa_gsi_setup_transfer_ring(struct ipa3_ep_context *ep, gsi_channel_props.ring_len = ring_size; gsi_channel_props.ring_base_vaddr = - dma_alloc_coherent(ipa3_ctx->pdev, gsi_channel_props.ring_len, + ipa3_ring_alloc(ipa3_ctx->pdev, gsi_channel_props.ring_len, &dma_addr, mem_flag); - if (!gsi_channel_props.ring_base_vaddr) { - IPAERR("fail to dma alloc %u bytes\n", - gsi_channel_props.ring_len); - result = -ENOMEM; - goto fail_alloc_channel_ring; - } gsi_channel_props.ring_base_addr = dma_addr; /* copy mem info */ @@ -5091,7 +5111,6 @@ fail_alloc_channel: dma_free_coherent(ipa3_ctx->pdev, ep->gsi_mem_info.chan_ring_len, ep->gsi_mem_info.chan_ring_base_vaddr, ep->gsi_mem_info.chan_ring_base_addr); -fail_alloc_channel_ring: fail_get_gsi_ep_info: if (ep->gsi_evt_ring_hdl != ~0) { gsi_dealloc_evt_ring(ep->gsi_evt_ring_hdl); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 2bc0d82040b3..a6a742fee493 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2154,6 +2154,7 @@ struct ipa3_context { bool is_bw_monitor_supported; bool modem_load_ipa_fw; bool fnr_stats_not_supported; + bool is_device_crashed; }; struct ipa3_plat_drv_res { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index e011fdcae27a..ae02f21d11de 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -893,7 +893,10 @@ int ipa3_qmi_add_offload_request_send( } /* check if the filter rules from IPACM is valid */ - if (req->filter_spec_ex2_list_len == 0) { + if (req->filter_spec_ex2_list_len < 0) { + IPAWANERR("IPACM pass invalid num of rules\n"); + return -EINVAL; + } else if (req->filter_spec_ex2_list_len == 0) { IPAWANDBG("IPACM pass zero rules to Q6\n"); } else { IPAWANDBG("IPACM pass %u rules to Q6\n", @@ -901,9 +904,10 @@ int ipa3_qmi_add_offload_request_send( } /* currently set total max to 64 */ - if (req->filter_spec_ex2_list_len + - ipa3_qmi_ctx->num_ipa_offload_connection - >= QMI_IPA_MAX_FILTERS_V01) { + if ((ipa3_qmi_ctx->num_ipa_offload_connection < 0) || + (req->filter_spec_ex2_list_len >= + (QMI_IPA_MAX_FILTERS_V01 - + ipa3_qmi_ctx->num_ipa_offload_connection))) { IPAWANDBG( "cur(%d), req(%d), exceed limit (%d)\n", ipa3_qmi_ctx->num_ipa_offload_connection, diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 358472ac9480..07c9fc828d24 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -2237,16 +2237,14 @@ static int rmnet_ipa_send_coalesce_notification(uint8_t qmap_id, if (!coalesce_info) return -ENOMEM; - if (enable) { - coalesce_info->qmap_id = qmap_id; - coalesce_info->tcp_enable = tcp; - coalesce_info->udp_enable = udp; + coalesce_info->qmap_id = qmap_id; + coalesce_info->tcp_enable = tcp; + coalesce_info->udp_enable = udp; + msg_meta.msg_len = sizeof(struct ipa_coalesce_info); + if (enable) msg_meta.msg_type = IPA_COALESCE_ENABLE; - msg_meta.msg_len = sizeof(struct ipa_coalesce_info); - } else { + else msg_meta.msg_type = IPA_COALESCE_DISABLE; - msg_meta.msg_len = sizeof(struct ipa_coalesce_info); - } rc = ipa_send_msg(&msg_meta, coalesce_info, ipa3_wwan_msg_free_cb); if (rc) { IPAWANERR("ipa_send_msg failed: %d\n", rc);