blob: 053a4dae3966f6f02172c5d1b4fd620fb6fdb206 [file] [log] [blame]
developer8fec8ae2022-08-15 15:01:09 -07001From 7c81104d65728fb1c0f156c46e3cfc5dec24b119 Mon Sep 17 00:00:00 2001
developer8cb3ac72022-07-04 10:55:14 +08002From: Sujuan Chen <sujuan.chen@mediatek.com>
3Date: Wed, 15 Jun 2022 14:38:54 +0800
4Subject: [PATCH 8/8] 9997-add-wed-rx-support-for-mt7896
5
6Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
7---
8 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 42 +-
9 arch/arm64/boot/dts/mediatek/mt7986b.dtsi | 42 +-
10 drivers/net/ethernet/mediatek/Makefile | 2 +-
developer144824b2022-11-25 21:27:43 +080011 drivers/net/ethernet/mediatek/mtk_wed.c | 639 ++++++++++++++++--
developera3f86ed2022-07-08 14:15:13 +080012 drivers/net/ethernet/mediatek/mtk_wed.h | 51 ++
13 drivers/net/ethernet/mediatek/mtk_wed_ccif.c | 133 ++++
developer8cb3ac72022-07-04 10:55:14 +080014 drivers/net/ethernet/mediatek/mtk_wed_ccif.h | 45 ++
15 .../net/ethernet/mediatek/mtk_wed_debugfs.c | 90 +++
developer8fec8ae2022-08-15 15:01:09 -070016 drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 586 ++++++++++++++++
developerfaaa5162022-10-24 14:12:16 +080017 drivers/net/ethernet/mediatek/mtk_wed_mcu.h | 96 +++
developere0cbe332022-09-10 17:36:02 +080018 drivers/net/ethernet/mediatek/mtk_wed_regs.h | 144 +++-
developer53bfd362022-09-29 12:02:18 +080019 drivers/net/ethernet/mediatek/mtk_wed_wo.c | 564 ++++++++++++++++
20 drivers/net/ethernet/mediatek/mtk_wed_wo.h | 324 +++++++++
developer144824b2022-11-25 21:27:43 +080021 include/linux/soc/mediatek/mtk_wed.h | 126 +++-
developer8fec8ae2022-08-15 15:01:09 -070022 14 files changed, 2796 insertions(+), 75 deletions(-)
developer8cb3ac72022-07-04 10:55:14 +080023 create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ccif.c
24 create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ccif.h
25 create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_mcu.c
26 create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_mcu.h
27 create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.c
28 create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.h
29
30diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
developer8fec8ae2022-08-15 15:01:09 -070031index 87d2b11a9..6abc06db8 100644
developer8cb3ac72022-07-04 10:55:14 +080032--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
33+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
34@@ -65,6 +65,12 @@
35 interrupt-parent = <&gic>;
36 interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
37 mediatek,wed_pcie = <&wed_pcie>;
38+ mediatek,ap2woccif = <&ap2woccif0>;
39+ mediatek,wocpu_ilm = <&wocpu0_ilm>;
40+ mediatek,wocpu_dlm = <&wocpu0_dlm>;
41+ mediatek,wocpu_boot = <&cpu_boot>;
42+ mediatek,wocpu_emi = <&wocpu0_emi>;
43+ mediatek,wocpu_data = <&wocpu_data>;
44 };
45
46 wed1: wed@15011000 {
47@@ -74,15 +80,26 @@
48 interrupt-parent = <&gic>;
49 interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
50 mediatek,wed_pcie = <&wed_pcie>;
51+ mediatek,ap2woccif = <&ap2woccif1>;
52+ mediatek,wocpu_ilm = <&wocpu1_ilm>;
53+ mediatek,wocpu_dlm = <&wocpu1_dlm>;
54+ mediatek,wocpu_boot = <&cpu_boot>;
55+ mediatek,wocpu_emi = <&wocpu1_emi>;
56+ mediatek,wocpu_data = <&wocpu_data>;
57 };
58
59- ap2woccif: ap2woccif@151A5000 {
60- compatible = "mediatek,ap2woccif";
61- reg = <0 0x151A5000 0 0x1000>,
62- <0 0x151AD000 0 0x1000>;
63+ ap2woccif0: ap2woccif@151A5000 {
64+ compatible = "mediatek,ap2woccif", "syscon";
65+ reg = <0 0x151A5000 0 0x1000>;
66 interrupt-parent = <&gic>;
67- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
68- <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
69+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
70+ };
71+
72+ ap2woccif1: ap2woccif@0x151AD000 {
73+ compatible = "mediatek,ap2woccif", "syscon";
74+ reg = <0 0x151AD000 0 0x1000>;
75+ interrupt-parent = <&gic>;
76+ interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
77 };
78
79 wocpu0_ilm: wocpu0_ilm@151E0000 {
80@@ -95,10 +112,17 @@
81 reg = <0 0x151F0000 0 0x8000>;
82 };
83
84- wocpu_dlm: wocpu_dlm@151E8000 {
85+ wocpu0_dlm: wocpu_dlm@151E8000 {
86+ compatible = "mediatek,wocpu_dlm";
87+ reg = <0 0x151E8000 0 0x2000>;
88+
89+ resets = <&ethsysrst 0>;
90+ reset-names = "wocpu_rst";
91+ };
92+
93+ wocpu1_dlm: wocpu_dlm@0x151F8000 {
94 compatible = "mediatek,wocpu_dlm";
95- reg = <0 0x151E8000 0 0x2000>,
96- <0 0x151F8000 0 0x2000>;
97+ reg = <0 0x151F8000 0 0x2000>;
98
99 resets = <&ethsysrst 0>;
100 reset-names = "wocpu_rst";
101diff --git a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
102index 67bf86f6a..6710b388b 100644
103--- a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
104+++ b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
105@@ -65,6 +65,12 @@
106 interrupt-parent = <&gic>;
107 interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
108 mediatek,wed_pcie = <&wed_pcie>;
109+ mediatek,ap2woccif = <&ap2woccif0>;
110+ mediatek,wocpu_ilm = <&wocpu0_ilm>;
111+ mediatek,wocpu_dlm = <&wocpu0_dlm>;
112+ mediatek,wocpu_boot = <&cpu_boot>;
113+ mediatek,wocpu_emi = <&wocpu0_emi>;
114+ mediatek,wocpu_data = <&wocpu_data>;
115 };
116
117 wed1: wed@15011000 {
118@@ -74,15 +80,26 @@
119 interrupt-parent = <&gic>;
120 interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
121 mediatek,wed_pcie = <&wed_pcie>;
122+ mediatek,ap2woccif = <&ap2woccif1>;
123+ mediatek,wocpu_ilm = <&wocpu1_ilm>;
124+ mediatek,wocpu_dlm = <&wocpu1_dlm>;
125+ mediatek,wocpu_boot = <&cpu_boot>;
126+ mediatek,wocpu_emi = <&wocpu1_emi>;
127+ mediatek,wocpu_data = <&wocpu_data>;
128 };
129
130- ap2woccif: ap2woccif@151A5000 {
131- compatible = "mediatek,ap2woccif";
132- reg = <0 0x151A5000 0 0x1000>,
133- <0 0x151AD000 0 0x1000>;
134+ ap2woccif0: ap2woccif@151A5000 {
135+ compatible = "mediatek,ap2woccif", "syscon";
136+ reg = <0 0x151A5000 0 0x1000>;
137 interrupt-parent = <&gic>;
138- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
139- <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
140+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
141+ };
142+
143+ ap2woccif1: ap2woccif@0x151AD000 {
144+ compatible = "mediatek,ap2woccif", "syscon";
145+ reg = <0 0x151AD000 0 0x1000>;
146+ interrupt-parent = <&gic>;
147+ interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
148 };
149
150 wocpu0_ilm: wocpu0_ilm@151E0000 {
151@@ -95,10 +112,17 @@
152 reg = <0 0x151F0000 0 0x8000>;
153 };
154
155- wocpu_dlm: wocpu_dlm@151E8000 {
156+ wocpu0_dlm: wocpu_dlm@151E8000 {
157+ compatible = "mediatek,wocpu_dlm";
158+ reg = <0 0x151E8000 0 0x2000>;
159+
160+ resets = <&ethsysrst 0>;
161+ reset-names = "wocpu_rst";
162+ };
163+
164+ wocpu1_dlm: wocpu_dlm@0x151F8000 {
165 compatible = "mediatek,wocpu_dlm";
166- reg = <0 0x151E8000 0 0x2000>,
167- <0 0x151F8000 0 0x2000>;
168+ reg = <0 0x151F8000 0 0x2000>;
169
170 resets = <&ethsysrst 0>;
171 reset-names = "wocpu_rst";
172diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile
developere0cbe332022-09-10 17:36:02 +0800173index 3528f1b..0c724a5 100644
developer8cb3ac72022-07-04 10:55:14 +0800174--- a/drivers/net/ethernet/mediatek/Makefile
175+++ b/drivers/net/ethernet/mediatek/Makefile
176@@ -10,5 +10,5 @@ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o
177 ifdef CONFIG_DEBUG_FS
178 mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
179 endif
180-obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o
181+obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o mtk_wed_wo.o mtk_wed_mcu.o mtk_wed_ccif.o
182 obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtk_hnat/
183diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
developere0cbe332022-09-10 17:36:02 +0800184index 2700176..b037d00 100644
developer8cb3ac72022-07-04 10:55:14 +0800185--- a/drivers/net/ethernet/mediatek/mtk_wed.c
186+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
187@@ -13,11 +13,19 @@
188 #include <linux/debugfs.h>
189 #include <linux/iopoll.h>
190 #include <linux/soc/mediatek/mtk_wed.h>
191+
192 #include "mtk_eth_soc.h"
193 #include "mtk_wed_regs.h"
194 #include "mtk_wed.h"
195 #include "mtk_ppe.h"
196-
197+#include "mtk_wed_mcu.h"
198+#include "mtk_wed_wo.h"
199+
200+struct wo_cmd_ring {
201+ u32 q_base;
202+ u32 cnt;
203+ u32 unit;
204+};
205 static struct mtk_wed_hw *hw_list[2];
206 static DEFINE_MUTEX(hw_lock);
207
developera3f86ed2022-07-08 14:15:13 +0800208@@ -51,6 +59,56 @@ wdma_set(struct mtk_wed_device *dev, u32 reg, u32 mask)
developer8cb3ac72022-07-04 10:55:14 +0800209 wdma_m32(dev, reg, 0, mask);
210 }
211
212+static void
213+wdma_clr(struct mtk_wed_device *dev, u32 reg, u32 mask)
214+{
215+ wdma_m32(dev, reg, mask, 0);
216+}
217+
developera3f86ed2022-07-08 14:15:13 +0800218+static u32
219+mtk_wdma_read_reset(struct mtk_wed_device *dev)
220+{
221+ return wdma_r32(dev, MTK_WDMA_GLO_CFG);
222+}
223+
224+static void
225+mtk_wdma_rx_reset(struct mtk_wed_device *dev)
226+{
227+ u32 status;
228+ u32 mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
229+ int i;
230+
231+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
232+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
233+ !(status & mask), 0, 1000))
234+ WARN_ON_ONCE(1);
235+
236+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
237+ if (!dev->rx_wdma[i].desc) {
238+ wdma_w32(dev, MTK_WDMA_RING_RX(i) +
239+ MTK_WED_RING_OFS_CPU_IDX, 0);
240+ }
241+}
242+
243+static void
244+mtk_wdma_tx_reset(struct mtk_wed_device *dev)
245+{
246+ u32 status;
247+ u32 mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
248+ int i;
249+
250+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
251+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
252+ !(status & mask), 0, 1000))
253+ WARN_ON_ONCE(1);
254+
255+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
256+ if (!dev->tx_wdma[i].desc) {
257+ wdma_w32(dev, MTK_WDMA_RING_TX(i) +
258+ MTK_WED_RING_OFS_CPU_IDX, 0);
259+ }
260+}
261+
developer8cb3ac72022-07-04 10:55:14 +0800262 static u32
263 mtk_wed_read_reset(struct mtk_wed_device *dev)
264 {
developerd7d9aa42022-12-23 16:09:53 +0800265@@ -68,6 +126,52 @@ mtk_wed_reset(struct mtk_wed_device *dev, u32 mask)
developer8cb3ac72022-07-04 10:55:14 +0800266 WARN_ON_ONCE(1);
267 }
268
269+static void
270+mtk_wed_wo_reset(struct mtk_wed_device *dev)
271+{
272+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
273+ u8 state = WO_STATE_DISABLE;
274+ u8 state_done = WOIF_DISABLE_DONE;
275+ void __iomem *reg;
276+ u32 value;
277+ unsigned long timeout = jiffies + WOCPU_TIMEOUT;
278+
developerc1b2cd12022-07-28 18:35:24 +0800279+ mtk_wdma_tx_reset(dev);
developera3f86ed2022-07-08 14:15:13 +0800280+
281+ mtk_wed_reset(dev, MTK_WED_RESET_WED);
282+
developerd7d9aa42022-12-23 16:09:53 +0800283+ mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
284+ &state, sizeof(state), false);
developer8cb3ac72022-07-04 10:55:14 +0800285+
286+ do {
287+ value = wed_r32(dev, MTK_WED_SCR0 + 4 * WED_DUMMY_CR_WO_STATUS);
288+ } while (value != state_done && !time_after(jiffies, timeout));
289+
290+ reg = ioremap(WOCPU_MCUSYS_RESET_ADDR, 4);
291+ value = readl((void *)reg);
292+ switch(dev->hw->index) {
293+ case 0:
294+ value |= WOCPU_WO0_MCUSYS_RESET_MASK;
295+ writel(value, (void *)reg);
296+ value &= ~WOCPU_WO0_MCUSYS_RESET_MASK;
297+ writel(value, (void *)reg);
298+ break;
299+ case 1:
300+ value |= WOCPU_WO1_MCUSYS_RESET_MASK;
301+ writel(value, (void *)reg);
302+ value &= ~WOCPU_WO1_MCUSYS_RESET_MASK;
303+ writel(value, (void *)reg);
304+ break;
305+ default:
306+ dev_err(dev->hw->dev, "wrong mtk_wed%d\n",
307+ dev->hw->index);
308+
309+ break;
310+ }
311+
312+ iounmap((void *)reg);
313+}
314+
315 static struct mtk_wed_hw *
316 mtk_wed_assign(struct mtk_wed_device *dev)
317 {
developerd7d9aa42022-12-23 16:09:53 +0800318@@ -178,7 +282,7 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
developera3f86ed2022-07-08 14:15:13 +0800319 {
320 struct mtk_wdma_desc *desc = dev->buf_ring.desc;
321 void **page_list = dev->buf_ring.pages;
322- int page_idx;
323+ int ring_size, page_idx;
324 int i;
325
326 if (!page_list)
developerd7d9aa42022-12-23 16:09:53 +0800327@@ -187,7 +291,14 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
developera3f86ed2022-07-08 14:15:13 +0800328 if (!desc)
329 goto free_pagelist;
330
developerf11dcd72022-08-27 18:29:27 +0800331- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
developera3f86ed2022-07-08 14:15:13 +0800332+ if (dev->ver == MTK_WED_V1) {
333+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
334+ } else {
335+ ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
336+ MTK_WED_WDMA_RING_SIZE * 2;
337+ }
338+
developerf11dcd72022-08-27 18:29:27 +0800339+ for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
developera3f86ed2022-07-08 14:15:13 +0800340 void *page = page_list[page_idx++];
341
developerf11dcd72022-08-27 18:29:27 +0800342 if (!page)
developerd7d9aa42022-12-23 16:09:53 +0800343@@ -198,13 +309,49 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
developerf11dcd72022-08-27 18:29:27 +0800344 __free_page(page);
345 }
346
347- dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc),
348+ dma_free_coherent(dev->hw->dev, ring_size * sizeof(*desc),
349 desc, dev->buf_ring.desc_phys);
350
351 free_pagelist:
developer8cb3ac72022-07-04 10:55:14 +0800352 kfree(page_list);
353 }
354
355+static int
356+mtk_wed_rx_bm_alloc(struct mtk_wed_device *dev)
357+{
358+ struct mtk_rxbm_desc *desc;
359+ dma_addr_t desc_phys;
360+ int ring_size;
361+
362+ ring_size = dev->wlan.rx_nbuf;
363+ dev->rx_buf_ring.size = ring_size;
364+ desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
365+ &desc_phys, GFP_KERNEL);
366+ if (!desc)
367+ return -ENOMEM;
368+
369+ dev->rx_buf_ring.desc = desc;
370+ dev->rx_buf_ring.desc_phys = desc_phys;
371+
developer144824b2022-11-25 21:27:43 +0800372+ dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt);
developer8cb3ac72022-07-04 10:55:14 +0800373+ return 0;
374+}
375+
376+static void
377+mtk_wed_free_rx_bm(struct mtk_wed_device *dev)
378+{
379+ struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
developera3f86ed2022-07-08 14:15:13 +0800380+ int ring_size = dev->rx_buf_ring.size;
developer8cb3ac72022-07-04 10:55:14 +0800381+
382+ if (!desc)
383+ return;
384+
385+ dev->wlan.release_rx_buf(dev);
386+
developer9dbe57a2022-08-05 18:23:53 +0800387+ dma_free_coherent(dev->hw->dev, ring_size * sizeof(*desc),
388+ desc, dev->rx_buf_ring.desc_phys);
developer8cb3ac72022-07-04 10:55:14 +0800389+}
390+
391 static void
392 mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, int scale)
393 {
developerd7d9aa42022-12-23 16:09:53 +0800394@@ -226,13 +373,22 @@ mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800395 mtk_wed_free_ring(dev, &dev->tx_wdma[i], dev->ver);
396 }
397
398+static void
399+mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
400+{
401+ mtk_wed_free_rx_bm(dev);
402+ mtk_wed_free_ring(dev, &dev->rro.rro_ring, 1);
403+}
404+
405 static void
406 mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
407 {
408 u32 wdma_mask;
409
410 wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
411-
412+ if (dev->ver > MTK_WED_V1)
413+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
414+ GENMASK(1, 0));
415 /* wed control cr set */
416 wed_set(dev, MTK_WED_CTRL,
417 MTK_WED_CTRL_WDMA_INT_AGENT_EN |
developerd7d9aa42022-12-23 16:09:53 +0800418@@ -251,7 +407,7 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
developer8cb3ac72022-07-04 10:55:14 +0800419 wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
420 MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
421 } else {
422- /* initail tx interrupt trigger */
423+
424 wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
425 MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
426 MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR |
developerd7d9aa42022-12-23 16:09:53 +0800427@@ -262,22 +418,30 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
developer8cb3ac72022-07-04 10:55:14 +0800428 FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG,
429 dev->wlan.tx_tbit[1]));
430
431- /* initail txfree interrupt trigger */
432 wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX_FREE,
433 MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN |
434 MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR |
435 FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
436 dev->wlan.txfree_tbit));
437+
438+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
439+ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
440+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
441+ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
442+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
443+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
444+ dev->wlan.rx_tbit[0]) |
445+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
446+ dev->wlan.rx_tbit[1]));
447 }
448- /* initail wdma interrupt agent */
449 wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
450 if (dev->ver == MTK_WED_V1) {
451 wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
452 } else {
453 wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
454 wed_set(dev, MTK_WED_WDMA_INT_CTRL,
455- FIELD_PREP(MTK_WED_WDMA_INT_POLL_SRC_SEL,dev->wdma_idx));
456-
457+ FIELD_PREP(MTK_WED_WDMA_INT_POLL_SRC_SEL,
458+ dev->wdma_idx));
459 }
460
461 wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask);
developerd7d9aa42022-12-23 16:09:53 +0800462@@ -312,6 +476,40 @@ mtk_wed_set_512_support(struct mtk_wed_device *dev, bool en)
developer8cb3ac72022-07-04 10:55:14 +0800463 }
464 }
465
466+static void
467+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
468+{
469+#define MTK_WFMDA_RX_DMA_EN BIT(2)
470+
471+ int timeout = 3;
472+ u32 cur_idx, regs;
473+
474+ do {
475+ regs = MTK_WED_WPDMA_RING_RX_DATA(idx) +
developerc1b2cd12022-07-28 18:35:24 +0800476+ MTK_WED_RING_OFS_CPU_IDX;
developer8cb3ac72022-07-04 10:55:14 +0800477+ cur_idx = wed_r32(dev, regs);
478+ if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
479+ break;
480+
481+ usleep_range(100000, 200000);
developerc1b2cd12022-07-28 18:35:24 +0800482+ timeout--;
483+ } while (timeout > 0);
developer8cb3ac72022-07-04 10:55:14 +0800484+
485+ if (timeout) {
486+ unsigned int val;
487+
488+ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo -
489+ dev->wlan.phy_base);
490+ val |= MTK_WFMDA_RX_DMA_EN;
491+
492+ wifi_w32(dev, dev->wlan.wpdma_rx_glo -
493+ dev->wlan.phy_base, val);
494+ } else {
495+ dev_err(dev->hw->dev, "mtk_wed%d: rx dma enable failed!\n",
496+ dev->hw->index);
497+ }
498+}
499+
500 static void
501 mtk_wed_dma_enable(struct mtk_wed_device *dev)
502 {
developerd7d9aa42022-12-23 16:09:53 +0800503@@ -336,9 +534,15 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800504 wdma_set(dev, MTK_WDMA_GLO_CFG,
505 MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
506 } else {
507+ int idx = 0;
508+
509 wed_set(dev, MTK_WED_WPDMA_CTRL,
510 MTK_WED_WPDMA_CTRL_SDL1_FIXED);
511
512+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
developerc1b2cd12022-07-28 18:35:24 +0800513+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
developer8cb3ac72022-07-04 10:55:14 +0800514+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
515+
516 wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
517 MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
518 MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
developerd7d9aa42022-12-23 16:09:53 +0800519@@ -346,6 +550,15 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800520 wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
521 MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
522 MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
523+
524+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
525+ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
526+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
527+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
528+ 0x2));
529+
530+ for (idx = 0; idx < MTK_WED_RX_QUEUES; idx++)
531+ mtk_wed_check_wfdma_rx_fill(dev, idx);
532 }
533 }
534
developerd7d9aa42022-12-23 16:09:53 +0800535@@ -363,19 +576,23 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800536 MTK_WED_GLO_CFG_TX_DMA_EN |
537 MTK_WED_GLO_CFG_RX_DMA_EN);
538
539- wdma_m32(dev, MTK_WDMA_GLO_CFG,
540+ wdma_clr(dev, MTK_WDMA_GLO_CFG,
541 MTK_WDMA_GLO_CFG_TX_DMA_EN |
542 MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
543- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0);
544+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
545
546 if (dev->ver == MTK_WED_V1) {
547 regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
548- wdma_m32(dev, MTK_WDMA_GLO_CFG,
549- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0);
550+ wdma_clr(dev, MTK_WDMA_GLO_CFG,
551+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
552 } else {
553 wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
554 MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
555 MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
556+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
557+ MTK_WED_WPDMA_RX_D_RX_DRV_EN);
558+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
559+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
560 }
561 }
562
developerd7d9aa42022-12-23 16:09:53 +0800563@@ -383,10 +600,12 @@ static void
developerc1b2cd12022-07-28 18:35:24 +0800564 mtk_wed_stop(struct mtk_wed_device *dev)
developera3f86ed2022-07-08 14:15:13 +0800565 {
566 mtk_wed_dma_disable(dev);
developerc1b2cd12022-07-28 18:35:24 +0800567+ mtk_wed_set_512_support(dev, false);
developera3f86ed2022-07-08 14:15:13 +0800568
569- if (dev->ver > MTK_WED_V1)
developerc1b2cd12022-07-28 18:35:24 +0800570- mtk_wed_set_512_support(dev, false);
571-
developera3f86ed2022-07-08 14:15:13 +0800572+ if (dev->ver > MTK_WED_V1) {
developera3f86ed2022-07-08 14:15:13 +0800573+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
574+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
575+ }
developera3f86ed2022-07-08 14:15:13 +0800576 mtk_wed_set_ext_int(dev, false);
577
developerc1b2cd12022-07-28 18:35:24 +0800578 wed_clr(dev, MTK_WED_CTRL,
developerd7d9aa42022-12-23 16:09:53 +0800579@@ -395,6 +614,11 @@ mtk_wed_stop(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800580 MTK_WED_CTRL_WED_TX_BM_EN |
581 MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
582
583+ if (dev->ver > MTK_WED_V1) {
584+ wed_clr(dev, MTK_WED_CTRL,
585+ MTK_WED_CTRL_WED_RX_BM_EN);
586+ }
587+
588 wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
589 wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
590 wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
developerd7d9aa42022-12-23 16:09:53 +0800591@@ -417,10 +641,21 @@ mtk_wed_detach(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800592
593 mtk_wed_reset(dev, MTK_WED_RESET_WED);
developera3f86ed2022-07-08 14:15:13 +0800594
developer8cb3ac72022-07-04 10:55:14 +0800595+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
596+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
597+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
developera3f86ed2022-07-08 14:15:13 +0800598+
developer8cb3ac72022-07-04 10:55:14 +0800599 mtk_wed_free_buffer(dev);
600 mtk_wed_free_tx_rings(dev);
developera3f86ed2022-07-08 14:15:13 +0800601+ if (dev->ver > MTK_WED_V1) {
developerd7d9aa42022-12-23 16:09:53 +0800602+ mtk_wed_wo_reset(dev);
developerf50c1802022-07-05 20:35:53 +0800603+ mtk_wed_free_rx_rings(dev);
developerd7d9aa42022-12-23 16:09:53 +0800604+ mtk_wed_wo_exit(hw);
developera3f86ed2022-07-08 14:15:13 +0800605+ }
developerd7d9aa42022-12-23 16:09:53 +0800606+
607+ mtk_wdma_rx_reset(dev);
developer8cb3ac72022-07-04 10:55:14 +0800608
developer144824b2022-11-25 21:27:43 +0800609- if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
610+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
developer8cb3ac72022-07-04 10:55:14 +0800611 wlan_node = dev->wlan.pci_dev->dev.of_node;
developer144824b2022-11-25 21:27:43 +0800612 if (of_dma_is_coherent(wlan_node))
613 regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
developerd7d9aa42022-12-23 16:09:53 +0800614@@ -443,7 +678,7 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
developer144824b2022-11-25 21:27:43 +0800615 {
616 #define PCIE_BASE_ADDR0 0x11280000
617
618- if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
619+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
620 struct device_node *node;
621 void __iomem * base_addr;
622 u32 value = 0;
developerd7d9aa42022-12-23 16:09:53 +0800623@@ -477,7 +712,6 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800624 value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
625 value = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
626
627- /* pcie interrupt status trigger register */
628 wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
629 wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
630
developerd7d9aa42022-12-23 16:09:53 +0800631@@ -485,7 +719,7 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
developer144824b2022-11-25 21:27:43 +0800632 value = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
633 wed_set(dev, MTK_WED_PCIE_INT_CTRL,
634 MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
635- } else if (dev->wlan.bus_type == MTK_BUS_TYPE_AXI) {
636+ } else if (dev->wlan.bus_type == MTK_WED_BUS_AXI) {
637 wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
638 MTK_WED_WPDMA_INT_CTRL_SIG_SRC |
639 FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0));
developerd7d9aa42022-12-23 16:09:53 +0800640@@ -501,6 +735,9 @@ mtk_wed_set_wpdma(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800641 wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
642 wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
643 wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
644+
645+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
646+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
647 } else {
648 wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
649 }
developerd7d9aa42022-12-23 16:09:53 +0800650@@ -549,24 +786,92 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800651 FIELD_PREP(MTK_WED_WDMA_OFST1_RX_CTRL,
652 MTK_WDMA_RING_RX(0)));
653 }
654+}
developerd7d9aa42022-12-23 16:09:53 +0800655
developer8cb3ac72022-07-04 10:55:14 +0800656+static void
657+mtk_wed_rx_bm_hw_init(struct mtk_wed_device *dev)
658+{
659+ wed_w32(dev, MTK_WED_RX_BM_RX_DMAD,
developer144824b2022-11-25 21:27:43 +0800660+ FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0, dev->wlan.rx_size));
developer8cb3ac72022-07-04 10:55:14 +0800661+
662+ wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys);
developerd7d9aa42022-12-23 16:09:53 +0800663+
developer8cb3ac72022-07-04 10:55:14 +0800664+ wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL |
developer144824b2022-11-25 21:27:43 +0800665+ FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt));
developer8cb3ac72022-07-04 10:55:14 +0800666+
667+ wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH,
668+ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
669+
670+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
671 }
672
673 static void
674-mtk_wed_hw_init(struct mtk_wed_device *dev)
675+mtk_wed_rro_hw_init(struct mtk_wed_device *dev)
676+{
677+ wed_w32(dev, MTK_WED_RROQM_MIOD_CFG,
678+ FIELD_PREP(MTK_WED_RROQM_MIOD_MID_DW, 0x70 >> 2) |
679+ FIELD_PREP(MTK_WED_RROQM_MIOD_MOD_DW, 0x10 >> 2) |
680+ FIELD_PREP(MTK_WED_RROQM_MIOD_ENTRY_DW,
681+ MTK_WED_MIOD_ENTRY_CNT >> 2));
682+
683+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL0, dev->rro.miod_desc_phys);
684+
685+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL1,
686+ FIELD_PREP(MTK_WED_RROQM_MIOD_CNT, MTK_WED_MIOD_CNT));
687+
688+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL0, dev->rro.fdbk_desc_phys);
689+
690+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL1,
691+ FIELD_PREP(MTK_WED_RROQM_FDBK_CNT, MTK_WED_FB_CMD_CNT));
692+
693+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL2, 0);
694+
695+ wed_w32(dev, MTK_WED_RROQ_BASE_L, dev->rro.rro_ring.desc_phys);
696+
697+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
698+ MTK_WED_RROQM_RST_IDX_MIOD |
699+ MTK_WED_RROQM_RST_IDX_FDBK);
700+
701+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
702+
703+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL2, MTK_WED_MIOD_CNT -1);
704+
705+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN);
706+}
707+
708+static void
709+mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev)
710+{
711+ wed_w32(dev, MTK_WED_RESET, MTK_WED_RESET_RX_ROUTE_QM);
712+
713+ do {
714+ udelay(100);
715+
716+ if (!(wed_r32(dev, MTK_WED_RESET) & MTK_WED_RESET_RX_ROUTE_QM))
717+ break;
718+ } while (1);
719+
720+ /* configure RX_ROUTE_QM */
721+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
722+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
723+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
724+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
725+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
726+
727+ /* enable RX_ROUTE_QM */
728+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
729+}
730+
731+static void
732+mtk_wed_tx_hw_init(struct mtk_wed_device *dev)
733 {
734 int size = dev->buf_ring.size;
735 int rev_size = MTK_WED_TX_RING_SIZE / 2;
736 int thr = 1;
737
738- if (dev->init_done)
739- return;
740-
741- dev->init_done = true;
742- mtk_wed_set_ext_int(dev, false);
743-
744 if (dev->ver > MTK_WED_V1) {
745- size = MTK_WED_WDMA_RING_SIZE * 2 + dev->buf_ring.size;
746+ size = MTK_WED_WDMA_RING_SIZE * ARRAY_SIZE(dev->tx_wdma) +
747+ dev->buf_ring.size;
748 rev_size = size;
749 thr = 0;
750 }
developerd7d9aa42022-12-23 16:09:53 +0800751@@ -609,13 +914,46 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800752 }
753
754 static void
755-mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size, int scale)
756+mtk_wed_rx_hw_init(struct mtk_wed_device *dev)
developerd7d9aa42022-12-23 16:09:53 +0800757 {
developer8cb3ac72022-07-04 10:55:14 +0800758+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
developerc1b2cd12022-07-28 18:35:24 +0800759+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
760+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
developer8cb3ac72022-07-04 10:55:14 +0800761+
762+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
763+
764+ mtk_wed_rx_bm_hw_init(dev);
765+ mtk_wed_rro_hw_init(dev);
766+ mtk_wed_route_qm_hw_init(dev);
767+}
768+
769+static void
770+mtk_wed_hw_init(struct mtk_wed_device *dev)
771+{
772+ if (dev->init_done)
773+ return;
774+
775+ dev->init_done = true;
776+ mtk_wed_set_ext_int(dev, false);
777+ mtk_wed_tx_hw_init(dev);
778+ if (dev->ver > MTK_WED_V1)
779+ mtk_wed_rx_hw_init(dev);
780+}
781+
782+static void
783+mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size, int scale, bool tx)
developerd7d9aa42022-12-23 16:09:53 +0800784+{
developer8cb3ac72022-07-04 10:55:14 +0800785+ __le32 ctrl;
786 int i;
787
788+ if (tx)
789+ ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
790+ else
791+ ctrl = cpu_to_le32(MTK_WFDMA_DESC_CTRL_TO_HOST);
792+
793 for (i = 0; i < size; i++) {
794 desc->buf0 = 0;
795- desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
796+ desc->ctrl = ctrl;
797 desc->buf1 = 0;
798 desc->info = 0;
799 desc += scale;
developerd7d9aa42022-12-23 16:09:53 +0800800@@ -674,7 +1012,7 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800801 if (!desc)
802 continue;
803
804- mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE, dev->ver);
805+ mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE, dev->ver, true);
806 }
807
808 if (mtk_wed_poll_busy(dev))
developerd7d9aa42022-12-23 16:09:53 +0800809@@ -692,6 +1030,8 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
developerc1b2cd12022-07-28 18:35:24 +0800810 wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
811 wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
812
813+ mtk_wdma_rx_reset(dev);
814+
815 if (busy) {
816 mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
817 mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
developerd7d9aa42022-12-23 16:09:53 +0800818@@ -729,9 +1069,24 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +0800819
820 }
821
822+static int
823+mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
824+ int size)
825+{
826+ ring->desc = dma_alloc_coherent(dev->hw->dev,
827+ size * sizeof(*ring->desc),
828+ &ring->desc_phys, GFP_KERNEL);
829+ if (!ring->desc)
830+ return -ENOMEM;
831+
832+ ring->size = size;
833+ memset(ring->desc, 0, size);
834+ return 0;
835+}
836+
837 static int
838 mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
839- int size, int scale)
840+ int size, int scale, bool tx)
841 {
842 ring->desc = dma_alloc_coherent(dev->hw->dev,
843 size * sizeof(*ring->desc) * scale,
developerd7d9aa42022-12-23 16:09:53 +0800844@@ -740,17 +1095,18 @@ mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
developer8cb3ac72022-07-04 10:55:14 +0800845 return -ENOMEM;
846
847 ring->size = size;
848- mtk_wed_ring_reset(ring->desc, size, scale);
849+ mtk_wed_ring_reset(ring->desc, size, scale, tx);
850
851 return 0;
852 }
853
854 static int
855-mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
856+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
857 {
858 struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
859
860- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, dev->ver))
861+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
862+ dev->ver, true))
863 return -ENOMEM;
864
865 wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
developerd7d9aa42022-12-23 16:09:53 +0800866@@ -767,22 +1123,143 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
developer8cb3ac72022-07-04 10:55:14 +0800867 return 0;
868 }
869
870+static int
871+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
872+{
873+ struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
874+
875+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
876+ dev->ver, true))
877+ return -ENOMEM;
878+
879+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
880+ wdma->desc_phys);
881+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
882+ size);
883+ wdma_w32(dev,
884+ MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
885+ wdma_w32(dev,
886+ MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
887+
888+ if (idx == 0) {
889+ wed_w32(dev, MTK_WED_WDMA_RING_TX
890+ + MTK_WED_RING_OFS_BASE, wdma->desc_phys);
891+ wed_w32(dev, MTK_WED_WDMA_RING_TX
892+ + MTK_WED_RING_OFS_COUNT, size);
893+ wed_w32(dev, MTK_WED_WDMA_RING_TX
894+ + MTK_WED_RING_OFS_CPU_IDX, 0);
895+ wed_w32(dev, MTK_WED_WDMA_RING_TX
896+ + MTK_WED_RING_OFS_DMA_IDX, 0);
897+ }
898+
899+ return 0;
900+}
901+
902+static int
903+mtk_wed_rro_alloc(struct mtk_wed_device *dev)
904+{
905+ struct device_node *np, *node = dev->hw->node;
906+ struct mtk_wed_ring *ring;
907+ struct resource res;
908+ int ret;
909+
910+ np = of_parse_phandle(node, "mediatek,wocpu_dlm", 0);
911+ if (!np)
912+ return -ENODEV;
913+
914+ ret = of_address_to_resource(np, 0, &res);
915+ if (ret)
916+ return ret;
917+
918+ dev->rro.rro_desc = ioremap(res.start, resource_size(&res));
919+
920+ ring = &dev->rro.rro_ring;
921+
922+ dev->rro.miod_desc_phys = res.start;
923+
924+ dev->rro.mcu_view_miod = MTK_WED_WOCPU_VIEW_MIOD_BASE;
925+ dev->rro.fdbk_desc_phys = MTK_WED_MIOD_ENTRY_CNT * MTK_WED_MIOD_CNT
926+ + dev->rro.miod_desc_phys;
927+
928+ if (mtk_wed_rro_ring_alloc(dev, ring, MTK_WED_RRO_QUE_CNT))
929+ return -ENOMEM;
930+
931+ return 0;
932+}
933+
934+static int
935+mtk_wed_rro_cfg(struct mtk_wed_device *dev)
936+{
937+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
938+ struct {
939+ struct wo_cmd_ring ring[2];
940+
941+ u32 wed;
942+ u8 ver;
943+ } req = {
944+ .ring = {
945+ [0] = {
946+ .q_base = dev->rro.mcu_view_miod,
947+ .cnt = MTK_WED_MIOD_CNT,
948+ .unit = MTK_WED_MIOD_ENTRY_CNT,
949+ },
950+ [1] = {
951+ .q_base = dev->rro.mcu_view_miod +
952+ MTK_WED_MIOD_ENTRY_CNT *
953+ MTK_WED_MIOD_CNT,
954+ .cnt = MTK_WED_FB_CMD_CNT,
955+ .unit = 4,
956+ },
957+ },
958+ .wed = 0,
959+ };
960+
developer144824b2022-11-25 21:27:43 +0800961+ return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_WED_CFG,
developer8cb3ac72022-07-04 10:55:14 +0800962+ &req, sizeof(req), true);
963+}
964+
965+static int
966+mtk_wed_send_msg(struct mtk_wed_device *dev, int cmd_id, void *data, int len)
967+{
968+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
969+
developerf50c1802022-07-05 20:35:53 +0800970+ if (dev->ver == MTK_WED_V1)
971+ return 0;
972+
developer8cb3ac72022-07-04 10:55:14 +0800973+ return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, cmd_id, data, len, true);
974+}
975+
976+static void
977+mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
978+ u32 reason, u32 hash)
979+{
980+ int idx = dev->hw->index;
981+ struct mtk_eth *eth = dev->hw->eth;
982+ struct ethhdr *eh;
983+
984+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) {
985+ if (!skb)
986+ return;
987+
988+ skb_set_mac_header(skb, 0);
989+ eh = eth_hdr(skb);
990+ skb->protocol = eh->h_proto;
991+ mtk_ppe_check_skb(eth->ppe[idx], skb, hash);
992+ }
993+}
994+
995 static void
996 mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
997 {
998- u32 wdma_mask;
999- int i;
1000+ int i, ret;
1001
1002 for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
1003 if (!dev->tx_wdma[i].desc)
1004- mtk_wed_wdma_ring_setup(dev, i, 16);
1005-
1006+ mtk_wed_wdma_rx_ring_setup(dev, i, 16);
1007
1008 mtk_wed_hw_init(dev);
1009
1010 mtk_wed_set_int(dev, irq_mask);
1011-
1012-
1013 mtk_wed_set_ext_int(dev, true);
1014
1015 if (dev->ver == MTK_WED_V1) {
developerd7d9aa42022-12-23 16:09:53 +08001016@@ -797,8 +1274,20 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
developer8cb3ac72022-07-04 10:55:14 +08001017 val |= BIT(0);
1018 regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
1019 } else {
developer203096a2022-09-13 21:07:19 +08001020- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
developer8cb3ac72022-07-04 10:55:14 +08001021+ /* driver set mid ready and only once */
1022+ wed_w32(dev, MTK_WED_EXT_INT_MASK1,
1023+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
1024+ wed_w32(dev, MTK_WED_EXT_INT_MASK2,
1025+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
1026+
1027+ wed_r32(dev, MTK_WED_EXT_INT_MASK1);
1028+ wed_r32(dev, MTK_WED_EXT_INT_MASK2);
1029+
1030+ ret = mtk_wed_rro_cfg(dev);
1031+ if (ret)
1032+ return;
developer8cb3ac72022-07-04 10:55:14 +08001033 }
developer203096a2022-09-13 21:07:19 +08001034+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
developer8cb3ac72022-07-04 10:55:14 +08001035
developerc1b2cd12022-07-28 18:35:24 +08001036 mtk_wed_dma_enable(dev);
1037 dev->running = true;
developerd7d9aa42022-12-23 16:09:53 +08001038@@ -809,6 +1298,7 @@ mtk_wed_attach(struct mtk_wed_device *dev)
developer144824b2022-11-25 21:27:43 +08001039 __releases(RCU)
1040 {
1041 struct mtk_wed_hw *hw;
1042+ struct device *device;
1043 u16 ver;
1044 int ret = 0;
1045
developerd7d9aa42022-12-23 16:09:53 +08001046@@ -829,6 +1319,12 @@ mtk_wed_attach(struct mtk_wed_device *dev)
developer144824b2022-11-25 21:27:43 +08001047 goto out;
1048 }
1049
1050+ device = dev->wlan.bus_type == MTK_WED_BUS_PCIE
1051+ ? &dev->wlan.pci_dev->dev
1052+ : &dev->wlan.platform_dev->dev;
1053+ dev_info(device, "attaching wed device %d version %d\n",
1054+ hw->index, hw->ver);
1055+
1056 dev->hw = hw;
1057 dev->dev = hw->dev;
1058 dev->irq = hw->irq;
developerd7d9aa42022-12-23 16:09:53 +08001059@@ -847,9 +1343,17 @@ mtk_wed_attach(struct mtk_wed_device *dev)
developere0cbe332022-09-10 17:36:02 +08001060 dev->rev_id = ((dev->ver << 28) | ver << 16);
developer8cb3ac72022-07-04 10:55:14 +08001061
1062 ret = mtk_wed_buffer_alloc(dev);
1063- if (ret) {
1064- mtk_wed_detach(dev);
1065- goto out;
1066+ if (ret)
1067+ goto error;
1068+
1069+ if (dev->ver > MTK_WED_V1) {
1070+ ret = mtk_wed_rx_bm_alloc(dev);
1071+ if (ret)
1072+ goto error;
1073+
1074+ ret = mtk_wed_rro_alloc(dev);
1075+ if (ret)
1076+ goto error;
1077 }
1078
1079 mtk_wed_hw_init_early(dev);
developerd7d9aa42022-12-23 16:09:53 +08001080@@ -857,7 +1361,12 @@ mtk_wed_attach(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +08001081 if (dev->ver == MTK_WED_V1)
1082 regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
1083 BIT(hw->index), 0);
1084+ else
1085+ ret = mtk_wed_wo_init(hw);
1086
1087+error:
developerd7d9aa42022-12-23 16:09:53 +08001088+ if (ret)
1089+ mtk_wed_detach(dev);
developer8cb3ac72022-07-04 10:55:14 +08001090 out:
1091 mutex_unlock(&hw_lock);
1092
developerd7d9aa42022-12-23 16:09:53 +08001093@@ -883,10 +1392,10 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
developer8cb3ac72022-07-04 10:55:14 +08001094
1095 BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
1096
1097- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, 1))
1098+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, 1, true))
1099 return -ENOMEM;
1100
1101- if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
1102+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
1103 return -ENOMEM;
1104
1105 ring->reg_base = MTK_WED_RING_TX(idx);
developerd7d9aa42022-12-23 16:09:53 +08001106@@ -933,6 +1442,35 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
developer8cb3ac72022-07-04 10:55:14 +08001107 return 0;
1108 }
1109
1110+static int
1111+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
1112+{
1113+ struct mtk_wed_ring *ring = &dev->rx_ring[idx];
1114+
1115+ BUG_ON(idx > ARRAY_SIZE(dev->rx_ring));
1116+
1117+
1118+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, 1, false))
1119+ return -ENOMEM;
1120+
1121+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
1122+ return -ENOMEM;
1123+
1124+ ring->reg_base = MTK_WED_RING_RX_DATA(idx);
1125+ ring->wpdma = regs;
1126+
1127+ /* WPDMA -> WED */
1128+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
1129+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_RX_RING_SIZE);
1130+
1131+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_BASE,
1132+ ring->desc_phys);
1133+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_COUNT,
1134+ MTK_WED_RX_RING_SIZE);
1135+
1136+ return 0;
1137+}
1138+
1139 static u32
1140 mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
1141 {
developerd7d9aa42022-12-23 16:09:53 +08001142@@ -1020,6 +1558,8 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
developer8cb3ac72022-07-04 10:55:14 +08001143 .attach = mtk_wed_attach,
1144 .tx_ring_setup = mtk_wed_tx_ring_setup,
1145 .txfree_ring_setup = mtk_wed_txfree_ring_setup,
1146+ .rx_ring_setup = mtk_wed_rx_ring_setup,
1147+ .msg_update = mtk_wed_send_msg,
1148 .start = mtk_wed_start,
1149 .stop = mtk_wed_stop,
1150 .reset_dma = mtk_wed_reset_dma,
developerd7d9aa42022-12-23 16:09:53 +08001151@@ -1028,6 +1568,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
developer8cb3ac72022-07-04 10:55:14 +08001152 .irq_get = mtk_wed_irq_get,
1153 .irq_set_mask = mtk_wed_irq_set_mask,
1154 .detach = mtk_wed_detach,
1155+ .ppe_check = mtk_wed_ppe_check,
1156 };
1157 struct device_node *eth_np = eth->dev->of_node;
1158 struct platform_device *pdev;
developerd7d9aa42022-12-23 16:09:53 +08001159@@ -1067,6 +1608,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
developer144824b2022-11-25 21:27:43 +08001160 hw->wdma_phy = wdma_phy;
1161 hw->index = index;
1162 hw->irq = irq;
1163+ hw->ver = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
1164
1165 if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
1166 hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
developerd7d9aa42022-12-23 16:09:53 +08001167@@ -1083,6 +1625,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
developerc1b2cd12022-07-28 18:35:24 +08001168 regmap_write(hw->mirror, 0, 0);
1169 regmap_write(hw->mirror, 4, 0);
1170 }
1171+ hw->ver = MTK_WED_V1;
1172 }
1173
1174 mtk_wed_hw_add_debugfs(hw);
developer8cb3ac72022-07-04 10:55:14 +08001175diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h
developere0cbe332022-09-10 17:36:02 +08001176index 9b17b74..8ef5253 100644
developer8cb3ac72022-07-04 10:55:14 +08001177--- a/drivers/net/ethernet/mediatek/mtk_wed.h
1178+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
1179@@ -13,6 +13,7 @@
1180 #define MTK_WED_PKT_SIZE 1900
1181 #define MTK_WED_BUF_SIZE 2048
1182 #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
1183+#define MTK_WED_RX_RING_SIZE 1536
1184
1185 #define MTK_WED_TX_RING_SIZE 2048
1186 #define MTK_WED_WDMA_RING_SIZE 512
1187@@ -21,8 +22,15 @@
1188 #define MTK_WED_PER_GROUP_PKT 128
1189
1190 #define MTK_WED_FBUF_SIZE 128
1191+#define MTK_WED_MIOD_CNT 16
1192+#define MTK_WED_FB_CMD_CNT 1024
1193+#define MTK_WED_RRO_QUE_CNT 8192
1194+#define MTK_WED_MIOD_ENTRY_CNT 128
1195+
1196+#define MODULE_ID_WO 1
1197
1198 struct mtk_eth;
1199+struct mtk_wed_wo;
1200
1201 struct mtk_wed_hw {
1202 struct device_node *node;
1203@@ -34,12 +42,14 @@ struct mtk_wed_hw {
1204 struct regmap *mirror;
1205 struct dentry *debugfs_dir;
1206 struct mtk_wed_device *wed_dev;
1207+ struct mtk_wed_wo *wed_wo;
1208 u32 debugfs_reg;
1209 u32 num_flows;
1210 u32 wdma_phy;
1211 char dirname[5];
1212 int irq;
1213 int index;
1214+ u32 ver;
1215 };
1216
1217 struct mtk_wdma_info {
1218@@ -66,6 +76,18 @@ wed_r32(struct mtk_wed_device *dev, u32 reg)
1219 return val;
1220 }
1221
1222+static inline u32
1223+wifi_r32(struct mtk_wed_device *dev, u32 reg)
1224+{
1225+ return readl(dev->wlan.base + reg);
1226+}
1227+
1228+static inline void
1229+wifi_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
1230+{
1231+ writel(val, dev->wlan.base + reg);
1232+}
1233+
1234 static inline void
1235 wdma_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
1236 {
1237@@ -114,6 +136,23 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
1238 writel(val, dev->txfree_ring.wpdma + reg);
1239 }
1240
1241+static inline u32
1242+wpdma_rx_r32(struct mtk_wed_device *dev, int ring, u32 reg)
1243+{
1244+ if (!dev->rx_ring[ring].wpdma)
1245+ return 0;
1246+
1247+ return readl(dev->rx_ring[ring].wpdma + reg);
1248+}
1249+
1250+static inline void
1251+wpdma_rx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val)
1252+{
1253+ if (!dev->rx_ring[ring].wpdma)
1254+ return;
1255+
1256+ writel(val, dev->rx_ring[ring].wpdma + reg);
1257+}
1258 void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
1259 void __iomem *wdma, u32 wdma_phy, int index);
1260 void mtk_wed_exit(void);
developera3f86ed2022-07-08 14:15:13 +08001261@@ -146,4 +185,16 @@ static inline void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
developer8cb3ac72022-07-04 10:55:14 +08001262 }
1263 #endif
1264
1265+int wed_wo_hardware_init(struct mtk_wed_wo *wo, irq_handler_t isr);
developera3f86ed2022-07-08 14:15:13 +08001266+void wed_wo_hardware_exit(struct mtk_wed_wo *wo);
developer8cb3ac72022-07-04 10:55:14 +08001267+int wed_wo_mcu_init(struct mtk_wed_wo *wo);
1268+int mtk_wed_exception_init(struct mtk_wed_wo *wo);
1269+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, struct sk_buff *skb);
1270+int mtk_wed_mcu_cmd_sanity_check(struct mtk_wed_wo *wo, struct sk_buff *skb);
1271+void wed_wo_mcu_debugfs(struct mtk_wed_hw *hw, struct dentry *dir);
1272+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb);
1273+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo,int to_id, int cmd,
1274+ const void *data, int len, bool wait_resp);
1275+int mtk_wed_wo_rx_poll(struct napi_struct *napi, int budget);
1276+
1277 #endif
1278diff --git a/drivers/net/ethernet/mediatek/mtk_wed_ccif.c b/drivers/net/ethernet/mediatek/mtk_wed_ccif.c
1279new file mode 100644
developerd7d9aa42022-12-23 16:09:53 +08001280index 0000000..951278b
developer8cb3ac72022-07-04 10:55:14 +08001281--- /dev/null
1282+++ b/drivers/net/ethernet/mediatek/mtk_wed_ccif.c
developerd7d9aa42022-12-23 16:09:53 +08001283@@ -0,0 +1,133 @@
developer8cb3ac72022-07-04 10:55:14 +08001284+// SPDX-License-Identifier: GPL-2.0-only
1285+
1286+#include <linux/soc/mediatek/mtk_wed.h>
1287+#include <linux/of_address.h>
1288+#include <linux/mfd/syscon.h>
1289+#include <linux/of_irq.h>
1290+#include "mtk_wed_ccif.h"
1291+#include "mtk_wed_regs.h"
1292+#include "mtk_wed_wo.h"
1293+
1294+static inline void woif_set_isr(struct mtk_wed_wo *wo, u32 mask)
1295+{
1296+ woccif_w32(wo, MTK_WED_WO_CCIF_IRQ0_MASK, mask);
1297+}
1298+
1299+static inline u32 woif_get_csr(struct mtk_wed_wo *wo)
1300+{
1301+ u32 val;
1302+
1303+ val = woccif_r32(wo, MTK_WED_WO_CCIF_RCHNUM);
1304+
1305+ return val & MTK_WED_WO_CCIF_RCHNUM_MASK;
1306+}
1307+
1308+static inline void woif_set_ack(struct mtk_wed_wo *wo, u32 mask)
1309+{
1310+ woccif_w32(wo, MTK_WED_WO_CCIF_ACK, mask);
1311+}
1312+
1313+static inline void woif_kickout(struct mtk_wed_wo *wo)
1314+{
1315+ woccif_w32(wo, MTK_WED_WO_CCIF_BUSY, 1 << MTK_WED_WO_TXCH_NUM);
1316+ woccif_w32(wo, MTK_WED_WO_CCIF_TCHNUM, MTK_WED_WO_TXCH_NUM);
1317+}
1318+
1319+static inline void woif_clear_int(struct mtk_wed_wo *wo, u32 mask)
1320+{
1321+ woccif_w32(wo, MTK_WED_WO_CCIF_ACK, mask);
1322+ woccif_r32(wo, MTK_WED_WO_CCIF_RCHNUM);
1323+}
1324+
1325+int wed_wo_hardware_init(struct mtk_wed_wo *wo, irq_handler_t isr)
1326+{
1327+ static const struct wed_wo_drv_ops wo_drv_ops = {
1328+ .kickout = woif_kickout,
1329+ .set_ack = woif_set_ack,
1330+ .set_isr = woif_set_isr,
1331+ .get_csr = woif_get_csr,
1332+ .clear_int = woif_clear_int,
1333+ };
1334+ struct device_node *np, *node = wo->hw->node;
1335+ struct wed_wo_queue_regs queues;
1336+ struct regmap *regs;
1337+ int ret;
1338+
1339+ np = of_parse_phandle(node, "mediatek,ap2woccif", 0);
1340+ if (!np)
1341+ return -ENODEV;
1342+
developerd7d9aa42022-12-23 16:09:53 +08001343+ regs = syscon_regmap_lookup_by_phandle(np, NULL);
1344+ if (!regs)
1345+ return -ENODEV;
developer8cb3ac72022-07-04 10:55:14 +08001346+
1347+ wo->drv_ops = &wo_drv_ops;
developerd7d9aa42022-12-23 16:09:53 +08001348+
1349+ wo->ccif.regs = regs;
developer8cb3ac72022-07-04 10:55:14 +08001350+ wo->ccif.irq = irq_of_parse_and_map(np, 0);
1351+
1352+ spin_lock_init(&wo->ccif.irq_lock);
1353+
1354+ ret = request_irq(wo->ccif.irq, isr, IRQF_TRIGGER_HIGH,
1355+ "wo_ccif_isr", wo);
1356+ if (ret)
1357+ goto free_irq;
1358+
1359+ queues.desc_base = MTK_WED_WO_CCIF_DUMMY1;
1360+ queues.ring_size = MTK_WED_WO_CCIF_DUMMY2;
1361+ queues.cpu_idx = MTK_WED_WO_CCIF_DUMMY3;
1362+ queues.dma_idx = MTK_WED_WO_CCIF_SHADOW4;
1363+
1364+ ret = mtk_wed_wo_q_alloc(wo, &wo->q_tx, MTK_WED_WO_RING_SIZE,
1365+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_TXCH_NUM,
1366+ &queues);
1367+
1368+ if (ret)
1369+ goto free_irq;
1370+
1371+ queues.desc_base = MTK_WED_WO_CCIF_DUMMY5;
1372+ queues.ring_size = MTK_WED_WO_CCIF_DUMMY6;
1373+ queues.cpu_idx = MTK_WED_WO_CCIF_DUMMY7;
1374+ queues.dma_idx = MTK_WED_WO_CCIF_SHADOW8;
1375+
1376+ ret = mtk_wed_wo_q_alloc(wo, &wo->q_rx, MTK_WED_WO_RING_SIZE,
1377+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_RXCH_NUM,
1378+ &queues);
1379+ if (ret)
1380+ goto free_irq;
1381+
1382+ wo->ccif.q_int_mask = MTK_WED_WO_RXCH_INT_MASK;
1383+
1384+ ret = mtk_wed_wo_q_init(wo, mtk_wed_wo_rx_poll);
1385+ if (ret)
1386+ goto free_irq;
1387+
1388+ wo->ccif.q_exep_mask = MTK_WED_WO_EXCEPTION_INT_MASK;
1389+ wo->ccif.irqmask = MTK_WED_WO_ALL_INT_MASK;
1390+
1391+ /* rx queue irqmask */
1392+ wo->drv_ops->set_isr(wo, wo->ccif.irqmask);
1393+
1394+ return 0;
1395+
1396+free_irq:
developera3f86ed2022-07-08 14:15:13 +08001397+ free_irq(wo->ccif.irq, wo);
developer8cb3ac72022-07-04 10:55:14 +08001398+
1399+ return ret;
1400+}
1401+
developera3f86ed2022-07-08 14:15:13 +08001402+void wed_wo_hardware_exit(struct mtk_wed_wo *wo)
developer8cb3ac72022-07-04 10:55:14 +08001403+{
developera3f86ed2022-07-08 14:15:13 +08001404+ wo->drv_ops->set_isr(wo, 0);
1405+
1406+ disable_irq(wo->ccif.irq);
1407+ free_irq(wo->ccif.irq, wo);
1408+
1409+ tasklet_disable(&wo->irq_tasklet);
1410+ netif_napi_del(&wo->napi);
1411+
developer53bfd362022-09-29 12:02:18 +08001412+ mtk_wed_wo_q_tx_clean(wo, &wo->q_tx);
developera3f86ed2022-07-08 14:15:13 +08001413+ mtk_wed_wo_q_rx_clean(wo, &wo->q_rx);
1414+ mtk_wed_wo_q_free(wo, &wo->q_tx);
1415+ mtk_wed_wo_q_free(wo, &wo->q_rx);
developer8cb3ac72022-07-04 10:55:14 +08001416+}
1417diff --git a/drivers/net/ethernet/mediatek/mtk_wed_ccif.h b/drivers/net/ethernet/mediatek/mtk_wed_ccif.h
1418new file mode 100644
developere0cbe332022-09-10 17:36:02 +08001419index 0000000..68ade44
developer8cb3ac72022-07-04 10:55:14 +08001420--- /dev/null
1421+++ b/drivers/net/ethernet/mediatek/mtk_wed_ccif.h
1422@@ -0,0 +1,45 @@
1423+// SPDX-License-Identifier: GPL-2.0-only
1424+
1425+#ifndef __MTK_WED_CCIF_H
1426+#define __MTK_WED_CCIF_H
1427+
1428+#define MTK_WED_WO_RING_SIZE 256
1429+#define MTK_WED_WO_CMD_LEN 1504
1430+
1431+#define MTK_WED_WO_TXCH_NUM 0
1432+#define MTK_WED_WO_RXCH_NUM 1
1433+#define MTK_WED_WO_RXCH_WO_EXCEPTION 7
1434+
1435+#define MTK_WED_WO_TXCH_INT_MASK BIT(0)
1436+#define MTK_WED_WO_RXCH_INT_MASK BIT(1)
1437+#define MTK_WED_WO_EXCEPTION_INT_MASK BIT(7)
1438+#define MTK_WED_WO_ALL_INT_MASK MTK_WED_WO_RXCH_INT_MASK | \
1439+ MTK_WED_WO_EXCEPTION_INT_MASK
1440+
1441+#define MTK_WED_WO_CCIF_BUSY 0x004
1442+#define MTK_WED_WO_CCIF_START 0x008
1443+#define MTK_WED_WO_CCIF_TCHNUM 0x00c
1444+#define MTK_WED_WO_CCIF_RCHNUM 0x010
1445+#define MTK_WED_WO_CCIF_RCHNUM_MASK GENMASK(7, 0)
1446+
1447+#define MTK_WED_WO_CCIF_ACK 0x014
1448+#define MTK_WED_WO_CCIF_IRQ0_MASK 0x018
1449+#define MTK_WED_WO_CCIF_IRQ1_MASK 0x01c
1450+#define MTK_WED_WO_CCIF_DUMMY1 0x020
1451+#define MTK_WED_WO_CCIF_DUMMY2 0x024
1452+#define MTK_WED_WO_CCIF_DUMMY3 0x028
1453+#define MTK_WED_WO_CCIF_DUMMY4 0x02c
1454+#define MTK_WED_WO_CCIF_SHADOW1 0x030
1455+#define MTK_WED_WO_CCIF_SHADOW2 0x034
1456+#define MTK_WED_WO_CCIF_SHADOW3 0x038
1457+#define MTK_WED_WO_CCIF_SHADOW4 0x03c
1458+#define MTK_WED_WO_CCIF_DUMMY5 0x050
1459+#define MTK_WED_WO_CCIF_DUMMY6 0x054
1460+#define MTK_WED_WO_CCIF_DUMMY7 0x058
1461+#define MTK_WED_WO_CCIF_DUMMY8 0x05c
1462+#define MTK_WED_WO_CCIF_SHADOW5 0x060
1463+#define MTK_WED_WO_CCIF_SHADOW6 0x064
1464+#define MTK_WED_WO_CCIF_SHADOW7 0x068
1465+#define MTK_WED_WO_CCIF_SHADOW8 0x06c
1466+
1467+#endif
1468diff --git a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
developere0cbe332022-09-10 17:36:02 +08001469index f420f18..4a9e684 100644
developer8cb3ac72022-07-04 10:55:14 +08001470--- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
1471+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
1472@@ -2,6 +2,7 @@
1473 /* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
1474
1475 #include <linux/seq_file.h>
1476+#include <linux/soc/mediatek/mtk_wed.h>
1477 #include "mtk_wed.h"
1478 #include "mtk_wed_regs.h"
1479
1480@@ -18,6 +19,8 @@ enum {
1481 DUMP_TYPE_WDMA,
1482 DUMP_TYPE_WPDMA_TX,
1483 DUMP_TYPE_WPDMA_TXFREE,
1484+ DUMP_TYPE_WPDMA_RX,
1485+ DUMP_TYPE_WED_RRO,
1486 };
1487
1488 #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
1489@@ -36,6 +39,10 @@ enum {
1490
1491 #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n)
1492 #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE)
1493+#define DUMP_WPDMA_RX_RING(_n) DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n)
1494+#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO)
1495+#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO)
1496+
1497
1498 static void
1499 print_reg_val(struct seq_file *s, const char *name, u32 val)
1500@@ -58,6 +65,7 @@ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
1501 cur->name);
1502 continue;
1503 case DUMP_TYPE_WED:
1504+ case DUMP_TYPE_WED_RRO:
1505 val = wed_r32(dev, cur->offset);
1506 break;
1507 case DUMP_TYPE_WDMA:
1508@@ -69,6 +77,9 @@ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
1509 case DUMP_TYPE_WPDMA_TXFREE:
1510 val = wpdma_txfree_r32(dev, cur->offset);
1511 break;
1512+ case DUMP_TYPE_WPDMA_RX:
1513+ val = wpdma_rx_r32(dev, cur->base, cur->offset);
1514+ break;
1515 }
1516 print_reg_val(s, cur->name, val);
1517 }
1518@@ -132,6 +143,81 @@ wed_txinfo_show(struct seq_file *s, void *data)
1519 }
1520 DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
1521
1522+static int
1523+wed_rxinfo_show(struct seq_file *s, void *data)
1524+{
1525+ static const struct reg_dump regs[] = {
1526+ DUMP_STR("WPDMA RX"),
1527+ DUMP_WPDMA_RX_RING(0),
1528+ DUMP_WPDMA_RX_RING(1),
1529+
1530+ DUMP_STR("WPDMA RX"),
1531+ DUMP_WED(WED_WPDMA_RX_D_MIB(0)),
1532+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)),
1533+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)),
1534+ DUMP_WED(WED_WPDMA_RX_D_MIB(1)),
1535+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)),
1536+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)),
1537+ DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB),
1538+
1539+ DUMP_STR("WED RX"),
1540+ DUMP_WED_RING(WED_RING_RX_DATA(0)),
1541+ DUMP_WED_RING(WED_RING_RX_DATA(1)),
1542+
1543+ DUMP_STR("WED RRO"),
1544+ DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
1545+ DUMP_WED(WED_RROQM_MID_MIB),
1546+ DUMP_WED(WED_RROQM_MOD_MIB),
1547+ DUMP_WED(WED_RROQM_MOD_COHERENT_MIB),
1548+ DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0),
1549+ DUMP_WED(WED_RROQM_FDBK_IND_MIB),
1550+ DUMP_WED(WED_RROQM_FDBK_ENQ_MIB),
1551+ DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
1552+ DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
1553+
1554+ DUMP_STR("WED Route QM"),
1555+ DUMP_WED(WED_RTQM_R2H_MIB(0)),
1556+ DUMP_WED(WED_RTQM_R2Q_MIB(0)),
1557+ DUMP_WED(WED_RTQM_Q2H_MIB(0)),
1558+ DUMP_WED(WED_RTQM_R2H_MIB(1)),
1559+ DUMP_WED(WED_RTQM_R2Q_MIB(1)),
1560+ DUMP_WED(WED_RTQM_Q2H_MIB(1)),
1561+ DUMP_WED(WED_RTQM_Q2N_MIB),
1562+ DUMP_WED(WED_RTQM_Q2B_MIB),
1563+ DUMP_WED(WED_RTQM_PFDBK_MIB),
1564+
1565+ DUMP_STR("WED WDMA TX"),
1566+ DUMP_WED(WED_WDMA_TX_MIB),
1567+ DUMP_WED_RING(WED_WDMA_RING_TX),
1568+
1569+ DUMP_STR("WDMA TX"),
1570+ DUMP_WDMA(WDMA_GLO_CFG),
1571+ DUMP_WDMA_RING(WDMA_RING_TX(0)),
1572+ DUMP_WDMA_RING(WDMA_RING_TX(1)),
1573+
1574+ DUMP_STR("WED RX BM"),
1575+ DUMP_WED(WED_RX_BM_BASE),
1576+ DUMP_WED(WED_RX_BM_RX_DMAD),
1577+ DUMP_WED(WED_RX_BM_PTR),
1578+ DUMP_WED(WED_RX_BM_TKID_MIB),
1579+ DUMP_WED(WED_RX_BM_BLEN),
1580+ DUMP_WED(WED_RX_BM_STS),
1581+ DUMP_WED(WED_RX_BM_INTF2),
1582+ DUMP_WED(WED_RX_BM_INTF),
1583+ DUMP_WED(WED_RX_BM_ERR_STS),
1584+ };
1585+
1586+ struct mtk_wed_hw *hw = s->private;
1587+ struct mtk_wed_device *dev = hw->wed_dev;
1588+
1589+ if (!dev)
1590+ return 0;
1591+
1592+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
1593+
1594+ return 0;
1595+}
1596+DEFINE_SHOW_ATTRIBUTE(wed_rxinfo);
1597
1598 static int
1599 mtk_wed_reg_set(void *data, u64 val)
1600@@ -175,4 +261,8 @@ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
1601 debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
1602 debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
1603 debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
1604+ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, &wed_rxinfo_fops);
developerc1b2cd12022-07-28 18:35:24 +08001605+ if (hw->ver != MTK_WED_V1) {
developer8cb3ac72022-07-04 10:55:14 +08001606+ wed_wo_mcu_debugfs(hw, dir);
1607+ }
1608 }
1609diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
1610new file mode 100644
developer144824b2022-11-25 21:27:43 +08001611index 0000000..96e30a3
developer8cb3ac72022-07-04 10:55:14 +08001612--- /dev/null
1613+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
developer8fec8ae2022-08-15 15:01:09 -07001614@@ -0,0 +1,586 @@
developer8cb3ac72022-07-04 10:55:14 +08001615+// SPDX-License-Identifier: GPL-2.0-only
1616+
1617+#include <linux/skbuff.h>
1618+#include <linux/debugfs.h>
1619+#include <linux/firmware.h>
1620+#include <linux/of_address.h>
1621+#include <linux/soc/mediatek/mtk_wed.h>
1622+#include "mtk_wed_regs.h"
1623+#include "mtk_wed_mcu.h"
1624+#include "mtk_wed_wo.h"
1625+
1626+struct sk_buff *
1627+mtk_wed_mcu_msg_alloc(struct mtk_wed_wo *wo,
1628+ const void *data, int data_len)
1629+{
1630+ const struct wed_wo_mcu_ops *ops = wo->mcu_ops;
1631+ int length = ops->headroom + data_len;
1632+ struct sk_buff *skb;
1633+
1634+ skb = alloc_skb(length, GFP_KERNEL);
1635+ if (!skb)
1636+ return NULL;
1637+
1638+ memset(skb->head, 0, length);
1639+ skb_reserve(skb, ops->headroom);
1640+
1641+ if (data && data_len)
1642+ skb_put_data(skb, data, data_len);
1643+
1644+ return skb;
1645+}
1646+
1647+struct sk_buff *
1648+mtk_wed_mcu_get_response(struct mtk_wed_wo *wo, unsigned long expires)
1649+{
1650+ unsigned long timeout;
1651+
1652+ if (!time_is_after_jiffies(expires))
1653+ return NULL;
1654+
1655+ timeout = expires - jiffies;
1656+ wait_event_timeout(wo->mcu.wait,
1657+ (!skb_queue_empty(&wo->mcu.res_q)),
1658+ timeout);
1659+
1660+ return skb_dequeue(&wo->mcu.res_q);
1661+}
1662+
1663+int
1664+mtk_wed_mcu_skb_send_and_get_msg(struct mtk_wed_wo *wo,
1665+ int to_id, int cmd, struct sk_buff *skb,
1666+ bool wait_resp, struct sk_buff **ret_skb)
1667+{
1668+ unsigned long expires;
1669+ int ret, seq;
1670+
1671+ if (ret_skb)
1672+ *ret_skb = NULL;
1673+
1674+ mutex_lock(&wo->mcu.mutex);
1675+
1676+ ret = wo->mcu_ops->mcu_skb_send_msg(wo, to_id, cmd, skb, &seq, wait_resp);
1677+ if (ret < 0)
1678+ goto out;
1679+
1680+ if (!wait_resp) {
1681+ ret = 0;
1682+ goto out;
1683+ }
1684+
1685+ expires = jiffies + wo->mcu.timeout;
1686+
1687+ do {
1688+ skb = mtk_wed_mcu_get_response(wo, expires);
1689+ ret = wo->mcu_ops->mcu_parse_response(wo, cmd, skb, seq);
1690+
1691+ if (!ret && ret_skb)
1692+ *ret_skb = skb;
1693+ else
1694+ dev_kfree_skb(skb);
1695+ } while (ret == -EAGAIN);
1696+
1697+out:
1698+ mutex_unlock(&wo->mcu.mutex);
1699+
1700+ return ret;
1701+}
1702+
1703+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo,
1704+ struct sk_buff *skb)
1705+{
1706+ skb_queue_tail(&wo->mcu.res_q, skb);
1707+ wake_up(&wo->mcu.wait);
1708+}
1709+
1710+static int mtk_wed_mcu_send_and_get_msg(struct mtk_wed_wo *wo,
1711+ int to_id, int cmd, const void *data, int len,
1712+ bool wait_resp, struct sk_buff **ret_skb)
1713+{
1714+ struct sk_buff *skb;
1715+
1716+ skb = mtk_wed_mcu_msg_alloc(wo, data, len);
1717+ if (!skb)
1718+ return -ENOMEM;
1719+
1720+ return mtk_wed_mcu_skb_send_and_get_msg(wo, to_id, cmd, skb, wait_resp, ret_skb);
1721+}
1722+
1723+int
1724+mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo,
1725+ int to_id, int cmd,
1726+ const void *data, int len, bool wait_resp)
1727+{
1728+ struct sk_buff *skb = NULL;
1729+ int ret = 0;
1730+
1731+ ret = mtk_wed_mcu_send_and_get_msg(wo, to_id, cmd, data,
1732+ len, wait_resp, &skb);
1733+ if (skb)
1734+ dev_kfree_skb(skb);
1735+
1736+ return ret;
1737+}
1738+
1739+int mtk_wed_exception_init(struct mtk_wed_wo *wo)
1740+{
1741+ struct wed_wo_exception *exp = &wo->exp;
1742+ struct {
1743+ u32 arg0;
1744+ u32 arg1;
1745+ }req;
1746+
1747+ exp->log_size = EXCEPTION_LOG_SIZE;
1748+ exp->log = kmalloc(exp->log_size, GFP_ATOMIC);
1749+ if (!exp->log)
1750+ return -ENOMEM;
1751+
1752+ memset(exp->log, 0, exp->log_size);
1753+ exp->phys = dma_map_single(wo->hw->dev, exp->log, exp->log_size,
1754+ DMA_FROM_DEVICE);
1755+
1756+ if (unlikely(dma_mapping_error(wo->hw->dev, exp->phys))) {
1757+ dev_info(wo->hw->dev, "dma map error\n");
1758+ goto free;
1759+ }
1760+
1761+ req.arg0 = (u32)exp->phys;
1762+ req.arg1 = (u32)exp->log_size;
1763+
developer144824b2022-11-25 21:27:43 +08001764+ return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_EXCEPTION_INIT,
developer8cb3ac72022-07-04 10:55:14 +08001765+ &req, sizeof(req), false);
1766+
1767+free:
1768+ kfree(exp->log);
1769+ return -ENOMEM;
1770+}
1771+
1772+int
1773+mtk_wed_mcu_cmd_sanity_check(struct mtk_wed_wo *wo, struct sk_buff *skb)
1774+{
1775+ struct wed_cmd_hdr *hdr = (struct wed_cmd_hdr *)skb->data;
1776+
1777+ if (hdr->ver != 0)
1778+ return WARP_INVALID_PARA_STATUS;
1779+
1780+ if (skb->len < sizeof(struct wed_cmd_hdr))
1781+ return WARP_INVALID_PARA_STATUS;
1782+
1783+ if (skb->len != hdr->length)
1784+ return WARP_INVALID_PARA_STATUS;
1785+
1786+ return WARP_OK_STATUS;
1787+}
1788+
1789+void
1790+mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, struct sk_buff *skb)
1791+{
developer8fec8ae2022-08-15 15:01:09 -07001792+ struct mtk_wed_device *wed = wo->hw->wed_dev;
developer8cb3ac72022-07-04 10:55:14 +08001793+ struct wed_cmd_hdr *hdr = (struct wed_cmd_hdr *)skb->data;
1794+ struct wed_wo_log *record;
developer144824b2022-11-25 21:27:43 +08001795+ struct mtk_wed_wo_rx_stats *rxcnt;
developer8cb3ac72022-07-04 10:55:14 +08001796+ char *msg = (char *)(skb->data + sizeof(struct wed_cmd_hdr));
1797+ u16 msg_len = skb->len - sizeof(struct wed_cmd_hdr);
1798+ u32 i, cnt = 0;
1799+
1800+ switch (hdr->cmd_id) {
1801+ case WO_EVT_LOG_DUMP:
1802+ pr_info("[WO LOG]: %s\n", msg);
1803+ break;
1804+ case WO_EVT_PROFILING:
1805+ cnt = msg_len / (sizeof(struct wed_wo_log));
1806+ record = (struct wed_wo_log *) msg;
1807+ dev_info(wo->hw->dev, "[WO Profiling]: %d report arrived!\n", cnt);
1808+
1809+ for (i = 0 ; i < cnt ; i++) {
1810+ //PROFILE_STAT(wo->total, record[i].total);
1811+ //PROFILE_STAT(wo->mod, record[i].mod);
1812+ //PROFILE_STAT(wo->rro, record[i].rro);
1813+
1814+ dev_info(wo->hw->dev, "[WO Profiling]: SN:%u with latency: total=%u, rro:%u, mod:%u\n",
1815+ record[i].sn,
1816+ record[i].total,
1817+ record[i].rro,
1818+ record[i].mod);
1819+ }
1820+ break;
developer8fec8ae2022-08-15 15:01:09 -07001821+ case WO_EVT_RXCNT_INFO:
1822+ cnt = *(u32 *)msg;
developer144824b2022-11-25 21:27:43 +08001823+ rxcnt = (struct mtk_wed_wo_rx_stats *)((u32 *)msg+1);
developer8cb3ac72022-07-04 10:55:14 +08001824+
developer8fec8ae2022-08-15 15:01:09 -07001825+ for (i = 0; i < cnt; i++)
developer144824b2022-11-25 21:27:43 +08001826+ if (wed->wlan.update_wo_rx_stats)
1827+ wed->wlan.update_wo_rx_stats(wed, &rxcnt[i]);
developer8fec8ae2022-08-15 15:01:09 -07001828+ break;
developer8cb3ac72022-07-04 10:55:14 +08001829+ default:
1830+ break;
1831+ }
1832+
1833+ dev_kfree_skb(skb);
1834+
1835+}
1836+
1837+static int
1838+mtk_wed_load_firmware(struct mtk_wed_wo *wo)
1839+{
1840+ struct fw_info {
1841+ __le32 decomp_crc;
1842+ __le32 decomp_len;
1843+ __le32 decomp_blk_sz;
1844+ u8 reserved[4];
1845+ __le32 addr;
1846+ __le32 len;
1847+ u8 feature_set;
1848+ u8 reserved1[15];
1849+ } __packed *region;
1850+
1851+ char *mcu;
1852+ const struct mtk_wed_fw_trailer *hdr;
1853+ static u8 shared[MAX_REGION_SIZE] = {0};
1854+ const struct firmware *fw;
1855+ int ret, i;
1856+ u32 ofs = 0;
1857+ u32 boot_cr, val;
1858+
1859+ mcu = wo->hw->index ? MT7986_FIRMWARE_WO_2 : MT7986_FIRMWARE_WO_1;
1860+
1861+ ret = request_firmware(&fw, mcu, wo->hw->dev);
1862+ if (ret)
1863+ return ret;
1864+
1865+ hdr = (const struct mtk_wed_fw_trailer *)(fw->data + fw->size -
1866+ sizeof(*hdr));
1867+
1868+ dev_info(wo->hw->dev, "WO Firmware Version: %.10s, Build Time: %.15s\n",
1869+ hdr->fw_ver, hdr->build_date);
1870+
1871+ for (i = 0; i < hdr->n_region; i++) {
1872+ int j = 0;
1873+ region = (struct fw_info *)(fw->data + fw->size -
1874+ sizeof(*hdr) -
1875+ sizeof(*region) *
1876+ (hdr->n_region - i));
1877+
1878+ while (j < MAX_REGION_SIZE) {
1879+ struct mtk_wed_fw_region *wo_region;
1880+
1881+ wo_region = &wo->region[j];
1882+ if (!wo_region->addr)
1883+ break;
1884+
1885+ if (wo_region->addr_pa == region->addr) {
1886+ if (!wo_region->shared) {
1887+ memcpy(wo_region->addr,
1888+ fw->data + ofs, region->len);
1889+ } else if (!shared[j]) {
1890+ memcpy(wo_region->addr,
1891+ fw->data + ofs, region->len);
1892+ shared[j] = true;
1893+ }
1894+ }
1895+ j++;
1896+ }
1897+
1898+ if (j == __WO_REGION_MAX) {
1899+ ret = -ENOENT;
1900+ goto done;
1901+ }
1902+ ofs += region->len;
1903+ }
1904+
1905+ /* write the start address */
1906+ boot_cr = wo->hw->index ?
1907+ WOX_MCU_CFG_LS_WA_BOOT_ADDR_ADDR : WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
1908+ wo_w32(wo, boot_cr, (wo->region[WO_REGION_EMI].addr_pa >> 16));
1909+
1910+ /* wo firmware reset */
1911+ wo_w32(wo, WOX_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
1912+
1913+ val = wo_r32(wo, WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
1914+
1915+ val |= wo->hw->index ? WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WA_CPU_RSTB_MASK :
1916+ WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WM_CPU_RSTB_MASK;
1917+
1918+ wo_w32(wo, WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
1919+
1920+done:
1921+ release_firmware(fw);
1922+
1923+ return ret;
1924+}
1925+
1926+static int
1927+mtk_wed_get_firmware_region(struct mtk_wed_wo *wo)
1928+{
1929+ struct device_node *node, *np = wo->hw->node;
1930+ struct mtk_wed_fw_region *region;
1931+ struct resource res;
1932+ const char *compat;
1933+ int i, ret;
1934+
1935+ static const char *const wo_region_compat[__WO_REGION_MAX] = {
1936+ [WO_REGION_EMI] = WOCPU_EMI_DEV_NODE,
1937+ [WO_REGION_ILM] = WOCPU_ILM_DEV_NODE,
1938+ [WO_REGION_DATA] = WOCPU_DATA_DEV_NODE,
1939+ [WO_REGION_BOOT] = WOCPU_BOOT_DEV_NODE,
1940+ };
1941+
1942+ for (i = 0; i < __WO_REGION_MAX; i++) {
1943+ region = &wo->region[i];
1944+ compat = wo_region_compat[i];
1945+
1946+ node = of_parse_phandle(np, compat, 0);
1947+ if (!node)
1948+ return -ENODEV;
1949+
1950+ ret = of_address_to_resource(node, 0, &res);
1951+ if (ret)
1952+ return ret;
1953+
1954+ region->addr_pa = res.start;
1955+ region->size = resource_size(&res);
1956+ region->addr = ioremap(region->addr_pa, region->size);
1957+
1958+ of_property_read_u32_index(node, "shared", 0, &region->shared);
1959+ }
1960+
1961+ return 0;
1962+}
1963+
1964+static int
1965+wo_mcu_send_message(struct mtk_wed_wo *wo,
1966+ int to_id, int cmd, struct sk_buff *skb,
1967+ int *wait_seq, bool wait_resp)
1968+{
1969+ struct wed_cmd_hdr *hdr;
1970+ u8 seq = 0;
1971+
1972+ /* TDO: make dynamic based on msg type */
1973+ wo->mcu.timeout = 20 * HZ;
1974+
1975+ if (wait_resp && wait_seq) {
1976+ seq = wo->mcu.msg_seq++ ;
1977+ *wait_seq = seq;
1978+ }
1979+
1980+ hdr = (struct wed_cmd_hdr *)skb_push(skb, sizeof(*hdr));
1981+
1982+ hdr->cmd_id = cmd;
1983+ hdr->length = cpu_to_le16(skb->len);
1984+ hdr->uni_id = seq;
1985+
1986+ if (to_id == MODULE_ID_WO)
1987+ hdr->flag |= WARP_CMD_FLAG_FROM_TO_WO;
1988+
1989+ if (wait_resp && wait_seq)
1990+ hdr->flag |= WARP_CMD_FLAG_NEED_RSP;
1991+
1992+ return mtk_wed_wo_q_tx_skb(wo, &wo->q_tx, skb);
1993+}
1994+
1995+static int
1996+wo_mcu_parse_response(struct mtk_wed_wo *wo, int cmd,
1997+ struct sk_buff *skb, int seq)
1998+{
developer8fec8ae2022-08-15 15:01:09 -07001999+ struct mtk_wed_device *wed = wo->hw->wed_dev;
developer8cb3ac72022-07-04 10:55:14 +08002000+ struct wed_cmd_hdr *hdr;
developer144824b2022-11-25 21:27:43 +08002001+ struct mtk_wed_wo_rx_stats *rxcnt = NULL;
developer8fec8ae2022-08-15 15:01:09 -07002002+ u32 i, cnt = 0;
developer8cb3ac72022-07-04 10:55:14 +08002003+
2004+ if (!skb) {
2005+ dev_err(wo->hw->dev, "Message %08x (seq %d) timeout\n",
2006+ cmd, seq);
2007+ return -ETIMEDOUT;
2008+ }
2009+
2010+ hdr = (struct wed_cmd_hdr *)skb->data;
2011+ if (seq != hdr->uni_id) {
2012+ dev_err(wo->hw->dev, "Message %08x (seq %d) with not match uid(%d)\n",
2013+ cmd, seq, hdr->uni_id);
2014+ return -EAGAIN;
2015+ }
2016+
developer8fec8ae2022-08-15 15:01:09 -07002017+ skb_pull(skb, sizeof(struct wed_cmd_hdr));
2018+
2019+ switch (cmd) {
developer144824b2022-11-25 21:27:43 +08002020+ case MTK_WED_WO_CMD_RXCNT_INFO:
developer8fec8ae2022-08-15 15:01:09 -07002021+ cnt = *(u32 *)skb->data;
developer144824b2022-11-25 21:27:43 +08002022+ rxcnt = (struct mtk_wed_wo_rx_stats *)((u32 *)skb->data+1);
developer8fec8ae2022-08-15 15:01:09 -07002023+
2024+ for (i = 0; i < cnt; i++)
developer144824b2022-11-25 21:27:43 +08002025+ if (wed->wlan.update_wo_rx_stats)
2026+ wed->wlan.update_wo_rx_stats(wed, &rxcnt[i]);
developer8fec8ae2022-08-15 15:01:09 -07002027+ break;
2028+ default:
2029+ break;
2030+ }
developer8cb3ac72022-07-04 10:55:14 +08002031+
2032+ return 0;
2033+}
2034+
2035+int wed_wo_mcu_init(struct mtk_wed_wo *wo)
2036+{
2037+ static const struct wed_wo_mcu_ops wo_mcu_ops = {
2038+ .headroom = sizeof(struct wed_cmd_hdr),
2039+ .mcu_skb_send_msg = wo_mcu_send_message,
2040+ .mcu_parse_response = wo_mcu_parse_response,
2041+ /*TDO .mcu_restart = wo_mcu_restart,*/
2042+ };
2043+ unsigned long timeout = jiffies + FW_DL_TIMEOUT;
2044+ int ret;
2045+ u32 val;
2046+
2047+ wo->mcu_ops = &wo_mcu_ops;
2048+
2049+ ret = mtk_wed_get_firmware_region(wo);
2050+ if (ret)
2051+ return ret;
2052+
2053+ /* set dummy cr */
2054+ wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * WED_DUMMY_CR_FWDL,
2055+ wo->hw->index + 1);
2056+
2057+ ret = mtk_wed_load_firmware(wo);
2058+ if (ret)
2059+ return ret;
2060+
2061+ do {
2062+ /* get dummy cr */
2063+ val = wed_r32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * WED_DUMMY_CR_FWDL);
2064+ } while (val != 0 && !time_after(jiffies, timeout));
2065+
2066+ if (val)
2067+ return -EBUSY;
2068+
2069+ return 0;
2070+}
2071+
2072+static ssize_t
2073+mtk_wed_wo_ctrl(struct file *file,
2074+ const char __user *user_buf,
2075+ size_t count,
2076+ loff_t *ppos)
2077+{
2078+ struct mtk_wed_hw *hw = file->private_data;
2079+ struct mtk_wed_wo *wo = hw->wed_wo;
2080+ char buf[100], *cmd = NULL, *input[11] = {0};
2081+ char msgbuf[128] = {0};
2082+ struct wo_cmd_query *query = (struct wo_cmd_query *)msgbuf;
2083+ u32 cmd_id;
2084+ bool wait = false;
2085+ char *sub_str = NULL;
2086+ int input_idx = 0, input_total = 0, scan_num = 0;
2087+ char *p;
2088+
2089+ if (count > sizeof(buf))
2090+ return -EINVAL;
2091+
2092+ if (copy_from_user(buf, user_buf, count))
2093+ return -EFAULT;
2094+
2095+ if (count && buf[count - 1] == '\n')
2096+ buf[count - 1] = '\0';
2097+ else
2098+ buf[count] = '\0';
2099+
2100+ p = buf;
2101+
2102+ while ((sub_str = strsep(&p, " ")) != NULL) {
2103+ input[input_idx] = sub_str;
2104+ input_idx++;
2105+ input_total++;
2106+ }
2107+ cmd = input[0];
2108+ if (input_total == 1 && cmd) {
2109+ if (strncmp(cmd, "bainfo", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002110+ cmd_id = MTK_WED_WO_CMD_BA_INFO_DUMP;
developer8cb3ac72022-07-04 10:55:14 +08002111+ } else if (strncmp(cmd, "bactrl", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002112+ cmd_id = MTK_WED_WO_CMD_BA_CTRL_DUMP;
developer8cb3ac72022-07-04 10:55:14 +08002113+ } else if (strncmp(cmd, "fbcmdq", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002114+ cmd_id = MTK_WED_WO_CMD_FBCMD_Q_DUMP;
developer8cb3ac72022-07-04 10:55:14 +08002115+ } else if (strncmp(cmd, "logflush", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002116+ cmd_id = MTK_WED_WO_CMD_LOG_FLUSH;
developer8cb3ac72022-07-04 10:55:14 +08002117+ } else if (strncmp(cmd, "cpustat.dump", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002118+ cmd_id = MTK_WED_WO_CMD_CPU_STATS_DUMP;
developer8cb3ac72022-07-04 10:55:14 +08002119+ } else if (strncmp(cmd, "state", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002120+ cmd_id = MTK_WED_WO_CMD_WED_RX_STAT;
developer8cb3ac72022-07-04 10:55:14 +08002121+ } else if (strncmp(cmd, "prof_hit_dump", strlen(cmd)) == 0) {
2122+ //wo_profiling_report();
2123+ return count;
2124+ } else if (strncmp(cmd, "rxcnt_info", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002125+ cmd_id = MTK_WED_WO_CMD_RXCNT_INFO;
developer8cb3ac72022-07-04 10:55:14 +08002126+ wait = true;
2127+ } else {
2128+ pr_info("(%s) unknown comand string(%s)!\n", __func__, cmd);
2129+ return count;
2130+ }
2131+ } else if (input_total > 1) {
2132+ for (input_idx = 1 ; input_idx < input_total ; input_idx++) {
2133+ scan_num = sscanf(input[input_idx], "%u", &query->query0+(input_idx - 1));
2134+
2135+ if (scan_num < 1) {
2136+ pr_info("(%s) require more input!\n", __func__);
2137+ return count;
2138+ }
2139+ }
2140+ if(strncmp(cmd, "devinfo", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002141+ cmd_id = MTK_WED_WO_CMD_DEV_INFO_DUMP;
developer8cb3ac72022-07-04 10:55:14 +08002142+ } else if (strncmp(cmd, "bssinfo", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002143+ cmd_id = MTK_WED_WO_CMD_BSS_INFO_DUMP;
developer8cb3ac72022-07-04 10:55:14 +08002144+ } else if (strncmp(cmd, "starec", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002145+ cmd_id = MTK_WED_WO_CMD_STA_REC_DUMP;
developer8cb3ac72022-07-04 10:55:14 +08002146+ } else if (strncmp(cmd, "starec_ba", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002147+ cmd_id = MTK_WED_WO_CMD_STA_BA_DUMP;
developer8cb3ac72022-07-04 10:55:14 +08002148+ } else if (strncmp(cmd, "logctrl", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002149+ cmd_id = MTK_WED_WO_CMD_FW_LOG_CTRL;
developer8cb3ac72022-07-04 10:55:14 +08002150+ } else if (strncmp(cmd, "cpustat.en", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002151+ cmd_id = MTK_WED_WO_CMD_CPU_STATS_ENABLE;
developer8cb3ac72022-07-04 10:55:14 +08002152+ } else if (strncmp(cmd, "prof_conf", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002153+ cmd_id = MTK_WED_WO_CMD_PROF_CTRL;
developer8cb3ac72022-07-04 10:55:14 +08002154+ } else if (strncmp(cmd, "rxcnt_ctrl", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002155+ cmd_id = MTK_WED_WO_CMD_RXCNT_CTRL;
developer8cb3ac72022-07-04 10:55:14 +08002156+ } else if (strncmp(cmd, "dbg_set", strlen(cmd)) == 0) {
developer144824b2022-11-25 21:27:43 +08002157+ cmd_id = MTK_WED_WO_CMD_DBG_INFO;
developer8cb3ac72022-07-04 10:55:14 +08002158+ }
2159+ } else {
2160+ dev_info(hw->dev, "usage: echo cmd='cmd_str' > wo_write\n");
2161+ dev_info(hw->dev, "cmd_str value range:\n");
2162+ dev_info(hw->dev, "\tbainfo:\n");
2163+ dev_info(hw->dev, "\tbactrl:\n");
2164+ dev_info(hw->dev, "\tfbcmdq:\n");
2165+ dev_info(hw->dev, "\tlogflush:\n");
2166+ dev_info(hw->dev, "\tcpustat.dump:\n");
2167+ dev_info(hw->dev, "\tprof_hit_dump:\n");
2168+ dev_info(hw->dev, "\trxcnt_info:\n");
2169+ dev_info(hw->dev, "\tdevinfo:\n");
2170+ dev_info(hw->dev, "\tbssinfo:\n");
2171+ dev_info(hw->dev, "\tstarec:\n");
2172+ dev_info(hw->dev, "\tstarec_ba:\n");
2173+ dev_info(hw->dev, "\tlogctrl:\n");
2174+ dev_info(hw->dev, "\tcpustat.en:\n");
2175+ dev_info(hw->dev, "\tprof_conf:\n");
2176+ dev_info(hw->dev, "\trxcnt_ctrl:\n");
2177+ dev_info(hw->dev, "\tdbg_set [level] [category]:\n");
2178+ return count;
2179+ }
2180+
2181+ mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, cmd_id, (void *)msgbuf, sizeof(struct wo_cmd_query), wait);
2182+
2183+ return count;
2184+
2185+}
2186+
2187+static const struct file_operations fops_wo_ctrl = {
2188+ .write = mtk_wed_wo_ctrl,
2189+ .open = simple_open,
2190+ .llseek = default_llseek,
2191+};
2192+
2193+void wed_wo_mcu_debugfs(struct mtk_wed_hw *hw, struct dentry *dir)
2194+{
2195+ if (!dir)
2196+ return;
2197+
2198+ debugfs_create_file("wo_write", 0600, dir, hw, &fops_wo_ctrl);
2199+}
2200+
2201diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
2202new file mode 100644
developer144824b2022-11-25 21:27:43 +08002203index 0000000..19e1199
developer8cb3ac72022-07-04 10:55:14 +08002204--- /dev/null
2205+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
developerfaaa5162022-10-24 14:12:16 +08002206@@ -0,0 +1,96 @@
developer8cb3ac72022-07-04 10:55:14 +08002207+// SPDX-License-Identifier: GPL-2.0-only
2208+
2209+#ifndef __MTK_WED_MCU_H
2210+#define __MTK_WED_MCU_H
2211+
2212+#define EXCEPTION_LOG_SIZE 32768
2213+#define WOCPU_MCUSYS_RESET_ADDR 0x15194050
2214+#define WOCPU_WO0_MCUSYS_RESET_MASK 0x20
2215+#define WOCPU_WO1_MCUSYS_RESET_MASK 0x1
2216+
2217+#define WARP_INVALID_LENGTH_STATUS (-2)
2218+#define WARP_NULL_POINTER_STATUS (-3)
2219+#define WARP_INVALID_PARA_STATUS (-4)
2220+#define WARP_NOT_HANDLE_STATUS (-5)
2221+#define WARP_FAIL_STATUS (-1)
2222+#define WARP_OK_STATUS (0)
2223+#define WARP_ALREADY_DONE_STATUS (1)
2224+
2225+#define MT7986_FIRMWARE_WO_1 "mediatek/mt7986_wo_0.bin"
2226+#define MT7986_FIRMWARE_WO_2 "mediatek/mt7986_wo_1.bin"
2227+
2228+#define WOCPU_EMI_DEV_NODE "mediatek,wocpu_emi"
2229+#define WOCPU_ILM_DEV_NODE "mediatek,wocpu_ilm"
2230+#define WOCPU_DLM_DEV_NODE "mediatek,wocpu_dlm"
2231+#define WOCPU_DATA_DEV_NODE "mediatek,wocpu_data"
2232+#define WOCPU_BOOT_DEV_NODE "mediatek,wocpu_boot"
2233+
2234+#define FW_DL_TIMEOUT ((3000 * HZ) / 1000)
2235+#define WOCPU_TIMEOUT ((1000 * HZ) / 1000)
2236+
2237+#define MAX_REGION_SIZE 3
2238+
2239+#define WOX_MCU_CFG_LS_BASE 0 /*0x15194000*/
2240+
2241+#define WOX_MCU_CFG_LS_HW_VER_ADDR (WOX_MCU_CFG_LS_BASE + 0x000) // 4000
2242+#define WOX_MCU_CFG_LS_FW_VER_ADDR (WOX_MCU_CFG_LS_BASE + 0x004) // 4004
2243+#define WOX_MCU_CFG_LS_CFG_DBG1_ADDR (WOX_MCU_CFG_LS_BASE + 0x00C) // 400C
2244+#define WOX_MCU_CFG_LS_CFG_DBG2_ADDR (WOX_MCU_CFG_LS_BASE + 0x010) // 4010
2245+#define WOX_MCU_CFG_LS_WF_MCCR_ADDR (WOX_MCU_CFG_LS_BASE + 0x014) // 4014
2246+#define WOX_MCU_CFG_LS_WF_MCCR_SET_ADDR (WOX_MCU_CFG_LS_BASE + 0x018) // 4018
2247+#define WOX_MCU_CFG_LS_WF_MCCR_CLR_ADDR (WOX_MCU_CFG_LS_BASE + 0x01C) // 401C
2248+#define WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR (WOX_MCU_CFG_LS_BASE + 0x050) // 4050
2249+#define WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR (WOX_MCU_CFG_LS_BASE + 0x060) // 4060
2250+#define WOX_MCU_CFG_LS_WA_BOOT_ADDR_ADDR (WOX_MCU_CFG_LS_BASE + 0x064) // 4064
2251+
2252+#define WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WM_CPU_RSTB_MASK BIT(5)
2253+#define WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WA_CPU_RSTB_MASK BIT(0)
2254+
2255+
2256+enum wo_event_id {
2257+ WO_EVT_LOG_DUMP = 0x1,
2258+ WO_EVT_PROFILING = 0x2,
2259+ WO_EVT_RXCNT_INFO = 0x3
2260+};
2261+
developer8cb3ac72022-07-04 10:55:14 +08002262+enum wo_state {
2263+ WO_STATE_UNDEFINED = 0x0,
2264+ WO_STATE_INIT = 0x1,
2265+ WO_STATE_ENABLE = 0x2,
2266+ WO_STATE_DISABLE = 0x3,
2267+ WO_STATE_HALT = 0x4,
2268+ WO_STATE_GATING = 0x5,
2269+ WO_STATE_SER_RESET = 0x6,
2270+ WO_STATE_WF_RESET = 0x7,
2271+ WO_STATE_END
2272+};
2273+
2274+enum wo_done_state {
2275+ WOIF_UNDEFINED = 0,
2276+ WOIF_DISABLE_DONE = 1,
2277+ WOIF_TRIGGER_ENABLE = 2,
2278+ WOIF_ENABLE_DONE = 3,
2279+ WOIF_TRIGGER_GATING = 4,
2280+ WOIF_GATING_DONE = 5,
2281+ WOIF_TRIGGER_HALT = 6,
2282+ WOIF_HALT_DONE = 7,
2283+};
2284+
2285+enum wed_dummy_cr_idx {
2286+ WED_DUMMY_CR_FWDL = 0,
2287+ WED_DUMMY_CR_WO_STATUS = 1
2288+};
2289+
2290+struct mtk_wed_fw_trailer {
2291+ u8 chip_id;
2292+ u8 eco_code;
2293+ u8 n_region;
2294+ u8 format_ver;
2295+ u8 format_flag;
2296+ u8 reserved[2];
2297+ char fw_ver[10];
2298+ char build_date[15];
2299+ u32 crc;
2300+};
2301+
2302+#endif
2303diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
developere0cbe332022-09-10 17:36:02 +08002304index b189761..9d021e2 100644
developer8cb3ac72022-07-04 10:55:14 +08002305--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
2306+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
2307@@ -4,6 +4,8 @@
2308 #ifndef __MTK_WED_REGS_H
2309 #define __MTK_WED_REGS_H
2310
2311+#define MTK_WFDMA_DESC_CTRL_TO_HOST BIT(8)
2312+
2313 #if defined(CONFIG_MEDIATEK_NETSYS_V2)
2314 #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(13, 0)
2315 #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(14)
2316@@ -16,6 +18,7 @@
2317 #define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16)
2318 #define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30)
2319 #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
2320+#define MTK_WED_RX_BM_TOKEN GENMASK(31, 16)
2321
2322 struct mtk_wdma_desc {
2323 __le32 buf0;
developere0cbe332022-09-10 17:36:02 +08002324@@ -42,6 +45,8 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002325 #define MTK_WED_RESET_WED_TX_DMA BIT(12)
2326 #define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
2327 #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
2328+#define MTK_WED_RESET_RX_RRO_QM BIT(20)
2329+#define MTK_WED_RESET_RX_ROUTE_QM BIT(21)
2330 #define MTK_WED_RESET_WED BIT(31)
2331
2332 #define MTK_WED_CTRL 0x00c
developere0cbe332022-09-10 17:36:02 +08002333@@ -53,8 +58,12 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002334 #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
2335 #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
2336 #define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11)
2337-#define MTK_WED_CTRL_RESERVE_EN BIT(12)
2338-#define MTK_WED_CTRL_RESERVE_BUSY BIT(13)
2339+#define MTK_WED_CTRL_WED_RX_BM_EN BIT(12)
2340+#define MTK_WED_CTRL_WED_RX_BM_BUSY BIT(13)
2341+#define MTK_WED_CTRL_RX_RRO_QM_EN BIT(14)
2342+#define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15)
2343+#define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16)
2344+#define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17)
2345 #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24)
2346 #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25)
2347 #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
developere0cbe332022-09-10 17:36:02 +08002348@@ -69,8 +78,8 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002349 #define MTK_WED_EXT_INT_STATUS_TX_TKID_LO_TH BIT(10)
2350 #define MTK_WED_EXT_INT_STATUS_TX_TKID_HI_TH BIT(11)
2351 #endif
2352-#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12)
2353-#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13)
2354+#define MTK_WED_EXT_INT_STATUS_RX_FREE_AT_EMPTY BIT(12)
2355+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_DMAD_ER BIT(13)
2356 #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16)
2357 #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17)
2358 #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18)
developere0cbe332022-09-10 17:36:02 +08002359@@ -87,8 +96,8 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002360 #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
2361 MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
2362 MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \
2363- MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | \
2364- MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | \
2365+ MTK_WED_EXT_INT_STATUS_RX_FREE_AT_EMPTY | \
2366+ MTK_WED_EXT_INT_STATUS_RX_FBUF_DMAD_ER | \
2367 MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \
2368 MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \
2369 MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | \
developere0cbe332022-09-10 17:36:02 +08002370@@ -97,6 +106,8 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002371 MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR)
2372
2373 #define MTK_WED_EXT_INT_MASK 0x028
2374+#define MTK_WED_EXT_INT_MASK1 0x02c
2375+#define MTK_WED_EXT_INT_MASK2 0x030
2376
2377 #define MTK_WED_STATUS 0x060
2378 #define MTK_WED_STATUS_TX GENMASK(15, 8)
developere0cbe332022-09-10 17:36:02 +08002379@@ -184,6 +195,9 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002380
2381 #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10)
2382
2383+#define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10)
2384+
2385+#define MTK_WED_SCR0 0x3c0
2386 #define MTK_WED_WPDMA_INT_TRIGGER 0x504
2387 #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
2388 #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
developere0cbe332022-09-10 17:36:02 +08002389@@ -240,13 +254,19 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002390
2391 #define MTK_WED_WPDMA_INT_CTRL_TX 0x530
2392 #define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN BIT(0)
2393-#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR BIT(1)
2394+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR BIT(1)
2395 #define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG GENMASK(6, 2)
2396 #define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN BIT(8)
2397 #define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR BIT(9)
2398 #define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10)
2399
2400 #define MTK_WED_WPDMA_INT_CTRL_RX 0x534
2401+#define MTK_WED_WPDMA_INT_CTRL_RX0_EN BIT(0)
2402+#define MTK_WED_WPDMA_INT_CTRL_RX0_CLR BIT(1)
2403+#define MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG GENMASK(6, 2)
2404+#define MTK_WED_WPDMA_INT_CTRL_RX1_EN BIT(8)
2405+#define MTK_WED_WPDMA_INT_CTRL_RX1_CLR BIT(9)
2406+#define MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG GENMASK(14, 10)
2407
2408 #define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538
2409 #define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0)
developere0cbe332022-09-10 17:36:02 +08002410@@ -271,13 +291,40 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002411 #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4)
2412 #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4)
2413
2414+#define MTK_WED_WPDMA_RX_MIB(_n) (0x5e0 + (_n) * 4)
2415+#define MTK_WED_WPDMA_RX_COHERENT_MIB(_n) (0x5f0 + (_n) * 4)
2416+
2417 #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10)
2418 #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10)
developerc1b2cd12022-07-28 18:35:24 +08002419+#define MTK_WED_WPDMA_RING_RX_DATA(_n) (0x730 + (_n) * 0x10)
developer8cb3ac72022-07-04 10:55:14 +08002420+
2421+#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c
2422+#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0)
2423+#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7)
2424+#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)
2425+
2426+#define MTK_WED_WPDMA_RX_D_RST_IDX 0x760
developerc1b2cd12022-07-28 18:35:24 +08002427+#define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16)
2428+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
developer8cb3ac72022-07-04 10:55:14 +08002429+
2430+#define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
2431+#define MTK_WED_WPDMA_RX_RING 0x770
2432+
2433+#define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4)
2434+#define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
2435+#define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c
2436+
2437+#define MTK_WED_WDMA_RING_TX 0x800
2438+
2439+#define MTK_WED_WDMA_TX_MIB 0x810
2440+
2441+
2442 #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
2443 #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
2444
2445 #define MTK_WED_WDMA_GLO_CFG 0xa04
2446 #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
2447+#define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1)
2448 #define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2)
2449 #define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3)
2450 #define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4)
developere0cbe332022-09-10 17:36:02 +08002451@@ -321,6 +368,20 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002452 #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4)
2453 #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4)
2454
2455+#define MTK_WED_RX_BM_RX_DMAD 0xd80
2456+#define MTK_WED_RX_BM_RX_DMAD_SDL0 GENMASK(13, 0)
2457+
2458+#define MTK_WED_RX_BM_BASE 0xd84
2459+#define MTK_WED_RX_BM_INIT_PTR 0xd88
2460+#define MTK_WED_RX_BM_SW_TAIL GENMASK(15, 0)
2461+#define MTK_WED_RX_BM_INIT_SW_TAIL BIT(16)
2462+
2463+#define MTK_WED_RX_PTR 0xd8c
2464+
2465+#define MTK_WED_RX_BM_DYN_ALLOC_TH 0xdb4
2466+#define MTK_WED_RX_BM_DYN_ALLOC_TH_H GENMASK(31, 16)
2467+#define MTK_WED_RX_BM_DYN_ALLOC_TH_L GENMASK(15, 0)
2468+
2469 #define MTK_WED_RING_OFS_BASE 0x00
2470 #define MTK_WED_RING_OFS_COUNT 0x04
2471 #define MTK_WED_RING_OFS_CPU_IDX 0x08
developere0cbe332022-09-10 17:36:02 +08002472@@ -331,12 +392,13 @@ struct mtk_wdma_desc {
developera3f86ed2022-07-08 14:15:13 +08002473
2474 #define MTK_WDMA_GLO_CFG 0x204
2475 #define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0)
2476+#define MTK_WDMA_GLO_CFG_TX_DMA_BUSY BIT(1)
2477 #define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2)
2478+#define MTK_WDMA_GLO_CFG_RX_DMA_BUSY BIT(3)
2479 #define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26)
2480 #define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27)
2481 #define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28)
developerc1b2cd12022-07-28 18:35:24 +08002482
2483-
2484 #define MTK_WDMA_RESET_IDX 0x208
2485 #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0)
2486 #define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16)
developere0cbe332022-09-10 17:36:02 +08002487@@ -360,4 +422,70 @@ struct mtk_wdma_desc {
developer8cb3ac72022-07-04 10:55:14 +08002488 /* DMA channel mapping */
2489 #define HIFSYS_DMA_AG_MAP 0x008
2490
2491+#define MTK_WED_RTQM_GLO_CFG 0xb00
2492+#define MTK_WED_RTQM_BUSY BIT(1)
2493+#define MTK_WED_RTQM_Q_RST BIT(2)
2494+#define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
2495+#define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
2496+
2497+#define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4)
2498+#define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4)
2499+#define MTK_WED_RTQM_Q2N_MIB 0xb80
2500+#define MTK_WED_RTQM_Q2H_MIB(_n) (0xb84 + (_n) * 0x4)
2501+
2502+#define MTK_WED_RTQM_Q2B_MIB 0xb8c
2503+#define MTK_WED_RTQM_PFDBK_MIB 0xb90
2504+
2505+#define MTK_WED_RROQM_GLO_CFG 0xc04
2506+#define MTK_WED_RROQM_RST_IDX 0xc08
2507+#define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
2508+#define MTK_WED_RROQM_RST_IDX_FDBK BIT(4)
2509+
2510+#define MTK_WED_RROQM_MIOD_CTRL0 0xc40
2511+#define MTK_WED_RROQM_MIOD_CTRL1 0xc44
2512+#define MTK_WED_RROQM_MIOD_CNT GENMASK(11, 0)
2513+
2514+#define MTK_WED_RROQM_MIOD_CTRL2 0xc48
2515+#define MTK_WED_RROQM_MIOD_CTRL3 0xc4c
2516+
2517+#define MTK_WED_RROQM_FDBK_CTRL0 0xc50
2518+#define MTK_WED_RROQM_FDBK_CTRL1 0xc54
2519+#define MTK_WED_RROQM_FDBK_CNT GENMASK(11, 0)
2520+
2521+#define MTK_WED_RROQM_FDBK_CTRL2 0xc58
2522+
2523+#define MTK_WED_RROQ_BASE_L 0xc80
2524+#define MTK_WED_RROQ_BASE_H 0xc84
2525+
developer8cb3ac72022-07-04 10:55:14 +08002526+#define MTK_WED_RROQM_MIOD_CFG 0xc8c
2527+#define MTK_WED_RROQM_MIOD_MID_DW GENMASK(5, 0)
2528+#define MTK_WED_RROQM_MIOD_MOD_DW GENMASK(13, 8)
2529+#define MTK_WED_RROQM_MIOD_ENTRY_DW GENMASK(22, 16)
2530+
2531+#define MTK_WED_RROQM_MID_MIB 0xcc0
2532+#define MTK_WED_RROQM_MOD_MIB 0xcc4
2533+#define MTK_WED_RROQM_MOD_COHERENT_MIB 0xcc8
2534+#define MTK_WED_RROQM_FDBK_MIB 0xcd0
2535+#define MTK_WED_RROQM_FDBK_COHERENT_MIB 0xcd4
2536+#define MTK_WED_RROQM_FDBK_IND_MIB 0xce0
2537+#define MTK_WED_RROQM_FDBK_ENQ_MIB 0xce4
2538+#define MTK_WED_RROQM_FDBK_ANC_MIB 0xce8
2539+#define MTK_WED_RROQM_FDBK_ANC2H_MIB 0xcec
2540+
2541+#define MTK_WED_RX_BM_RX_DMAD 0xd80
2542+#define MTK_WED_RX_BM_BASE 0xd84
2543+#define MTK_WED_RX_BM_INIT_PTR 0xd88
2544+#define MTK_WED_RX_BM_PTR 0xd8c
2545+#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
2546+#define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0)
2547+
2548+#define MTK_WED_RX_BM_BLEN 0xd90
2549+#define MTK_WED_RX_BM_STS 0xd94
2550+#define MTK_WED_RX_BM_INTF2 0xd98
2551+#define MTK_WED_RX_BM_INTF 0xd9c
2552+#define MTK_WED_RX_BM_ERR_STS 0xda8
2553+
2554+#define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
2555+#define MTK_WED_PCIE_INT_MASK 0x0
2556+
2557 #endif
2558diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.c b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
2559new file mode 100644
developer144824b2022-11-25 21:27:43 +08002560index 0000000..54b7787
developer8cb3ac72022-07-04 10:55:14 +08002561--- /dev/null
2562+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
developer53bfd362022-09-29 12:02:18 +08002563@@ -0,0 +1,564 @@
developer8cb3ac72022-07-04 10:55:14 +08002564+// SPDX-License-Identifier: GPL-2.0-only
2565+
2566+#include <linux/kernel.h>
2567+#include <linux/bitfield.h>
2568+#include <linux/dma-mapping.h>
2569+#include <linux/skbuff.h>
2570+#include <linux/of_platform.h>
2571+#include <linux/interrupt.h>
2572+#include <linux/of_address.h>
2573+#include <linux/iopoll.h>
2574+#include <linux/soc/mediatek/mtk_wed.h>
2575+#include "mtk_wed.h"
2576+#include "mtk_wed_regs.h"
2577+#include "mtk_wed_ccif.h"
2578+#include "mtk_wed_wo.h"
2579+
2580+struct wed_wo_profile_stat profile_total[6] = {
2581+ {1001, 0},
2582+ {1501, 0},
2583+ {3001, 0},
2584+ {5001, 0},
2585+ {10001, 0},
2586+ {0xffffffff, 0}
2587+};
2588+
2589+struct wed_wo_profile_stat profiling_mod[6] = {
2590+ {1001, 0},
2591+ {1501, 0},
2592+ {3001, 0},
2593+ {5001, 0},
2594+ {10001, 0},
2595+ {0xffffffff, 0}
2596+};
2597+
2598+struct wed_wo_profile_stat profiling_rro[6] = {
2599+ {1001, 0},
2600+ {1501, 0},
2601+ {3001, 0},
2602+ {5001, 0},
2603+ {10001, 0},
2604+ {0xffffffff, 0}
2605+};
2606+
2607+static void
2608+woif_q_sync_idx(struct mtk_wed_wo *wo, struct wed_wo_queue *q)
2609+{
2610+ woccif_w32(wo, q->regs->desc_base, q->desc_dma);
2611+ woccif_w32(wo, q->regs->ring_size, q->ndesc);
2612+
developer8cb3ac72022-07-04 10:55:14 +08002613+}
2614+
2615+static void
2616+woif_q_reset(struct mtk_wed_wo *dev, struct wed_wo_queue *q)
2617+{
2618+
2619+ if (!q || !q->ndesc)
2620+ return;
2621+
2622+ woccif_w32(dev, q->regs->cpu_idx, 0);
2623+
2624+ woif_q_sync_idx(dev, q);
2625+}
2626+
2627+static void
2628+woif_q_kick(struct mtk_wed_wo *wo, struct wed_wo_queue *q, int offset)
2629+{
2630+ wmb();
2631+ woccif_w32(wo, q->regs->cpu_idx, q->head + offset);
2632+}
2633+
2634+static int
developer53bfd362022-09-29 12:02:18 +08002635+woif_q_rx_fill(struct mtk_wed_wo *wo, struct wed_wo_queue *q, bool rx)
developer8cb3ac72022-07-04 10:55:14 +08002636+{
2637+ int len = q->buf_size, frames = 0;
2638+ struct wed_wo_queue_entry *entry;
developer53bfd362022-09-29 12:02:18 +08002639+ struct page_frag_cache *page = &q->tx_page;
developer8cb3ac72022-07-04 10:55:14 +08002640+ struct wed_wo_desc *desc;
2641+ dma_addr_t addr;
2642+ u32 ctrl = 0;
2643+ void *buf;
2644+
2645+ if (!q->ndesc)
2646+ return 0;
2647+
2648+ spin_lock_bh(&q->lock);
2649+
developer53bfd362022-09-29 12:02:18 +08002650+ if(rx)
2651+ page = &q->rx_page;
developer8cb3ac72022-07-04 10:55:14 +08002652+
developer53bfd362022-09-29 12:02:18 +08002653+ while (q->queued < q->ndesc) {
2654+ buf = page_frag_alloc(page, len, GFP_ATOMIC);
developer8cb3ac72022-07-04 10:55:14 +08002655+ if (!buf)
2656+ break;
2657+
2658+ addr = dma_map_single(wo->hw->dev, buf, len, DMA_FROM_DEVICE);
2659+ if (unlikely(dma_mapping_error(wo->hw->dev, addr))) {
2660+ skb_free_frag(buf);
2661+ break;
2662+ }
developerf11dcd72022-08-27 18:29:27 +08002663+
2664+ q->head = (q->head + 1) % q->ndesc;
2665+
developer8cb3ac72022-07-04 10:55:14 +08002666+ desc = &q->desc[q->head];
2667+ entry = &q->entry[q->head];
2668+
2669+ entry->dma_addr = addr;
2670+ entry->dma_len = len;
2671+
developer53bfd362022-09-29 12:02:18 +08002672+ if (rx) {
2673+ ctrl = FIELD_PREP(WED_CTL_SD_LEN0, entry->dma_len);
2674+ ctrl |= WED_CTL_LAST_SEC0;
developer8cb3ac72022-07-04 10:55:14 +08002675+
developer53bfd362022-09-29 12:02:18 +08002676+ WRITE_ONCE(desc->buf0, cpu_to_le32(addr));
2677+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
2678+ }
developer8cb3ac72022-07-04 10:55:14 +08002679+ q->queued++;
2680+ q->entry[q->head].buf = buf;
2681+
developer8cb3ac72022-07-04 10:55:14 +08002682+ frames++;
2683+ }
2684+
2685+ spin_unlock_bh(&q->lock);
2686+
2687+ return frames;
2688+}
2689+
2690+static void
2691+woif_q_rx_fill_process(struct mtk_wed_wo *wo, struct wed_wo_queue *q)
2692+{
developer53bfd362022-09-29 12:02:18 +08002693+ if(woif_q_rx_fill(wo, q, true))
developer8cb3ac72022-07-04 10:55:14 +08002694+ woif_q_kick(wo, q, -1);
2695+}
2696+
2697+static int
2698+woif_q_alloc(struct mtk_wed_wo *dev, struct wed_wo_queue *q,
2699+ int n_desc, int bufsize, int idx,
2700+ struct wed_wo_queue_regs *regs)
2701+{
2702+ struct wed_wo_queue_regs *q_regs;
2703+ int size;
2704+
2705+ spin_lock_init(&q->lock);
2706+ spin_lock_init(&q->cleanup_lock);
2707+
2708+ q_regs = devm_kzalloc(dev->hw->dev, sizeof(*q_regs), GFP_KERNEL);
2709+
2710+ q_regs->desc_base = regs->desc_base;
2711+ q_regs->ring_size = regs->ring_size;
2712+ q_regs->cpu_idx = regs->cpu_idx;
2713+ q_regs->dma_idx = regs->dma_idx;
2714+
2715+ q->regs = q_regs;
2716+ q->ndesc = n_desc;
2717+ q->buf_size = bufsize;
2718+
2719+ size = q->ndesc * sizeof(struct wed_wo_desc);
2720+
2721+ q->desc = dmam_alloc_coherent(dev->hw->dev, size,
2722+ &q->desc_dma, GFP_KERNEL);
2723+ if (!q->desc)
2724+ return -ENOMEM;
2725+
2726+ size = q->ndesc * sizeof(*q->entry);
2727+ q->entry = devm_kzalloc(dev->hw->dev, size, GFP_KERNEL);
2728+ if (!q->entry)
2729+ return -ENOMEM;
2730+
developer53bfd362022-09-29 12:02:18 +08002731+ if (idx == 0) {
2732+ /* alloc tx buf */
2733+ woif_q_rx_fill(dev, &dev->q_tx, false);
developer8cb3ac72022-07-04 10:55:14 +08002734+ woif_q_reset(dev, &dev->q_tx);
developer53bfd362022-09-29 12:02:18 +08002735+ }
developer8cb3ac72022-07-04 10:55:14 +08002736+
2737+ return 0;
2738+}
2739+
2740+static void
developera3f86ed2022-07-08 14:15:13 +08002741+woif_q_free(struct mtk_wed_wo *dev, struct wed_wo_queue *q)
2742+{
2743+ int size;
2744+
2745+ if (!q)
2746+ return;
2747+
2748+ if (!q->desc)
2749+ return;
2750+
2751+ woccif_w32(dev, q->regs->cpu_idx, 0);
2752+
2753+ size = q->ndesc * sizeof(struct wed_wo_desc);
2754+ dma_free_coherent(dev->hw->dev, size, q->desc, q->desc_dma);
2755+}
2756+
2757+static void
developer53bfd362022-09-29 12:02:18 +08002758+woif_q_tx_clean(struct mtk_wed_wo *wo, struct wed_wo_queue *q)
developer8cb3ac72022-07-04 10:55:14 +08002759+{
developer53bfd362022-09-29 12:02:18 +08002760+ struct page *page;
2761+ int i = 0;
developer8cb3ac72022-07-04 10:55:14 +08002762+
2763+ if (!q || !q->ndesc)
2764+ return;
2765+
developer53bfd362022-09-29 12:02:18 +08002766+ spin_lock_bh(&q->lock);
2767+ while (i < q->ndesc) {
developer8cb3ac72022-07-04 10:55:14 +08002768+ struct wed_wo_queue_entry *e;
2769+
developer53bfd362022-09-29 12:02:18 +08002770+ e = &q->entry[i];
2771+ i++;
developer8cb3ac72022-07-04 10:55:14 +08002772+
developer53bfd362022-09-29 12:02:18 +08002773+ if (!e)
2774+ continue;
developer8cb3ac72022-07-04 10:55:14 +08002775+ dma_unmap_single(wo->hw->dev, e->dma_addr, e->dma_len,
2776+ DMA_TO_DEVICE);
2777+
developer53bfd362022-09-29 12:02:18 +08002778+ skb_free_frag(e->buf);
developer8cb3ac72022-07-04 10:55:14 +08002779+ }
developer53bfd362022-09-29 12:02:18 +08002780+ spin_unlock_bh(&q->lock);
developer8cb3ac72022-07-04 10:55:14 +08002781+
developer53bfd362022-09-29 12:02:18 +08002782+ if (!q->tx_page.va)
2783+ return;
2784+
2785+ page = virt_to_page(q->tx_page.va);
2786+ __page_frag_cache_drain(page, q->tx_page.pagecnt_bias);
2787+ memset(&q->tx_page, 0, sizeof(q->tx_page));
developer8cb3ac72022-07-04 10:55:14 +08002788+}
2789+
developer8cb3ac72022-07-04 10:55:14 +08002790+static void *
2791+woif_q_deq(struct mtk_wed_wo *wo, struct wed_wo_queue *q, bool flush,
2792+ int *len, u32 *info, bool *more)
2793+{
2794+ int buf_len = SKB_WITH_OVERHEAD(q->buf_size);
2795+ struct wed_wo_queue_entry *e;
2796+ struct wed_wo_desc *desc;
developerf11dcd72022-08-27 18:29:27 +08002797+ int idx = (q->tail + 1) % q->ndesc;;
developer8cb3ac72022-07-04 10:55:14 +08002798+ void *buf;
2799+
2800+ *more = false;
2801+ if (!q->queued)
2802+ return NULL;
2803+
2804+ if (flush)
2805+ q->desc[idx].ctrl |= cpu_to_le32(WED_CTL_DMA_DONE);
2806+ else if (!(q->desc[idx].ctrl & cpu_to_le32(WED_CTL_DMA_DONE)))
2807+ return NULL;
2808+
developerf11dcd72022-08-27 18:29:27 +08002809+ q->tail = idx;
developer8cb3ac72022-07-04 10:55:14 +08002810+ q->queued--;
2811+
2812+ desc = &q->desc[idx];
2813+ e = &q->entry[idx];
2814+
2815+ buf = e->buf;
2816+ if (len) {
2817+ u32 ctl = le32_to_cpu(READ_ONCE(desc->ctrl));
2818+ *len = FIELD_GET(WED_CTL_SD_LEN0, ctl);
2819+ *more = !(ctl & WED_CTL_LAST_SEC0);
2820+ }
2821+
2822+ if (info)
2823+ *info = le32_to_cpu(desc->info);
2824+ if(buf)
2825+ dma_unmap_single(wo->hw->dev, e->dma_addr, buf_len,
2826+ DMA_FROM_DEVICE);
2827+ e->skb = NULL;
2828+
2829+ return buf;
2830+}
2831+
developera3f86ed2022-07-08 14:15:13 +08002832+static void
2833+woif_q_rx_clean(struct mtk_wed_wo *wo, struct wed_wo_queue *q)
2834+{
2835+ struct page *page;
2836+ void *buf;
2837+ bool more;
2838+
2839+ if (!q->ndesc)
2840+ return;
2841+
2842+ spin_lock_bh(&q->lock);
2843+ do {
2844+ buf = woif_q_deq(wo, q, true, NULL, NULL, &more);
2845+ if (!buf)
2846+ break;
2847+
2848+ skb_free_frag(buf);
2849+ } while (1);
2850+ spin_unlock_bh(&q->lock);
2851+
2852+ if (!q->rx_page.va)
2853+ return;
2854+
2855+ page = virt_to_page(q->rx_page.va);
2856+ __page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
2857+ memset(&q->rx_page, 0, sizeof(q->rx_page));
developera3f86ed2022-07-08 14:15:13 +08002858+}
2859+
developer8cb3ac72022-07-04 10:55:14 +08002860+static int
2861+woif_q_init(struct mtk_wed_wo *dev,
2862+ int (*poll)(struct napi_struct *napi, int budget))
2863+{
2864+ init_dummy_netdev(&dev->napi_dev);
2865+ snprintf(dev->napi_dev.name, sizeof(dev->napi_dev.name), "%s",
2866+ "woif_q");
2867+
2868+ if (dev->q_rx.ndesc) {
2869+ netif_napi_add(&dev->napi_dev, &dev->napi, poll, 64);
developer53bfd362022-09-29 12:02:18 +08002870+ woif_q_rx_fill(dev, &dev->q_rx, true);
developer8cb3ac72022-07-04 10:55:14 +08002871+ woif_q_reset(dev, &dev->q_rx);
2872+ napi_enable(&dev->napi);
2873+ }
2874+
2875+ return 0;
2876+}
2877+
2878+void woif_q_rx_skb(struct mtk_wed_wo *wo, struct sk_buff *skb)
2879+{
2880+ struct wed_cmd_hdr *hdr = (struct wed_cmd_hdr *)skb->data;
2881+ int ret;
2882+
2883+ ret = mtk_wed_mcu_cmd_sanity_check(wo, skb);
2884+ if (ret)
2885+ goto free_skb;
2886+
2887+ if (WED_WO_CMD_FLAG_IS_RSP(hdr))
2888+ mtk_wed_mcu_rx_event(wo, skb);
2889+ else
2890+ mtk_wed_mcu_rx_unsolicited_event(wo, skb);
2891+
2892+ return;
2893+free_skb:
2894+ dev_kfree_skb(skb);
2895+}
2896+
2897+static int
2898+woif_q_tx_skb(struct mtk_wed_wo *wo, struct wed_wo_queue *q,
2899+ struct sk_buff *skb)
2900+{
2901+ struct wed_wo_queue_entry *entry;
2902+ struct wed_wo_desc *desc;
developer53bfd362022-09-29 12:02:18 +08002903+ int len, ret = 0, idx = -1;
developer8cb3ac72022-07-04 10:55:14 +08002904+ dma_addr_t addr;
2905+ u32 ctrl = 0;
2906+
2907+ len = skb->len;
developer53bfd362022-09-29 12:02:18 +08002908+ spin_lock_bh(&q->lock);
developer8cb3ac72022-07-04 10:55:14 +08002909+
developer53bfd362022-09-29 12:02:18 +08002910+ q->tail = woccif_r32(wo, q->regs->dma_idx);
2911+ q->head = (q->head + 1) % q->ndesc;
2912+ if (q->tail == q->head) {
developer8cb3ac72022-07-04 10:55:14 +08002913+ ret = -ENOMEM;
2914+ goto error;
2915+ }
2916+
developer8cb3ac72022-07-04 10:55:14 +08002917+ idx = q->head;
developer8cb3ac72022-07-04 10:55:14 +08002918+ desc = &q->desc[idx];
2919+ entry = &q->entry[idx];
2920+
developer53bfd362022-09-29 12:02:18 +08002921+ if (len > entry->dma_len) {
2922+ ret = -ENOMEM;
2923+ goto error;
2924+ }
2925+ addr = entry->dma_addr;
2926+
2927+ dma_sync_single_for_cpu(wo->hw->dev, addr, len, DMA_TO_DEVICE);
2928+ memcpy(entry->buf, skb->data, len);
2929+ dma_sync_single_for_device(wo->hw->dev, addr, len, DMA_TO_DEVICE);
developer8cb3ac72022-07-04 10:55:14 +08002930+
2931+ ctrl = FIELD_PREP(WED_CTL_SD_LEN0, len);
2932+ ctrl |= WED_CTL_LAST_SEC0;
2933+ ctrl |= WED_CTL_DMA_DONE;
2934+
2935+ WRITE_ONCE(desc->buf0, cpu_to_le32(addr));
2936+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
2937+
developer8cb3ac72022-07-04 10:55:14 +08002938+ woif_q_kick(wo, q, 0);
2939+ wo->drv_ops->kickout(wo);
2940+
developer8cb3ac72022-07-04 10:55:14 +08002941+ spin_unlock_bh(&q->lock);
developer8cb3ac72022-07-04 10:55:14 +08002942+
2943+error:
2944+ dev_kfree_skb(skb);
developer53bfd362022-09-29 12:02:18 +08002945+ return ret;
developer8cb3ac72022-07-04 10:55:14 +08002946+}
2947+
2948+static const struct wed_wo_queue_ops wo_queue_ops = {
2949+ .init = woif_q_init,
2950+ .alloc = woif_q_alloc,
developera3f86ed2022-07-08 14:15:13 +08002951+ .free = woif_q_free,
developer8cb3ac72022-07-04 10:55:14 +08002952+ .reset = woif_q_reset,
2953+ .tx_skb = woif_q_tx_skb,
2954+ .tx_clean = woif_q_tx_clean,
2955+ .rx_clean = woif_q_rx_clean,
2956+ .kick = woif_q_kick,
2957+};
2958+
2959+static int
2960+mtk_wed_wo_rx_process(struct mtk_wed_wo *wo, struct wed_wo_queue *q, int budget)
2961+{
developer53bfd362022-09-29 12:02:18 +08002962+ int len, done = 0;
developer8cb3ac72022-07-04 10:55:14 +08002963+ struct sk_buff *skb;
2964+ unsigned char *data;
2965+ bool more;
2966+
2967+ while (done < budget) {
2968+ u32 info;
2969+
2970+ data = woif_q_deq(wo, q, false, &len, &info, &more);
2971+ if (!data)
2972+ break;
2973+
developer8cb3ac72022-07-04 10:55:14 +08002974+ skb = build_skb(data, q->buf_size);
2975+ if (!skb) {
2976+ skb_free_frag(data);
2977+ continue;
2978+ }
2979+
2980+ __skb_put(skb, len);
2981+ done++;
2982+
2983+ woif_q_rx_skb(wo, skb);
2984+ }
2985+
2986+ woif_q_rx_fill_process(wo, q);
2987+
2988+ return done;
2989+}
2990+
2991+void mtk_wed_wo_set_isr_mask(struct mtk_wed_wo *wo, bool set,
2992+ u32 clear, u32 val)
2993+{
2994+ unsigned long flags;
2995+
2996+ spin_lock_irqsave(&wo->ccif.irq_lock, flags);
2997+ wo->ccif.irqmask &= ~clear;
2998+ wo->ccif.irqmask |= val;
2999+ if (set)
3000+ wo->drv_ops->set_isr(wo, wo->ccif.irqmask);
3001+
3002+ spin_unlock_irqrestore(&wo->ccif.irq_lock, flags);
3003+}
3004+
3005+static inline void mtk_wed_wo_set_ack_mask(struct mtk_wed_wo *wo, u32 mask)
3006+{
3007+ wo->drv_ops->set_ack(wo, mask);
3008+}
3009+
3010+static void mtk_wed_wo_poll_complete(struct mtk_wed_wo *wo)
3011+{
3012+ mtk_wed_wo_set_ack_mask(wo, wo->ccif.q_int_mask);
3013+ mtk_wed_wo_isr_enable(wo, wo->ccif.q_int_mask);
3014+}
3015+
3016+int mtk_wed_wo_rx_poll(struct napi_struct *napi, int budget)
3017+{
3018+ struct mtk_wed_wo *wo;
3019+ int done = 0, cur;
3020+
3021+ wo = container_of(napi->dev, struct mtk_wed_wo, napi_dev);
3022+
3023+ rcu_read_lock();
3024+
3025+ do {
3026+ cur = mtk_wed_wo_rx_process(wo, &wo->q_rx, budget - done);
3027+ /* rx packet handle */
3028+ done += cur;
3029+ } while (cur && done < budget);
3030+
3031+ rcu_read_unlock();
3032+
3033+ if (done < budget && napi_complete(napi))
3034+ mtk_wed_wo_poll_complete(wo);
3035+
3036+ return done;
3037+}
3038+
3039+static void mtk_wed_wo_isr_tasklet(unsigned long data)
3040+{
3041+ struct mtk_wed_wo *wo = (struct mtk_wed_wo *)data;
3042+ u32 intr, mask;
3043+
3044+ /* disable isr */
3045+ wo->drv_ops->set_isr(wo, 0);
3046+
3047+ intr = wo->drv_ops->get_csr(wo);
3048+ intr &= wo->ccif.irqmask;
3049+
3050+ mask = intr & (wo->ccif.q_int_mask | wo->ccif.q_exep_mask);
3051+ mtk_wed_wo_isr_disable(wo, mask);
3052+
3053+ if (intr & wo->ccif.q_int_mask)
3054+ napi_schedule(&wo->napi);
3055+
3056+ if (intr & wo->ccif.q_exep_mask) {
3057+ /* todo */
3058+ }
3059+}
3060+
3061+static irqreturn_t mtk_wed_wo_isr_handler(int irq, void *wo_instance)
3062+{
3063+ struct mtk_wed_wo *wo = wo_instance;
3064+
3065+ wo->drv_ops->set_isr(wo, 0);
3066+
3067+ tasklet_schedule(&wo->irq_tasklet);
3068+
3069+ return IRQ_HANDLED;
3070+}
3071+
3072+int mtk_wed_wo_init(struct mtk_wed_hw *hw)
3073+{
3074+ struct mtk_wed_wo *wo;
3075+ int ret = 0;
3076+
3077+ wo = kzalloc(sizeof(struct mtk_wed_wo), GFP_KERNEL);
3078+ if (!wo)
3079+ return -ENOMEM;
3080+
3081+ wo->hw = hw;
3082+ wo->queue_ops = &wo_queue_ops;
3083+ hw->wed_wo = wo;
3084+
3085+ tasklet_init(&wo->irq_tasklet, mtk_wed_wo_isr_tasklet,
3086+ (unsigned long)wo);
3087+
3088+ skb_queue_head_init(&wo->mcu.res_q);
3089+ init_waitqueue_head(&wo->mcu.wait);
3090+ mutex_init(&wo->mcu.mutex);
3091+
3092+ ret = wed_wo_hardware_init(wo, mtk_wed_wo_isr_handler);
3093+ if (ret)
3094+ goto error;
3095+
3096+ /* fw download */
3097+ ret = wed_wo_mcu_init(wo);
3098+ if (ret)
3099+ goto error;
3100+
3101+ ret = mtk_wed_exception_init(wo);
3102+ if (ret)
3103+ goto error;
3104+
3105+ return ret;
3106+
3107+error:
3108+ kfree(wo);
3109+
3110+ return ret;
3111+}
3112+
3113+void mtk_wed_wo_exit(struct mtk_wed_hw *hw)
3114+{
developer8cb3ac72022-07-04 10:55:14 +08003115+ struct mtk_wed_wo *wo = hw->wed_wo;
3116+
developera3f86ed2022-07-08 14:15:13 +08003117+ wed_wo_hardware_exit(wo);
3118+
developer8cb3ac72022-07-04 10:55:14 +08003119+ if (wo->exp.log) {
3120+ dma_unmap_single(wo->hw->dev, wo->exp.phys, wo->exp.log_size, DMA_FROM_DEVICE);
3121+ kfree(wo->exp.log);
3122+ }
3123+
developera3f86ed2022-07-08 14:15:13 +08003124+ wo->hw = NULL;
3125+ memset(wo, 0, sizeof(*wo));
3126+ kfree(wo);
developer8cb3ac72022-07-04 10:55:14 +08003127+}
3128diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
3129new file mode 100644
developer144824b2022-11-25 21:27:43 +08003130index 0000000..548b38e
developer8cb3ac72022-07-04 10:55:14 +08003131--- /dev/null
3132+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
developer53bfd362022-09-29 12:02:18 +08003133@@ -0,0 +1,324 @@
developer8cb3ac72022-07-04 10:55:14 +08003134+// SPDX-License-Identifier: GPL-2.0-only
3135+/* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
3136+
3137+#ifndef __MTK_WED_WO_H
3138+#define __MTK_WED_WO_H
3139+
3140+#include <linux/netdevice.h>
3141+#include <linux/skbuff.h>
3142+#include "mtk_wed.h"
3143+
3144+#define WED_CTL_SD_LEN1 GENMASK(13, 0)
3145+#define WED_CTL_LAST_SEC1 BIT(14)
3146+#define WED_CTL_BURST BIT(15)
3147+#define WED_CTL_SD_LEN0_SHIFT 16
3148+#define WED_CTL_SD_LEN0 GENMASK(29, 16)
3149+#define WED_CTL_LAST_SEC0 BIT(30)
3150+#define WED_CTL_DMA_DONE BIT(31)
3151+#define WED_INFO_WINFO GENMASK(15, 0)
3152+
3153+#define MTK_WED_WO_TXQ_FREE_THR 10
3154+
3155+#define WED_WO_PROFILE_MAX_LVL 6
3156+
3157+
3158+enum mtk_wed_fw_region_id {
3159+ WO_REGION_EMI = 0,
3160+ WO_REGION_ILM,
3161+ WO_REGION_DATA,
3162+ WO_REGION_BOOT,
3163+ __WO_REGION_MAX
3164+};
3165+
3166+struct wed_wo_profile_stat {
3167+ u32 bound;
3168+ u32 record;
3169+};
3170+
3171+#define PROFILE_STAT(record, val) do { \
3172+ u8 lvl = 0; \
3173+ while (lvl < WED_WO_PROFILE_MAX_LVL) { \
3174+ if (val < record[lvl].bound) { \
3175+ record[lvl].record++; \
3176+ break; \
3177+ } \
3178+ lvl++; \
3179+ } \
3180+ } while (0)
3181+
3182+/* align with wo report structure */
3183+struct wed_wo_log {
3184+ u32 sn;
3185+ u32 total;
3186+ u32 rro;
3187+ u32 mod;
3188+};
3189+
3190+struct wed_wo_rxcnt {
3191+ u16 wlan_idx;
3192+ u16 tid;
3193+ u32 rx_pkt_cnt;
3194+ u32 rx_byte_cnt;
3195+ u32 rx_err_cnt;
3196+ u32 rx_drop_cnt;
3197+};
3198+
3199+struct wed_wo_queue {
3200+ struct wed_wo_queue_regs *regs;
3201+
3202+ spinlock_t lock;
3203+ spinlock_t cleanup_lock;
3204+ struct wed_wo_queue_entry *entry;
3205+ struct wed_wo_desc *desc;
3206+
3207+ u16 first;
3208+ u16 head;
3209+ u16 tail;
3210+ int ndesc;
3211+ int queued;
3212+ int buf_size;
3213+
3214+ u8 hw_idx;
3215+ u8 qid;
3216+ u8 flags;
3217+
3218+ dma_addr_t desc_dma;
3219+ struct page_frag_cache rx_page;
developer53bfd362022-09-29 12:02:18 +08003220+ struct page_frag_cache tx_page;
developer8cb3ac72022-07-04 10:55:14 +08003221+};
3222+
3223+
3224+struct wed_wo_mmio {
3225+ struct regmap *regs;
3226+
3227+ spinlock_t irq_lock;
3228+ u8 irq;
3229+ u32 irqmask;
3230+
3231+ u32 q_int_mask;
3232+ u32 q_exep_mask;
3233+};
3234+
3235+struct wed_wo_mcu {
3236+ struct mutex mutex;
3237+ u32 msg_seq;
3238+ int timeout;
3239+
3240+ struct sk_buff_head res_q;
3241+ wait_queue_head_t wait;
3242+};
3243+
3244+struct wed_wo_exception {
3245+ void* log;
3246+ int log_size;
3247+ dma_addr_t phys;
3248+};
3249+
3250+struct wed_wo_queue_regs {
3251+ u32 desc_base;
3252+ u32 ring_size;
3253+ u32 cpu_idx;
3254+ u32 dma_idx;
3255+};
3256+
3257+struct wed_wo_desc {
3258+ __le32 buf0;
3259+ __le32 ctrl;
3260+ __le32 buf1;
3261+ __le32 info;
3262+ __le32 reserved[4];
3263+} __packed __aligned(32);
3264+
3265+struct wed_wo_queue_entry {
3266+ union {
3267+ void *buf;
3268+ struct sk_buff *skb;
3269+ };
3270+
3271+ u32 dma_addr;
3272+ u16 dma_len;
3273+ u16 wcid;
3274+ bool skip_buf0:1;
3275+ bool skip_buf1:1;
3276+ bool done:1;
3277+};
3278+
developer8cb3ac72022-07-04 10:55:14 +08003279+struct wo_cmd_query {
3280+ u32 query0;
3281+ u32 query1;
3282+};
3283+
3284+struct wed_cmd_hdr {
3285+ /*DW0*/
3286+ u8 ver;
3287+ u8 cmd_id;
3288+ u16 length;
3289+
3290+ /*DW1*/
3291+ u16 uni_id;
3292+ u16 flag;
3293+
3294+ /*DW2*/
3295+ int status;
3296+
3297+ /*DW3*/
3298+ u8 reserved[20];
3299+};
3300+
3301+struct mtk_wed_fw_region {
3302+ void *addr;
3303+ u32 addr_pa;
3304+ u32 size;
3305+ u32 shared;
3306+};
3307+
3308+struct wed_wo_queue_ops;
3309+struct wed_wo_drv_ops;
3310+struct wed_wo_mcu_ops;
3311+
3312+struct wo_rx_total_cnt {
3313+ u64 rx_pkt_cnt;
3314+ u64 rx_byte_cnt;
3315+ u64 rx_err_cnt;
3316+ u64 rx_drop_cnt;
3317+};
3318+
3319+struct mtk_wed_wo {
3320+ struct mtk_wed_hw *hw;
3321+
3322+ struct wed_wo_mmio ccif;
3323+ struct wed_wo_mcu mcu;
3324+ struct wed_wo_exception exp;
3325+
3326+ const struct wed_wo_drv_ops *drv_ops;
3327+ const struct wed_wo_mcu_ops *mcu_ops;
3328+ const struct wed_wo_queue_ops *queue_ops;
3329+
3330+ struct net_device napi_dev;
3331+ spinlock_t rx_lock;
3332+ struct napi_struct napi;
3333+ struct sk_buff_head rx_skb;
3334+ struct wed_wo_queue q_rx;
3335+ struct tasklet_struct irq_tasklet;
3336+
3337+ struct wed_wo_queue q_tx;
3338+
3339+ struct mtk_wed_fw_region region[__WO_REGION_MAX];
3340+
3341+ struct wed_wo_profile_stat total[WED_WO_PROFILE_MAX_LVL];
3342+ struct wed_wo_profile_stat mod[WED_WO_PROFILE_MAX_LVL];
3343+ struct wed_wo_profile_stat rro[WED_WO_PROFILE_MAX_LVL];
3344+ char dirname[4];
3345+ struct wo_rx_total_cnt wo_rxcnt[8][544];
3346+};
3347+
3348+struct wed_wo_queue_ops {
3349+ int (*init)(struct mtk_wed_wo *wo,
3350+ int (*poll)(struct napi_struct *napi, int budget));
3351+
3352+ int (*alloc)(struct mtk_wed_wo *wo, struct wed_wo_queue *q,
3353+ int idx, int n_desc, int bufsize,
3354+ struct wed_wo_queue_regs *regs);
developera3f86ed2022-07-08 14:15:13 +08003355+ void (*free)(struct mtk_wed_wo *wo, struct wed_wo_queue *q);
developer8cb3ac72022-07-04 10:55:14 +08003356+ void (*reset)(struct mtk_wed_wo *wo, struct wed_wo_queue *q);
3357+
3358+ int (*tx_skb)(struct mtk_wed_wo *wo, struct wed_wo_queue *q,
3359+ struct sk_buff *skb);
developer53bfd362022-09-29 12:02:18 +08003360+ void (*tx_clean)(struct mtk_wed_wo *wo, struct wed_wo_queue *q);
developer8cb3ac72022-07-04 10:55:14 +08003361+
3362+ void (*rx_clean)(struct mtk_wed_wo *wo, struct wed_wo_queue *q);
3363+
3364+ void (*kick)(struct mtk_wed_wo *wo, struct wed_wo_queue *q, int offset);
3365+};
3366+
3367+struct wed_wo_drv_ops {
3368+ void (*kickout)(struct mtk_wed_wo *wo);
3369+ void (*set_ack)(struct mtk_wed_wo *wo, u32 mask);
3370+ void (*set_isr)(struct mtk_wed_wo *wo, u32 mask);
3371+ u32 (*get_csr)(struct mtk_wed_wo *wo);
3372+ int (*tx_prepare_skb)(struct mtk_wed_wo *wo);
3373+ bool (*check_excpetion)(struct mtk_wed_wo *wo);
3374+ void (*clear_int)(struct mtk_wed_wo *wo, u32 mask);
3375+};
3376+
3377+struct wed_wo_mcu_ops {
3378+ u32 headroom;
3379+
3380+ int (*mcu_skb_send_msg)(struct mtk_wed_wo *wo, int to_id,
3381+ int cmd, struct sk_buff *skb,
3382+ int *seq, bool wait_resp);
3383+
3384+ int (*mcu_parse_response)(struct mtk_wed_wo *wo, int cmd,
3385+ struct sk_buff *skb, int seq);
3386+
3387+ int (*mcu_restart)(struct mtk_wed_wo *wo);
3388+};
3389+
3390+#define mtk_wed_wo_q_init(wo, ...) (wo)->queue_ops->init((wo), __VA_ARGS__)
3391+#define mtk_wed_wo_q_alloc(wo, ...) (wo)->queue_ops->alloc((wo), __VA_ARGS__)
developera3f86ed2022-07-08 14:15:13 +08003392+#define mtk_wed_wo_q_free(wo, ...) (wo)->queue_ops->free((wo), __VA_ARGS__)
3393+#define mtk_wed_wo_q_reset(wo, ...) (wo)->queue_ops->reset((wo), __VA_ARGS__)
developer8cb3ac72022-07-04 10:55:14 +08003394+#define mtk_wed_wo_q_tx_skb(wo, ...) (wo)->queue_ops->tx_skb((wo), __VA_ARGS__)
developer8cb3ac72022-07-04 10:55:14 +08003395+#define mtk_wed_wo_q_tx_clean(wo, ...) (wo)->queue_ops->tx_clean((wo), __VA_ARGS__)
3396+#define mtk_wed_wo_q_rx_clean(wo, ...) (wo)->queue_ops->rx_clean((wo), __VA_ARGS__)
3397+#define mtk_wed_wo_q_kick(wo, ...) (wo)->queue_ops->kick((wo), __VA_ARGS__)
3398+
3399+enum {
3400+ WARP_CMD_FLAG_RSP = 1 << 0, /* is responce*/
3401+ WARP_CMD_FLAG_NEED_RSP = 1 << 1, /* need responce */
3402+ WARP_CMD_FLAG_FROM_TO_WO = 1 << 2, /* send between host and wo */
3403+};
3404+
3405+#define WED_WO_CMD_FLAG_IS_RSP(_hdr) ((_hdr)->flag & (WARP_CMD_FLAG_RSP))
3406+#define WED_WO_CMD_FLAG_SET_RSP(_hdr) ((_hdr)->flag |= (WARP_CMD_FLAG_RSP))
3407+#define WED_WO_CMD_FLAG_IS_NEED_RSP(_hdr) ((_hdr)->flag & (WARP_CMD_FLAG_NEED_RSP))
3408+#define WED_WO_CMD_FLAG_SET_NEED_RSP(_hdr) ((_hdr)->flag |= (WARP_CMD_FLAG_NEED_RSP))
3409+#define WED_WO_CMD_FLAG_IS_FROM_TO_WO(_hdr) ((_hdr)->flag & (WARP_CMD_FLAG_FROM_TO_WO))
3410+#define WED_WO_CMD_FLAG_SET_FROM_TO_WO(_hdr) ((_hdr)->flag |= (WARP_CMD_FLAG_FROM_TO_WO))
3411+
3412+void mtk_wed_wo_set_isr_mask(struct mtk_wed_wo *wo, bool set,
3413+ u32 clear, u32 val);
3414+
3415+static inline void mtk_wed_wo_isr_enable(struct mtk_wed_wo *wo, u32 mask)
3416+{
3417+ mtk_wed_wo_set_isr_mask(wo, false, 0, mask);
3418+
3419+ tasklet_schedule(&wo->irq_tasklet);
3420+}
3421+
3422+static inline void mtk_wed_wo_isr_disable(struct mtk_wed_wo *wo, u32 mask)
3423+{
3424+ mtk_wed_wo_set_isr_mask(wo, true, mask, 0);
3425+}
3426+
3427+static inline void
3428+wo_w32(struct mtk_wed_wo *dev, u32 reg, u32 val)
3429+{
3430+ writel(val, dev->region[WO_REGION_BOOT].addr + reg);
3431+}
3432+
3433+static inline u32
3434+wo_r32(struct mtk_wed_wo *dev, u32 reg)
3435+{
3436+ return readl(dev->region[WO_REGION_BOOT].addr + reg);
3437+}
3438+static inline void
3439+woccif_w32(struct mtk_wed_wo *dev, u32 reg, u32 val)
3440+{
3441+ regmap_write(dev->ccif.regs, reg, val);
3442+}
3443+
3444+static inline u32
3445+woccif_r32(struct mtk_wed_wo *dev, u32 reg)
3446+{
3447+ unsigned int val;
3448+
3449+ regmap_read(dev->ccif.regs, reg, &val);
3450+
3451+ return val;
3452+}
3453+
3454+int mtk_wed_wo_init(struct mtk_wed_hw *hw);
developera3f86ed2022-07-08 14:15:13 +08003455+void mtk_wed_wo_exit(struct mtk_wed_hw *hw);
developer8cb3ac72022-07-04 10:55:14 +08003456+#endif
3457+
3458diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
developer144824b2022-11-25 21:27:43 +08003459index e914cb4..e8fca31 100644
developer8cb3ac72022-07-04 10:55:14 +08003460--- a/include/linux/soc/mediatek/mtk_wed.h
3461+++ b/include/linux/soc/mediatek/mtk_wed.h
developer144824b2022-11-25 21:27:43 +08003462@@ -6,7 +6,39 @@
3463 #include <linux/regmap.h>
developer8cb3ac72022-07-04 10:55:14 +08003464 #include <linux/pci.h>
3465
developer144824b2022-11-25 21:27:43 +08003466+#define WED_WO_STA_REC 0x6
3467+
developer8cb3ac72022-07-04 10:55:14 +08003468 #define MTK_WED_TX_QUEUES 2
3469+#define MTK_WED_RX_QUEUES 2
3470+
developer144824b2022-11-25 21:27:43 +08003471+enum mtk_wed_wo_cmd {
3472+ MTK_WED_WO_CMD_WED_CFG,
3473+ MTK_WED_WO_CMD_WED_RX_STAT,
3474+ MTK_WED_WO_CMD_RRO_SER,
3475+ MTK_WED_WO_CMD_DBG_INFO,
3476+ MTK_WED_WO_CMD_DEV_INFO,
3477+ MTK_WED_WO_CMD_BSS_INFO,
3478+ MTK_WED_WO_CMD_STA_REC,
3479+ MTK_WED_WO_CMD_DEV_INFO_DUMP,
3480+ MTK_WED_WO_CMD_BSS_INFO_DUMP,
3481+ MTK_WED_WO_CMD_STA_REC_DUMP,
3482+ MTK_WED_WO_CMD_BA_INFO_DUMP,
3483+ MTK_WED_WO_CMD_FBCMD_Q_DUMP,
3484+ MTK_WED_WO_CMD_FW_LOG_CTRL,
3485+ MTK_WED_WO_CMD_LOG_FLUSH,
3486+ MTK_WED_WO_CMD_CHANGE_STATE,
3487+ MTK_WED_WO_CMD_CPU_STATS_ENABLE,
3488+ MTK_WED_WO_CMD_CPU_STATS_DUMP,
3489+ MTK_WED_WO_CMD_EXCEPTION_INIT,
3490+ MTK_WED_WO_CMD_PROF_CTRL,
3491+ MTK_WED_WO_CMD_STA_BA_DUMP,
3492+ MTK_WED_WO_CMD_BA_CTRL_DUMP,
3493+ MTK_WED_WO_CMD_RXCNT_CTRL,
3494+ MTK_WED_WO_CMD_RXCNT_INFO,
3495+ MTK_WED_WO_CMD_SET_CAP,
3496+ MTK_WED_WO_CMD_CCIF_RING_DUMP,
3497+ MTK_WED_WO_CMD_WED_END
developerfaaa5162022-10-24 14:12:16 +08003498+};
developer8cb3ac72022-07-04 10:55:14 +08003499
3500 enum {
3501 MTK_NO_WED,
developer144824b2022-11-25 21:27:43 +08003502@@ -15,10 +47,9 @@ enum {
3503 MTK_WED_VMAX
3504 };
3505
3506-enum {
3507- MTK_BUS_TYPE_PCIE,
3508- MTK_BUS_TYPE_AXI,
3509- MTK_BUS_TYPE_MAX
3510+enum mtk_wed_bus_tye {
3511+ MTK_WED_BUS_PCIE,
3512+ MTK_WED_BUS_AXI,
3513 };
3514
3515 struct mtk_wed_hw;
3516@@ -33,6 +64,33 @@ struct mtk_wed_ring {
developer8cb3ac72022-07-04 10:55:14 +08003517 void __iomem *wpdma;
3518 };
3519
3520+struct mtk_rxbm_desc {
3521+ __le32 buf0;
3522+ __le32 token;
3523+} __packed __aligned(4);
3524+
3525+struct dma_buf {
3526+ int size;
3527+ void **pages;
3528+ struct mtk_wdma_desc *desc;
3529+ dma_addr_t desc_phys;
3530+};
3531+
3532+struct dma_entry {
3533+ int size;
3534+ struct mtk_rxbm_desc *desc;
3535+ dma_addr_t desc_phys;
3536+};
3537+
developer144824b2022-11-25 21:27:43 +08003538+struct mtk_wed_wo_rx_stats {
3539+ __le16 wlan_idx;
3540+ __le16 tid;
3541+ __le32 rx_pkt_cnt;
3542+ __le32 rx_byte_cnt;
3543+ __le32 rx_err_cnt;
3544+ __le32 rx_drop_cnt;
developer8fec8ae2022-08-15 15:01:09 -07003545+};
3546+
developer8cb3ac72022-07-04 10:55:14 +08003547 struct mtk_wed_device {
3548 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
3549 const struct mtk_wed_ops *ops;
developer144824b2022-11-25 21:27:43 +08003550@@ -47,37 +105,64 @@ struct mtk_wed_device {
developer8cb3ac72022-07-04 10:55:14 +08003551 struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
3552 struct mtk_wed_ring txfree_ring;
3553 struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
3554+ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
3555+ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
3556+
3557+ struct dma_buf buf_ring;
developer8cb3ac72022-07-04 10:55:14 +08003558
3559 struct {
developer144824b2022-11-25 21:27:43 +08003560 int size;
developer8cb3ac72022-07-04 10:55:14 +08003561- void **pages;
3562- struct mtk_wdma_desc *desc;
developer144824b2022-11-25 21:27:43 +08003563+ struct page_frag_cache rx_page;
3564+ struct mtk_rxbm_desc *desc;
3565 dma_addr_t desc_phys;
developer8cb3ac72022-07-04 10:55:14 +08003566- } buf_ring;
developer144824b2022-11-25 21:27:43 +08003567+ } rx_buf_ring;
3568+
3569+ struct {
developer8cb3ac72022-07-04 10:55:14 +08003570+ struct mtk_wed_ring rro_ring;
3571+ void __iomem *rro_desc;
3572+ dma_addr_t miod_desc_phys;
3573+ dma_addr_t fdbk_desc_phys;
3574+ u32 mcu_view_miod;
3575+ } rro;
3576
3577 /* filled by driver: */
3578 struct {
developer144824b2022-11-25 21:27:43 +08003579- struct pci_dev *pci_dev;
3580+ union {
3581+ struct platform_device *platform_dev;
3582+ struct pci_dev *pci_dev;
3583+ };
developer8cb3ac72022-07-04 10:55:14 +08003584 void __iomem *base;
3585 u32 bus_type;
3586+ u32 phy_base;
3587
developerbbca0f92022-07-26 17:26:12 +08003588 u32 wpdma_phys;
3589 u32 wpdma_int;
developer8cb3ac72022-07-04 10:55:14 +08003590 u32 wpdma_mask;
3591 u32 wpdma_tx;
3592 u32 wpdma_txfree;
3593+ u32 wpdma_rx_glo;
3594+ u32 wpdma_rx;
3595
3596 u8 tx_tbit[MTK_WED_TX_QUEUES];
3597+ u8 rx_tbit[MTK_WED_RX_QUEUES];
3598 u8 txfree_tbit;
3599
3600 u16 token_start;
3601 unsigned int nbuf;
3602+ unsigned int rx_nbuf;
developer144824b2022-11-25 21:27:43 +08003603+ unsigned int rx_npkt;
3604+ unsigned int rx_size;
developer8cb3ac72022-07-04 10:55:14 +08003605
developer203096a2022-09-13 21:07:19 +08003606 bool wcid_512;
3607
developer8cb3ac72022-07-04 10:55:14 +08003608 u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
3609 int (*offload_enable)(struct mtk_wed_device *wed);
3610 void (*offload_disable)(struct mtk_wed_device *wed);
3611+ u32 (*init_rx_buf)(struct mtk_wed_device *wed,
3612+ int pkt_num);
3613+ void (*release_rx_buf)(struct mtk_wed_device *wed);
developer144824b2022-11-25 21:27:43 +08003614+ void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
3615+ struct mtk_wed_wo_rx_stats *stats);
developer8cb3ac72022-07-04 10:55:14 +08003616 } wlan;
3617 #endif
3618 };
developer144824b2022-11-25 21:27:43 +08003619@@ -88,6 +173,10 @@ struct mtk_wed_ops {
developer8cb3ac72022-07-04 10:55:14 +08003620 void __iomem *regs);
3621 int (*txfree_ring_setup)(struct mtk_wed_device *dev,
3622 void __iomem *regs);
3623+ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
3624+ void __iomem *regs);
3625+ int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
3626+ void *data, int len);
3627 void (*detach)(struct mtk_wed_device *dev);
3628
3629 void (*stop)(struct mtk_wed_device *dev);
developer144824b2022-11-25 21:27:43 +08003630@@ -99,6 +188,8 @@ struct mtk_wed_ops {
developer8cb3ac72022-07-04 10:55:14 +08003631
3632 u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
3633 void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
developerbbca0f92022-07-26 17:26:12 +08003634+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
developer8cb3ac72022-07-04 10:55:14 +08003635+ u32 reason, u32 hash);
3636 };
3637
3638 extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
developer144824b2022-11-25 21:27:43 +08003639@@ -123,6 +214,16 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
3640 return ret;
3641 }
3642
3643+static inline bool
3644+mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
3645+{
3646+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
3647+ return dev->ver != 1;
3648+#else
3649+ return false;
3650+#endif
3651+}
3652+
3653 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
3654 #define mtk_wed_device_active(_dev) !!(_dev)->ops
3655 #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
3656@@ -131,6 +232,10 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +08003657 (_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
3658 #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
3659 (_dev)->ops->txfree_ring_setup(_dev, _regs)
3660+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
3661+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
3662+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
3663+ (_dev)->ops->msg_update(_dev, _id, _msg, _len)
3664 #define mtk_wed_device_reg_read(_dev, _reg) \
3665 (_dev)->ops->reg_read(_dev, _reg)
3666 #define mtk_wed_device_reg_write(_dev, _reg, _val) \
developer144824b2022-11-25 21:27:43 +08003667@@ -139,6 +244,8 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +08003668 (_dev)->ops->irq_get(_dev, _mask)
3669 #define mtk_wed_device_irq_set_mask(_dev, _mask) \
3670 (_dev)->ops->irq_set_mask(_dev, _mask)
3671+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
3672+ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
3673 #else
3674 static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
3675 {
developer144824b2022-11-25 21:27:43 +08003676@@ -148,10 +255,13 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
developer8cb3ac72022-07-04 10:55:14 +08003677 #define mtk_wed_device_start(_dev, _mask) do {} while (0)
3678 #define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
3679 #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
3680+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
3681+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
3682 #define mtk_wed_device_reg_read(_dev, _reg) 0
3683 #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
3684 #define mtk_wed_device_irq_get(_dev, _mask) 0
3685 #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
3686+#define mtk_wed_device_ppe_check(_dev, _hash) do {} while (0)
3687 #endif
3688
3689 #endif
3690--
developere0cbe332022-09-10 17:36:02 +080036912.18.0
developer8cb3ac72022-07-04 10:55:14 +08003692