[PATCH v5 14/21] wifi: mt76: mt792x: factor out common DMA queue allocation

Sean Wang
2026-04-25T19:51:36Z

The mt792x PCIe DMA setup uses the same standard queue allocation
sequence for data, MCU, firmware download and RX rings.

Factor this part out into a small common helper so later chip support
can reuse the existing flow without duplicating the queue setup logic.

This keeps the common DMA skeleton in one place and makes follow-up
chip-specific DMA changes smaller and easier to review.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt792x.h | 19 +++++++
.../net/wireless/mediatek/mt76/mt792x_dma.c | 56 +++++++++++++++++++
2 files changed, 75 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h
index 09840483fe2a..59562567cc13 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x.h
@@ -206,6 +206,23 @@ struct mt792x_irq_map {
} rx;
};

+struct mt792x_dma_ring {
+ u8 qid;
+ u16 n_desc;
+ u32 ring_base;
+};
+
+struct mt792x_dma_layout {
+ struct mt792x_dma_ring tx_data0;
+ struct mt792x_dma_ring tx_mcu;
+ struct mt792x_dma_ring tx_fwdl;
+ struct mt792x_dma_ring rx_data;
+ struct mt792x_dma_ring rx_mcu;
+};
+
+#define mt792x_dma_ring(_qid, _n_desc, _ring_base) \
+ { .qid = (_qid), .n_desc = (_n_desc), .ring_base = (_ring_base) }
+
#define mt792x_init_reset(dev) ((dev)->hif_ops->init_reset(dev))
#define mt792x_dev_reset(dev) ((dev)->hif_ops->reset(dev))
#define mt792x_mcu_init(dev) ((dev)->hif_ops->mcu_init(dev))
@@ -421,6 +438,8 @@ void mt792x_sta_statistics(struct ieee80211_hw *hw,
void mt792x_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,
s16 coverage_class);
void mt792x_dma_cleanup(struct mt792x_dev *dev);
+int mt792x_dma_alloc_queues(struct mt792x_dev *dev,
+ const struct mt792x_dma_layout *layout);
int mt792x_dma_enable(struct mt792x_dev *dev);
int mt792x_wpdma_reset(struct mt792x_dev *dev, bool force);
int mt792x_wpdma_reinit_cond(struct mt792x_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
index 2835bf273154..c52d0c85913c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
@@ -87,6 +87,62 @@ void mt792x_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
}
EXPORT_SYMBOL_GPL(mt792x_rx_poll_complete);

+int mt792x_dma_alloc_queues(struct mt792x_dev *dev,
+ const struct mt792x_dma_layout *layout)
+{
+ int ret;
+
+ mt76_dma_attach(&dev->mt76);
+
+ ret = mt792x_dma_disable(dev, true);
+ if (ret)
+ return ret;
+
+ /* init tx queue */
+ ret = mt76_connac_init_tx_queues(dev->phy.mt76, layout->tx_data0.qid,
+ layout->tx_data0.n_desc,
+ layout->tx_data0.ring_base,
+ NULL, 0);
+ if (ret)
+ return ret;
+
+ mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4);
+
+ /* command to WM */
+ ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM,
+ layout->tx_mcu.qid,
+ layout->tx_mcu.n_desc,
+ layout->tx_mcu.ring_base);
+ if (ret)
+ return ret;
+
+ /* firmware download */
+ ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL,
+ layout->tx_fwdl.qid,
+ layout->tx_fwdl.n_desc,
+ layout->tx_fwdl.ring_base);
+ if (ret)
+ return ret;
+
+ /* rx event */
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
+ layout->rx_mcu.qid,
+ layout->rx_mcu.n_desc,
+ MT_RX_BUF_SIZE,
+ layout->rx_mcu.ring_base);
+ if (ret)
+ return ret;
+
+ /* rx data */
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
+ layout->rx_data.qid,
+ layout->rx_data.n_desc,
+ MT_RX_BUF_SIZE,
+ layout->rx_data.ring_base);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mt792x_dma_alloc_queues);
+
#define PREFETCH(base, depth) ((base) << 16 | (depth))
static void mt792x_dma_prefetch(struct mt792x_dev *dev)
{
--
2.43.0