blob: 0f3c078224d730f8ac2a153ef7fdc3156b241bea [file] [log] [blame]
developer67bb1212024-02-04 16:58:38 +08001From 52dd48547a15ef9060f3f594660c846268b763e3 Mon Sep 17 00:00:00 2001
developer5f4e6c32023-12-20 06:12:53 +08002From: "sujuan.chen" <sujuan.chen@mediatek.com>
3Date: Thu, 12 Oct 2023 10:04:54 +0800
developer67bb1212024-02-04 16:58:38 +08004Subject: [PATCH 2012/2032] mtk: wifi: mt76: mt7996: wed: add SER0.5 support w/
developer5f4e6c32023-12-20 06:12:53 +08005 wed3.0
6
7Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
8---
developer67bb1212024-02-04 16:58:38 +08009 dma.c | 9 ++--
10 dma.h | 4 +-
developer5f4e6c32023-12-20 06:12:53 +080011 mt76.h | 14 ++++--
12 mt792x_dma.c | 6 +--
13 mt7996/dma.c | 20 ++++++--
14 mt7996/init.c | 127 +++++++++++++++++++++++++++++++-----------------
15 mt7996/mac.c | 25 ++++++++++
16 mt7996/mt7996.h | 1 +
developer67bb1212024-02-04 16:58:38 +080017 wed.c | 4 +-
18 9 files changed, 146 insertions(+), 64 deletions(-)
developer5f4e6c32023-12-20 06:12:53 +080019
20diff --git a/dma.c b/dma.c
developer67bb1212024-02-04 16:58:38 +080021index 6a30adcc..a5225db5 100644
developer5f4e6c32023-12-20 06:12:53 +080022--- a/dma.c
23+++ b/dma.c
developer67bb1212024-02-04 16:58:38 +080024@@ -218,9 +218,9 @@ void __mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
25 mt76_dma_sync_idx(dev, q);
developer5f4e6c32023-12-20 06:12:53 +080026 }
27
developer67bb1212024-02-04 16:58:38 +080028-void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
29+void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
developer5f4e6c32023-12-20 06:12:53 +080030 {
31- __mt76_dma_queue_reset(dev, q, true);
32+ __mt76_dma_queue_reset(dev, q, reset);
33 }
34
35 static int
developer67bb1212024-02-04 16:58:38 +080036@@ -540,7 +540,8 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
developer5f4e6c32023-12-20 06:12:53 +080037 if (!q->queued)
38 return NULL;
39
40- if (mt76_queue_is_wed_rro_data(q))
41+ if (mt76_queue_is_wed_rro_data(q) ||
42+ mt76_queue_is_wed_rro_msdu_pg(q))
43 return NULL;
44
45 if (!mt76_queue_is_wed_rro_ind(q)) {
developer67bb1212024-02-04 16:58:38 +080046@@ -791,7 +792,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
developer5f4e6c32023-12-20 06:12:53 +080047 return 0;
48 }
49
50- mt76_dma_queue_reset(dev, q);
51+ mt76_dma_queue_reset(dev, q, true);
52
53 return 0;
54 }
55diff --git a/dma.h b/dma.h
developer67bb1212024-02-04 16:58:38 +080056index 1de5a2b2..3a8c2e55 100644
developer5f4e6c32023-12-20 06:12:53 +080057--- a/dma.h
58+++ b/dma.h
developer67bb1212024-02-04 16:58:38 +080059@@ -83,12 +83,12 @@ int mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
60 bool allow_direct);
61 void __mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
62 bool reset_idx);
63-void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q);
64+void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q, bool reset);
65
developer5f4e6c32023-12-20 06:12:53 +080066 static inline void
67 mt76_dma_reset_tx_queue(struct mt76_dev *dev, struct mt76_queue *q)
68 {
69- dev->queue_ops->reset_q(dev, q);
70+ dev->queue_ops->reset_q(dev, q, true);
71 if (mtk_wed_device_active(&dev->mmio.wed))
developer67bb1212024-02-04 16:58:38 +080072 mt76_wed_dma_setup(dev, q, true);
developer5f4e6c32023-12-20 06:12:53 +080073 }
74diff --git a/mt76.h b/mt76.h
developer67bb1212024-02-04 16:58:38 +080075index 1080384b..fbf66407 100644
developer5f4e6c32023-12-20 06:12:53 +080076--- a/mt76.h
77+++ b/mt76.h
developer67bb1212024-02-04 16:58:38 +080078@@ -296,7 +296,7 @@ struct mt76_queue_ops {
developer5f4e6c32023-12-20 06:12:53 +080079
80 void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
81
82- void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q);
developer67bb1212024-02-04 16:58:38 +080083+ void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q, bool reset);
developer5f4e6c32023-12-20 06:12:53 +080084 };
85
86 enum mt76_phy_type {
developer67bb1212024-02-04 16:58:38 +080087@@ -1731,8 +1731,13 @@ static inline bool mt76_queue_is_wed_rro_ind(struct mt76_queue *q)
developer5f4e6c32023-12-20 06:12:53 +080088 static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q)
89 {
90 return mt76_queue_is_wed_rro(q) &&
91- (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA ||
92- FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG);
93+ (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA);
94+}
95+
96+static inline bool mt76_queue_is_wed_rro_msdu_pg(struct mt76_queue *q)
97+{
98+ return mt76_queue_is_wed_rro(q) &&
99+ (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG);
100 }
101
102 static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
developer67bb1212024-02-04 16:58:38 +0800103@@ -1741,7 +1746,8 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
developer5f4e6c32023-12-20 06:12:53 +0800104 return false;
105
106 return FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX ||
107- mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q);
108+ mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q) ||
109+ mt76_queue_is_wed_rro_msdu_pg(q);
110
111 }
112
113diff --git a/mt792x_dma.c b/mt792x_dma.c
developer67bb1212024-02-04 16:58:38 +0800114index 5cc2d59b..c224bcc8 100644
developer5f4e6c32023-12-20 06:12:53 +0800115--- a/mt792x_dma.c
116+++ b/mt792x_dma.c
developer67bb1212024-02-04 16:58:38 +0800117@@ -181,13 +181,13 @@ mt792x_dma_reset(struct mt792x_dev *dev, bool force)
developer5f4e6c32023-12-20 06:12:53 +0800118
119 /* reset hw queues */
120 for (i = 0; i < __MT_TXQ_MAX; i++)
121- mt76_queue_reset(dev, dev->mphy.q_tx[i]);
122+ mt76_queue_reset(dev, dev->mphy.q_tx[i], true);
123
124 for (i = 0; i < __MT_MCUQ_MAX; i++)
125- mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
126+ mt76_queue_reset(dev, dev->mt76.q_mcu[i], true);
127
128 mt76_for_each_q_rx(&dev->mt76, i)
129- mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
130+ mt76_queue_reset(dev, &dev->mt76.q_rx[i], true);
131
132 mt76_tx_status_check(&dev->mt76, true);
133
134diff --git a/mt7996/dma.c b/mt7996/dma.c
developer67bb1212024-02-04 16:58:38 +0800135index 5d85e9ea..d9e1b17f 100644
developer5f4e6c32023-12-20 06:12:53 +0800136--- a/mt7996/dma.c
137+++ b/mt7996/dma.c
developer67bb1212024-02-04 16:58:38 +0800138@@ -711,21 +711,31 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
developer5f4e6c32023-12-20 06:12:53 +0800139 }
140
141 for (i = 0; i < __MT_MCUQ_MAX; i++)
142- mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
143+ mt76_queue_reset(dev, dev->mt76.q_mcu[i], true);
144
145 mt76_for_each_q_rx(&dev->mt76, i) {
146- if (mtk_wed_device_active(&dev->mt76.mmio.wed))
147+ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
148 if (mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]) ||
149- mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i]))
150+ mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i])) {
151+ if (force && mt76_queue_is_wed_rro_data(&dev->mt76.q_rx[i]))
152+ mt76_queue_reset(dev, &dev->mt76.q_rx[i], false);
153 continue;
154+ }
155+ }
156
157- mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
158+ mt76_queue_reset(dev, &dev->mt76.q_rx[i], true);
159 }
160
161 mt76_tx_status_check(&dev->mt76, true);
162
163- mt76_for_each_q_rx(&dev->mt76, i)
164+ mt76_for_each_q_rx(&dev->mt76, i) {
165+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) && force &&
166+ (mt76_queue_is_wed_rro_ind(&dev->mt76.q_rx[i]) ||
167+ mt76_queue_is_wed_rro_msdu_pg(&dev->mt76.q_rx[i])))
168+ continue;
169+
170 mt76_queue_rx_reset(dev, i);
171+ }
172
173 mt7996_dma_enable(dev, !force);
174 }
175diff --git a/mt7996/init.c b/mt7996/init.c
developer67bb1212024-02-04 16:58:38 +0800176index b902bcc5..a9720120 100644
developer5f4e6c32023-12-20 06:12:53 +0800177--- a/mt7996/init.c
178+++ b/mt7996/init.c
developer07b5baf2024-01-10 04:38:47 +0800179@@ -724,11 +724,91 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
developer5f4e6c32023-12-20 06:12:53 +0800180 msleep(20);
181 }
182
183-static int mt7996_wed_rro_init(struct mt7996_dev *dev)
184+void mt7996_rro_hw_init(struct mt7996_dev *dev)
185 {
186 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
187 struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
188 u32 reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;
189+ int i;
190+
191+ if (!dev->has_rro)
192+ return;
193+
194+ if (is_mt7992(&dev->mt76)) {
195+ /* set emul 3.0 function */
196+ mt76_wr(dev, MT_RRO_3_0_EMU_CONF,
197+ MT_RRO_3_0_EMU_CONF_EN_MASK);
198+
199+ mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE0,
200+ dev->wed_rro.addr_elem[0].phy_addr);
201+ } else {
202+ /* TODO: remove line after WM has set */
203+ mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
204+
205+ /* setup BA bitmap cache address */
206+ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
207+ dev->wed_rro.ba_bitmap[0].phy_addr);
208+ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
209+ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
210+ dev->wed_rro.ba_bitmap[1].phy_addr);
211+ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
212+
213+ /* setup Address element address */
214+ for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
215+ mt76_wr(dev, reg, dev->wed_rro.addr_elem[i].phy_addr >> 4);
216+ reg += 4;
217+ }
218+
219+ /* setup Address element address - separate address segment mode */
220+ mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
221+ MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
222+ }
223+ wed->wlan.ind_cmd.win_size = ffs(MT7996_RRO_WINDOW_MAX_LEN) - 6;
224+ if (is_mt7996(&dev->mt76))
225+ wed->wlan.ind_cmd.particular_sid = MT7996_RRO_MAX_SESSION;
226+ else
227+ wed->wlan.ind_cmd.particular_sid = 1;
228+ wed->wlan.ind_cmd.particular_se_phys = dev->wed_rro.session.phy_addr;
229+ wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_LEN;
230+ wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
231+
232+ mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
233+ mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
234+ MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
235+
236+ /* particular session configure */
237+ /* use max session idx + 1 as particular session id */
238+ mt76_wr(dev, MT_RRO_PARTICULAR_CFG0, dev->wed_rro.session.phy_addr);
239+
240+ if (is_mt7992(&dev->mt76)) {
241+ reg = MT_RRO_MSDU_PG_SEG_ADDR0;
242+
243+ mt76_set(dev, MT_RRO_3_1_GLOBAL_CONFIG,
244+ MT_RRO_3_1_GLOBAL_CONFIG_INTERLEAVE_EN);
245+
246+ /* setup Msdu page address */
247+ for (i = 0; i < MT7996_RRO_MSDU_PG_CR_CNT; i++) {
248+ mt76_wr(dev, reg, dev->wed_rro.msdu_pg[i].phy_addr >> 4);
249+ reg += 4;
250+ }
251+ mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
252+ MT_RRO_PARTICULAR_CONFG_EN |
253+ FIELD_PREP(MT_RRO_PARTICULAR_SID, 1));
254+ } else {
255+ mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
256+ MT_RRO_PARTICULAR_CONFG_EN |
257+ FIELD_PREP(MT_RRO_PARTICULAR_SID, MT7996_RRO_MAX_SESSION));
258+ }
259+ /* interrupt enable */
260+ mt76_wr(dev, MT_RRO_HOST_INT_ENA,
261+ MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
262+#endif
263+}
264+
265+static int mt7996_wed_rro_init(struct mt7996_dev *dev)
266+{
267+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
268+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
269 struct mt7996_wed_rro_addr *addr;
270 void *ptr;
271 int i;
developer07b5baf2024-01-10 04:38:47 +0800272@@ -788,50 +868,9 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
developer5f4e6c32023-12-20 06:12:53 +0800273 addr++;
274 }
275
276- /* rro hw init */
277- /* TODO: remove line after WM has set */
278- mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
279-
280- /* setup BA bitmap cache address */
281- mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
282- dev->wed_rro.ba_bitmap[0].phy_addr);
283- mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
284- mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
285- dev->wed_rro.ba_bitmap[1].phy_addr);
286- mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
287-
288- /* setup Address element address */
289- for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
290- mt76_wr(dev, reg, dev->wed_rro.addr_elem[i].phy_addr >> 4);
291- reg += 4;
292- }
293-
294- /* setup Address element address - separate address segment mode */
295- mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
296- MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
297-
298- wed->wlan.ind_cmd.win_size = ffs(MT7996_RRO_WINDOW_MAX_LEN) - 6;
299- wed->wlan.ind_cmd.particular_sid = MT7996_RRO_MAX_SESSION;
300- wed->wlan.ind_cmd.particular_se_phys = dev->wed_rro.session.phy_addr;
301- wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_LEN;
302- wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
303-
304- mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
305- mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
306- MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
307-
308- /* particular session configure */
309- /* use max session idx + 1 as particular session id */
310- mt76_wr(dev, MT_RRO_PARTICULAR_CFG0, dev->wed_rro.session.phy_addr);
311- mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
312- MT_RRO_PARTICULAR_CONFG_EN |
313- FIELD_PREP(MT_RRO_PARTICULAR_SID, MT7996_RRO_MAX_SESSION));
314-
315- /* interrupt enable */
316- mt76_wr(dev, MT_RRO_HOST_INT_ENA,
317- MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
318-
319 /* rro ind cmd queue init */
320+ mt7996_rro_hw_init(dev);
321+
322 return mt7996_dma_rro_init(dev);
323 #else
324 return 0;
325diff --git a/mt7996/mac.c b/mt7996/mac.c
developer67bb1212024-02-04 16:58:38 +0800326index 339c92bb..53049672 100644
developer5f4e6c32023-12-20 06:12:53 +0800327--- a/mt7996/mac.c
328+++ b/mt7996/mac.c
developer67bb1212024-02-04 16:58:38 +0800329@@ -1756,6 +1756,31 @@ mt7996_mac_restart(struct mt7996_dev *dev)
developer5f4e6c32023-12-20 06:12:53 +0800330 if (ret)
331 goto out;
332
333+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->has_rro) {
334+ u32 wed_irq_mask = dev->mt76.mmio.irqmask |
335+ MT_INT_RRO_RX_DONE |
336+ MT_INT_TX_DONE_BAND2;
337+
338+ mt7996_rro_hw_init(dev);
339+ mt76_for_each_q_rx(&dev->mt76, i) {
340+ if (mt76_queue_is_wed_rro_ind(&dev->mt76.q_rx[i]) ||
341+ mt76_queue_is_wed_rro_msdu_pg(&dev->mt76.q_rx[i]))
342+ mt76_queue_rx_reset(dev, i);
343+ }
344+
345+ mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
346+ mtk_wed_device_start_hwrro(&dev->mt76.mmio.wed, wed_irq_mask, false);
347+ mt7996_irq_enable(dev, wed_irq_mask);
348+ mt7996_irq_disable(dev, 0);
349+ }
350+
351+ if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) {
352+ mt76_wr(dev, MT_INT_PCIE1_MASK_CSR,
353+ MT_INT_TX_RX_DONE_EXT);
354+ mtk_wed_device_start(&dev->mt76.mmio.wed_hif2,
355+ MT_INT_TX_RX_DONE_EXT);
356+ }
357+
358 /* set the necessary init items */
359 ret = mt7996_mcu_set_eeprom(dev);
360 if (ret)
361diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developer07b5baf2024-01-10 04:38:47 +0800362index b1abe42b..84b34ea9 100644
developer5f4e6c32023-12-20 06:12:53 +0800363--- a/mt7996/mt7996.h
364+++ b/mt7996/mt7996.h
developer07b5baf2024-01-10 04:38:47 +0800365@@ -713,6 +713,7 @@ extern const struct mt76_testmode_ops mt7996_testmode_ops;
developer5f4e6c32023-12-20 06:12:53 +0800366 struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
367 void __iomem *mem_base, u32 device_id);
368 void mt7996_wfsys_reset(struct mt7996_dev *dev);
369+void mt7996_rro_hw_init(struct mt7996_dev *dev);
370 irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
371 u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
372 int mt7996_register_device(struct mt7996_dev *dev);
developer67bb1212024-02-04 16:58:38 +0800373diff --git a/wed.c b/wed.c
374index 1c6d53c8..61a6badf 100644
375--- a/wed.c
376+++ b/wed.c
377@@ -155,7 +155,7 @@ int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
378 case MT76_WED_Q_TXFREE:
379 /* WED txfree queue needs ring to be initialized before setup */
380 q->flags = 0;
381- mt76_dma_queue_reset(dev, q);
382+ mt76_dma_queue_reset(dev, q, true);
383 mt76_dma_rx_fill(dev, q, false);
384
385 ret = mtk_wed_device_txfree_ring_setup(q->wed, q->regs);
386@@ -184,7 +184,7 @@ int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
387 break;
388 case MT76_WED_RRO_Q_IND:
389 q->flags &= ~MT_QFLAG_WED;
390- mt76_dma_queue_reset(dev, q);
391+ mt76_dma_queue_reset(dev, q, true);
392 mt76_dma_rx_fill(dev, q, false);
393 mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
394 break;
developer5f4e6c32023-12-20 06:12:53 +0800395--
3962.18.0
397