mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 14:04:27 -04:00
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 <rex.lu@mediatek.com> Signed-off-by: Rex Lu <rex.lu@mediatek.com> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://patch.msgid.link/20250909-mt7996-rro-rework-v5-15-7d66f6eb7795@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
committed by
Felix Fietkau
parent
7b3c83dd87
commit
e50d4d710e
@@ -427,15 +427,61 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
|
|||||||
wake_up(&dev->tx_wait);
|
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_RXDMAD_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_RXDMAD_DATA1_SDL0_MASK, data1);
|
||||||
|
if (more)
|
||||||
|
*more = !FIELD_GET(RRO_RXDMAD_DATA1_LS_MASK, data1);
|
||||||
|
|
||||||
|
buf = t->ptr;
|
||||||
|
ind_reason = FIELD_GET(RRO_RXDMAD_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 *
|
static void *
|
||||||
mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
|
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_queue_entry *e = &q->entry[idx];
|
||||||
struct mt76_desc *desc = &q->desc[idx];
|
struct mt76_desc *desc = &q->desc[idx];
|
||||||
u32 ctrl, desc_info, buf1;
|
u32 ctrl, desc_info, buf1;
|
||||||
void *buf = e->buf;
|
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))
|
if (mt76_queue_is_wed_rro(q))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -516,7 +562,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
|
|||||||
q->tail = (q->tail + 1) % q->ndesc;
|
q->tail = (q->tail + 1) % q->ndesc;
|
||||||
q->queued--;
|
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
|
static int
|
||||||
@@ -885,10 +931,16 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
|
|||||||
if (!data)
|
if (!data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (PTR_ERR(data) == -EAGAIN) {
|
||||||
|
done++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (mt76_queue_is_wed_rro_ind(q) && dev->drv->rx_rro_ind_process)
|
if (mt76_queue_is_wed_rro_ind(q) && dev->drv->rx_rro_ind_process)
|
||||||
dev->drv->rx_rro_ind_process(dev, data);
|
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++;
|
done++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,21 @@ struct mt76_wed_rro_desc {
|
|||||||
__le32 buf1;
|
__le32 buf1;
|
||||||
} __packed __aligned(4);
|
} __packed __aligned(4);
|
||||||
|
|
||||||
|
/* data1 */
|
||||||
|
#define RRO_RXDMAD_DATA1_LS_MASK BIT(30)
|
||||||
|
#define RRO_RXDMAD_DATA1_SDL0_MASK GENMASK(29, 16)
|
||||||
|
/* data2 */
|
||||||
|
#define RRO_RXDMAD_DATA2_RX_TOKEN_ID_MASK GENMASK(31, 16)
|
||||||
|
#define RRO_RXDMAD_DATA2_IND_REASON_MASK GENMASK(15, 12)
|
||||||
|
/* data3 */
|
||||||
|
#define RRO_RXDMAD_DATA3_MAGIC_CNT_MASK GENMASK(31, 28)
|
||||||
|
struct mt76_rro_rxdmad_c {
|
||||||
|
__le32 data0;
|
||||||
|
__le32 data1;
|
||||||
|
__le32 data2;
|
||||||
|
__le32 data3;
|
||||||
|
};
|
||||||
|
|
||||||
enum mt76_qsel {
|
enum mt76_qsel {
|
||||||
MT_QSEL_MGMT,
|
MT_QSEL_MGMT,
|
||||||
MT_QSEL_HCCA,
|
MT_QSEL_HCCA,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#define MT_WED_RRO_Q_DATA(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_DATA, _n)
|
#define MT_WED_RRO_Q_DATA(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_DATA, _n)
|
||||||
#define MT_WED_RRO_Q_MSDU_PG(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n)
|
#define MT_WED_RRO_Q_MSDU_PG(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n)
|
||||||
#define MT_WED_RRO_Q_IND __MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0)
|
#define MT_WED_RRO_Q_IND __MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0)
|
||||||
|
#define MT_WED_RRO_Q_RXDMAD_C __MT_WED_RRO_Q(MT76_WED_RRO_Q_RXDMAD_C, 0)
|
||||||
|
|
||||||
struct mt76_dev;
|
struct mt76_dev;
|
||||||
struct mt76_phy;
|
struct mt76_phy;
|
||||||
@@ -71,6 +72,7 @@ enum mt76_wed_type {
|
|||||||
MT76_WED_RRO_Q_DATA,
|
MT76_WED_RRO_Q_DATA,
|
||||||
MT76_WED_RRO_Q_MSDU_PG,
|
MT76_WED_RRO_Q_MSDU_PG,
|
||||||
MT76_WED_RRO_Q_IND,
|
MT76_WED_RRO_Q_IND,
|
||||||
|
MT76_WED_RRO_Q_RXDMAD_C,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mt76_bus_ops {
|
struct mt76_bus_ops {
|
||||||
@@ -1794,6 +1796,12 @@ static inline bool mt76_queue_is_wed_rro_ind(struct mt76_queue *q)
|
|||||||
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_IND;
|
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_IND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool mt76_queue_is_wed_rro_rxdmad_c(struct mt76_queue *q)
|
||||||
|
{
|
||||||
|
return mt76_queue_is_wed_rro(q) &&
|
||||||
|
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_RXDMAD_C;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q)
|
static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q)
|
||||||
{
|
{
|
||||||
return mt76_queue_is_wed_rro(q) &&
|
return mt76_queue_is_wed_rro(q) &&
|
||||||
|
|||||||
Reference in New Issue
Block a user