From 76401f5e2e052bb1b47b6e047d51e1b9aa8dfc1a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 9 Sep 2025 15:06:04 +0200 Subject: [PATCH] mt76: update RRO patches to the latest version Fix endian issues Signed-off-by: Felix Fietkau --- dma.c | 12 +++++------ dma.h | 10 ++++----- mt7996/init.c | 8 +++++--- mt7996/mac.c | 52 +++++++++++++++++++++++++++++++++-------------- mt7996/main.c | 2 +- mt7996/mt7996.h | 54 ++++++++++++++++++------------------------------- 6 files changed, 74 insertions(+), 64 deletions(-) diff --git a/dma.c b/dma.c index 40501d39..5dc093b2 100644 --- a/dma.c +++ b/dma.c @@ -205,7 +205,7 @@ mt76_dma_queue_magic_cnt_init(struct mt76_dev *dev, struct mt76_queue *q) } } else if (mt76_queue_is_wed_rro_rxdmad_c(q)) { struct mt76_rro_rxdmad_c *dmad = (void *)q->desc; - u32 data3 = FIELD_PREP(RRO_DATA3_MAGIC_CNT_MASK, + u32 data3 = FIELD_PREP(RRO_RXDMAD_DATA3_MAGIC_CNT_MASK, MT_DMA_MAGIC_CNT - 1); int i; @@ -480,7 +480,7 @@ mt76_dma_get_rxdmad_c_buf(struct mt76_dev *dev, struct mt76_queue *q, u8 ind_reason; void *buf; - rx_token_id = FIELD_GET(RRO_DATA2_RX_TOKEN_ID_MASK, data2); + 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); @@ -491,12 +491,12 @@ mt76_dma_get_rxdmad_c_buf(struct mt76_dev *dev, struct mt76_queue *q, page_pool_get_dma_dir(q->page_pool)); if (len) - *len = FIELD_GET(RRO_DATA1_SDL0_MASK, data1); + *len = FIELD_GET(RRO_RXDMAD_DATA1_SDL0_MASK, data1); if (more) - *more = !FIELD_GET(RRO_DATA1_LS_MASK, data1); + *more = !FIELD_GET(RRO_RXDMAD_DATA1_LS_MASK, data1); buf = t->ptr; - ind_reason = FIELD_GET(RRO_DATA2_IND_REASON_MASK, data2); + 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); @@ -600,7 +600,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush, goto done; dmad = q->entry[idx].buf; - magic_cnt = FIELD_GET(RRO_DATA3_MAGIC_CNT_MASK, + magic_cnt = FIELD_GET(RRO_RXDMAD_DATA3_MAGIC_CNT_MASK, le32_to_cpu(dmad->data3)); if (magic_cnt != q->magic_cnt) return NULL; diff --git a/dma.h b/dma.h index 08373f14..17a80e17 100644 --- a/dma.h +++ b/dma.h @@ -59,13 +59,13 @@ struct mt76_wed_rro_desc { } __packed __aligned(4); /* data1 */ -#define RRO_DATA1_LS_MASK BIT(30) -#define RRO_DATA1_SDL0_MASK GENMASK(29, 16) +#define RRO_RXDMAD_DATA1_LS_MASK BIT(30) +#define RRO_RXDMAD_DATA1_SDL0_MASK GENMASK(29, 16) /* data2 */ -#define RRO_DATA2_RX_TOKEN_ID_MASK GENMASK(31, 16) -#define RRO_DATA2_IND_REASON_MASK GENMASK(15, 12) +#define RRO_RXDMAD_DATA2_RX_TOKEN_ID_MASK GENMASK(31, 16) +#define RRO_RXDMAD_DATA2_IND_REASON_MASK GENMASK(15, 12) /* data3 */ -#define RRO_DATA3_MAGIC_CNT_MASK GENMASK(31, 28) +#define RRO_RXDMAD_DATA3_MAGIC_CNT_MASK GENMASK(31, 28) struct mt76_rro_rxdmad_c { __le32 data0; __le32 data1; diff --git a/mt7996/init.c b/mt7996/init.c index e6ad2315..007f16ad 100644 --- a/mt7996/init.c +++ b/mt7996/init.c @@ -891,6 +891,7 @@ void mt7996_rro_hw_init(struct mt7996_dev *dev) static int mt7996_wed_rro_init(struct mt7996_dev *dev) { + u32 val = FIELD_PREP(WED_RRO_ADDR_SIGNATURE_MASK, 0xff); struct mt7996_wed_rro_addr *addr; void *ptr; int i; @@ -927,7 +928,7 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev) addr = dev->wed_rro.addr_elem[i].ptr; for (j = 0; j < MT7996_RRO_WINDOW_MAX_SIZE; j++) { - addr->signature = 0xff; + addr->data = cpu_to_le32(val); addr++; } @@ -986,7 +987,7 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev) dev->wed_rro.session.ptr = ptr; addr = dev->wed_rro.session.ptr; for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) { - addr->signature = 0xff; + addr->data = cpu_to_le32(val); addr++; } @@ -1045,6 +1046,7 @@ static void mt7996_wed_rro_free(struct mt7996_dev *dev) static void mt7996_wed_rro_work(struct work_struct *work) { + u32 val = FIELD_PREP(WED_RRO_ADDR_SIGNATURE_MASK, 0xff); struct mt7996_dev *dev; LIST_HEAD(list); @@ -1081,7 +1083,7 @@ static void mt7996_wed_rro_work(struct work_struct *work) MT7996_RRO_WINDOW_MAX_LEN; reset: elem = ptr + elem_id * sizeof(*elem); - elem->signature = 0xff; + elem->data |= cpu_to_le32(val); } mt7996_mcu_wed_rro_reset_sessions(dev, e->id); out: diff --git a/mt7996/mac.c b/mt7996/mac.c index 8ab408d2..55721ef9 100644 --- a/mt7996/mac.c +++ b/mt7996/mac.c @@ -1780,7 +1780,7 @@ int mt7996_rro_msdu_page_add(struct mt76_dev *mdev, struct mt76_queue *q, struct mt7996_msdu_page *p; u32 hash; - pinfo->owner = 1; + pinfo->data |= cpu_to_le32(FIELD_PREP(MSDU_PAGE_INFO_OWNER_MASK, 1)); p = mt7996_msdu_page_get(dev); if (!p) return -ENOMEM; @@ -1834,24 +1834,35 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data) struct mt7996_rro_hif *rxd; int j, len, qid, data_len; struct mt76_txwi_cache *t; + dma_addr_t dma_addr = 0; + u16 rx_token_id, count; struct mt76_queue *q; - dma_addr_t dma_addr; struct sk_buff *skb; - u32 info = 0; + u32 info = 0, data; + u8 signature; void *buf; + bool ls; seq_num = FIELD_GET(MT996_RRO_SN_MASK, cmd->start_sn + i); e = mt7996_rro_addr_elem_get(dev, cmd->se_id, seq_num); - if (e->signature != (seq_num / MT7996_RRO_WINDOW_MAX_LEN)) { - e->signature = 0xff; + data = le32_to_cpu(e->data); + signature = FIELD_GET(WED_RRO_ADDR_SIGNATURE_MASK, data); + if (signature != (seq_num / MT7996_RRO_WINDOW_MAX_LEN)) { + u32 val = FIELD_PREP(WED_RRO_ADDR_SIGNATURE_MASK, + 0xff); + + e->data |= cpu_to_le32(val); goto update_ack_seq_num; } - dma_addr = e->head_high; +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT + dma_addr = FIELD_GET(WED_RRO_ADDR_HEAD_HIGH_MASK, data); dma_addr <<= 32; - dma_addr |= e->head_low; +#endif + dma_addr |= le32_to_cpu(e->head_low); - for (j = 0; j < e->count; j++) { + count = FIELD_GET(WED_RRO_ADDR_COUNT_MASK, data); + for (j = 0; j < count; j++) { if (!p) { p = mt7996_rro_msdu_page_get(dev, dma_addr); if (!p) @@ -1864,9 +1875,12 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data) } rxd = &pinfo->rxd[j % MT7996_MAX_HIF_RXD_IN_PG]; - len = rxd->sdl; + len = FIELD_GET(RRO_HIF_DATA1_SDL_MASK, + le32_to_cpu(rxd->data1)); - t = mt76_rx_token_release(mdev, rxd->rx_token_id); + rx_token_id = FIELD_GET(RRO_HIF_DATA4_RX_TOKEN_ID_MASK, + le32_to_cpu(rxd->data4)); + t = mt76_rx_token_release(mdev, rx_token_id); if (!t) goto next_page; @@ -1895,17 +1909,19 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data) goto next_page; } + ls = FIELD_GET(RRO_HIF_DATA1_LS_MASK, + le32_to_cpu(rxd->data1)); if (q->rx_head) { /* TODO: Take into account non-linear skb. */ mt76_put_page_pool_buf(buf, false); - if (rxd->ls) { + if (ls) { dev_kfree_skb(q->rx_head); q->rx_head = NULL; } goto next_page; } - if (rxd->ls && !mt7996_rx_check(mdev, buf, len)) + if (ls && !mt7996_rx_check(mdev, buf, len)) goto next_page; skb = build_skb(buf, q->buf_size); @@ -1921,7 +1937,7 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data) goto next_page; } - if (!rxd->ls) { + if (!ls) { q->rx_head = skb; goto next_page; } @@ -1933,9 +1949,15 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data) mt7996_queue_rx_skb(mdev, qid, skb, &info); next_page: if ((j + 1) % MT7996_MAX_HIF_RXD_IN_PG == 0) { - dma_addr = pinfo->next_pg_high; +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT + dma_addr = + FIELD_GET(MSDU_PAGE_INFO_PG_HIGH_MASK, + le32_to_cpu(pinfo->data)); dma_addr <<= 32; - dma_addr |= pinfo->next_pg_low; + dma_addr |= le32_to_cpu(pinfo->pg_low); +#else + dma_addr = le32_to_cpu(pinfo->pg_low); +#endif mt7996_msdu_page_put_to_cache(dev, p); p = NULL; } diff --git a/mt7996/main.c b/mt7996/main.c index 96607541..a8f05cad 100644 --- a/mt7996/main.c +++ b/mt7996/main.c @@ -2170,7 +2170,7 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw, if (dev->hif2 && ((is_mt7996(&dev->mt76) && msta_link->wcid.phy_idx == MT_BAND2) || (is_mt7992(&dev->mt76) && msta_link->wcid.phy_idx == MT_BAND1))) - wed = &dev->mt76.mmio.wed_hif2; + wed = &dev->mt76.mmio.wed_hif2; if (!mtk_wed_device_active(wed)) return -ENODEV; diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h index 606d26a7..be26e04b 100644 --- a/mt7996/mt7996.h +++ b/mt7996/mt7996.h @@ -287,13 +287,12 @@ struct mt7996_hif { enum pcie_link_width width; }; +#define WED_RRO_ADDR_SIGNATURE_MASK GENMASK(31, 24) +#define WED_RRO_ADDR_COUNT_MASK GENMASK(14, 4) +#define WED_RRO_ADDR_HEAD_HIGH_MASK GENMASK(3, 0) struct mt7996_wed_rro_addr { - u32 head_low; - u32 head_high : 4; - u32 count: 11; - u32 oor: 1; - u32 rsv : 8; - u32 signature : 8; + __le32 head_low; + __le32 data; }; struct mt7996_wed_rro_session_id { @@ -309,39 +308,26 @@ struct mt7996_msdu_page { void *buf; }; +/* data1 */ +#define RRO_HIF_DATA1_LS_MASK BIT(30) +#define RRO_HIF_DATA1_SDL_MASK GENMASK(29, 16) +/* data4 */ +#define RRO_HIF_DATA4_RX_TOKEN_ID_MASK GENMASK(15, 0) struct mt7996_rro_hif { - u32 rx_blk_base_low; - u32 rx_blk_base_high : 4; - u32 eth_hdr_ofst : 7; - u32 rsv : 1; - u32 ring_no : 2; - u32 dst_sel : 2; - u32 sdl : 14; - u32 ls : 1; - u32 rsv2 : 1; - u32 pn_31_0; - u32 pn_47_32 : 16; - u32 cs_status : 4; - u32 cs_type : 4; - u32 c : 1; - u32 f : 1; - u32 un : 1; - u32 rsv3 : 1; - u32 is_fc_data : 1; - u32 uc : 1; - u32 mc : 1; - u32 bc : 1; - u16 rx_token_id; - u16 rsv4; - u32 rsv5; + __le32 data0; + __le32 data1; + __le32 data2; + __le32 data3; + __le32 data4; + __le32 data5; }; +#define MSDU_PAGE_INFO_OWNER_MASK BIT(31) +#define MSDU_PAGE_INFO_PG_HIGH_MASK GENMASK(3, 0) struct mt7996_msdu_page_info { struct mt7996_rro_hif rxd[MT7996_MAX_HIF_RXD_IN_PG]; - u32 next_pg_low; - u32 next_pg_high : 4; - u32 rsv : 27; - u32 owner : 1; + __le32 pg_low; + __le32 data; }; #define MT7996_MAX_RRO_RRS_RING 4