summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mediatek/mt76/dma.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2020-07-25 14:44:07 +0200
committerFelix Fietkau <nbd@nbd.name>2020-09-24 18:10:13 +0200
commit27d5c528a7ca08dcd44877fdd9fc08b76630bf77 (patch)
tree77c1fb9608ea744470aa3833359f4ae2f14d391b /drivers/net/wireless/mediatek/mt76/dma.c
parentc12b7c7944e56e526c0a457282603ebcdd04ca90 (diff)
downloadlinux-stable-27d5c528a7ca08dcd44877fdd9fc08b76630bf77.tar.gz
linux-stable-27d5c528a7ca08dcd44877fdd9fc08b76630bf77.tar.bz2
linux-stable-27d5c528a7ca08dcd44877fdd9fc08b76630bf77.zip
mt76: fix double DMA unmap of the first buffer on 7615/7915
A small part of the first skb buffer is passed to the firmware for parsing via DMA, while the full buffer is passed as part of the TXP. Avoid calling DMA unmap on the first part (with a different length than map) Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/dma.c')
-rw-r--r--drivers/net/wireless/mediatek/mt76/dma.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 6c25859dd386..ade2d58b8da9 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -61,10 +61,16 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
for (i = 0; i < nbufs; i += 2, buf += 2) {
u32 buf0 = buf[0].addr, buf1 = 0;
+ if (buf[0].skip_unmap)
+ q->entry[q->head].skip_buf0 = true;
+ q->entry[q->head].skip_buf1 = i == nbufs - 1;
+
ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
if (i < nbufs - 1) {
buf1 = buf[1].addr;
ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len);
+ if (buf[1].skip_unmap)
+ q->entry[q->head].skip_buf1 = true;
}
if (i == nbufs - 1)
@@ -107,7 +113,7 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx,
DMA_TO_DEVICE);
}
- if (!(ctrl & MT_DMA_CTL_LAST_SEC0)) {
+ if (!e->skip_buf1) {
__le32 addr = READ_ONCE(q->desc[idx].buf1);
u32 len = FIELD_GET(MT_DMA_CTL_SD_LEN1, ctrl);