xref: /linux/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c (revision 151ebcf0797b1a3ba53c8843dc21748c80e098c7)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
3 
4 #include <linux/seq_file.h>
5 #include <linux/soc/mediatek/mtk_wed.h>
6 #include "mtk_wed.h"
7 #include "mtk_wed_regs.h"
8 
9 struct reg_dump {
10 	const char *name;
11 	u16 offset;
12 	u8 type;
13 	u8 base;
14 	u32 mask;
15 };
16 
17 enum {
18 	DUMP_TYPE_STRING,
19 	DUMP_TYPE_WED,
20 	DUMP_TYPE_WDMA,
21 	DUMP_TYPE_WPDMA_TX,
22 	DUMP_TYPE_WPDMA_TXFREE,
23 	DUMP_TYPE_WPDMA_RX,
24 	DUMP_TYPE_WED_RRO,
25 };
26 
27 #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
28 #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ }
29 #define DUMP_REG_MASK(_reg, _mask)	\
30 	{ #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask }
31 #define DUMP_RING(_prefix, _base, ...)				\
32 	{ _prefix " BASE", _base, __VA_ARGS__ },		\
33 	{ _prefix " CNT",  _base + 0x4, __VA_ARGS__ },	\
34 	{ _prefix " CIDX", _base + 0x8, __VA_ARGS__ },	\
35 	{ _prefix " DIDX", _base + 0xc, __VA_ARGS__ }
36 
37 #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
38 #define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask)
39 #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
40 
41 #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
42 #define DUMP_WDMA_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WDMA)
43 
44 #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n)
45 #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE)
46 #define DUMP_WPDMA_RX_RING(_n)	DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n)
47 #define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO)
48 #define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO)
49 
50 static void
51 print_reg_val(struct seq_file *s, const char *name, u32 val)
52 {
53 	seq_printf(s, "%-32s %08x\n", name, val);
54 }
55 
56 static void
57 dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
58 	      const struct reg_dump *regs, int n_regs)
59 {
60 	const struct reg_dump *cur;
61 	u32 val;
62 
63 	for (cur = regs; cur < &regs[n_regs]; cur++) {
64 		switch (cur->type) {
65 		case DUMP_TYPE_STRING:
66 			seq_printf(s, "%s======== %s:\n",
67 				   cur > regs ? "\n" : "",
68 				   cur->name);
69 			continue;
70 		case DUMP_TYPE_WED_RRO:
71 		case DUMP_TYPE_WED:
72 			val = wed_r32(dev, cur->offset);
73 			break;
74 		case DUMP_TYPE_WDMA:
75 			val = wdma_r32(dev, cur->offset);
76 			break;
77 		case DUMP_TYPE_WPDMA_TX:
78 			val = wpdma_tx_r32(dev, cur->base, cur->offset);
79 			break;
80 		case DUMP_TYPE_WPDMA_TXFREE:
81 			val = wpdma_txfree_r32(dev, cur->offset);
82 			break;
83 		case DUMP_TYPE_WPDMA_RX:
84 			val = wpdma_rx_r32(dev, cur->base, cur->offset);
85 			break;
86 		}
87 		print_reg_val(s, cur->name, val);
88 	}
89 }
90 
91 static int
92 wed_txinfo_show(struct seq_file *s, void *data)
93 {
94 	static const struct reg_dump regs[] = {
95 		DUMP_STR("WED TX"),
96 		DUMP_WED(WED_TX_MIB(0)),
97 		DUMP_WED_RING(WED_RING_TX(0)),
98 
99 		DUMP_WED(WED_TX_MIB(1)),
100 		DUMP_WED_RING(WED_RING_TX(1)),
101 
102 		DUMP_STR("WPDMA TX"),
103 		DUMP_WED(WED_WPDMA_TX_MIB(0)),
104 		DUMP_WED_RING(WED_WPDMA_RING_TX(0)),
105 		DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(0)),
106 
107 		DUMP_WED(WED_WPDMA_TX_MIB(1)),
108 		DUMP_WED_RING(WED_WPDMA_RING_TX(1)),
109 		DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(1)),
110 
111 		DUMP_STR("WPDMA TX"),
112 		DUMP_WPDMA_TX_RING(0),
113 		DUMP_WPDMA_TX_RING(1),
114 
115 		DUMP_STR("WED WDMA RX"),
116 		DUMP_WED(WED_WDMA_RX_MIB(0)),
117 		DUMP_WED_RING(WED_WDMA_RING_RX(0)),
118 		DUMP_WED(WED_WDMA_RX_THRES(0)),
119 		DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(0)),
120 		DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(0)),
121 
122 		DUMP_WED(WED_WDMA_RX_MIB(1)),
123 		DUMP_WED_RING(WED_WDMA_RING_RX(1)),
124 		DUMP_WED(WED_WDMA_RX_THRES(1)),
125 		DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(1)),
126 		DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(1)),
127 
128 		DUMP_STR("WDMA RX"),
129 		DUMP_WDMA(WDMA_GLO_CFG),
130 		DUMP_WDMA_RING(WDMA_RING_RX(0)),
131 		DUMP_WDMA_RING(WDMA_RING_RX(1)),
132 
133 		DUMP_STR("WED TX FREE"),
134 		DUMP_WED(WED_RX_MIB(0)),
135 		DUMP_WED_RING(WED_RING_RX(0)),
136 		DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)),
137 		DUMP_WED(WED_RX_MIB(1)),
138 		DUMP_WED_RING(WED_RING_RX(1)),
139 		DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)),
140 
141 		DUMP_STR("WED WPDMA TX FREE"),
142 		DUMP_WED_RING(WED_WPDMA_RING_RX(0)),
143 		DUMP_WED_RING(WED_WPDMA_RING_RX(1)),
144 	};
145 	struct mtk_wed_hw *hw = s->private;
146 	struct mtk_wed_device *dev = hw->wed_dev;
147 
148 	if (dev)
149 		dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
150 
151 	return 0;
152 }
153 DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
154 
155 static int
156 wed_rxinfo_show(struct seq_file *s, void *data)
157 {
158 	static const struct reg_dump regs_common[] = {
159 		DUMP_STR("WPDMA RX"),
160 		DUMP_WPDMA_RX_RING(0),
161 		DUMP_WPDMA_RX_RING(1),
162 
163 		DUMP_STR("WPDMA RX"),
164 		DUMP_WED(WED_WPDMA_RX_D_MIB(0)),
165 		DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)),
166 		DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)),
167 		DUMP_WED(WED_WPDMA_RX_D_MIB(1)),
168 		DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)),
169 		DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)),
170 		DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB),
171 
172 		DUMP_STR("WED RX"),
173 		DUMP_WED_RING(WED_RING_RX_DATA(0)),
174 		DUMP_WED_RING(WED_RING_RX_DATA(1)),
175 
176 		DUMP_STR("WED WO RRO"),
177 		DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
178 		DUMP_WED(WED_RROQM_MID_MIB),
179 		DUMP_WED(WED_RROQM_MOD_MIB),
180 		DUMP_WED(WED_RROQM_MOD_COHERENT_MIB),
181 		DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0),
182 		DUMP_WED(WED_RROQM_FDBK_IND_MIB),
183 		DUMP_WED(WED_RROQM_FDBK_ENQ_MIB),
184 		DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
185 		DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
186 
187 		DUMP_STR("WED WDMA TX"),
188 		DUMP_WED(WED_WDMA_TX_MIB),
189 		DUMP_WED_RING(WED_WDMA_RING_TX),
190 
191 		DUMP_STR("WDMA TX"),
192 		DUMP_WDMA(WDMA_GLO_CFG),
193 		DUMP_WDMA_RING(WDMA_RING_TX(0)),
194 		DUMP_WDMA_RING(WDMA_RING_TX(1)),
195 
196 		DUMP_STR("WED RX BM"),
197 		DUMP_WED(WED_RX_BM_BASE),
198 		DUMP_WED(WED_RX_BM_RX_DMAD),
199 		DUMP_WED(WED_RX_BM_PTR),
200 		DUMP_WED(WED_RX_BM_TKID_MIB),
201 		DUMP_WED(WED_RX_BM_BLEN),
202 		DUMP_WED(WED_RX_BM_STS),
203 		DUMP_WED(WED_RX_BM_INTF2),
204 		DUMP_WED(WED_RX_BM_INTF),
205 		DUMP_WED(WED_RX_BM_ERR_STS),
206 	};
207 	static const struct reg_dump regs_wed_v2[] = {
208 		DUMP_STR("WED Route QM"),
209 		DUMP_WED(WED_RTQM_R2H_MIB(0)),
210 		DUMP_WED(WED_RTQM_R2Q_MIB(0)),
211 		DUMP_WED(WED_RTQM_Q2H_MIB(0)),
212 		DUMP_WED(WED_RTQM_R2H_MIB(1)),
213 		DUMP_WED(WED_RTQM_R2Q_MIB(1)),
214 		DUMP_WED(WED_RTQM_Q2H_MIB(1)),
215 		DUMP_WED(WED_RTQM_Q2N_MIB),
216 		DUMP_WED(WED_RTQM_Q2B_MIB),
217 		DUMP_WED(WED_RTQM_PFDBK_MIB),
218 	};
219 	static const struct reg_dump regs_wed_v3[] = {
220 		DUMP_STR("WED RX RRO DATA"),
221 		DUMP_WED_RING(WED_RRO_RX_D_RX(0)),
222 		DUMP_WED_RING(WED_RRO_RX_D_RX(1)),
223 
224 		DUMP_STR("WED RX MSDU PAGE"),
225 		DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)),
226 		DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)),
227 		DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)),
228 
229 		DUMP_STR("WED RX IND CMD"),
230 		DUMP_WED(WED_IND_CMD_RX_CTRL1),
231 		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT),
232 		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX),
233 		DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX),
234 		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT),
235 		DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT),
236 		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0,
237 			      WED_IND_CMD_PREFETCH_FREE_CNT),
238 		DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID),
239 
240 		DUMP_STR("WED ADDR ELEM"),
241 		DUMP_WED(WED_ADDR_ELEM_CFG0),
242 		DUMP_WED_MASK(WED_ADDR_ELEM_CFG1,
243 			      WED_ADDR_ELEM_PREFETCH_FREE_CNT),
244 
245 		DUMP_STR("WED Route QM"),
246 		DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT),
247 		DUMP_WED(WED_RTQM_ENQ_I2N_DMAD_CNT),
248 		DUMP_WED(WED_RTQM_ENQ_I2Q_PKT_CNT),
249 		DUMP_WED(WED_RTQM_ENQ_I2N_PKT_CNT),
250 		DUMP_WED(WED_RTQM_ENQ_USED_ENTRY_CNT),
251 		DUMP_WED(WED_RTQM_ENQ_ERR_CNT),
252 
253 		DUMP_WED(WED_RTQM_DEQ_DMAD_CNT),
254 		DUMP_WED(WED_RTQM_DEQ_Q2I_DMAD_CNT),
255 		DUMP_WED(WED_RTQM_DEQ_PKT_CNT),
256 		DUMP_WED(WED_RTQM_DEQ_Q2I_PKT_CNT),
257 		DUMP_WED(WED_RTQM_DEQ_USED_PFDBK_CNT),
258 		DUMP_WED(WED_RTQM_DEQ_ERR_CNT),
259 	};
260 	struct mtk_wed_hw *hw = s->private;
261 	struct mtk_wed_device *dev = hw->wed_dev;
262 
263 	if (dev) {
264 		dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common));
265 		if (mtk_wed_is_v2(hw))
266 			dump_wed_regs(s, dev,
267 				      regs_wed_v2, ARRAY_SIZE(regs_wed_v2));
268 		else
269 			dump_wed_regs(s, dev,
270 				      regs_wed_v3, ARRAY_SIZE(regs_wed_v3));
271 	}
272 
273 	return 0;
274 }
275 DEFINE_SHOW_ATTRIBUTE(wed_rxinfo);
276 
277 static int
278 wed_amsdu_show(struct seq_file *s, void *data)
279 {
280 	static const struct reg_dump regs[] = {
281 		DUMP_STR("WED AMDSU INFO"),
282 		DUMP_WED(WED_MON_AMSDU_FIFO_DMAD),
283 
284 		DUMP_STR("WED AMDSU ENG0 INFO"),
285 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(0)),
286 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(0)),
287 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(0)),
288 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(0)),
289 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(0)),
290 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0),
291 			      WED_AMSDU_ENG_MAX_PL_CNT),
292 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0),
293 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
294 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
295 			      WED_AMSDU_ENG_CUR_ENTRY),
296 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
297 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
298 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
299 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
300 
301 		DUMP_STR("WED AMDSU ENG1 INFO"),
302 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(1)),
303 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(1)),
304 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(1)),
305 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(1)),
306 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(1)),
307 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1),
308 			      WED_AMSDU_ENG_MAX_PL_CNT),
309 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1),
310 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
311 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1),
312 			      WED_AMSDU_ENG_CUR_ENTRY),
313 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
314 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
315 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
316 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
317 
318 		DUMP_STR("WED AMDSU ENG2 INFO"),
319 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(2)),
320 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(2)),
321 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(2)),
322 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(2)),
323 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(2)),
324 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2),
325 			      WED_AMSDU_ENG_MAX_PL_CNT),
326 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2),
327 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
328 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
329 			      WED_AMSDU_ENG_CUR_ENTRY),
330 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
331 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
332 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
333 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
334 
335 		DUMP_STR("WED AMDSU ENG3 INFO"),
336 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(3)),
337 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(3)),
338 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(3)),
339 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(3)),
340 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(3)),
341 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3),
342 			      WED_AMSDU_ENG_MAX_PL_CNT),
343 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3),
344 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
345 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
346 			      WED_AMSDU_ENG_CUR_ENTRY),
347 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
348 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
349 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
350 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
351 
352 		DUMP_STR("WED AMDSU ENG4 INFO"),
353 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(4)),
354 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(4)),
355 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(4)),
356 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(4)),
357 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(4)),
358 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4),
359 			      WED_AMSDU_ENG_MAX_PL_CNT),
360 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4),
361 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
362 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
363 			      WED_AMSDU_ENG_CUR_ENTRY),
364 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
365 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
366 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
367 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
368 
369 		DUMP_STR("WED AMDSU ENG5 INFO"),
370 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(5)),
371 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(5)),
372 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(5)),
373 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(5)),
374 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(5)),
375 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5),
376 			      WED_AMSDU_ENG_MAX_PL_CNT),
377 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5),
378 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
379 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
380 			      WED_AMSDU_ENG_CUR_ENTRY),
381 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
382 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
383 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
384 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
385 
386 		DUMP_STR("WED AMDSU ENG6 INFO"),
387 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(6)),
388 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(6)),
389 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(6)),
390 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(6)),
391 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(6)),
392 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6),
393 			      WED_AMSDU_ENG_MAX_PL_CNT),
394 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6),
395 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
396 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
397 			      WED_AMSDU_ENG_CUR_ENTRY),
398 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
399 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
400 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
401 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
402 
403 		DUMP_STR("WED AMDSU ENG7 INFO"),
404 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(7)),
405 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(7)),
406 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(7)),
407 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(7)),
408 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(7)),
409 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7),
410 			      WED_AMSDU_ENG_MAX_PL_CNT),
411 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7),
412 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
413 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
414 			      WED_AMSDU_ENG_CUR_ENTRY),
415 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
416 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
417 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
418 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
419 
420 		DUMP_STR("WED AMDSU ENG8 INFO"),
421 		DUMP_WED(WED_MON_AMSDU_ENG_DMAD(8)),
422 		DUMP_WED(WED_MON_AMSDU_ENG_QFPL(8)),
423 		DUMP_WED(WED_MON_AMSDU_ENG_QENI(8)),
424 		DUMP_WED(WED_MON_AMSDU_ENG_QENO(8)),
425 		DUMP_WED(WED_MON_AMSDU_ENG_MERG(8)),
426 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8),
427 			      WED_AMSDU_ENG_MAX_PL_CNT),
428 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8),
429 			      WED_AMSDU_ENG_MAX_QGPP_CNT),
430 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
431 			      WED_AMSDU_ENG_CUR_ENTRY),
432 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
433 			      WED_AMSDU_ENG_MAX_BUF_MERGED),
434 		DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
435 			      WED_AMSDU_ENG_MAX_MSDU_MERGED),
436 
437 		DUMP_STR("WED QMEM INFO"),
438 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_FQ_CNT),
439 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_SP_QCNT),
440 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID0_QCNT),
441 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID1_QCNT),
442 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID2_QCNT),
443 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID3_QCNT),
444 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID4_QCNT),
445 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID5_QCNT),
446 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID6_QCNT),
447 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID7_QCNT),
448 
449 		DUMP_STR("WED QMEM HEAD INFO"),
450 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_FQ_HEAD),
451 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_SP_QHEAD),
452 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID0_QHEAD),
453 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID1_QHEAD),
454 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID2_QHEAD),
455 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID3_QHEAD),
456 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID4_QHEAD),
457 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID5_QHEAD),
458 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID6_QHEAD),
459 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID7_QHEAD),
460 
461 		DUMP_STR("WED QMEM TAIL INFO"),
462 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_FQ_TAIL),
463 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_SP_QTAIL),
464 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID0_QTAIL),
465 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID1_QTAIL),
466 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID2_QTAIL),
467 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID3_QTAIL),
468 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID4_QTAIL),
469 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID5_QTAIL),
470 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID6_QTAIL),
471 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID7_QTAIL),
472 
473 		DUMP_STR("WED HIFTXD MSDU INFO"),
474 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(1)),
475 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(2)),
476 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(3)),
477 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(4)),
478 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(5)),
479 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(6)),
480 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(7)),
481 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(8)),
482 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(9)),
483 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(10)),
484 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(11)),
485 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(12)),
486 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(13)),
487 	};
488 	struct mtk_wed_hw *hw = s->private;
489 	struct mtk_wed_device *dev = hw->wed_dev;
490 
491 	if (dev)
492 		dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
493 
494 	return 0;
495 }
496 DEFINE_SHOW_ATTRIBUTE(wed_amsdu);
497 
498 static int
499 wed_rtqm_show(struct seq_file *s, void *data)
500 {
501 	static const struct reg_dump regs[] = {
502 		DUMP_STR("WED Route QM IGRS0(N2H + Recycle)"),
503 		DUMP_WED(WED_RTQM_IGRS0_I2HW_DMAD_CNT),
504 		DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(0)),
505 		DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(1)),
506 		DUMP_WED(WED_RTQM_IGRS0_I2HW_PKT_CNT),
507 		DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
508 		DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
509 		DUMP_WED(WED_RTQM_IGRS0_FDROP_CNT),
510 
511 		DUMP_STR("WED Route QM IGRS1(Legacy)"),
512 		DUMP_WED(WED_RTQM_IGRS1_I2HW_DMAD_CNT),
513 		DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(0)),
514 		DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(1)),
515 		DUMP_WED(WED_RTQM_IGRS1_I2HW_PKT_CNT),
516 		DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(0)),
517 		DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(1)),
518 		DUMP_WED(WED_RTQM_IGRS1_FDROP_CNT),
519 
520 		DUMP_STR("WED Route QM IGRS2(RRO3.0)"),
521 		DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
522 		DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(0)),
523 		DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(1)),
524 		DUMP_WED(WED_RTQM_IGRS2_I2HW_PKT_CNT),
525 		DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(0)),
526 		DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(1)),
527 		DUMP_WED(WED_RTQM_IGRS2_FDROP_CNT),
528 
529 		DUMP_STR("WED Route QM IGRS3(DEBUG)"),
530 		DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
531 		DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(0)),
532 		DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(1)),
533 		DUMP_WED(WED_RTQM_IGRS3_I2HW_PKT_CNT),
534 		DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(0)),
535 		DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(1)),
536 		DUMP_WED(WED_RTQM_IGRS3_FDROP_CNT),
537 	};
538 	struct mtk_wed_hw *hw = s->private;
539 	struct mtk_wed_device *dev = hw->wed_dev;
540 
541 	if (dev)
542 		dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
543 
544 	return 0;
545 }
546 DEFINE_SHOW_ATTRIBUTE(wed_rtqm);
547 
548 static int
549 wed_rro_show(struct seq_file *s, void *data)
550 {
551 	static const struct reg_dump regs[] = {
552 		DUMP_STR("RRO/IND CMD CNT"),
553 		DUMP_WED(WED_RX_IND_CMD_CNT(1)),
554 		DUMP_WED(WED_RX_IND_CMD_CNT(2)),
555 		DUMP_WED(WED_RX_IND_CMD_CNT(3)),
556 		DUMP_WED(WED_RX_IND_CMD_CNT(4)),
557 		DUMP_WED(WED_RX_IND_CMD_CNT(5)),
558 		DUMP_WED(WED_RX_IND_CMD_CNT(6)),
559 		DUMP_WED(WED_RX_IND_CMD_CNT(7)),
560 		DUMP_WED(WED_RX_IND_CMD_CNT(8)),
561 		DUMP_WED_MASK(WED_RX_IND_CMD_CNT(9),
562 			      WED_IND_CMD_MAGIC_CNT_FAIL_CNT),
563 
564 		DUMP_WED(WED_RX_ADDR_ELEM_CNT(0)),
565 		DUMP_WED_MASK(WED_RX_ADDR_ELEM_CNT(1),
566 			      WED_ADDR_ELEM_SIG_FAIL_CNT),
567 		DUMP_WED(WED_RX_MSDU_PG_CNT(1)),
568 		DUMP_WED(WED_RX_MSDU_PG_CNT(2)),
569 		DUMP_WED(WED_RX_MSDU_PG_CNT(3)),
570 		DUMP_WED(WED_RX_MSDU_PG_CNT(4)),
571 		DUMP_WED(WED_RX_MSDU_PG_CNT(5)),
572 		DUMP_WED_MASK(WED_RX_PN_CHK_CNT,
573 			      WED_PN_CHK_FAIL_CNT),
574 	};
575 	struct mtk_wed_hw *hw = s->private;
576 	struct mtk_wed_device *dev = hw->wed_dev;
577 
578 	if (dev)
579 		dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
580 
581 	return 0;
582 }
583 DEFINE_SHOW_ATTRIBUTE(wed_rro);
584 
585 static int
586 mtk_wed_reg_set(void *data, u64 val)
587 {
588 	struct mtk_wed_hw *hw = data;
589 
590 	regmap_write(hw->regs, hw->debugfs_reg, val);
591 
592 	return 0;
593 }
594 
595 static int
596 mtk_wed_reg_get(void *data, u64 *val)
597 {
598 	struct mtk_wed_hw *hw = data;
599 	unsigned int regval;
600 	int ret;
601 
602 	ret = regmap_read(hw->regs, hw->debugfs_reg, &regval);
603 	if (ret)
604 		return ret;
605 
606 	*val = regval;
607 
608 	return 0;
609 }
610 
611 DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set,
612              "0x%08llx\n");
613 
614 void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
615 {
616 	struct dentry *dir;
617 
618 	snprintf(hw->dirname, sizeof(hw->dirname), "wed%d", hw->index);
619 	dir = debugfs_create_dir(hw->dirname, NULL);
620 
621 	hw->debugfs_dir = dir;
622 	debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
623 	debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
624 	debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
625 	if (!mtk_wed_is_v1(hw)) {
626 		debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
627 					   &wed_rxinfo_fops);
628 		if (mtk_wed_is_v3_or_greater(hw)) {
629 			debugfs_create_file_unsafe("amsdu", 0400, dir, hw,
630 						   &wed_amsdu_fops);
631 			debugfs_create_file_unsafe("rtqm", 0400, dir, hw,
632 						   &wed_rtqm_fops);
633 			debugfs_create_file_unsafe("rro", 0400, dir, hw,
634 						   &wed_rro_fops);
635 		}
636 	}
637 }
638