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(m: s, fmt: "%-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(m: s, fmt: "%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, reg: cur->offset);
73 break;
74 case DUMP_TYPE_WDMA:
75 val = wdma_r32(dev, reg: cur->offset);
76 break;
77 case DUMP_TYPE_WPDMA_TX:
78 val = wpdma_tx_r32(dev, ring: cur->base, reg: cur->offset);
79 break;
80 case DUMP_TYPE_WPDMA_TXFREE:
81 val = wpdma_txfree_r32(dev, reg: cur->offset);
82 break;
83 case DUMP_TYPE_WPDMA_RX:
84 val = wpdma_rx_r32(dev, ring: cur->base, reg: cur->offset);
85 break;
86 }
87 print_reg_val(s, name: 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: regs_common, ARRAY_SIZE(regs_common));
265 if (mtk_wed_is_v2(hw))
266 dump_wed_regs(s, dev,
267 regs: regs_wed_v2, ARRAY_SIZE(regs_wed_v2));
268 else
269 dump_wed_regs(s, dev,
270 regs: 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(map: hw->regs, reg: 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(map: hw->regs, reg: hw->debugfs_reg, val: &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(buf: hw->dirname, size: sizeof(hw->dirname), fmt: "wed%d", hw->index);
619 dir = debugfs_create_dir(name: hw->dirname, NULL);
620
621 hw->debugfs_dir = dir;
622 debugfs_create_u32(name: "regidx", mode: 0600, parent: dir, value: &hw->debugfs_reg);
623 debugfs_create_file_unsafe(name: "regval", mode: 0600, parent: dir, data: hw, fops: &fops_regval);
624 debugfs_create_file_unsafe(name: "txinfo", mode: 0400, parent: dir, data: hw, fops: &wed_txinfo_fops);
625 if (!mtk_wed_is_v1(hw)) {
626 debugfs_create_file_unsafe(name: "rxinfo", mode: 0400, parent: dir, data: hw,
627 fops: &wed_rxinfo_fops);
628 if (mtk_wed_is_v3_or_greater(hw)) {
629 debugfs_create_file_unsafe(name: "amsdu", mode: 0400, parent: dir, data: hw,
630 fops: &wed_amsdu_fops);
631 debugfs_create_file_unsafe(name: "rtqm", mode: 0400, parent: dir, data: hw,
632 fops: &wed_rtqm_fops);
633 debugfs_create_file_unsafe(name: "rro", mode: 0400, parent: dir, data: hw,
634 fops: &wed_rro_fops);
635 }
636 }
637}
638

source code of linux/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c