From: Lorenzo Bianconi <lorenzo@kernel.org>
To: nbd@nbd.name
Cc: linux-wireless@vger.kernel.org, lorenzo.bianconi@redhat.com
Subject: [PATCH v2 3/4] wifi: mt76: dma: keep rx pages DMA mapped
Date: Tue, 17 Jan 2023 14:53:16 +0100 [thread overview]
Message-ID: <68081e02cbe2afa2d35c8aa93194f0adddbd0f05.1673963374.git.lorenzo@kernel.org> (raw)
In-Reply-To: <cover.1673963374.git.lorenzo@kernel.org>
For mmio devices rely on page_pool capability to keep rx buffers DMA
mapped and just sync rx buffers before accessing them.
Tested-by: Felix Fietkau <nbd@nbd.name>
Tested-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/dma.c | 34 +++++++++++--------
drivers/net/wireless/mediatek/mt76/mac80211.c | 8 +++++
.../net/wireless/mediatek/mt76/mt7915/mmio.c | 5 +--
3 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 7fd9aa9c3d9e..33e47ea0368e 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -407,9 +407,14 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
if (!t)
return NULL;
- dma_unmap_single(dev->dma_dev, t->dma_addr,
- SKB_WITH_OVERHEAD(q->buf_size),
- DMA_FROM_DEVICE);
+ if (mt76_is_page_from_pp(t->ptr))
+ dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
+ SKB_WITH_OVERHEAD(q->buf_size),
+ page_pool_get_dma_dir(q->page_pool));
+ else
+ dma_unmap_single(dev->dma_dev, t->dma_addr,
+ SKB_WITH_OVERHEAD(q->buf_size),
+ DMA_FROM_DEVICE);
buf = t->ptr;
t->dma_addr = 0;
@@ -426,9 +431,14 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
} else {
buf = e->buf;
e->buf = NULL;
- dma_unmap_single(dev->dma_dev, e->dma_addr[0],
- SKB_WITH_OVERHEAD(q->buf_size),
- DMA_FROM_DEVICE);
+ if (mt76_is_page_from_pp(buf))
+ dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0],
+ SKB_WITH_OVERHEAD(q->buf_size),
+ page_pool_get_dma_dir(q->page_pool));
+ else
+ dma_unmap_single(dev->dma_dev, e->dma_addr[0],
+ SKB_WITH_OVERHEAD(q->buf_size),
+ DMA_FROM_DEVICE);
}
return buf;
@@ -592,6 +602,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
spin_lock_bh(&q->lock);
while (q->queued < q->ndesc - 1) {
+ enum dma_data_direction dir;
struct mt76_queue_buf qbuf;
dma_addr_t addr;
int offset;
@@ -601,19 +612,14 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
if (!buf)
break;
- addr = dma_map_single(dev->dma_dev, buf + offset, len,
- DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
- mt76_put_page_pool_buf(buf, allow_direct);
- break;
- }
+ addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
+ dir = page_pool_get_dma_dir(q->page_pool);
+ dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
qbuf.addr = addr + q->buf_offset;
qbuf.len = len - q->buf_offset;
qbuf.skip_unmap = false;
if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
- dma_unmap_single(dev->dma_dev, addr, len,
- DMA_FROM_DEVICE);
mt76_put_page_pool_buf(buf, allow_direct);
break;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 9fefb441e4d4..3d6b6f12ffde 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -567,6 +567,14 @@ int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q)
.dev = dev->dma_dev,
};
+ if (mt76_is_mmio(dev)) {
+ /* rely on page_pool for DMA mapping */
+ pp_params.flags |= PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
+ pp_params.dma_dir = DMA_FROM_DEVICE;
+ pp_params.max_len = PAGE_SIZE;
+ pp_params.offset = 0;
+ }
+
q->page_pool = page_pool_create(&pp_params);
if (IS_ERR(q->page_pool)) {
int err = PTR_ERR(q->page_pool);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
index 58213e590ac5..3ab2e5bf7d45 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
@@ -604,8 +604,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
if (!t || !t->ptr)
continue;
- dma_unmap_single(dev->mt76.dma_dev, t->dma_addr,
- wed->wlan.rx_size, DMA_FROM_DEVICE);
+ if (!mt76_is_page_from_pp(t->ptr))
+ dma_unmap_single(dev->mt76.dma_dev, t->dma_addr,
+ wed->wlan.rx_size, DMA_FROM_DEVICE);
mt76_put_page_pool_buf(t->ptr, false);
t->ptr = NULL;
--
2.39.0
next prev parent reply other threads:[~2023-01-17 13:53 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-17 13:53 [PATCH v2 0/4] mt76: switch to page_pool allocator Lorenzo Bianconi
2023-01-17 13:53 ` [PATCH v2 1/4] wifi: mt76: mt7915: fix memory leak in mt7915_mmio_wed_init_rx_buf Lorenzo Bianconi
2023-01-17 13:53 ` [PATCH v2 2/4] wifi: mt76: switch to page_pool allocator Lorenzo Bianconi
2023-01-17 13:53 ` Lorenzo Bianconi [this message]
2023-01-17 13:53 ` [PATCH v2 4/4] wifi: mt76: enable page_pool stats Lorenzo Bianconi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=68081e02cbe2afa2d35c8aa93194f0adddbd0f05.1673963374.git.lorenzo@kernel.org \
--to=lorenzo@kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=lorenzo.bianconi@redhat.com \
--cc=nbd@nbd.name \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.