Loading drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +37 −22 Original line number Original line Diff line number Diff line Loading @@ -1723,6 +1723,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, struct ipa3_sys_context *sys; struct ipa3_sys_context *sys; int src_ep_idx; int src_ep_idx; int num_frags, f; int num_frags, f; struct ipa_gsi_ep_config *gsi_ep; if (unlikely(!ipa3_ctx)) { if (unlikely(!ipa3_ctx)) { IPAERR("IPA3 driver was not initialized\n"); IPAERR("IPA3 driver was not initialized\n"); Loading @@ -1734,23 +1735,6 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, return -EINVAL; return -EINVAL; } } num_frags = skb_shinfo(skb)->nr_frags; if (num_frags) { /* 1 desc for tag to resolve status out-of-order issue; * 1 desc is needed for the linear portion of skb; * 1 desc may be needed for the PACKET_INIT; * 1 desc for each frag */ desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC); if (!desc) { IPAERR("failed to alloc desc array\n"); goto fail_mem; } } else { memset(_desc, 0, 3 * sizeof(struct ipa3_desc)); desc = &_desc[0]; } /* /* * USB_CONS: PKT_INIT ep_idx = dst pipe * USB_CONS: PKT_INIT ep_idx = dst pipe * Q6_CONS: PKT_INIT ep_idx = sender pipe * Q6_CONS: PKT_INIT ep_idx = sender pipe Loading Loading @@ -1787,6 +1771,37 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, goto fail_gen; goto fail_gen; } } num_frags = skb_shinfo(skb)->nr_frags; /* * make sure TLV FIFO supports the needed frags. * 2 descriptors are needed for IP_PACKET_INIT and TAG_STATUS. * 1 descriptor needed for the linear portion of skb. */ gsi_ep = ipa3_get_gsi_ep_info(src_ep_idx); if (gsi_ep && (num_frags + 3 > gsi_ep->ipa_if_tlv)) { if (skb_linearize(skb)) { IPAERR("Failed to linear skb with %d frags\n", num_frags); goto fail_gen; } num_frags = 0; } if (num_frags) { /* 1 desc for tag to resolve status out-of-order issue; * 1 desc is needed for the linear portion of skb; * 1 desc may be needed for the PACKET_INIT; * 1 desc for each frag */ desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC); if (!desc) { IPAERR("failed to alloc desc array\n"); goto fail_gen; } } else { memset(_desc, 0, 3 * sizeof(struct ipa3_desc)); desc = &_desc[0]; } if (dst_ep_idx != -1) { if (dst_ep_idx != -1) { /* SW data path */ /* SW data path */ cmd.destination_pipe_index = dst_ep_idx; cmd.destination_pipe_index = dst_ep_idx; Loading @@ -1794,7 +1809,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, IPA_IMM_CMD_IP_PACKET_INIT, &cmd, true); IPA_IMM_CMD_IP_PACKET_INIT, &cmd, true); if (unlikely(!cmd_pyld)) { if (unlikely(!cmd_pyld)) { IPAERR("failed to construct ip_packet_init imm cmd\n"); IPAERR("failed to construct ip_packet_init imm cmd\n"); goto fail_gen; goto fail_mem; } } /* the tag field will be populated in ipa3_send() function */ /* the tag field will be populated in ipa3_send() function */ Loading Loading @@ -1863,7 +1878,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, if (num_frags == 0) { if (num_frags == 0) { if (ipa3_send(sys, 2, desc, true)) { if (ipa3_send(sys, 2, desc, true)) { IPAERR("fail to send skb %p HWP\n", skb); IPAERR("fail to send skb %p HWP\n", skb); goto fail_gen; goto fail_mem; } } } else { } else { for (f = 0; f < num_frags; f++) { for (f = 0; f < num_frags; f++) { Loading @@ -1880,7 +1895,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, if (ipa3_send(sys, num_frags + 2, desc, true)) { if (ipa3_send(sys, num_frags + 2, desc, true)) { IPAERR("fail to send skb %p num_frags %u HWP\n", IPAERR("fail to send skb %p num_frags %u HWP\n", skb, num_frags); skb, num_frags); goto fail_gen; goto fail_mem; } } } } IPA_STATS_INC_CNT(ipa3_ctx->stats.tx_hw_pkts); IPA_STATS_INC_CNT(ipa3_ctx->stats.tx_hw_pkts); Loading @@ -1894,10 +1909,10 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, fail_send: fail_send: ipahal_destroy_imm_cmd(cmd_pyld); ipahal_destroy_imm_cmd(cmd_pyld); fail_gen: fail_mem: if (num_frags) if (num_frags) kfree(desc); kfree(desc); fail_mem: fail_gen: return -EFAULT; return -EFAULT; } } Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +37 −22 Original line number Original line Diff line number Diff line Loading @@ -1723,6 +1723,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, struct ipa3_sys_context *sys; struct ipa3_sys_context *sys; int src_ep_idx; int src_ep_idx; int num_frags, f; int num_frags, f; struct ipa_gsi_ep_config *gsi_ep; if (unlikely(!ipa3_ctx)) { if (unlikely(!ipa3_ctx)) { IPAERR("IPA3 driver was not initialized\n"); IPAERR("IPA3 driver was not initialized\n"); Loading @@ -1734,23 +1735,6 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, return -EINVAL; return -EINVAL; } } num_frags = skb_shinfo(skb)->nr_frags; if (num_frags) { /* 1 desc for tag to resolve status out-of-order issue; * 1 desc is needed for the linear portion of skb; * 1 desc may be needed for the PACKET_INIT; * 1 desc for each frag */ desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC); if (!desc) { IPAERR("failed to alloc desc array\n"); goto fail_mem; } } else { memset(_desc, 0, 3 * sizeof(struct ipa3_desc)); desc = &_desc[0]; } /* /* * USB_CONS: PKT_INIT ep_idx = dst pipe * USB_CONS: PKT_INIT ep_idx = dst pipe * Q6_CONS: PKT_INIT ep_idx = sender pipe * Q6_CONS: PKT_INIT ep_idx = sender pipe Loading Loading @@ -1787,6 +1771,37 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, goto fail_gen; goto fail_gen; } } num_frags = skb_shinfo(skb)->nr_frags; /* * make sure TLV FIFO supports the needed frags. * 2 descriptors are needed for IP_PACKET_INIT and TAG_STATUS. * 1 descriptor needed for the linear portion of skb. */ gsi_ep = ipa3_get_gsi_ep_info(src_ep_idx); if (gsi_ep && (num_frags + 3 > gsi_ep->ipa_if_tlv)) { if (skb_linearize(skb)) { IPAERR("Failed to linear skb with %d frags\n", num_frags); goto fail_gen; } num_frags = 0; } if (num_frags) { /* 1 desc for tag to resolve status out-of-order issue; * 1 desc is needed for the linear portion of skb; * 1 desc may be needed for the PACKET_INIT; * 1 desc for each frag */ desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC); if (!desc) { IPAERR("failed to alloc desc array\n"); goto fail_gen; } } else { memset(_desc, 0, 3 * sizeof(struct ipa3_desc)); desc = &_desc[0]; } if (dst_ep_idx != -1) { if (dst_ep_idx != -1) { /* SW data path */ /* SW data path */ cmd.destination_pipe_index = dst_ep_idx; cmd.destination_pipe_index = dst_ep_idx; Loading @@ -1794,7 +1809,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, IPA_IMM_CMD_IP_PACKET_INIT, &cmd, true); IPA_IMM_CMD_IP_PACKET_INIT, &cmd, true); if (unlikely(!cmd_pyld)) { if (unlikely(!cmd_pyld)) { IPAERR("failed to construct ip_packet_init imm cmd\n"); IPAERR("failed to construct ip_packet_init imm cmd\n"); goto fail_gen; goto fail_mem; } } /* the tag field will be populated in ipa3_send() function */ /* the tag field will be populated in ipa3_send() function */ Loading Loading @@ -1863,7 +1878,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, if (num_frags == 0) { if (num_frags == 0) { if (ipa3_send(sys, 2, desc, true)) { if (ipa3_send(sys, 2, desc, true)) { IPAERR("fail to send skb %p HWP\n", skb); IPAERR("fail to send skb %p HWP\n", skb); goto fail_gen; goto fail_mem; } } } else { } else { for (f = 0; f < num_frags; f++) { for (f = 0; f < num_frags; f++) { Loading @@ -1880,7 +1895,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, if (ipa3_send(sys, num_frags + 2, desc, true)) { if (ipa3_send(sys, num_frags + 2, desc, true)) { IPAERR("fail to send skb %p num_frags %u HWP\n", IPAERR("fail to send skb %p num_frags %u HWP\n", skb, num_frags); skb, num_frags); goto fail_gen; goto fail_mem; } } } } IPA_STATS_INC_CNT(ipa3_ctx->stats.tx_hw_pkts); IPA_STATS_INC_CNT(ipa3_ctx->stats.tx_hw_pkts); Loading @@ -1894,10 +1909,10 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, fail_send: fail_send: ipahal_destroy_imm_cmd(cmd_pyld); ipahal_destroy_imm_cmd(cmd_pyld); fail_gen: fail_mem: if (num_frags) if (num_frags) kfree(desc); kfree(desc); fail_mem: fail_gen: return -EFAULT; return -EFAULT; } } Loading