wifi: mt76: Add mt76_dma_get_rxdmad_c_buf utility routione

Introduce mt76_dma_get_rxdmad_c_buf routine to process packets received
by HW-RRO v3.1 module.
This is a preliminary patch to introduce SW path for HW-RRO v3.1 module
available on MT7992 chipset.

Co-developed-by: Rex Lu <[email protected]>
Signed-off-by: Rex Lu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Lorenzo Bianconi
2025-09-04 19:09:11 +02:00
committed by Felix Fietkau
parent d82330a9d0
commit 0a32ae3cc2
3 changed files with 78 additions and 3 deletions
+55 -3
View File
@@ -427,15 +427,61 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
wake_up(&dev->tx_wait);
}
static void *
mt76_dma_get_rxdmad_c_buf(struct mt76_dev *dev, struct mt76_queue *q,
int idx, int *len, bool *more)
{
struct mt76_queue_entry *e = &q->entry[idx];
struct mt76_rro_rxdmad_c *dmad = e->buf;
u32 data1 = le32_to_cpu(dmad->data1);
u32 data2 = le32_to_cpu(dmad->data2);
struct mt76_txwi_cache *t;
u16 rx_token_id;
u8 ind_reason;
void *buf;
rx_token_id = FIELD_GET(RRO_DATA2_RX_TOKEN_ID_MASK, data2);
t = mt76_rx_token_release(dev, rx_token_id);
if (!t)
return ERR_PTR(-EAGAIN);
q = &dev->q_rx[t->qid];
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));
if (len)
*len = FIELD_GET(RRO_DATA1_SDL0_MASK, data1);
if (more)
*more = !FIELD_GET(RRO_DATA1_LS_MASK, data1);
buf = t->ptr;
ind_reason = FIELD_GET(RRO_DATA2_IND_REASON_MASK, data2);
if (ind_reason == MT_DMA_WED_IND_REASON_REPEAT ||
ind_reason == MT_DMA_WED_IND_REASON_OLDPKT) {
mt76_put_page_pool_buf(buf, false);
buf = ERR_PTR(-EAGAIN);
}
t->ptr = NULL;
t->dma_addr = 0;
mt76_put_rxwi(dev, t);
return buf;
}
static void *
mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
int *len, u32 *info, bool *more, bool *drop)
int *len, u32 *info, bool *more, bool *drop, bool flush)
{
struct mt76_queue_entry *e = &q->entry[idx];
struct mt76_desc *desc = &q->desc[idx];
u32 ctrl, desc_info, buf1;
void *buf = e->buf;
if (mt76_queue_is_wed_rro_rxdmad_c(q) && !flush)
buf = mt76_dma_get_rxdmad_c_buf(dev, q, idx, len, more);
if (mt76_queue_is_wed_rro(q))
goto done;
@@ -516,7 +562,7 @@ done:
q->tail = (q->tail + 1) % q->ndesc;
q->queued--;
return mt76_dma_get_buf(dev, q, idx, len, info, more, drop);
return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush);
}
static int
@@ -885,10 +931,16 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
if (!data)
break;
if (PTR_ERR(data) == -EAGAIN) {
done++;
continue;
}
if (mt76_queue_is_wed_rro_ind(q) && dev->drv->rx_rro_ind_process)
dev->drv->rx_rro_ind_process(dev, data);
if (mt76_queue_is_wed_rro(q)) {
if (mt76_queue_is_wed_rro(q) &&
!mt76_queue_is_wed_rro_rxdmad_c(q)) {
done++;
continue;
}