Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c839339 authored by Gidon Studinski's avatar Gidon Studinski Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: optimize sys2bam data path



add the ability to provide DMA address of an skb sent
to IPA driver if it was already DMA mapped for saving the
MIPS of mapping the same buffer again.

Change-Id: Iaf06e45d0d4fab0a5968688eae768b79148e8270
Acked-by: default avatarAdy Abraham <adya@qti.qualcomm.com>
Signed-off-by: default avatarGidon Studinski <gidons@codeaurora.org>
parent e2305a16
Loading
Loading
Loading
Loading
+68 −42
Original line number Diff line number Diff line
@@ -74,7 +74,9 @@ static void ipa_wq_write_done_common(struct ipa_sys_context *sys, u32 cnt)
						   link);
		list_del(&tx_pkt_expected->link);
		sys->len--;
		dma_unmap_single(ipa_ctx->pdev, tx_pkt_expected->mem.phys_base,
		if (!tx_pkt_expected->no_unmap_dma)
			dma_unmap_single(ipa_ctx->pdev,
					tx_pkt_expected->mem.phys_base,
					tx_pkt_expected->mem.size,
					DMA_TO_DEVICE);
		spin_unlock_bh(&sys->spinlock);
@@ -275,12 +277,13 @@ int ipa_send_one(struct ipa_sys_context *sys, struct ipa_desc *desc,
		goto fail_mem_alloc;
	}

	if (!desc->dma_address_valid) {
		if (unlikely(ipa_ctx->ipa_hw_type == IPA_HW_v1_0)) {
			WARN_ON(desc->len > 512);

			/*
		 * Due to a HW limitation, we need to make sure that the packet
		 * does not cross a 1KB boundary
			 * Due to a HW limitation, we need to make sure that
			 * the packet does not cross a 1KB boundary
			 */
			tx_pkt->bounce = dma_pool_alloc(
				ipa_ctx->dma_pool,
@@ -298,6 +301,10 @@ int ipa_send_one(struct ipa_sys_context *sys, struct ipa_desc *desc,
			dma_address = dma_map_single(ipa_ctx->pdev, desc->pyld,
				desc->len, DMA_TO_DEVICE);
		}
	} else {
		dma_address = desc->dma_address;
		tx_pkt->no_unmap_dma = true;
	}
	if (!dma_address) {
		IPAERR("failed to DMA wrap\n");
		goto fail_dma_map;
@@ -438,12 +445,14 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
		tx_pkt->mem.base = desc[i].pyld;
		tx_pkt->mem.size = desc[i].len;

		if (!desc->dma_address_valid) {
			if (unlikely(ipa_ctx->ipa_hw_type == IPA_HW_v1_0)) {
				WARN_ON(tx_pkt->mem.size > 512);

				/*
			 * Due to a HW limitation, we need to make sure that the
			 * packet does not cross a 1KB boundary
				 * Due to a HW limitation, we need to make sure
				 * that the packet does not cross a
				 * 1KB boundary
				 */
				tx_pkt->bounce =
				dma_pool_alloc(ipa_ctx->dma_pool,
@@ -461,10 +470,16 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
				}
			} else {
				tx_pkt->mem.phys_base =
			   dma_map_single(ipa_ctx->pdev, tx_pkt->mem.base,
					dma_map_single(ipa_ctx->pdev,
					tx_pkt->mem.base,
					tx_pkt->mem.size,
					DMA_TO_DEVICE);
			}
		} else {
			tx_pkt->mem.phys_base = desc->dma_address;
			tx_pkt->no_unmap_dma = true;
		}

		if (!tx_pkt->mem.phys_base) {
			IPAERR("failed to alloc tx wrapper\n");
			fail_dma_wrap = 1;
@@ -1194,6 +1209,8 @@ int ipa_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
	struct ipa_sys_context *sys;
	int src_ep_idx;

	memset(desc, 0, 2 * sizeof(struct ipa_desc));

	/*
	 * USB_CONS: PKT_INIT ep_idx = dst pipe
	 * Q6_CONS: PKT_INIT ep_idx = sender pipe
@@ -1242,6 +1259,10 @@ int ipa_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
				meta->pkt_init_dst_ep_remote) ?
				src_ep_idx :
				dst_ep_idx;
		if (meta && meta->dma_address_valid) {
			desc[1].dma_address_valid = true;
			desc[1].dma_address = meta->dma_address;
		}

		if (ipa_send(sys, 2, desc, true)) {
			IPAERR("fail to send immediate command\n");
@@ -1257,6 +1278,11 @@ int ipa_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
		desc[0].user1 = skb;
		desc[0].user2 = src_ep_idx;

		if (meta && meta->dma_address_valid) {
			desc[0].dma_address_valid = true;
			desc[0].dma_address = meta->dma_address;
		}

		if (ipa_send_one(sys, &desc[0], true)) {
			IPAERR("fail to send skb\n");
			goto fail_gen;
@@ -2275,7 +2301,7 @@ int ipa_tx_dp_mul(enum ipa_client_type src,
#define IPA_WLAN_HDR_QMAP_ID_OFFSET 1
	struct ipa_tx_data_desc *entry;
	struct ipa_sys_context *sys;
	struct ipa_desc desc;
	struct ipa_desc desc = { 0 };
	u32 num_desc, cnt;
	int ep_idx;

+6 −0
Original line number Diff line number Diff line
@@ -423,6 +423,7 @@ enum ipa_desc_type {
 * >1 and <0xFFFF for first of a "multiple" tranfer,
 * 0xFFFF for last desc, 0 for rest of "multiple' transfer
 * @bounce: va of bounce buffer
 * @unmap_dma: in case this is true, the buffer will not be dma unmapped
 *
 * This struct can wrap both data packet and immediate command packet.
 */
@@ -438,6 +439,7 @@ struct ipa_tx_pkt_wrapper {
	struct ipa_mem_buffer mult;
	u32 cnt;
	void *bounce;
	bool no_unmap_dma;
};

/**
@@ -445,6 +447,8 @@ struct ipa_tx_pkt_wrapper {
 * @type: skb or immediate command or plain old data
 * @pyld: points to skb
 * or kmalloc'ed immediate command parameters/plain old data
 * @dma_address: dma mapped address of pyld
 * @dma_address_valid: valid field for dma_address
 * @len: length of the pyld
 * @opcode: for immediate commands
 * @callback: IPA client provided completion callback
@@ -455,6 +459,8 @@ struct ipa_tx_pkt_wrapper {
struct ipa_desc {
	enum ipa_desc_type type;
	void *pyld;
	dma_addr_t dma_address;
	bool dma_address_valid;
	u16 len;
	u16 opcode;
	void (*callback)(void *user1, int user2);
+1 −1
Original line number Diff line number Diff line
@@ -387,7 +387,7 @@ int ipa_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma)
		goto bail;
	}
	size = sizeof(struct ipa_desc) * dma->entries;
	desc = kmalloc(size, GFP_KERNEL);
	desc = kzalloc(size, GFP_KERNEL);
	if (desc == NULL) {
		IPAERR("Failed to alloc memory\n");
		ret = -ENOMEM;
+4 −0
Original line number Diff line number Diff line
@@ -496,6 +496,8 @@ struct ipa_sys_connect_params {
 * struct ipa_tx_meta - meta-data for the TX packet
 * @mbim_stream_id:	the stream ID used in NDP signature
 * @mbim_stream_id_valid:	 is above field valid?
 * @dma_address: dma mapped address of TX packet
 * @dma_address_valid: is above field valid?
 */
struct ipa_tx_meta {
	u8 mbim_stream_id;
@@ -503,6 +505,8 @@ struct ipa_tx_meta {
	u8 pkt_init_dst_ep;
	bool pkt_init_dst_ep_valid;
	bool pkt_init_dst_ep_remote;
	dma_addr_t dma_address;
	bool dma_address_valid;
};

/**