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
9struct reg_dump {
10	const char *name;
11	u16 offset;
12	u8 type;
13	u8 base;
14	u32 mask;
15};
16
17enum {
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
50static void
51print_reg_val(struct seq_file *s, const char *name, u32 val)
52{
53	seq_printf(s, "%-32s %08x\n", name, val);
54}
55
56static void
57dump_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
91static int
92wed_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}
153DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
154
155static int
156wed_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}
275DEFINE_SHOW_ATTRIBUTE(wed_rxinfo);
276
277static int
278wed_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}
496DEFINE_SHOW_ATTRIBUTE(wed_amsdu);
497
498static int
499wed_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}
546DEFINE_SHOW_ATTRIBUTE(wed_rtqm);
547
548static int
549wed_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}
583DEFINE_SHOW_ATTRIBUTE(wed_rro);
584
585static int
586mtk_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
595static int
596mtk_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
611DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set,
612             "0x%08llx\n");
613
614void 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