mtk_wed_debugfs.c 20 KB

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