fbnic_debugfs.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) Meta Platforms, Inc. and affiliates. */
  3. #include <linux/debugfs.h>
  4. #include <linux/pci.h>
  5. #include <linux/rtnetlink.h>
  6. #include <linux/seq_file.h>
  7. #include "fbnic.h"
  8. #include "fbnic_txrx.h"
  9. static struct dentry *fbnic_dbg_root;
  10. /* Descriptor Seq Functions */
  11. static void fbnic_dbg_desc_break(struct seq_file *s, int i)
  12. {
  13. while (i--)
  14. seq_putc(s, '-');
  15. seq_putc(s, '\n');
  16. }
  17. static void fbnic_dbg_ring_show(struct seq_file *s)
  18. {
  19. struct fbnic_ring *ring = s->private;
  20. unsigned long doorbell_offset;
  21. u32 head = 0, tail = 0;
  22. u32 __iomem *csr_base;
  23. csr_base = fbnic_ring_csr_base(ring);
  24. doorbell_offset = ring->doorbell - csr_base;
  25. seq_printf(s, "doorbell CSR: %#05lx q_idx: %d\n",
  26. doorbell_offset, ring->q_idx);
  27. seq_printf(s, "size_mask: %#06x size: %zu flags: 0x%02x\n",
  28. ring->size_mask, ring->size, ring->flags);
  29. seq_printf(s, "SW: head: %#06x tail: %#06x\n",
  30. ring->head, ring->tail);
  31. switch (doorbell_offset) {
  32. case FBNIC_QUEUE_TWQ0_TAIL:
  33. tail = readl(csr_base + FBNIC_QUEUE_TWQ0_PTRS);
  34. head = FIELD_GET(FBNIC_QUEUE_TWQ_PTRS_HEAD_MASK, tail);
  35. break;
  36. case FBNIC_QUEUE_TWQ1_TAIL:
  37. tail = readl(csr_base + FBNIC_QUEUE_TWQ1_PTRS);
  38. head = FIELD_GET(FBNIC_QUEUE_TWQ_PTRS_HEAD_MASK, tail);
  39. break;
  40. case FBNIC_QUEUE_TCQ_HEAD:
  41. head = readl(csr_base + FBNIC_QUEUE_TCQ_PTRS);
  42. tail = FIELD_GET(FBNIC_QUEUE_TCQ_PTRS_TAIL_MASK, head);
  43. break;
  44. case FBNIC_QUEUE_BDQ_HPQ_TAIL:
  45. tail = readl(csr_base + FBNIC_QUEUE_BDQ_HPQ_PTRS);
  46. head = FIELD_GET(FBNIC_QUEUE_BDQ_PTRS_HEAD_MASK, tail);
  47. break;
  48. case FBNIC_QUEUE_BDQ_PPQ_TAIL:
  49. tail = readl(csr_base + FBNIC_QUEUE_BDQ_PPQ_PTRS);
  50. head = FIELD_GET(FBNIC_QUEUE_BDQ_PTRS_HEAD_MASK, tail);
  51. break;
  52. case FBNIC_QUEUE_RCQ_HEAD:
  53. head = readl(csr_base + FBNIC_QUEUE_RCQ_PTRS);
  54. tail = FIELD_GET(FBNIC_QUEUE_RCQ_PTRS_TAIL_MASK, head);
  55. break;
  56. }
  57. tail &= FBNIC_QUEUE_BDQ_PTRS_TAIL_MASK;
  58. head &= FBNIC_QUEUE_RCQ_PTRS_HEAD_MASK;
  59. seq_printf(s, "HW: head: %#06x tail: %#06x\n", head, tail);
  60. seq_puts(s, "\n");
  61. }
  62. static void fbnic_dbg_twd_desc_seq_show(struct seq_file *s, int i)
  63. {
  64. struct fbnic_ring *ring = s->private;
  65. u64 twd = le64_to_cpu(ring->desc[i]);
  66. switch (FIELD_GET(FBNIC_TWD_TYPE_MASK, twd)) {
  67. case FBNIC_TWD_TYPE_META:
  68. seq_printf(s, "%04x %#06llx %llx %llx %llx %llx %llx %#llx %#llx %llx %#04llx %#04llx %llx %#04llx\n",
  69. i, FIELD_GET(FBNIC_TWD_LEN_MASK, twd),
  70. FIELD_GET(FBNIC_TWD_TYPE_MASK, twd),
  71. FIELD_GET(FBNIC_TWD_FLAG_REQ_COMPLETION, twd),
  72. FIELD_GET(FBNIC_TWD_FLAG_REQ_CSO, twd),
  73. FIELD_GET(FBNIC_TWD_FLAG_REQ_LSO, twd),
  74. FIELD_GET(FBNIC_TWD_FLAG_REQ_TS, twd),
  75. FIELD_GET(FBNIC_TWD_L4_HLEN_MASK, twd),
  76. FIELD_GET(FBNIC_TWD_CSUM_OFFSET_MASK, twd),
  77. FIELD_GET(FBNIC_TWD_L4_TYPE_MASK, twd),
  78. FIELD_GET(FBNIC_TWD_L3_IHLEN_MASK, twd),
  79. FIELD_GET(FBNIC_TWD_L3_OHLEN_MASK, twd),
  80. FIELD_GET(FBNIC_TWD_L3_TYPE_MASK, twd),
  81. FIELD_GET(FBNIC_TWD_L2_HLEN_MASK, twd));
  82. break;
  83. default:
  84. seq_printf(s, "%04x %#06llx %llx %#014llx\n", i,
  85. FIELD_GET(FBNIC_TWD_LEN_MASK, twd),
  86. FIELD_GET(FBNIC_TWD_TYPE_MASK, twd),
  87. FIELD_GET(FBNIC_TWD_ADDR_MASK, twd));
  88. break;
  89. }
  90. }
  91. static int fbnic_dbg_twq_desc_seq_show(struct seq_file *s, void *v)
  92. {
  93. struct fbnic_ring *ring = s->private;
  94. char hdr[80];
  95. int i;
  96. /* Generate header on first entry */
  97. fbnic_dbg_ring_show(s);
  98. snprintf(hdr, sizeof(hdr), "%4s %5s %s %s\n",
  99. "DESC", "LEN/MSS", "T", "METADATA/TIMESTAMP/BUFFER_ADDR");
  100. seq_puts(s, hdr);
  101. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  102. /* Display descriptor */
  103. if (!ring->desc) {
  104. seq_puts(s, "Descriptor ring not allocated.\n");
  105. return 0;
  106. }
  107. for (i = 0; i <= ring->size_mask; i++)
  108. fbnic_dbg_twd_desc_seq_show(s, i);
  109. return 0;
  110. }
  111. static int fbnic_dbg_tcq_desc_seq_show(struct seq_file *s, void *v)
  112. {
  113. struct fbnic_ring *ring = s->private;
  114. char hdr[80];
  115. int i;
  116. /* Generate header on first entry */
  117. fbnic_dbg_ring_show(s);
  118. snprintf(hdr, sizeof(hdr), "%4s %s %s %s %5s %-16s %-6s %-6s\n",
  119. "DESC", "D", "T", "Q", "STATUS", "TIMESTAMP", "HEAD1", "HEAD0");
  120. seq_puts(s, hdr);
  121. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  122. /* Display descriptor */
  123. if (!ring->desc) {
  124. seq_puts(s, "Descriptor ring not allocated.\n");
  125. return 0;
  126. }
  127. for (i = 0; i <= ring->size_mask; i++) {
  128. u64 tcd = le64_to_cpu(ring->desc[i]);
  129. switch (FIELD_GET(FBNIC_TCD_TYPE_MASK, tcd)) {
  130. case FBNIC_TCD_TYPE_0:
  131. seq_printf(s, "%04x %llx %llx %llx %#05llx %-17s %#06llx %#06llx\n",
  132. i, FIELD_GET(FBNIC_TCD_DONE, tcd),
  133. FIELD_GET(FBNIC_TCD_TYPE_MASK, tcd),
  134. FIELD_GET(FBNIC_TCD_TWQ1, tcd),
  135. FIELD_GET(FBNIC_TCD_STATUS_MASK, tcd),
  136. "",
  137. FIELD_GET(FBNIC_TCD_TYPE0_HEAD1_MASK, tcd),
  138. FIELD_GET(FBNIC_TCD_TYPE0_HEAD0_MASK, tcd));
  139. break;
  140. case FBNIC_TCD_TYPE_1:
  141. seq_printf(s, "%04x %llx %llx %llx %#05llx %#012llx\n",
  142. i, FIELD_GET(FBNIC_TCD_DONE, tcd),
  143. FIELD_GET(FBNIC_TCD_TYPE_MASK, tcd),
  144. FIELD_GET(FBNIC_TCD_TWQ1, tcd),
  145. FIELD_GET(FBNIC_TCD_STATUS_MASK, tcd),
  146. FIELD_GET(FBNIC_TCD_TYPE1_TS_MASK, tcd));
  147. break;
  148. default:
  149. break;
  150. }
  151. }
  152. return 0;
  153. }
  154. static int fbnic_dbg_bdq_desc_seq_show(struct seq_file *s, void *v)
  155. {
  156. struct fbnic_ring *ring = s->private;
  157. char hdr[80];
  158. int i;
  159. /* Generate header on first entry */
  160. fbnic_dbg_ring_show(s);
  161. snprintf(hdr, sizeof(hdr), "%4s %-4s %s\n",
  162. "DESC", "ID", "BUFFER_ADDR");
  163. seq_puts(s, hdr);
  164. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  165. /* Display descriptor */
  166. if (!ring->desc) {
  167. seq_puts(s, "Descriptor ring not allocated.\n");
  168. return 0;
  169. }
  170. for (i = 0; i < (ring->size_mask + 1) * FBNIC_BD_FRAG_COUNT; i++) {
  171. u64 bd = le64_to_cpu(ring->desc[i]);
  172. seq_printf(s, "%04x %#04llx %#014llx\n", i,
  173. FIELD_GET(FBNIC_BD_DESC_ID_MASK, bd),
  174. FIELD_GET(FBNIC_BD_DESC_ADDR_MASK, bd));
  175. }
  176. return 0;
  177. }
  178. static void fbnic_dbg_rcd_desc_seq_show(struct seq_file *s, int i)
  179. {
  180. struct fbnic_ring *ring = s->private;
  181. u64 rcd = le64_to_cpu(ring->desc[i]);
  182. switch (FIELD_GET(FBNIC_RCD_TYPE_MASK, rcd)) {
  183. case FBNIC_RCD_TYPE_HDR_AL:
  184. case FBNIC_RCD_TYPE_PAY_AL:
  185. seq_printf(s, "%04x %llx %llx %llx %#06llx %#06llx %#06llx\n",
  186. i, FIELD_GET(FBNIC_RCD_DONE, rcd),
  187. FIELD_GET(FBNIC_RCD_TYPE_MASK, rcd),
  188. FIELD_GET(FBNIC_RCD_AL_PAGE_FIN, rcd),
  189. FIELD_GET(FBNIC_RCD_AL_BUFF_OFF_MASK, rcd),
  190. FIELD_GET(FBNIC_RCD_AL_BUFF_LEN_MASK, rcd),
  191. FIELD_GET(FBNIC_RCD_AL_BUFF_ID_MASK, rcd));
  192. break;
  193. case FBNIC_RCD_TYPE_OPT_META:
  194. seq_printf(s, "%04x %llx %llx %llx %llx %llx %#06llx %#012llx\n",
  195. i, FIELD_GET(FBNIC_RCD_DONE, rcd),
  196. FIELD_GET(FBNIC_RCD_TYPE_MASK, rcd),
  197. FIELD_GET(FBNIC_RCD_OPT_META_TYPE_MASK, rcd),
  198. FIELD_GET(FBNIC_RCD_OPT_META_TS, rcd),
  199. FIELD_GET(FBNIC_RCD_OPT_META_ACTION, rcd),
  200. FIELD_GET(FBNIC_RCD_OPT_META_ACTION_MASK, rcd),
  201. FIELD_GET(FBNIC_RCD_OPT_META_TS_MASK, rcd));
  202. break;
  203. case FBNIC_RCD_TYPE_META:
  204. seq_printf(s, "%04x %llx %llx %llx %llx %llx %llx %llx %llx %llx %#06llx %#010llx\n",
  205. i, FIELD_GET(FBNIC_RCD_DONE, rcd),
  206. FIELD_GET(FBNIC_RCD_TYPE_MASK, rcd),
  207. FIELD_GET(FBNIC_RCD_META_ECN, rcd),
  208. FIELD_GET(FBNIC_RCD_META_L4_CSUM_UNNECESSARY, rcd),
  209. FIELD_GET(FBNIC_RCD_META_ERR_MAC_EOP, rcd),
  210. FIELD_GET(FBNIC_RCD_META_ERR_TRUNCATED_FRAME, rcd),
  211. FIELD_GET(FBNIC_RCD_META_ERR_PARSER, rcd),
  212. FIELD_GET(FBNIC_RCD_META_L4_TYPE_MASK, rcd),
  213. FIELD_GET(FBNIC_RCD_META_L3_TYPE_MASK, rcd),
  214. FIELD_GET(FBNIC_RCD_META_L2_CSUM_MASK, rcd),
  215. FIELD_GET(FBNIC_RCD_META_RSS_HASH_MASK, rcd));
  216. break;
  217. }
  218. }
  219. static int fbnic_dbg_rcq_desc_seq_show(struct seq_file *s, void *v)
  220. {
  221. struct fbnic_ring *ring = s->private;
  222. char hdr[80];
  223. int i;
  224. /* Generate header on first entry */
  225. fbnic_dbg_ring_show(s);
  226. snprintf(hdr, sizeof(hdr),
  227. "%18s %s %s\n", "OFFSET/", "L", "L");
  228. seq_puts(s, hdr);
  229. snprintf(hdr, sizeof(hdr),
  230. "%4s %s %s %s %s %s %s %s %s %s %-8s %s\n",
  231. "DESC", "D", "T", "F", "C", "M", "T", "P", "4", "3", "LEN/CSUM", "ID/TS/RSS");
  232. seq_puts(s, hdr);
  233. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  234. /* Display descriptor */
  235. if (!ring->desc) {
  236. seq_puts(s, "Descriptor ring not allocated.\n");
  237. return 0;
  238. }
  239. for (i = 0; i <= ring->size_mask; i++)
  240. fbnic_dbg_rcd_desc_seq_show(s, i);
  241. return 0;
  242. }
  243. static int fbnic_dbg_desc_open(struct inode *inode, struct file *file)
  244. {
  245. struct fbnic_ring *ring = inode->i_private;
  246. int (*show)(struct seq_file *s, void *v);
  247. switch (ring->doorbell - fbnic_ring_csr_base(ring)) {
  248. case FBNIC_QUEUE_TWQ0_TAIL:
  249. case FBNIC_QUEUE_TWQ1_TAIL:
  250. show = fbnic_dbg_twq_desc_seq_show;
  251. break;
  252. case FBNIC_QUEUE_TCQ_HEAD:
  253. show = fbnic_dbg_tcq_desc_seq_show;
  254. break;
  255. case FBNIC_QUEUE_BDQ_HPQ_TAIL:
  256. case FBNIC_QUEUE_BDQ_PPQ_TAIL:
  257. show = fbnic_dbg_bdq_desc_seq_show;
  258. break;
  259. case FBNIC_QUEUE_RCQ_HEAD:
  260. show = fbnic_dbg_rcq_desc_seq_show;
  261. break;
  262. default:
  263. return -EINVAL;
  264. }
  265. return single_open(file, show, ring);
  266. }
  267. static const struct file_operations fbnic_dbg_desc_fops = {
  268. .owner = THIS_MODULE,
  269. .open = fbnic_dbg_desc_open,
  270. .read = seq_read,
  271. .llseek = seq_lseek,
  272. .release = single_release,
  273. };
  274. void fbnic_dbg_nv_init(struct fbnic_napi_vector *nv)
  275. {
  276. struct fbnic_dev *fbd = nv->fbd;
  277. char name[16];
  278. int i, j;
  279. /* Generate a folder for each napi vector */
  280. snprintf(name, sizeof(name), "nv.%03d", nv->v_idx);
  281. nv->dbg_nv = debugfs_create_dir(name, fbd->dbg_fbd);
  282. /* Generate a file for each Tx ring in the napi vector */
  283. for (i = 0; i < nv->txt_count; i++) {
  284. struct fbnic_q_triad *qt = &nv->qt[i];
  285. unsigned int hw_idx;
  286. hw_idx = fbnic_ring_csr_base(&qt->cmpl) -
  287. &fbd->uc_addr0[FBNIC_QUEUE(0)];
  288. hw_idx /= FBNIC_QUEUE_STRIDE;
  289. snprintf(name, sizeof(name), "twq0.%03d", hw_idx);
  290. debugfs_create_file(name, 0400, nv->dbg_nv, &qt->sub0,
  291. &fbnic_dbg_desc_fops);
  292. snprintf(name, sizeof(name), "twq1.%03d", hw_idx);
  293. debugfs_create_file(name, 0400, nv->dbg_nv, &qt->sub1,
  294. &fbnic_dbg_desc_fops);
  295. snprintf(name, sizeof(name), "tcq.%03d", hw_idx);
  296. debugfs_create_file(name, 0400, nv->dbg_nv, &qt->cmpl,
  297. &fbnic_dbg_desc_fops);
  298. }
  299. /* Generate a file for each Rx ring in the napi vector */
  300. for (j = 0; j < nv->rxt_count; j++, i++) {
  301. struct fbnic_q_triad *qt = &nv->qt[i];
  302. unsigned int hw_idx;
  303. hw_idx = fbnic_ring_csr_base(&qt->cmpl) -
  304. &fbd->uc_addr0[FBNIC_QUEUE(0)];
  305. hw_idx /= FBNIC_QUEUE_STRIDE;
  306. snprintf(name, sizeof(name), "hpq.%03d", hw_idx);
  307. debugfs_create_file(name, 0400, nv->dbg_nv, &qt->sub0,
  308. &fbnic_dbg_desc_fops);
  309. snprintf(name, sizeof(name), "ppq.%03d", hw_idx);
  310. debugfs_create_file(name, 0400, nv->dbg_nv, &qt->sub1,
  311. &fbnic_dbg_desc_fops);
  312. snprintf(name, sizeof(name), "rcq.%03d", hw_idx);
  313. debugfs_create_file(name, 0400, nv->dbg_nv, &qt->cmpl,
  314. &fbnic_dbg_desc_fops);
  315. }
  316. }
  317. void fbnic_dbg_nv_exit(struct fbnic_napi_vector *nv)
  318. {
  319. debugfs_remove_recursive(nv->dbg_nv);
  320. nv->dbg_nv = NULL;
  321. }
  322. static int fbnic_dbg_mac_addr_show(struct seq_file *s, void *v)
  323. {
  324. struct fbnic_dev *fbd = s->private;
  325. char hdr[80];
  326. int i;
  327. /* Generate Header */
  328. snprintf(hdr, sizeof(hdr), "%3s %s %-17s %s\n",
  329. "Idx", "S", "TCAM Bitmap", "Addr/Mask");
  330. seq_puts(s, hdr);
  331. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  332. for (i = 0; i < FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES; i++) {
  333. struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
  334. seq_printf(s, "%02d %d %64pb %pm\n",
  335. i, mac_addr->state, mac_addr->act_tcam,
  336. mac_addr->value.addr8);
  337. seq_printf(s, " %pm\n",
  338. mac_addr->mask.addr8);
  339. }
  340. return 0;
  341. }
  342. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_mac_addr);
  343. static int fbnic_dbg_tce_tcam_show(struct seq_file *s, void *v)
  344. {
  345. struct fbnic_dev *fbd = s->private;
  346. int i, tcam_idx = 0;
  347. char hdr[80];
  348. /* Generate Header */
  349. snprintf(hdr, sizeof(hdr), "%3s %s %-17s %s\n",
  350. "Idx", "S", "TCAM Bitmap", "Addr/Mask");
  351. seq_puts(s, hdr);
  352. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  353. for (i = 0; i < ARRAY_SIZE(fbd->mac_addr); i++) {
  354. struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
  355. /* Verify BMC bit is set */
  356. if (!test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam))
  357. continue;
  358. if (tcam_idx == FBNIC_TCE_TCAM_NUM_ENTRIES)
  359. break;
  360. seq_printf(s, "%02d %d %64pb %pm\n",
  361. tcam_idx, mac_addr->state, mac_addr->act_tcam,
  362. mac_addr->value.addr8);
  363. seq_printf(s, " %pm\n",
  364. mac_addr->mask.addr8);
  365. tcam_idx++;
  366. }
  367. return 0;
  368. }
  369. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_tce_tcam);
  370. static int fbnic_dbg_act_tcam_show(struct seq_file *s, void *v)
  371. {
  372. struct fbnic_dev *fbd = s->private;
  373. char hdr[80];
  374. int i;
  375. /* Generate Header */
  376. snprintf(hdr, sizeof(hdr), "%3s %s %-55s %-4s %s\n",
  377. "Idx", "S", "Value/Mask", "RSS", "Dest");
  378. seq_puts(s, hdr);
  379. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  380. for (i = 0; i < FBNIC_RPC_TCAM_ACT_NUM_ENTRIES; i++) {
  381. struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[i];
  382. seq_printf(s, "%02d %d %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %08x\n",
  383. i, act_tcam->state,
  384. act_tcam->value.tcam[10], act_tcam->value.tcam[9],
  385. act_tcam->value.tcam[8], act_tcam->value.tcam[7],
  386. act_tcam->value.tcam[6], act_tcam->value.tcam[5],
  387. act_tcam->value.tcam[4], act_tcam->value.tcam[3],
  388. act_tcam->value.tcam[2], act_tcam->value.tcam[1],
  389. act_tcam->value.tcam[0], act_tcam->rss_en_mask,
  390. act_tcam->dest);
  391. seq_printf(s, " %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
  392. act_tcam->mask.tcam[10], act_tcam->mask.tcam[9],
  393. act_tcam->mask.tcam[8], act_tcam->mask.tcam[7],
  394. act_tcam->mask.tcam[6], act_tcam->mask.tcam[5],
  395. act_tcam->mask.tcam[4], act_tcam->mask.tcam[3],
  396. act_tcam->mask.tcam[2], act_tcam->mask.tcam[1],
  397. act_tcam->mask.tcam[0]);
  398. }
  399. return 0;
  400. }
  401. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_act_tcam);
  402. static int fbnic_dbg_ip_addr_show(struct seq_file *s,
  403. struct fbnic_ip_addr *ip_addr)
  404. {
  405. char hdr[80];
  406. int i;
  407. /* Generate Header */
  408. snprintf(hdr, sizeof(hdr), "%3s %s %-17s %s %s\n",
  409. "Idx", "S", "TCAM Bitmap", "V", "Addr/Mask");
  410. seq_puts(s, hdr);
  411. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  412. for (i = 0; i < FBNIC_RPC_TCAM_IP_ADDR_NUM_ENTRIES; i++, ip_addr++) {
  413. seq_printf(s, "%02d %d %64pb %d %pi6\n",
  414. i, ip_addr->state, ip_addr->act_tcam,
  415. ip_addr->version, &ip_addr->value);
  416. seq_printf(s, " %pi6\n",
  417. &ip_addr->mask);
  418. }
  419. return 0;
  420. }
  421. static int fbnic_dbg_ip_src_show(struct seq_file *s, void *v)
  422. {
  423. struct fbnic_dev *fbd = s->private;
  424. return fbnic_dbg_ip_addr_show(s, fbd->ip_src);
  425. }
  426. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_ip_src);
  427. static int fbnic_dbg_ip_dst_show(struct seq_file *s, void *v)
  428. {
  429. struct fbnic_dev *fbd = s->private;
  430. return fbnic_dbg_ip_addr_show(s, fbd->ip_dst);
  431. }
  432. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_ip_dst);
  433. static int fbnic_dbg_ipo_src_show(struct seq_file *s, void *v)
  434. {
  435. struct fbnic_dev *fbd = s->private;
  436. return fbnic_dbg_ip_addr_show(s, fbd->ipo_src);
  437. }
  438. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_ipo_src);
  439. static int fbnic_dbg_ipo_dst_show(struct seq_file *s, void *v)
  440. {
  441. struct fbnic_dev *fbd = s->private;
  442. return fbnic_dbg_ip_addr_show(s, fbd->ipo_dst);
  443. }
  444. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_ipo_dst);
  445. static void fbnic_dbg_fw_mbx_display(struct seq_file *s,
  446. struct fbnic_dev *fbd, int mbx_idx)
  447. {
  448. struct fbnic_fw_mbx *mbx = &fbd->mbx[mbx_idx];
  449. char hdr[80];
  450. int i;
  451. /* Generate header */
  452. seq_puts(s, mbx_idx == FBNIC_IPC_MBX_RX_IDX ? "Rx\n" : "Tx\n");
  453. seq_printf(s, "Rdy: %d Head: %d Tail: %d\n",
  454. mbx->ready, mbx->head, mbx->tail);
  455. snprintf(hdr, sizeof(hdr), "%3s %-4s %s %-12s %s %-3s %-16s\n",
  456. "Idx", "Len", "E", "Addr", "F", "H", "Raw");
  457. seq_puts(s, hdr);
  458. fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
  459. for (i = 0; i < FBNIC_IPC_MBX_DESC_LEN; i++) {
  460. u64 desc = __fbnic_mbx_rd_desc(fbd, mbx_idx, i);
  461. seq_printf(s, "%-3.2d %04lld %d %012llx %d %-3d %016llx\n",
  462. i, FIELD_GET(FBNIC_IPC_MBX_DESC_LEN_MASK, desc),
  463. !!(desc & FBNIC_IPC_MBX_DESC_EOM),
  464. desc & FBNIC_IPC_MBX_DESC_ADDR_MASK,
  465. !!(desc & FBNIC_IPC_MBX_DESC_FW_CMPL),
  466. !!(desc & FBNIC_IPC_MBX_DESC_HOST_CMPL),
  467. desc);
  468. }
  469. }
  470. static int fbnic_dbg_fw_mbx_show(struct seq_file *s, void *v)
  471. {
  472. struct fbnic_dev *fbd = s->private;
  473. fbnic_dbg_fw_mbx_display(s, fbd, FBNIC_IPC_MBX_RX_IDX);
  474. /* Add blank line between Rx and Tx */
  475. seq_puts(s, "\n");
  476. fbnic_dbg_fw_mbx_display(s, fbd, FBNIC_IPC_MBX_TX_IDX);
  477. return 0;
  478. }
  479. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_fw_mbx);
  480. static int fbnic_dbg_fw_log_show(struct seq_file *s, void *v)
  481. {
  482. struct fbnic_dev *fbd = s->private;
  483. struct fbnic_fw_log_entry *entry;
  484. unsigned long flags;
  485. if (!fbnic_fw_log_ready(fbd))
  486. return -ENXIO;
  487. spin_lock_irqsave(&fbd->fw_log.lock, flags);
  488. list_for_each_entry_reverse(entry, &fbd->fw_log.entries, list) {
  489. seq_printf(s, FBNIC_FW_LOG_FMT, entry->index,
  490. (entry->timestamp / (MSEC_PER_SEC * 60 * 60 * 24)),
  491. (entry->timestamp / (MSEC_PER_SEC * 60 * 60)) % 24,
  492. ((entry->timestamp / (MSEC_PER_SEC * 60) % 60)),
  493. ((entry->timestamp / MSEC_PER_SEC) % 60),
  494. (entry->timestamp % MSEC_PER_SEC),
  495. entry->msg);
  496. }
  497. spin_unlock_irqrestore(&fbd->fw_log.lock, flags);
  498. return 0;
  499. }
  500. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_fw_log);
  501. static int fbnic_dbg_pcie_stats_show(struct seq_file *s, void *v)
  502. {
  503. struct fbnic_dev *fbd = s->private;
  504. rtnl_lock();
  505. fbnic_get_hw_stats(fbd);
  506. seq_printf(s, "ob_rd_tlp: %llu\n", fbd->hw_stats.pcie.ob_rd_tlp.value);
  507. seq_printf(s, "ob_rd_dword: %llu\n",
  508. fbd->hw_stats.pcie.ob_rd_dword.value);
  509. seq_printf(s, "ob_wr_tlp: %llu\n", fbd->hw_stats.pcie.ob_wr_tlp.value);
  510. seq_printf(s, "ob_wr_dword: %llu\n",
  511. fbd->hw_stats.pcie.ob_wr_dword.value);
  512. seq_printf(s, "ob_cpl_tlp: %llu\n",
  513. fbd->hw_stats.pcie.ob_cpl_tlp.value);
  514. seq_printf(s, "ob_cpl_dword: %llu\n",
  515. fbd->hw_stats.pcie.ob_cpl_dword.value);
  516. seq_printf(s, "ob_rd_no_tag: %llu\n",
  517. fbd->hw_stats.pcie.ob_rd_no_tag.value);
  518. seq_printf(s, "ob_rd_no_cpl_cred: %llu\n",
  519. fbd->hw_stats.pcie.ob_rd_no_cpl_cred.value);
  520. seq_printf(s, "ob_rd_no_np_cred: %llu\n",
  521. fbd->hw_stats.pcie.ob_rd_no_np_cred.value);
  522. rtnl_unlock();
  523. return 0;
  524. }
  525. DEFINE_SHOW_ATTRIBUTE(fbnic_dbg_pcie_stats);
  526. void fbnic_dbg_fbd_init(struct fbnic_dev *fbd)
  527. {
  528. struct pci_dev *pdev = to_pci_dev(fbd->dev);
  529. const char *name = pci_name(pdev);
  530. fbd->dbg_fbd = debugfs_create_dir(name, fbnic_dbg_root);
  531. debugfs_create_file("pcie_stats", 0400, fbd->dbg_fbd, fbd,
  532. &fbnic_dbg_pcie_stats_fops);
  533. debugfs_create_file("mac_addr", 0400, fbd->dbg_fbd, fbd,
  534. &fbnic_dbg_mac_addr_fops);
  535. debugfs_create_file("tce_tcam", 0400, fbd->dbg_fbd, fbd,
  536. &fbnic_dbg_tce_tcam_fops);
  537. debugfs_create_file("act_tcam", 0400, fbd->dbg_fbd, fbd,
  538. &fbnic_dbg_act_tcam_fops);
  539. debugfs_create_file("ip_src", 0400, fbd->dbg_fbd, fbd,
  540. &fbnic_dbg_ip_src_fops);
  541. debugfs_create_file("ip_dst", 0400, fbd->dbg_fbd, fbd,
  542. &fbnic_dbg_ip_dst_fops);
  543. debugfs_create_file("ipo_src", 0400, fbd->dbg_fbd, fbd,
  544. &fbnic_dbg_ipo_src_fops);
  545. debugfs_create_file("ipo_dst", 0400, fbd->dbg_fbd, fbd,
  546. &fbnic_dbg_ipo_dst_fops);
  547. debugfs_create_file("fw_mbx", 0400, fbd->dbg_fbd, fbd,
  548. &fbnic_dbg_fw_mbx_fops);
  549. debugfs_create_file("fw_log", 0400, fbd->dbg_fbd, fbd,
  550. &fbnic_dbg_fw_log_fops);
  551. }
  552. void fbnic_dbg_fbd_exit(struct fbnic_dev *fbd)
  553. {
  554. debugfs_remove_recursive(fbd->dbg_fbd);
  555. fbd->dbg_fbd = NULL;
  556. }
  557. void fbnic_dbg_init(void)
  558. {
  559. fbnic_dbg_root = debugfs_create_dir(fbnic_driver_name, NULL);
  560. }
  561. void fbnic_dbg_exit(void)
  562. {
  563. debugfs_remove_recursive(fbnic_dbg_root);
  564. fbnic_dbg_root = NULL;
  565. }