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

Commit 683b95e8 authored by Peter Oh's avatar Peter Oh Committed by Kalle Valo
Browse files

ath10k: use pre-allocated DMA buffer in Tx



ath10k driver is using dma_pool_alloc per packet and dma_pool_free
in coresponding at Tx completion.
Use of pre-allocated DMA buffer in Tx will improve saving CPU resource
by 5% while it consumes about 56KB memory more as trade off.

Signed-off-by: default avatarPeter Oh <poh@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent bc27e8cd
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -1488,7 +1488,6 @@ struct ath10k_htt {
	int num_pending_mgmt_tx;
	int num_pending_mgmt_tx;
	struct idr pending_tx;
	struct idr pending_tx;
	wait_queue_head_t empty_tx_wq;
	wait_queue_head_t empty_tx_wq;
	struct dma_pool *tx_pool;


	/* set if host-fw communication goes haywire
	/* set if host-fw communication goes haywire
	 * used to avoid further failures */
	 * used to avoid further failures */
@@ -1509,6 +1508,11 @@ struct ath10k_htt {
		dma_addr_t paddr;
		dma_addr_t paddr;
		struct htt_msdu_ext_desc *vaddr;
		struct htt_msdu_ext_desc *vaddr;
	} frag_desc;
	} frag_desc;

	struct {
		dma_addr_t paddr;
		struct ath10k_htt_txbuf *vaddr;
	} txbuf;
};
};


#define RX_HTT_HDR_STATUS_LEN 64
#define RX_HTT_HDR_STATUS_LEN 64
+23 −20
Original line number Original line Diff line number Diff line
@@ -108,9 +108,12 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
	spin_lock_init(&htt->tx_lock);
	spin_lock_init(&htt->tx_lock);
	idr_init(&htt->pending_tx);
	idr_init(&htt->pending_tx);


	htt->tx_pool = dma_pool_create("ath10k htt tx pool", htt->ar->dev,
	size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf);
				       sizeof(struct ath10k_htt_txbuf), 4, 0);
	htt->txbuf.vaddr = dma_alloc_coherent(ar->dev, size,
	if (!htt->tx_pool) {
						  &htt->txbuf.paddr,
						  GFP_DMA);
	if (!htt->txbuf.vaddr) {
		ath10k_err(ar, "failed to alloc tx buffer\n");
		ret = -ENOMEM;
		ret = -ENOMEM;
		goto free_idr_pending_tx;
		goto free_idr_pending_tx;
	}
	}
@@ -125,14 +128,17 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
	if (!htt->frag_desc.vaddr) {
	if (!htt->frag_desc.vaddr) {
		ath10k_warn(ar, "failed to alloc fragment desc memory\n");
		ath10k_warn(ar, "failed to alloc fragment desc memory\n");
		ret = -ENOMEM;
		ret = -ENOMEM;
		goto free_tx_pool;
		goto free_txbuf;
	}
	}


skip_frag_desc_alloc:
skip_frag_desc_alloc:
	return 0;
	return 0;


free_tx_pool:
free_txbuf:
	dma_pool_destroy(htt->tx_pool);
	size = htt->max_num_pending_tx *
			  sizeof(struct ath10k_htt_txbuf);
	dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr,
			  htt->txbuf.paddr);
free_idr_pending_tx:
free_idr_pending_tx:
	idr_destroy(&htt->pending_tx);
	idr_destroy(&htt->pending_tx);
	return ret;
	return ret;
@@ -160,7 +166,13 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt)


	idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
	idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
	idr_destroy(&htt->pending_tx);
	idr_destroy(&htt->pending_tx);
	dma_pool_destroy(htt->tx_pool);

	if (htt->txbuf.vaddr) {
		size = htt->max_num_pending_tx *
				  sizeof(struct ath10k_htt_txbuf);
		dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr,
				  htt->txbuf.paddr);
	}


	if (htt->frag_desc.vaddr) {
	if (htt->frag_desc.vaddr) {
		size = htt->max_num_pending_tx *
		size = htt->max_num_pending_tx *
@@ -521,7 +533,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
	int res;
	int res;
	u8 flags0 = 0;
	u8 flags0 = 0;
	u16 msdu_id, flags1 = 0;
	u16 msdu_id, flags1 = 0;
	dma_addr_t paddr = 0;
	u32 frags_paddr = 0;
	u32 frags_paddr = 0;
	struct htt_msdu_ext_desc *ext_desc = NULL;
	struct htt_msdu_ext_desc *ext_desc = NULL;
	bool limit_mgmt_desc = false;
	bool limit_mgmt_desc = false;
@@ -550,13 +561,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
	prefetch_len = min(htt->prefetch_len, msdu->len);
	prefetch_len = min(htt->prefetch_len, msdu->len);
	prefetch_len = roundup(prefetch_len, 4);
	prefetch_len = roundup(prefetch_len, 4);


	skb_cb->htt.txbuf = dma_pool_alloc(htt->tx_pool, GFP_ATOMIC,
	skb_cb->htt.txbuf = &htt->txbuf.vaddr[msdu_id];
					   &paddr);
	skb_cb->htt.txbuf_paddr = htt->txbuf.paddr +
	if (!skb_cb->htt.txbuf) {
		(sizeof(struct ath10k_htt_txbuf) * msdu_id);
		res = -ENOMEM;
		goto err_free_msdu_id;
	}
	skb_cb->htt.txbuf_paddr = paddr;


	if ((ieee80211_is_action(hdr->frame_control) ||
	if ((ieee80211_is_action(hdr->frame_control) ||
	     ieee80211_is_deauth(hdr->frame_control) ||
	     ieee80211_is_deauth(hdr->frame_control) ||
@@ -574,7 +581,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
	res = dma_mapping_error(dev, skb_cb->paddr);
	res = dma_mapping_error(dev, skb_cb->paddr);
	if (res) {
	if (res) {
		res = -EIO;
		res = -EIO;
		goto err_free_txbuf;
		goto err_free_msdu_id;
	}
	}


	switch (skb_cb->txmode) {
	switch (skb_cb->txmode) {
@@ -706,10 +713,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)


err_unmap_msdu:
err_unmap_msdu:
	dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
	dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
err_free_txbuf:
	dma_pool_free(htt->tx_pool,
		      skb_cb->htt.txbuf,
		      skb_cb->htt.txbuf_paddr);
err_free_msdu_id:
err_free_msdu_id:
	spin_lock_bh(&htt->tx_lock);
	spin_lock_bh(&htt->tx_lock);
	ath10k_htt_tx_free_msdu_id(htt, msdu_id);
	ath10k_htt_tx_free_msdu_id(htt, msdu_id);
+0 −5
Original line number Original line Diff line number Diff line
@@ -92,11 +92,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
	skb_cb = ATH10K_SKB_CB(msdu);
	skb_cb = ATH10K_SKB_CB(msdu);
	dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
	dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);


	if (skb_cb->htt.txbuf)
		dma_pool_free(htt->tx_pool,
			      skb_cb->htt.txbuf,
			      skb_cb->htt.txbuf_paddr);

	ath10k_report_offchan_tx(htt->ar, msdu);
	ath10k_report_offchan_tx(htt->ar, msdu);


	info = IEEE80211_SKB_CB(msdu);
	info = IEEE80211_SKB_CB(msdu);