1// SPDX-License-Identifier: GPL-2.0+
2/* Copyright (c) 2018-2019 Hisilicon Limited. */
3
4#include <linux/debugfs.h>
5#include <linux/device.h>
6
7#include "hnae3.h"
8#include "hns3_debugfs.h"
9#include "hns3_enet.h"
10
11static struct dentry *hns3_dbgfs_root;
12
13static struct hns3_dbg_dentry_info hns3_dbg_dentry[] = {
14 {
15 .name = "tm"
16 },
17 {
18 .name = "tx_bd_info"
19 },
20 {
21 .name = "rx_bd_info"
22 },
23 {
24 .name = "mac_list"
25 },
26 {
27 .name = "reg"
28 },
29 {
30 .name = "queue"
31 },
32 {
33 .name = "fd"
34 },
35 /* keep common at the bottom and add new directory above */
36 {
37 .name = "common"
38 },
39};
40
41static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd);
42static int hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd);
43
44static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
45 {
46 .name = "tm_nodes",
47 .cmd = HNAE3_DBG_CMD_TM_NODES,
48 .dentry = HNS3_DBG_DENTRY_TM,
49 .buf_len = HNS3_DBG_READ_LEN,
50 .init = hns3_dbg_common_file_init,
51 },
52 {
53 .name = "tm_priority",
54 .cmd = HNAE3_DBG_CMD_TM_PRI,
55 .dentry = HNS3_DBG_DENTRY_TM,
56 .buf_len = HNS3_DBG_READ_LEN,
57 .init = hns3_dbg_common_file_init,
58 },
59 {
60 .name = "tm_qset",
61 .cmd = HNAE3_DBG_CMD_TM_QSET,
62 .dentry = HNS3_DBG_DENTRY_TM,
63 .buf_len = HNS3_DBG_READ_LEN,
64 .init = hns3_dbg_common_file_init,
65 },
66 {
67 .name = "tm_map",
68 .cmd = HNAE3_DBG_CMD_TM_MAP,
69 .dentry = HNS3_DBG_DENTRY_TM,
70 .buf_len = HNS3_DBG_READ_LEN_1MB,
71 .init = hns3_dbg_common_file_init,
72 },
73 {
74 .name = "tm_pg",
75 .cmd = HNAE3_DBG_CMD_TM_PG,
76 .dentry = HNS3_DBG_DENTRY_TM,
77 .buf_len = HNS3_DBG_READ_LEN,
78 .init = hns3_dbg_common_file_init,
79 },
80 {
81 .name = "tm_port",
82 .cmd = HNAE3_DBG_CMD_TM_PORT,
83 .dentry = HNS3_DBG_DENTRY_TM,
84 .buf_len = HNS3_DBG_READ_LEN,
85 .init = hns3_dbg_common_file_init,
86 },
87 {
88 .name = "tc_sch_info",
89 .cmd = HNAE3_DBG_CMD_TC_SCH_INFO,
90 .dentry = HNS3_DBG_DENTRY_TM,
91 .buf_len = HNS3_DBG_READ_LEN,
92 .init = hns3_dbg_common_file_init,
93 },
94 {
95 .name = "qos_pause_cfg",
96 .cmd = HNAE3_DBG_CMD_QOS_PAUSE_CFG,
97 .dentry = HNS3_DBG_DENTRY_TM,
98 .buf_len = HNS3_DBG_READ_LEN,
99 .init = hns3_dbg_common_file_init,
100 },
101 {
102 .name = "qos_pri_map",
103 .cmd = HNAE3_DBG_CMD_QOS_PRI_MAP,
104 .dentry = HNS3_DBG_DENTRY_TM,
105 .buf_len = HNS3_DBG_READ_LEN,
106 .init = hns3_dbg_common_file_init,
107 },
108 {
109 .name = "qos_dscp_map",
110 .cmd = HNAE3_DBG_CMD_QOS_DSCP_MAP,
111 .dentry = HNS3_DBG_DENTRY_TM,
112 .buf_len = HNS3_DBG_READ_LEN,
113 .init = hns3_dbg_common_file_init,
114 },
115 {
116 .name = "qos_buf_cfg",
117 .cmd = HNAE3_DBG_CMD_QOS_BUF_CFG,
118 .dentry = HNS3_DBG_DENTRY_TM,
119 .buf_len = HNS3_DBG_READ_LEN,
120 .init = hns3_dbg_common_file_init,
121 },
122 {
123 .name = "dev_info",
124 .cmd = HNAE3_DBG_CMD_DEV_INFO,
125 .dentry = HNS3_DBG_DENTRY_COMMON,
126 .buf_len = HNS3_DBG_READ_LEN,
127 .init = hns3_dbg_common_file_init,
128 },
129 {
130 .name = "tx_bd_queue",
131 .cmd = HNAE3_DBG_CMD_TX_BD,
132 .dentry = HNS3_DBG_DENTRY_TX_BD,
133 .buf_len = HNS3_DBG_READ_LEN_5MB,
134 .init = hns3_dbg_bd_file_init,
135 },
136 {
137 .name = "rx_bd_queue",
138 .cmd = HNAE3_DBG_CMD_RX_BD,
139 .dentry = HNS3_DBG_DENTRY_RX_BD,
140 .buf_len = HNS3_DBG_READ_LEN_4MB,
141 .init = hns3_dbg_bd_file_init,
142 },
143 {
144 .name = "uc",
145 .cmd = HNAE3_DBG_CMD_MAC_UC,
146 .dentry = HNS3_DBG_DENTRY_MAC,
147 .buf_len = HNS3_DBG_READ_LEN_128KB,
148 .init = hns3_dbg_common_file_init,
149 },
150 {
151 .name = "mc",
152 .cmd = HNAE3_DBG_CMD_MAC_MC,
153 .dentry = HNS3_DBG_DENTRY_MAC,
154 .buf_len = HNS3_DBG_READ_LEN,
155 .init = hns3_dbg_common_file_init,
156 },
157 {
158 .name = "mng_tbl",
159 .cmd = HNAE3_DBG_CMD_MNG_TBL,
160 .dentry = HNS3_DBG_DENTRY_COMMON,
161 .buf_len = HNS3_DBG_READ_LEN,
162 .init = hns3_dbg_common_file_init,
163 },
164 {
165 .name = "loopback",
166 .cmd = HNAE3_DBG_CMD_LOOPBACK,
167 .dentry = HNS3_DBG_DENTRY_COMMON,
168 .buf_len = HNS3_DBG_READ_LEN,
169 .init = hns3_dbg_common_file_init,
170 },
171 {
172 .name = "interrupt_info",
173 .cmd = HNAE3_DBG_CMD_INTERRUPT_INFO,
174 .dentry = HNS3_DBG_DENTRY_COMMON,
175 .buf_len = HNS3_DBG_READ_LEN,
176 .init = hns3_dbg_common_file_init,
177 },
178 {
179 .name = "reset_info",
180 .cmd = HNAE3_DBG_CMD_RESET_INFO,
181 .dentry = HNS3_DBG_DENTRY_COMMON,
182 .buf_len = HNS3_DBG_READ_LEN,
183 .init = hns3_dbg_common_file_init,
184 },
185 {
186 .name = "imp_info",
187 .cmd = HNAE3_DBG_CMD_IMP_INFO,
188 .dentry = HNS3_DBG_DENTRY_COMMON,
189 .buf_len = HNS3_DBG_READ_LEN,
190 .init = hns3_dbg_common_file_init,
191 },
192 {
193 .name = "ncl_config",
194 .cmd = HNAE3_DBG_CMD_NCL_CONFIG,
195 .dentry = HNS3_DBG_DENTRY_COMMON,
196 .buf_len = HNS3_DBG_READ_LEN_128KB,
197 .init = hns3_dbg_common_file_init,
198 },
199 {
200 .name = "mac_tnl_status",
201 .cmd = HNAE3_DBG_CMD_MAC_TNL_STATUS,
202 .dentry = HNS3_DBG_DENTRY_COMMON,
203 .buf_len = HNS3_DBG_READ_LEN,
204 .init = hns3_dbg_common_file_init,
205 },
206 {
207 .name = "bios_common",
208 .cmd = HNAE3_DBG_CMD_REG_BIOS_COMMON,
209 .dentry = HNS3_DBG_DENTRY_REG,
210 .buf_len = HNS3_DBG_READ_LEN,
211 .init = hns3_dbg_common_file_init,
212 },
213 {
214 .name = "ssu",
215 .cmd = HNAE3_DBG_CMD_REG_SSU,
216 .dentry = HNS3_DBG_DENTRY_REG,
217 .buf_len = HNS3_DBG_READ_LEN,
218 .init = hns3_dbg_common_file_init,
219 },
220 {
221 .name = "igu_egu",
222 .cmd = HNAE3_DBG_CMD_REG_IGU_EGU,
223 .dentry = HNS3_DBG_DENTRY_REG,
224 .buf_len = HNS3_DBG_READ_LEN,
225 .init = hns3_dbg_common_file_init,
226 },
227 {
228 .name = "rpu",
229 .cmd = HNAE3_DBG_CMD_REG_RPU,
230 .dentry = HNS3_DBG_DENTRY_REG,
231 .buf_len = HNS3_DBG_READ_LEN,
232 .init = hns3_dbg_common_file_init,
233 },
234 {
235 .name = "ncsi",
236 .cmd = HNAE3_DBG_CMD_REG_NCSI,
237 .dentry = HNS3_DBG_DENTRY_REG,
238 .buf_len = HNS3_DBG_READ_LEN,
239 .init = hns3_dbg_common_file_init,
240 },
241 {
242 .name = "rtc",
243 .cmd = HNAE3_DBG_CMD_REG_RTC,
244 .dentry = HNS3_DBG_DENTRY_REG,
245 .buf_len = HNS3_DBG_READ_LEN,
246 .init = hns3_dbg_common_file_init,
247 },
248 {
249 .name = "ppp",
250 .cmd = HNAE3_DBG_CMD_REG_PPP,
251 .dentry = HNS3_DBG_DENTRY_REG,
252 .buf_len = HNS3_DBG_READ_LEN,
253 .init = hns3_dbg_common_file_init,
254 },
255 {
256 .name = "rcb",
257 .cmd = HNAE3_DBG_CMD_REG_RCB,
258 .dentry = HNS3_DBG_DENTRY_REG,
259 .buf_len = HNS3_DBG_READ_LEN,
260 .init = hns3_dbg_common_file_init,
261 },
262 {
263 .name = "tqp",
264 .cmd = HNAE3_DBG_CMD_REG_TQP,
265 .dentry = HNS3_DBG_DENTRY_REG,
266 .buf_len = HNS3_DBG_READ_LEN_128KB,
267 .init = hns3_dbg_common_file_init,
268 },
269 {
270 .name = "mac",
271 .cmd = HNAE3_DBG_CMD_REG_MAC,
272 .dentry = HNS3_DBG_DENTRY_REG,
273 .buf_len = HNS3_DBG_READ_LEN,
274 .init = hns3_dbg_common_file_init,
275 },
276 {
277 .name = "dcb",
278 .cmd = HNAE3_DBG_CMD_REG_DCB,
279 .dentry = HNS3_DBG_DENTRY_REG,
280 .buf_len = HNS3_DBG_READ_LEN,
281 .init = hns3_dbg_common_file_init,
282 },
283 {
284 .name = "queue_map",
285 .cmd = HNAE3_DBG_CMD_QUEUE_MAP,
286 .dentry = HNS3_DBG_DENTRY_QUEUE,
287 .buf_len = HNS3_DBG_READ_LEN,
288 .init = hns3_dbg_common_file_init,
289 },
290 {
291 .name = "rx_queue_info",
292 .cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,
293 .dentry = HNS3_DBG_DENTRY_QUEUE,
294 .buf_len = HNS3_DBG_READ_LEN_1MB,
295 .init = hns3_dbg_common_file_init,
296 },
297 {
298 .name = "tx_queue_info",
299 .cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,
300 .dentry = HNS3_DBG_DENTRY_QUEUE,
301 .buf_len = HNS3_DBG_READ_LEN_1MB,
302 .init = hns3_dbg_common_file_init,
303 },
304 {
305 .name = "fd_tcam",
306 .cmd = HNAE3_DBG_CMD_FD_TCAM,
307 .dentry = HNS3_DBG_DENTRY_FD,
308 .buf_len = HNS3_DBG_READ_LEN_1MB,
309 .init = hns3_dbg_common_file_init,
310 },
311 {
312 .name = "service_task_info",
313 .cmd = HNAE3_DBG_CMD_SERV_INFO,
314 .dentry = HNS3_DBG_DENTRY_COMMON,
315 .buf_len = HNS3_DBG_READ_LEN,
316 .init = hns3_dbg_common_file_init,
317 },
318 {
319 .name = "vlan_config",
320 .cmd = HNAE3_DBG_CMD_VLAN_CONFIG,
321 .dentry = HNS3_DBG_DENTRY_COMMON,
322 .buf_len = HNS3_DBG_READ_LEN,
323 .init = hns3_dbg_common_file_init,
324 },
325 {
326 .name = "ptp_info",
327 .cmd = HNAE3_DBG_CMD_PTP_INFO,
328 .dentry = HNS3_DBG_DENTRY_COMMON,
329 .buf_len = HNS3_DBG_READ_LEN,
330 .init = hns3_dbg_common_file_init,
331 },
332 {
333 .name = "fd_counter",
334 .cmd = HNAE3_DBG_CMD_FD_COUNTER,
335 .dentry = HNS3_DBG_DENTRY_FD,
336 .buf_len = HNS3_DBG_READ_LEN,
337 .init = hns3_dbg_common_file_init,
338 },
339 {
340 .name = "umv_info",
341 .cmd = HNAE3_DBG_CMD_UMV_INFO,
342 .dentry = HNS3_DBG_DENTRY_COMMON,
343 .buf_len = HNS3_DBG_READ_LEN,
344 .init = hns3_dbg_common_file_init,
345 },
346 {
347 .name = "page_pool_info",
348 .cmd = HNAE3_DBG_CMD_PAGE_POOL_INFO,
349 .dentry = HNS3_DBG_DENTRY_COMMON,
350 .buf_len = HNS3_DBG_READ_LEN,
351 .init = hns3_dbg_common_file_init,
352 },
353 {
354 .name = "coalesce_info",
355 .cmd = HNAE3_DBG_CMD_COAL_INFO,
356 .dentry = HNS3_DBG_DENTRY_COMMON,
357 .buf_len = HNS3_DBG_READ_LEN_1MB,
358 .init = hns3_dbg_common_file_init,
359 },
360};
361
362static struct hns3_dbg_cap_info hns3_dbg_cap[] = {
363 {
364 .name = "support FD",
365 .cap_bit = HNAE3_DEV_SUPPORT_FD_B,
366 }, {
367 .name = "support GRO",
368 .cap_bit = HNAE3_DEV_SUPPORT_GRO_B,
369 }, {
370 .name = "support FEC",
371 .cap_bit = HNAE3_DEV_SUPPORT_FEC_B,
372 }, {
373 .name = "support UDP GSO",
374 .cap_bit = HNAE3_DEV_SUPPORT_UDP_GSO_B,
375 }, {
376 .name = "support PTP",
377 .cap_bit = HNAE3_DEV_SUPPORT_PTP_B,
378 }, {
379 .name = "support INT QL",
380 .cap_bit = HNAE3_DEV_SUPPORT_INT_QL_B,
381 }, {
382 .name = "support HW TX csum",
383 .cap_bit = HNAE3_DEV_SUPPORT_HW_TX_CSUM_B,
384 }, {
385 .name = "support UDP tunnel csum",
386 .cap_bit = HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B,
387 }, {
388 .name = "support TX push",
389 .cap_bit = HNAE3_DEV_SUPPORT_TX_PUSH_B,
390 }, {
391 .name = "support imp-controlled PHY",
392 .cap_bit = HNAE3_DEV_SUPPORT_PHY_IMP_B,
393 }, {
394 .name = "support imp-controlled RAS",
395 .cap_bit = HNAE3_DEV_SUPPORT_RAS_IMP_B,
396 }, {
397 .name = "support rxd advanced layout",
398 .cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
399 }, {
400 .name = "support port vlan bypass",
401 .cap_bit = HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B,
402 }, {
403 .name = "support modify vlan filter state",
404 .cap_bit = HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B,
405 }, {
406 .name = "support FEC statistics",
407 .cap_bit = HNAE3_DEV_SUPPORT_FEC_STATS_B,
408 }, {
409 .name = "support lane num",
410 .cap_bit = HNAE3_DEV_SUPPORT_LANE_NUM_B,
411 }, {
412 .name = "support wake on lan",
413 .cap_bit = HNAE3_DEV_SUPPORT_WOL_B,
414 }, {
415 .name = "support tm flush",
416 .cap_bit = HNAE3_DEV_SUPPORT_TM_FLUSH_B,
417 }, {
418 .name = "support vf fault detect",
419 .cap_bit = HNAE3_DEV_SUPPORT_VF_FAULT_B,
420 }
421};
422
423static const struct hns3_dbg_item coal_info_items[] = {
424 { "VEC_ID", 2 },
425 { "ALGO_STATE", 2 },
426 { "PROFILE_ID", 2 },
427 { "CQE_MODE", 2 },
428 { "TUNE_STATE", 2 },
429 { "STEPS_LEFT", 2 },
430 { "STEPS_RIGHT", 2 },
431 { "TIRED", 2 },
432 { "SW_GL", 2 },
433 { "SW_QL", 2 },
434 { "HW_GL", 2 },
435 { "HW_QL", 2 },
436};
437
438static const char * const dim_cqe_mode_str[] = { "EQE", "CQE" };
439static const char * const dim_state_str[] = { "START", "IN_PROG", "APPLY" };
440static const char * const
441dim_tune_stat_str[] = { "ON_TOP", "TIRED", "RIGHT", "LEFT" };
442
443static void hns3_dbg_fill_content(char *content, u16 len,
444 const struct hns3_dbg_item *items,
445 const char **result, u16 size)
446{
447#define HNS3_DBG_LINE_END_LEN 2
448 char *pos = content;
449 u16 item_len;
450 u16 i;
451
452 if (!len) {
453 return;
454 } else if (len <= HNS3_DBG_LINE_END_LEN) {
455 *pos++ = '\0';
456 return;
457 }
458
459 memset(content, ' ', len);
460 len -= HNS3_DBG_LINE_END_LEN;
461
462 for (i = 0; i < size; i++) {
463 item_len = strlen(items[i].name) + items[i].interval;
464 if (len < item_len)
465 break;
466
467 if (result) {
468 if (item_len < strlen(result[i]))
469 break;
470 memcpy(pos, result[i], strlen(result[i]));
471 } else {
472 memcpy(pos, items[i].name, strlen(items[i].name));
473 }
474 pos += item_len;
475 len -= item_len;
476 }
477 *pos++ = '\n';
478 *pos++ = '\0';
479}
480
481static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector,
482 char **result, int i, bool is_tx)
483{
484 unsigned int gl_offset, ql_offset;
485 struct hns3_enet_coalesce *coal;
486 unsigned int reg_val;
487 unsigned int j = 0;
488 struct dim *dim;
489 bool ql_enable;
490
491 if (is_tx) {
492 coal = &tqp_vector->tx_group.coal;
493 dim = &tqp_vector->tx_group.dim;
494 gl_offset = HNS3_VECTOR_GL1_OFFSET;
495 ql_offset = HNS3_VECTOR_TX_QL_OFFSET;
496 ql_enable = tqp_vector->tx_group.coal.ql_enable;
497 } else {
498 coal = &tqp_vector->rx_group.coal;
499 dim = &tqp_vector->rx_group.dim;
500 gl_offset = HNS3_VECTOR_GL0_OFFSET;
501 ql_offset = HNS3_VECTOR_RX_QL_OFFSET;
502 ql_enable = tqp_vector->rx_group.coal.ql_enable;
503 }
504
505 sprintf(buf: result[j++], fmt: "%d", i);
506 sprintf(buf: result[j++], fmt: "%s", dim->state < ARRAY_SIZE(dim_state_str) ?
507 dim_state_str[dim->state] : "unknown");
508 sprintf(buf: result[j++], fmt: "%u", dim->profile_ix);
509 sprintf(buf: result[j++], fmt: "%s", dim->mode < ARRAY_SIZE(dim_cqe_mode_str) ?
510 dim_cqe_mode_str[dim->mode] : "unknown");
511 sprintf(buf: result[j++], fmt: "%s",
512 dim->tune_state < ARRAY_SIZE(dim_tune_stat_str) ?
513 dim_tune_stat_str[dim->tune_state] : "unknown");
514 sprintf(buf: result[j++], fmt: "%u", dim->steps_left);
515 sprintf(buf: result[j++], fmt: "%u", dim->steps_right);
516 sprintf(buf: result[j++], fmt: "%u", dim->tired);
517 sprintf(buf: result[j++], fmt: "%u", coal->int_gl);
518 sprintf(buf: result[j++], fmt: "%u", coal->int_ql);
519 reg_val = readl(addr: tqp_vector->mask_addr + gl_offset) &
520 HNS3_VECTOR_GL_MASK;
521 sprintf(buf: result[j++], fmt: "%u", reg_val);
522 if (ql_enable) {
523 reg_val = readl(addr: tqp_vector->mask_addr + ql_offset) &
524 HNS3_VECTOR_QL_MASK;
525 sprintf(buf: result[j++], fmt: "%u", reg_val);
526 } else {
527 sprintf(buf: result[j++], fmt: "NA");
528 }
529}
530
531static void hns3_dump_coal_info(struct hnae3_handle *h, char *buf, int len,
532 int *pos, bool is_tx)
533{
534 char data_str[ARRAY_SIZE(coal_info_items)][HNS3_DBG_DATA_STR_LEN];
535 char *result[ARRAY_SIZE(coal_info_items)];
536 struct hns3_enet_tqp_vector *tqp_vector;
537 struct hns3_nic_priv *priv = h->priv;
538 char content[HNS3_DBG_INFO_LEN];
539 unsigned int i;
540
541 for (i = 0; i < ARRAY_SIZE(coal_info_items); i++)
542 result[i] = &data_str[i][0];
543
544 *pos += scnprintf(buf: buf + *pos, size: len - *pos,
545 fmt: "%s interrupt coalesce info:\n",
546 is_tx ? "tx" : "rx");
547 hns3_dbg_fill_content(content, len: sizeof(content), items: coal_info_items,
548 NULL, ARRAY_SIZE(coal_info_items));
549 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "%s", content);
550
551 for (i = 0; i < priv->vector_num; i++) {
552 tqp_vector = &priv->tqp_vector[i];
553 hns3_get_coal_info(tqp_vector, result, i, is_tx);
554 hns3_dbg_fill_content(content, len: sizeof(content), items: coal_info_items,
555 result: (const char **)result,
556 ARRAY_SIZE(coal_info_items));
557 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "%s", content);
558 }
559}
560
561static int hns3_dbg_coal_info(struct hnae3_handle *h, char *buf, int len)
562{
563 int pos = 0;
564
565 hns3_dump_coal_info(h, buf, len, pos: &pos, is_tx: true);
566 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "\n");
567 hns3_dump_coal_info(h, buf, len, pos: &pos, is_tx: false);
568
569 return 0;
570}
571
572static const struct hns3_dbg_item tx_spare_info_items[] = {
573 { "QUEUE_ID", 2 },
574 { "COPYBREAK", 2 },
575 { "LEN", 7 },
576 { "NTU", 4 },
577 { "NTC", 4 },
578 { "LTC", 4 },
579 { "DMA", 17 },
580};
581
582static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf,
583 int len, u32 ring_num, int *pos)
584{
585 char data_str[ARRAY_SIZE(tx_spare_info_items)][HNS3_DBG_DATA_STR_LEN];
586 struct hns3_tx_spare *tx_spare = ring->tx_spare;
587 char *result[ARRAY_SIZE(tx_spare_info_items)];
588 char content[HNS3_DBG_INFO_LEN];
589 u32 i, j;
590
591 if (!tx_spare) {
592 *pos += scnprintf(buf: buf + *pos, size: len - *pos,
593 fmt: "tx spare buffer is not enabled\n");
594 return;
595 }
596
597 for (i = 0; i < ARRAY_SIZE(tx_spare_info_items); i++)
598 result[i] = &data_str[i][0];
599
600 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "tx spare buffer info\n");
601 hns3_dbg_fill_content(content, len: sizeof(content), items: tx_spare_info_items,
602 NULL, ARRAY_SIZE(tx_spare_info_items));
603 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "%s", content);
604
605 for (i = 0; i < ring_num; i++) {
606 j = 0;
607 sprintf(buf: result[j++], fmt: "%u", i);
608 sprintf(buf: result[j++], fmt: "%u", ring->tx_copybreak);
609 sprintf(buf: result[j++], fmt: "%u", tx_spare->len);
610 sprintf(buf: result[j++], fmt: "%u", tx_spare->next_to_use);
611 sprintf(buf: result[j++], fmt: "%u", tx_spare->next_to_clean);
612 sprintf(buf: result[j++], fmt: "%u", tx_spare->last_to_clean);
613 sprintf(buf: result[j++], fmt: "%pad", &tx_spare->dma);
614 hns3_dbg_fill_content(content, len: sizeof(content),
615 items: tx_spare_info_items,
616 result: (const char **)result,
617 ARRAY_SIZE(tx_spare_info_items));
618 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "%s", content);
619 }
620}
621
622static const struct hns3_dbg_item rx_queue_info_items[] = {
623 { "QUEUE_ID", 2 },
624 { "BD_NUM", 2 },
625 { "BD_LEN", 2 },
626 { "TAIL", 2 },
627 { "HEAD", 2 },
628 { "FBDNUM", 2 },
629 { "PKTNUM", 5 },
630 { "COPYBREAK", 2 },
631 { "RING_EN", 2 },
632 { "RX_RING_EN", 2 },
633 { "BASE_ADDR", 10 },
634};
635
636static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring,
637 struct hnae3_ae_dev *ae_dev, char **result,
638 u32 index)
639{
640 u32 base_add_l, base_add_h;
641 u32 j = 0;
642
643 sprintf(buf: result[j++], fmt: "%u", index);
644
645 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
646 HNS3_RING_RX_RING_BD_NUM_REG));
647
648 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
649 HNS3_RING_RX_RING_BD_LEN_REG));
650
651 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
652 HNS3_RING_RX_RING_TAIL_REG));
653
654 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
655 HNS3_RING_RX_RING_HEAD_REG));
656
657 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
658 HNS3_RING_RX_RING_FBDNUM_REG));
659
660 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
661 HNS3_RING_RX_RING_PKTNUM_RECORD_REG));
662 sprintf(buf: result[j++], fmt: "%u", ring->rx_copybreak);
663
664 sprintf(buf: result[j++], fmt: "%s", readl_relaxed(ring->tqp->io_base +
665 HNS3_RING_EN_REG) ? "on" : "off");
666
667 if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
668 sprintf(buf: result[j++], fmt: "%s", readl_relaxed(ring->tqp->io_base +
669 HNS3_RING_RX_EN_REG) ? "on" : "off");
670 else
671 sprintf(buf: result[j++], fmt: "%s", "NA");
672
673 base_add_h = readl_relaxed(ring->tqp->io_base +
674 HNS3_RING_RX_RING_BASEADDR_H_REG);
675 base_add_l = readl_relaxed(ring->tqp->io_base +
676 HNS3_RING_RX_RING_BASEADDR_L_REG);
677 sprintf(buf: result[j++], fmt: "0x%08x%08x", base_add_h, base_add_l);
678}
679
680static int hns3_dbg_rx_queue_info(struct hnae3_handle *h,
681 char *buf, int len)
682{
683 char data_str[ARRAY_SIZE(rx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];
684 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev: h->pdev);
685 char *result[ARRAY_SIZE(rx_queue_info_items)];
686 struct hns3_nic_priv *priv = h->priv;
687 char content[HNS3_DBG_INFO_LEN];
688 struct hns3_enet_ring *ring;
689 int pos = 0;
690 u32 i;
691
692 if (!priv->ring) {
693 dev_err(&h->pdev->dev, "priv->ring is NULL\n");
694 return -EFAULT;
695 }
696
697 for (i = 0; i < ARRAY_SIZE(rx_queue_info_items); i++)
698 result[i] = &data_str[i][0];
699
700 hns3_dbg_fill_content(content, len: sizeof(content), items: rx_queue_info_items,
701 NULL, ARRAY_SIZE(rx_queue_info_items));
702 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
703 for (i = 0; i < h->kinfo.num_tqps; i++) {
704 /* Each cycle needs to determine whether the instance is reset,
705 * to prevent reference to invalid memory. And need to ensure
706 * that the following code is executed within 100ms.
707 */
708 if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
709 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
710 return -EPERM;
711
712 ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];
713 hns3_dump_rx_queue_info(ring, ae_dev, result, index: i);
714 hns3_dbg_fill_content(content, len: sizeof(content),
715 items: rx_queue_info_items,
716 result: (const char **)result,
717 ARRAY_SIZE(rx_queue_info_items));
718 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
719 }
720
721 return 0;
722}
723
724static const struct hns3_dbg_item tx_queue_info_items[] = {
725 { "QUEUE_ID", 2 },
726 { "BD_NUM", 2 },
727 { "TC", 2 },
728 { "TAIL", 2 },
729 { "HEAD", 2 },
730 { "FBDNUM", 2 },
731 { "OFFSET", 2 },
732 { "PKTNUM", 5 },
733 { "RING_EN", 2 },
734 { "TX_RING_EN", 2 },
735 { "BASE_ADDR", 10 },
736};
737
738static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring,
739 struct hnae3_ae_dev *ae_dev, char **result,
740 u32 index)
741{
742 u32 base_add_l, base_add_h;
743 u32 j = 0;
744
745 sprintf(buf: result[j++], fmt: "%u", index);
746 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
747 HNS3_RING_TX_RING_BD_NUM_REG));
748
749 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
750 HNS3_RING_TX_RING_TC_REG));
751
752 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
753 HNS3_RING_TX_RING_TAIL_REG));
754
755 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
756 HNS3_RING_TX_RING_HEAD_REG));
757
758 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
759 HNS3_RING_TX_RING_FBDNUM_REG));
760
761 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
762 HNS3_RING_TX_RING_OFFSET_REG));
763
764 sprintf(buf: result[j++], fmt: "%u", readl_relaxed(ring->tqp->io_base +
765 HNS3_RING_TX_RING_PKTNUM_RECORD_REG));
766
767 sprintf(buf: result[j++], fmt: "%s", readl_relaxed(ring->tqp->io_base +
768 HNS3_RING_EN_REG) ? "on" : "off");
769
770 if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
771 sprintf(buf: result[j++], fmt: "%s", readl_relaxed(ring->tqp->io_base +
772 HNS3_RING_TX_EN_REG) ? "on" : "off");
773 else
774 sprintf(buf: result[j++], fmt: "%s", "NA");
775
776 base_add_h = readl_relaxed(ring->tqp->io_base +
777 HNS3_RING_TX_RING_BASEADDR_H_REG);
778 base_add_l = readl_relaxed(ring->tqp->io_base +
779 HNS3_RING_TX_RING_BASEADDR_L_REG);
780 sprintf(buf: result[j++], fmt: "0x%08x%08x", base_add_h, base_add_l);
781}
782
783static int hns3_dbg_tx_queue_info(struct hnae3_handle *h,
784 char *buf, int len)
785{
786 char data_str[ARRAY_SIZE(tx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];
787 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev: h->pdev);
788 char *result[ARRAY_SIZE(tx_queue_info_items)];
789 struct hns3_nic_priv *priv = h->priv;
790 char content[HNS3_DBG_INFO_LEN];
791 struct hns3_enet_ring *ring;
792 int pos = 0;
793 u32 i;
794
795 if (!priv->ring) {
796 dev_err(&h->pdev->dev, "priv->ring is NULL\n");
797 return -EFAULT;
798 }
799
800 for (i = 0; i < ARRAY_SIZE(tx_queue_info_items); i++)
801 result[i] = &data_str[i][0];
802
803 hns3_dbg_fill_content(content, len: sizeof(content), items: tx_queue_info_items,
804 NULL, ARRAY_SIZE(tx_queue_info_items));
805 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
806
807 for (i = 0; i < h->kinfo.num_tqps; i++) {
808 /* Each cycle needs to determine whether the instance is reset,
809 * to prevent reference to invalid memory. And need to ensure
810 * that the following code is executed within 100ms.
811 */
812 if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
813 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
814 return -EPERM;
815
816 ring = &priv->ring[i];
817 hns3_dump_tx_queue_info(ring, ae_dev, result, index: i);
818 hns3_dbg_fill_content(content, len: sizeof(content),
819 items: tx_queue_info_items,
820 result: (const char **)result,
821 ARRAY_SIZE(tx_queue_info_items));
822 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
823 }
824
825 hns3_dbg_tx_spare_info(ring, buf, len, ring_num: h->kinfo.num_tqps, pos: &pos);
826
827 return 0;
828}
829
830static const struct hns3_dbg_item queue_map_items[] = {
831 { "local_queue_id", 2 },
832 { "global_queue_id", 2 },
833 { "vector_id", 2 },
834};
835
836static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len)
837{
838 char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN];
839 char *result[ARRAY_SIZE(queue_map_items)];
840 struct hns3_nic_priv *priv = h->priv;
841 char content[HNS3_DBG_INFO_LEN];
842 int pos = 0;
843 int j;
844 u32 i;
845
846 if (!h->ae_algo->ops->get_global_queue_id)
847 return -EOPNOTSUPP;
848
849 for (i = 0; i < ARRAY_SIZE(queue_map_items); i++)
850 result[i] = &data_str[i][0];
851
852 hns3_dbg_fill_content(content, len: sizeof(content), items: queue_map_items,
853 NULL, ARRAY_SIZE(queue_map_items));
854 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
855 for (i = 0; i < h->kinfo.num_tqps; i++) {
856 if (!priv->ring || !priv->ring[i].tqp_vector)
857 continue;
858 j = 0;
859 sprintf(buf: result[j++], fmt: "%u", i);
860 sprintf(buf: result[j++], fmt: "%u",
861 h->ae_algo->ops->get_global_queue_id(h, i));
862 sprintf(buf: result[j++], fmt: "%d",
863 priv->ring[i].tqp_vector->vector_irq);
864 hns3_dbg_fill_content(content, len: sizeof(content), items: queue_map_items,
865 result: (const char **)result,
866 ARRAY_SIZE(queue_map_items));
867 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
868 }
869
870 return 0;
871}
872
873static const struct hns3_dbg_item rx_bd_info_items[] = {
874 { "BD_IDX", 3 },
875 { "L234_INFO", 2 },
876 { "PKT_LEN", 3 },
877 { "SIZE", 4 },
878 { "RSS_HASH", 4 },
879 { "FD_ID", 2 },
880 { "VLAN_TAG", 2 },
881 { "O_DM_VLAN_ID_FB", 2 },
882 { "OT_VLAN_TAG", 2 },
883 { "BD_BASE_INFO", 2 },
884 { "PTYPE", 2 },
885 { "HW_CSUM", 2 },
886};
887
888static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv,
889 struct hns3_desc *desc, char **result, int idx)
890{
891 unsigned int j = 0;
892
893 sprintf(buf: result[j++], fmt: "%d", idx);
894 sprintf(buf: result[j++], fmt: "%#x", le32_to_cpu(desc->rx.l234_info));
895 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->rx.pkt_len));
896 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->rx.size));
897 sprintf(buf: result[j++], fmt: "%#x", le32_to_cpu(desc->rx.rss_hash));
898 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->rx.fd_id));
899 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->rx.vlan_tag));
900 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb));
901 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->rx.ot_vlan_tag));
902 sprintf(buf: result[j++], fmt: "%#x", le32_to_cpu(desc->rx.bd_base_info));
903 if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) {
904 u32 ol_info = le32_to_cpu(desc->rx.ol_info);
905
906 sprintf(buf: result[j++], fmt: "%5lu", hnae3_get_field(ol_info,
907 HNS3_RXD_PTYPE_M,
908 HNS3_RXD_PTYPE_S));
909 sprintf(buf: result[j++], fmt: "%7u", le16_to_cpu(desc->csum));
910 } else {
911 sprintf(buf: result[j++], fmt: "NA");
912 sprintf(buf: result[j++], fmt: "NA");
913 }
914}
915
916static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
917{
918 char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];
919 struct hns3_nic_priv *priv = d->handle->priv;
920 char *result[ARRAY_SIZE(rx_bd_info_items)];
921 char content[HNS3_DBG_INFO_LEN];
922 struct hns3_enet_ring *ring;
923 struct hns3_desc *desc;
924 unsigned int i;
925 int pos = 0;
926
927 if (d->qid >= d->handle->kinfo.num_tqps) {
928 dev_err(&d->handle->pdev->dev,
929 "queue%u is not in use\n", d->qid);
930 return -EINVAL;
931 }
932
933 for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++)
934 result[i] = &data_str[i][0];
935
936 pos += scnprintf(buf: buf + pos, size: len - pos,
937 fmt: "Queue %u rx bd info:\n", d->qid);
938 hns3_dbg_fill_content(content, len: sizeof(content), items: rx_bd_info_items,
939 NULL, ARRAY_SIZE(rx_bd_info_items));
940 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
941
942 ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps];
943 for (i = 0; i < ring->desc_num; i++) {
944 desc = &ring->desc[i];
945
946 hns3_dump_rx_bd_info(priv, desc, result, idx: i);
947 hns3_dbg_fill_content(content, len: sizeof(content),
948 items: rx_bd_info_items, result: (const char **)result,
949 ARRAY_SIZE(rx_bd_info_items));
950 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
951 }
952
953 return 0;
954}
955
956static const struct hns3_dbg_item tx_bd_info_items[] = {
957 { "BD_IDX", 2 },
958 { "ADDRESS", 13 },
959 { "VLAN_TAG", 2 },
960 { "SIZE", 2 },
961 { "T_CS_VLAN_TSO", 2 },
962 { "OT_VLAN_TAG", 3 },
963 { "TV", 5 },
964 { "OLT_VLAN_LEN", 2 },
965 { "PAYLEN_OL4CS", 2 },
966 { "BD_FE_SC_VLD", 2 },
967 { "MSS_HW_CSUM", 0 },
968};
969
970static void hns3_dump_tx_bd_info(struct hns3_desc *desc, char **result, int idx)
971{
972 unsigned int j = 0;
973
974 sprintf(buf: result[j++], fmt: "%d", idx);
975 sprintf(buf: result[j++], fmt: "%#llx", le64_to_cpu(desc->addr));
976 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->tx.vlan_tag));
977 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->tx.send_size));
978 sprintf(buf: result[j++], fmt: "%#x",
979 le32_to_cpu(desc->tx.type_cs_vlan_tso_len));
980 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->tx.outer_vlan_tag));
981 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->tx.tv));
982 sprintf(buf: result[j++], fmt: "%u",
983 le32_to_cpu(desc->tx.ol_type_vlan_len_msec));
984 sprintf(buf: result[j++], fmt: "%#x", le32_to_cpu(desc->tx.paylen_ol4cs));
985 sprintf(buf: result[j++], fmt: "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri));
986 sprintf(buf: result[j++], fmt: "%u", le16_to_cpu(desc->tx.mss_hw_csum));
987}
988
989static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
990{
991 char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];
992 struct hns3_nic_priv *priv = d->handle->priv;
993 char *result[ARRAY_SIZE(tx_bd_info_items)];
994 char content[HNS3_DBG_INFO_LEN];
995 struct hns3_enet_ring *ring;
996 struct hns3_desc *desc;
997 unsigned int i;
998 int pos = 0;
999
1000 if (d->qid >= d->handle->kinfo.num_tqps) {
1001 dev_err(&d->handle->pdev->dev,
1002 "queue%u is not in use\n", d->qid);
1003 return -EINVAL;
1004 }
1005
1006 for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++)
1007 result[i] = &data_str[i][0];
1008
1009 pos += scnprintf(buf: buf + pos, size: len - pos,
1010 fmt: "Queue %u tx bd info:\n", d->qid);
1011 hns3_dbg_fill_content(content, len: sizeof(content), items: tx_bd_info_items,
1012 NULL, ARRAY_SIZE(tx_bd_info_items));
1013 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
1014
1015 ring = &priv->ring[d->qid];
1016 for (i = 0; i < ring->desc_num; i++) {
1017 desc = &ring->desc[i];
1018
1019 hns3_dump_tx_bd_info(desc, result, idx: i);
1020 hns3_dbg_fill_content(content, len: sizeof(content),
1021 items: tx_bd_info_items, result: (const char **)result,
1022 ARRAY_SIZE(tx_bd_info_items));
1023 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
1024 }
1025
1026 return 0;
1027}
1028
1029static void
1030hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos)
1031{
1032 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev: h->pdev);
1033 const char * const str[] = {"no", "yes"};
1034 unsigned long *caps = ae_dev->caps;
1035 u32 i, state;
1036
1037 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "dev capability:\n");
1038
1039 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) {
1040 state = test_bit(hns3_dbg_cap[i].cap_bit, caps);
1041 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "%s: %s\n",
1042 hns3_dbg_cap[i].name, str[state]);
1043 }
1044
1045 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "\n");
1046}
1047
1048static void
1049hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos)
1050{
1051 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev: h->pdev);
1052 struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs;
1053 struct hnae3_knic_private_info *kinfo = &h->kinfo;
1054 struct net_device *dev = kinfo->netdev;
1055
1056 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "dev_spec:\n");
1057 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "MAC entry num: %u\n",
1058 dev_specs->mac_entry_num);
1059 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "MNG entry num: %u\n",
1060 dev_specs->mng_entry_num);
1061 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "MAX non tso bd num: %u\n",
1062 dev_specs->max_non_tso_bd_num);
1063 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "RSS ind tbl size: %u\n",
1064 dev_specs->rss_ind_tbl_size);
1065 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "RSS key size: %u\n",
1066 dev_specs->rss_key_size);
1067 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "RSS size: %u\n",
1068 kinfo->rss_size);
1069 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "Allocated RSS size: %u\n",
1070 kinfo->req_rss_size);
1071 *pos += scnprintf(buf: buf + *pos, size: len - *pos,
1072 fmt: "Task queue pairs numbers: %u\n",
1073 kinfo->num_tqps);
1074 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "RX buffer length: %u\n",
1075 kinfo->rx_buf_len);
1076 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "Desc num per TX queue: %u\n",
1077 kinfo->num_tx_desc);
1078 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "Desc num per RX queue: %u\n",
1079 kinfo->num_rx_desc);
1080 *pos += scnprintf(buf: buf + *pos, size: len - *pos,
1081 fmt: "Total number of enabled TCs: %u\n",
1082 kinfo->tc_info.num_tc);
1083 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "MAX INT QL: %u\n",
1084 dev_specs->int_ql_max);
1085 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "MAX INT GL: %u\n",
1086 dev_specs->max_int_gl);
1087 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "MAX TM RATE: %u\n",
1088 dev_specs->max_tm_rate);
1089 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "MAX QSET number: %u\n",
1090 dev_specs->max_qset_num);
1091 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "umv size: %u\n",
1092 dev_specs->umv_size);
1093 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "mc mac size: %u\n",
1094 dev_specs->mc_mac_size);
1095 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "MAC statistics number: %u\n",
1096 dev_specs->mac_stats_num);
1097 *pos += scnprintf(buf: buf + *pos, size: len - *pos,
1098 fmt: "TX timeout threshold: %d seconds\n",
1099 dev->watchdog_timeo / HZ);
1100 *pos += scnprintf(buf: buf + *pos, size: len - *pos, fmt: "Hilink Version: %u\n",
1101 dev_specs->hilink_version);
1102}
1103
1104static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len)
1105{
1106 int pos = 0;
1107
1108 hns3_dbg_dev_caps(h, buf, len, pos: &pos);
1109
1110 hns3_dbg_dev_specs(h, buf, len, pos: &pos);
1111
1112 return 0;
1113}
1114
1115static const struct hns3_dbg_item page_pool_info_items[] = {
1116 { "QUEUE_ID", 2 },
1117 { "ALLOCATE_CNT", 2 },
1118 { "FREE_CNT", 6 },
1119 { "POOL_SIZE(PAGE_NUM)", 2 },
1120 { "ORDER", 2 },
1121 { "NUMA_ID", 2 },
1122 { "MAX_LEN", 2 },
1123};
1124
1125static void hns3_dump_page_pool_info(struct hns3_enet_ring *ring,
1126 char **result, u32 index)
1127{
1128 u32 j = 0;
1129
1130 sprintf(buf: result[j++], fmt: "%u", index);
1131 sprintf(buf: result[j++], fmt: "%u",
1132 READ_ONCE(ring->page_pool->pages_state_hold_cnt));
1133 sprintf(buf: result[j++], fmt: "%d",
1134 atomic_read(v: &ring->page_pool->pages_state_release_cnt));
1135 sprintf(buf: result[j++], fmt: "%u", ring->page_pool->p.pool_size);
1136 sprintf(buf: result[j++], fmt: "%u", ring->page_pool->p.order);
1137 sprintf(buf: result[j++], fmt: "%d", ring->page_pool->p.nid);
1138 sprintf(buf: result[j++], fmt: "%uK", ring->page_pool->p.max_len / 1024);
1139}
1140
1141static int
1142hns3_dbg_page_pool_info(struct hnae3_handle *h, char *buf, int len)
1143{
1144 char data_str[ARRAY_SIZE(page_pool_info_items)][HNS3_DBG_DATA_STR_LEN];
1145 char *result[ARRAY_SIZE(page_pool_info_items)];
1146 struct hns3_nic_priv *priv = h->priv;
1147 char content[HNS3_DBG_INFO_LEN];
1148 struct hns3_enet_ring *ring;
1149 int pos = 0;
1150 u32 i;
1151
1152 if (!priv->ring) {
1153 dev_err(&h->pdev->dev, "priv->ring is NULL\n");
1154 return -EFAULT;
1155 }
1156
1157 if (!priv->ring[h->kinfo.num_tqps].page_pool) {
1158 dev_err(&h->pdev->dev, "page pool is not initialized\n");
1159 return -EFAULT;
1160 }
1161
1162 for (i = 0; i < ARRAY_SIZE(page_pool_info_items); i++)
1163 result[i] = &data_str[i][0];
1164
1165 hns3_dbg_fill_content(content, len: sizeof(content), items: page_pool_info_items,
1166 NULL, ARRAY_SIZE(page_pool_info_items));
1167 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
1168 for (i = 0; i < h->kinfo.num_tqps; i++) {
1169 if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
1170 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
1171 return -EPERM;
1172 ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];
1173 hns3_dump_page_pool_info(ring, result, index: i);
1174 hns3_dbg_fill_content(content, len: sizeof(content),
1175 items: page_pool_info_items,
1176 result: (const char **)result,
1177 ARRAY_SIZE(page_pool_info_items));
1178 pos += scnprintf(buf: buf + pos, size: len - pos, fmt: "%s", content);
1179 }
1180
1181 return 0;
1182}
1183
1184static int hns3_dbg_get_cmd_index(struct hns3_dbg_data *dbg_data, u32 *index)
1185{
1186 u32 i;
1187
1188 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
1189 if (hns3_dbg_cmd[i].cmd == dbg_data->cmd) {
1190 *index = i;
1191 return 0;
1192 }
1193 }
1194
1195 dev_err(&dbg_data->handle->pdev->dev, "unknown command(%d)\n",
1196 dbg_data->cmd);
1197 return -EINVAL;
1198}
1199
1200static const struct hns3_dbg_func hns3_dbg_cmd_func[] = {
1201 {
1202 .cmd = HNAE3_DBG_CMD_QUEUE_MAP,
1203 .dbg_dump = hns3_dbg_queue_map,
1204 },
1205 {
1206 .cmd = HNAE3_DBG_CMD_DEV_INFO,
1207 .dbg_dump = hns3_dbg_dev_info,
1208 },
1209 {
1210 .cmd = HNAE3_DBG_CMD_TX_BD,
1211 .dbg_dump_bd = hns3_dbg_tx_bd_info,
1212 },
1213 {
1214 .cmd = HNAE3_DBG_CMD_RX_BD,
1215 .dbg_dump_bd = hns3_dbg_rx_bd_info,
1216 },
1217 {
1218 .cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,
1219 .dbg_dump = hns3_dbg_rx_queue_info,
1220 },
1221 {
1222 .cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,
1223 .dbg_dump = hns3_dbg_tx_queue_info,
1224 },
1225 {
1226 .cmd = HNAE3_DBG_CMD_PAGE_POOL_INFO,
1227 .dbg_dump = hns3_dbg_page_pool_info,
1228 },
1229 {
1230 .cmd = HNAE3_DBG_CMD_COAL_INFO,
1231 .dbg_dump = hns3_dbg_coal_info,
1232 },
1233};
1234
1235static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data,
1236 enum hnae3_dbg_cmd cmd, char *buf, int len)
1237{
1238 const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops;
1239 const struct hns3_dbg_func *cmd_func;
1240 u32 i;
1241
1242 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) {
1243 if (cmd == hns3_dbg_cmd_func[i].cmd) {
1244 cmd_func = &hns3_dbg_cmd_func[i];
1245 if (cmd_func->dbg_dump)
1246 return cmd_func->dbg_dump(dbg_data->handle, buf,
1247 len);
1248 else
1249 return cmd_func->dbg_dump_bd(dbg_data, buf,
1250 len);
1251 }
1252 }
1253
1254 if (!ops->dbg_read_cmd)
1255 return -EOPNOTSUPP;
1256
1257 return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len);
1258}
1259
1260static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
1261 size_t count, loff_t *ppos)
1262{
1263 struct hns3_dbg_data *dbg_data = filp->private_data;
1264 struct hnae3_handle *handle = dbg_data->handle;
1265 struct hns3_nic_priv *priv = handle->priv;
1266 ssize_t size = 0;
1267 char **save_buf;
1268 char *read_buf;
1269 u32 index;
1270 int ret;
1271
1272 ret = hns3_dbg_get_cmd_index(dbg_data, index: &index);
1273 if (ret)
1274 return ret;
1275
1276 mutex_lock(&handle->dbgfs_lock);
1277 save_buf = &handle->dbgfs_buf[index];
1278
1279 if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
1280 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) {
1281 ret = -EBUSY;
1282 goto out;
1283 }
1284
1285 if (*save_buf) {
1286 read_buf = *save_buf;
1287 } else {
1288 read_buf = kvzalloc(size: hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
1289 if (!read_buf) {
1290 ret = -ENOMEM;
1291 goto out;
1292 }
1293
1294 /* save the buffer addr until the last read operation */
1295 *save_buf = read_buf;
1296
1297 /* get data ready for the first time to read */
1298 ret = hns3_dbg_read_cmd(dbg_data, cmd: hns3_dbg_cmd[index].cmd,
1299 buf: read_buf, len: hns3_dbg_cmd[index].buf_len);
1300 if (ret)
1301 goto out;
1302 }
1303
1304 size = simple_read_from_buffer(to: buffer, count, ppos, from: read_buf,
1305 strlen(read_buf));
1306 if (size > 0) {
1307 mutex_unlock(lock: &handle->dbgfs_lock);
1308 return size;
1309 }
1310
1311out:
1312 /* free the buffer for the last read operation */
1313 if (*save_buf) {
1314 kvfree(addr: *save_buf);
1315 *save_buf = NULL;
1316 }
1317
1318 mutex_unlock(lock: &handle->dbgfs_lock);
1319 return ret;
1320}
1321
1322static const struct file_operations hns3_dbg_fops = {
1323 .owner = THIS_MODULE,
1324 .open = simple_open,
1325 .read = hns3_dbg_read,
1326};
1327
1328static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd)
1329{
1330 struct dentry *entry_dir;
1331 struct hns3_dbg_data *data;
1332 u16 max_queue_num;
1333 unsigned int i;
1334
1335 entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
1336 max_queue_num = hns3_get_max_available_channels(h: handle);
1337 data = devm_kzalloc(dev: &handle->pdev->dev, size: max_queue_num * sizeof(*data),
1338 GFP_KERNEL);
1339 if (!data)
1340 return -ENOMEM;
1341
1342 for (i = 0; i < max_queue_num; i++) {
1343 char name[HNS3_DBG_FILE_NAME_LEN];
1344
1345 data[i].handle = handle;
1346 data[i].cmd = hns3_dbg_cmd[cmd].cmd;
1347 data[i].qid = i;
1348 sprintf(buf: name, fmt: "%s%u", hns3_dbg_cmd[cmd].name, i);
1349 debugfs_create_file(name, mode: 0400, parent: entry_dir, data: &data[i],
1350 fops: &hns3_dbg_fops);
1351 }
1352
1353 return 0;
1354}
1355
1356static int
1357hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd)
1358{
1359 struct hns3_dbg_data *data;
1360 struct dentry *entry_dir;
1361
1362 data = devm_kzalloc(dev: &handle->pdev->dev, size: sizeof(*data), GFP_KERNEL);
1363 if (!data)
1364 return -ENOMEM;
1365
1366 data->handle = handle;
1367 data->cmd = hns3_dbg_cmd[cmd].cmd;
1368 entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
1369 debugfs_create_file(name: hns3_dbg_cmd[cmd].name, mode: 0400, parent: entry_dir,
1370 data, fops: &hns3_dbg_fops);
1371
1372 return 0;
1373}
1374
1375int hns3_dbg_init(struct hnae3_handle *handle)
1376{
1377 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev: handle->pdev);
1378 const char *name = pci_name(pdev: handle->pdev);
1379 int ret;
1380 u32 i;
1381
1382 handle->dbgfs_buf = devm_kcalloc(dev: &handle->pdev->dev,
1383 ARRAY_SIZE(hns3_dbg_cmd),
1384 size: sizeof(*handle->dbgfs_buf),
1385 GFP_KERNEL);
1386 if (!handle->dbgfs_buf)
1387 return -ENOMEM;
1388
1389 hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry =
1390 debugfs_create_dir(name, parent: hns3_dbgfs_root);
1391 handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry;
1392
1393 for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++)
1394 hns3_dbg_dentry[i].dentry =
1395 debugfs_create_dir(name: hns3_dbg_dentry[i].name,
1396 parent: handle->hnae3_dbgfs);
1397
1398 mutex_init(&handle->dbgfs_lock);
1399
1400 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
1401 if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
1402 ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) ||
1403 (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_PTP_INFO &&
1404 !test_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps)))
1405 continue;
1406
1407 if (!hns3_dbg_cmd[i].init) {
1408 dev_err(&handle->pdev->dev,
1409 "cmd %s lack of init func\n",
1410 hns3_dbg_cmd[i].name);
1411 ret = -EINVAL;
1412 goto out;
1413 }
1414
1415 ret = hns3_dbg_cmd[i].init(handle, i);
1416 if (ret) {
1417 dev_err(&handle->pdev->dev, "failed to init cmd %s\n",
1418 hns3_dbg_cmd[i].name);
1419 goto out;
1420 }
1421 }
1422
1423 return 0;
1424
1425out:
1426 debugfs_remove_recursive(dentry: handle->hnae3_dbgfs);
1427 handle->hnae3_dbgfs = NULL;
1428 mutex_destroy(lock: &handle->dbgfs_lock);
1429 return ret;
1430}
1431
1432void hns3_dbg_uninit(struct hnae3_handle *handle)
1433{
1434 u32 i;
1435
1436 debugfs_remove_recursive(dentry: handle->hnae3_dbgfs);
1437 handle->hnae3_dbgfs = NULL;
1438
1439 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++)
1440 if (handle->dbgfs_buf[i]) {
1441 kvfree(addr: handle->dbgfs_buf[i]);
1442 handle->dbgfs_buf[i] = NULL;
1443 }
1444
1445 mutex_destroy(lock: &handle->dbgfs_lock);
1446}
1447
1448void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
1449{
1450 hns3_dbgfs_root = debugfs_create_dir(name: debugfs_dir_name, NULL);
1451}
1452
1453void hns3_dbg_unregister_debugfs(void)
1454{
1455 debugfs_remove_recursive(dentry: hns3_dbgfs_root);
1456 hns3_dbgfs_root = NULL;
1457}
1458

source code of linux/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c