drivers/net/wireless/mediatek/mt76/dma.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/mediatek/mt76/dma.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/mediatek/mt76/dma.c- Extension
.c- Size
- 27205 bytes
- Lines
- 1210
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/dma-mapping.hmt76.hdma.hmt76_connac.h
Detected Declarations
function Copyrightfunction mt76_alloc_rxwifunction __mt76_get_txwifunction __mt76_get_rxwifunction mt76_get_txwifunction mt76_get_rxwifunction mt76_put_txwifunction mt76_put_rxwifunction mt76_free_pending_txwifunction mt76_free_pending_rxwifunction mt76_dma_queue_magic_cnt_initfunction mt76_dma_sync_idxfunction mt76_dma_queue_resetfunction mt76_dma_add_rx_buffunction mt76_dma_add_buffunction mt76_dma_tx_cleanup_idxfunction mt76_dma_kick_queuefunction mt76_dma_tx_cleanupfunction mt76_dma_get_rxdmad_c_buffunction mt76_dma_get_buffunction mt76_dma_dequeuefunction mt76_dma_tx_queue_skb_rawfunction mt76_dma_tx_queue_skbfunction skb_walk_fragsfunction mt76_dma_rx_fill_buffunction mt76_dma_rx_fillfunction mt76_dma_alloc_queuefunction mt76_dma_rx_cleanupfunction mt76_dma_rx_resetfunction mt76_add_fragmentfunction mt76_dma_rx_processfunction mt76_dma_rx_pollfunction mt76_dma_rx_queue_initfunction mt76_dma_initfunction mt76_for_each_q_rxfunction mt76_dma_attachfunction mt76_dma_cleanupfunction mt76_for_each_q_rxexport mt76_get_rxwiexport mt76_put_txwiexport mt76_put_rxwiexport mt76_free_pending_rxwiexport mt76_dma_rx_pollexport mt76_dma_attachexport mt76_dma_cleanup
Annotated Snippet
if (rx_token < 0) {
mt76_put_rxwi(dev, txwi);
return -ENOMEM;
}
buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token);
ctrl |= MT_DMA_CTL_TO_HOST;
txwi->qid = q - dev->q_rx;
}
if (mt76_queue_is_wed_rro_msdu_pg(q) &&
dev->drv->rx_rro_add_msdu_page) {
if (dev->drv->rx_rro_add_msdu_page(dev, q, buf->addr, data))
return -ENOMEM;
}
if (q->flags & MT_QFLAG_WED_RRO_EN) {
info |= FIELD_PREP(MT_DMA_MAGIC_MASK, q->magic_cnt);
if ((q->head + 1) == q->ndesc)
q->magic_cnt = (q->magic_cnt + 1) % MT_DMA_MAGIC_CNT;
}
WRITE_ONCE(desc->buf0, cpu_to_le32(buf->addr));
WRITE_ONCE(desc->buf1, cpu_to_le32(buf1));
WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
WRITE_ONCE(desc->info, cpu_to_le32(info));
done:
entry->dma_addr[0] = buf->addr;
entry->dma_len[0] = buf->len;
entry->txwi = txwi;
entry->buf = data;
entry->wcid = 0xffff;
entry->skip_buf1 = true;
q->head = (q->head + 1) % q->ndesc;
q->queued++;
return idx;
}
static int
mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
struct mt76_queue_buf *buf, int nbufs, u32 info,
struct sk_buff *skb, void *txwi)
{
struct mt76_queue_entry *entry;
struct mt76_desc *desc;
int i, idx = -1;
u32 ctrl, next;
if (txwi) {
q->entry[q->head].txwi = DMA_DUMMY_DATA;
q->entry[q->head].skip_buf0 = true;
}
for (i = 0; i < nbufs; i += 2, buf += 2) {
u32 buf0 = buf[0].addr, buf1 = 0;
idx = q->head;
next = (q->head + 1) % q->ndesc;
desc = &q->desc[idx];
entry = &q->entry[idx];
if (buf[0].skip_unmap)
entry->skip_buf0 = true;
entry->skip_buf1 = i == nbufs - 1;
entry->dma_addr[0] = buf[0].addr;
entry->dma_len[0] = buf[0].len;
ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
info |= FIELD_PREP(MT_DMA_CTL_SDP0_H, buf[0].addr >> 32);
#endif
if (i < nbufs - 1) {
entry->dma_addr[1] = buf[1].addr;
entry->dma_len[1] = buf[1].len;
buf1 = buf[1].addr;
ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len);
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
info |= FIELD_PREP(MT_DMA_CTL_SDP1_H,
buf[1].addr >> 32);
#endif
if (buf[1].skip_unmap)
entry->skip_buf1 = true;
}
if (i == nbufs - 1)
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `mt76.h`, `dma.h`, `mt76_connac.h`.
- Detected declarations: `function Copyright`, `function mt76_alloc_rxwi`, `function __mt76_get_txwi`, `function __mt76_get_rxwi`, `function mt76_get_txwi`, `function mt76_get_rxwi`, `function mt76_put_txwi`, `function mt76_put_rxwi`, `function mt76_free_pending_txwi`, `function mt76_free_pending_rxwi`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.