]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mt76: Convert mt76_wed_rro_ind to LE
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 9 Sep 2025 10:46:37 +0000 (12:46 +0200)
committerFelix Fietkau <nbd@nbd.name>
Mon, 15 Sep 2025 07:47:42 +0000 (09:47 +0200)
Do not use bitmask in mt76_wed_rro_ind DMA descriptor in order to not
break endianness.
This patch is based on the following series:
https://lore.kernel.org/linux-wireless/20250909-mt7996-rro-rework-v5-0-7d66f6eb7795@kernel.org/T/#m8b488004d69036cd3672b9eeca8005a937ec0313

Fixes: 950d0abb5cd94 ("wifi: mt76: mt7996: add wed rx support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/301d5f2982ddb729c876fb65f9ac2443ce3f5ff1.1757414621.git.lorenzo@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/dma.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7996/mac.c

index 5dc093b21838ca22d733a186b9097bdba0cc5c55..1fa7de1d2c45e16598f7bec05bab3e1e9e0f6d46 100644 (file)
@@ -194,6 +194,8 @@ mt76_dma_queue_magic_cnt_init(struct mt76_dev *dev, struct mt76_queue *q)
        q->magic_cnt = 0;
        if (mt76_queue_is_wed_rro_ind(q)) {
                struct mt76_wed_rro_desc *rro_desc;
+               u32 data1 = FIELD_PREP(RRO_IND_DATA1_MAGIC_CNT_MASK,
+                                      MT_DMA_WED_IND_CMD_CNT - 1);
                int i;
 
                rro_desc = (struct mt76_wed_rro_desc *)q->desc;
@@ -201,7 +203,7 @@ mt76_dma_queue_magic_cnt_init(struct mt76_dev *dev, struct mt76_queue *q)
                        struct mt76_wed_rro_ind *cmd;
 
                        cmd = (struct mt76_wed_rro_ind *)&rro_desc[i];
-                       cmd->magic_cnt = MT_DMA_WED_IND_CMD_CNT - 1;
+                       cmd->data1 = cpu_to_le32(data1);
                }
        } else if (mt76_queue_is_wed_rro_rxdmad_c(q)) {
                struct mt76_rro_rxdmad_c *dmad = (void *)q->desc;
@@ -582,12 +584,15 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
 
        if (mt76_queue_is_wed_rro_ind(q)) {
                struct mt76_wed_rro_ind *cmd;
+               u8 magic_cnt;
 
                if (flush)
                        goto done;
 
                cmd = q->entry[idx].buf;
-               if (cmd->magic_cnt != q->magic_cnt)
+               magic_cnt = FIELD_GET(RRO_IND_DATA1_MAGIC_CNT_MASK,
+                                     le32_to_cpu(cmd->data1));
+               if (magic_cnt != q->magic_cnt)
                        return NULL;
 
                if (q->tail == q->ndesc - 1)
index b102b6d798b8d84a8e5ccb5f9ba510ca8940c142..edda01ff111703154fafae5201084c26f1b0c82c 100644 (file)
@@ -415,15 +415,16 @@ struct mt76_txq {
        bool aggr;
 };
 
+/* data0 */
+#define RRO_IND_DATA0_IND_REASON_MASK  GENMASK(31, 28)
+#define RRO_IND_DATA0_START_SEQ_MASK   GENMASK(27, 16)
+#define RRO_IND_DATA0_SEQ_ID_MASK      GENMASK(11, 0)
+/* data1 */
+#define RRO_IND_DATA1_MAGIC_CNT_MASK   GENMASK(31, 29)
+#define RRO_IND_DATA1_IND_COUNT_MASK   GENMASK(12, 0)
 struct mt76_wed_rro_ind {
-       u32 se_id       : 12;
-       u32 rsv         : 4;
-       u32 start_sn    : 12;
-       u32 ind_reason  : 4;
-       u32 ind_cnt     : 13;
-       u32 win_sz      : 3;
-       u32 rsv2        : 13;
-       u32 magic_cnt   : 3;
+       __le32 data0;
+       __le32 data1;
 };
 
 struct mt76_txwi_cache {
index f4a897e7935e5f44e5a9832eba9973b4fff771af..2183193b26a6fe828afac2a734a3be7e7ad5fe39 100644 (file)
@@ -1830,11 +1830,17 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data)
 {
        struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
        struct mt76_wed_rro_ind *cmd = (struct mt76_wed_rro_ind *)data;
+       u32 cmd_data0 = le32_to_cpu(cmd->data0);
+       u32 cmd_data1 = le32_to_cpu(cmd->data1);
+       u8 ind_reason = FIELD_GET(RRO_IND_DATA0_IND_REASON_MASK, cmd_data0);
+       u16 start_seq = FIELD_GET(RRO_IND_DATA0_START_SEQ_MASK, cmd_data0);
+       u16 seq_id = FIELD_GET(RRO_IND_DATA0_SEQ_ID_MASK, cmd_data0);
+       u16 ind_count = FIELD_GET(RRO_IND_DATA1_IND_COUNT_MASK, cmd_data1);
        struct mt7996_msdu_page_info *pinfo = NULL;
        struct mt7996_msdu_page *p = NULL;
        int i, seq_num = 0;
 
-       for (i = 0; i < cmd->ind_cnt; i++) {
+       for (i = 0; i < ind_count; i++) {
                struct mt7996_wed_rro_addr *e;
                struct mt76_rx_status *status;
                struct mt7996_rro_hif *rxd;
@@ -1849,8 +1855,8 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data)
                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);
+               seq_num = FIELD_GET(MT996_RRO_SN_MASK, start_seq + i);
+               e = mt7996_rro_addr_elem_get(dev, seq_id, seq_num);
                data = le32_to_cpu(e->data);
                signature = FIELD_GET(WED_RRO_ADDR_SIGNATURE_MASK, data);
                if (signature != (seq_num / MT7996_RRO_WINDOW_MAX_LEN)) {
@@ -1938,7 +1944,7 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data)
                        skb_mark_for_recycle(skb);
                        __skb_put(skb, len);
 
-                       if (cmd->ind_reason == 1 || cmd->ind_reason == 2) {
+                       if (ind_reason == 1 || ind_reason == 2) {
                                dev_kfree_skb(skb);
                                goto next_page;
                        }
@@ -1949,7 +1955,7 @@ void mt7996_rro_rx_process(struct mt76_dev *mdev, void *data)
                        }
 
                        status = (struct mt76_rx_status *)skb->cb;
-                       if (cmd->se_id != MT7996_RRO_MAX_SESSION)
+                       if (seq_id != MT7996_RRO_MAX_SESSION)
                                status->aggr = true;
 
                        mt7996_queue_rx_skb(mdev, qid, skb, &info);
@@ -1973,7 +1979,7 @@ update_ack_seq_num:
                if ((i + 1) % 4 == 0)
                        mt76_wr(dev, MT_RRO_ACK_SN_CTRL,
                                FIELD_PREP(MT_RRO_ACK_SN_CTRL_SESSION_MASK,
-                                          cmd->se_id) |
+                                          seq_id) |
                                FIELD_PREP(MT_RRO_ACK_SN_CTRL_SN_MASK,
                                           seq_num));
                if (p) {
@@ -1985,8 +1991,7 @@ update_ack_seq_num:
        /* Update ack_seq_num for remaining addr_elem */
        if (i % 4)
                mt76_wr(dev, MT_RRO_ACK_SN_CTRL,
-                       FIELD_PREP(MT_RRO_ACK_SN_CTRL_SESSION_MASK,
-                                  cmd->se_id) |
+                       FIELD_PREP(MT_RRO_ACK_SN_CTRL_SESSION_MASK, seq_id) |
                        FIELD_PREP(MT_RRO_ACK_SN_CTRL_SN_MASK, seq_num));
 }