mirror of https://gitee.com/openkylin/linux.git
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: Peter Oh <poh@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
bc27e8cddd
commit
683b95e807
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue