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 
11 static struct dentry *hns3_dbgfs_root;
12 
13 static 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 
41 static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd);
42 static int hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd);
43 
44 static 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_4MB,
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 
362 static 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 };
413 
414 static const struct hns3_dbg_item coal_info_items[] = {
415 	{ "VEC_ID", 2 },
416 	{ "ALGO_STATE", 2 },
417 	{ "PROFILE_ID", 2 },
418 	{ "CQE_MODE", 2 },
419 	{ "TUNE_STATE", 2 },
420 	{ "STEPS_LEFT", 2 },
421 	{ "STEPS_RIGHT", 2 },
422 	{ "TIRED", 2 },
423 	{ "SW_GL", 2 },
424 	{ "SW_QL", 2 },
425 	{ "HW_GL", 2 },
426 	{ "HW_QL", 2 },
427 };
428 
429 static const char * const dim_cqe_mode_str[] = { "EQE", "CQE" };
430 static const char * const dim_state_str[] = { "START", "IN_PROG", "APPLY" };
431 static const char * const
432 dim_tune_stat_str[] = { "ON_TOP", "TIRED", "RIGHT", "LEFT" };
433 
434 static void hns3_dbg_fill_content(char *content, u16 len,
435 				  const struct hns3_dbg_item *items,
436 				  const char **result, u16 size)
437 {
438 	char *pos = content;
439 	u16 i;
440 
441 	memset(content, ' ', len);
442 	for (i = 0; i < size; i++) {
443 		if (result)
444 			strncpy(pos, result[i], strlen(result[i]));
445 		else
446 			strncpy(pos, items[i].name, strlen(items[i].name));
447 
448 		pos += strlen(items[i].name) + items[i].interval;
449 	}
450 
451 	*pos++ = '\n';
452 	*pos++ = '\0';
453 }
454 
455 static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector,
456 			       char **result, int i, bool is_tx)
457 {
458 	unsigned int gl_offset, ql_offset;
459 	struct hns3_enet_coalesce *coal;
460 	unsigned int reg_val;
461 	unsigned int j = 0;
462 	struct dim *dim;
463 	bool ql_enable;
464 
465 	if (is_tx) {
466 		coal = &tqp_vector->tx_group.coal;
467 		dim = &tqp_vector->tx_group.dim;
468 		gl_offset = HNS3_VECTOR_GL1_OFFSET;
469 		ql_offset = HNS3_VECTOR_TX_QL_OFFSET;
470 		ql_enable = tqp_vector->tx_group.coal.ql_enable;
471 	} else {
472 		coal = &tqp_vector->rx_group.coal;
473 		dim = &tqp_vector->rx_group.dim;
474 		gl_offset = HNS3_VECTOR_GL0_OFFSET;
475 		ql_offset = HNS3_VECTOR_RX_QL_OFFSET;
476 		ql_enable = tqp_vector->rx_group.coal.ql_enable;
477 	}
478 
479 	sprintf(result[j++], "%d", i);
480 	sprintf(result[j++], "%s", dim_state_str[dim->state]);
481 	sprintf(result[j++], "%u", dim->profile_ix);
482 	sprintf(result[j++], "%s", dim_cqe_mode_str[dim->mode]);
483 	sprintf(result[j++], "%s",
484 		dim_tune_stat_str[dim->tune_state]);
485 	sprintf(result[j++], "%u", dim->steps_left);
486 	sprintf(result[j++], "%u", dim->steps_right);
487 	sprintf(result[j++], "%u", dim->tired);
488 	sprintf(result[j++], "%u", coal->int_gl);
489 	sprintf(result[j++], "%u", coal->int_ql);
490 	reg_val = readl(tqp_vector->mask_addr + gl_offset) &
491 		  HNS3_VECTOR_GL_MASK;
492 	sprintf(result[j++], "%u", reg_val);
493 	if (ql_enable) {
494 		reg_val = readl(tqp_vector->mask_addr + ql_offset) &
495 			  HNS3_VECTOR_QL_MASK;
496 		sprintf(result[j++], "%u", reg_val);
497 	} else {
498 		sprintf(result[j++], "NA");
499 	}
500 }
501 
502 static void hns3_dump_coal_info(struct hnae3_handle *h, char *buf, int len,
503 				int *pos, bool is_tx)
504 {
505 	char data_str[ARRAY_SIZE(coal_info_items)][HNS3_DBG_DATA_STR_LEN];
506 	char *result[ARRAY_SIZE(coal_info_items)];
507 	struct hns3_enet_tqp_vector *tqp_vector;
508 	struct hns3_nic_priv *priv = h->priv;
509 	char content[HNS3_DBG_INFO_LEN];
510 	unsigned int i;
511 
512 	for (i = 0; i < ARRAY_SIZE(coal_info_items); i++)
513 		result[i] = &data_str[i][0];
514 
515 	*pos += scnprintf(buf + *pos, len - *pos,
516 			  "%s interrupt coalesce info:\n",
517 			  is_tx ? "tx" : "rx");
518 	hns3_dbg_fill_content(content, sizeof(content), coal_info_items,
519 			      NULL, ARRAY_SIZE(coal_info_items));
520 	*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
521 
522 	for (i = 0; i < priv->vector_num; i++) {
523 		tqp_vector = &priv->tqp_vector[i];
524 		hns3_get_coal_info(tqp_vector, result, i, is_tx);
525 		hns3_dbg_fill_content(content, sizeof(content), coal_info_items,
526 				      (const char **)result,
527 				      ARRAY_SIZE(coal_info_items));
528 		*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
529 	}
530 }
531 
532 static int hns3_dbg_coal_info(struct hnae3_handle *h, char *buf, int len)
533 {
534 	int pos = 0;
535 
536 	hns3_dump_coal_info(h, buf, len, &pos, true);
537 	pos += scnprintf(buf + pos, len - pos, "\n");
538 	hns3_dump_coal_info(h, buf, len, &pos, false);
539 
540 	return 0;
541 }
542 
543 static const struct hns3_dbg_item tx_spare_info_items[] = {
544 	{ "QUEUE_ID", 2 },
545 	{ "COPYBREAK", 2 },
546 	{ "LEN", 7 },
547 	{ "NTU", 4 },
548 	{ "NTC", 4 },
549 	{ "LTC", 4 },
550 	{ "DMA", 17 },
551 };
552 
553 static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf,
554 				   int len, u32 ring_num, int *pos)
555 {
556 	char data_str[ARRAY_SIZE(tx_spare_info_items)][HNS3_DBG_DATA_STR_LEN];
557 	struct hns3_tx_spare *tx_spare = ring->tx_spare;
558 	char *result[ARRAY_SIZE(tx_spare_info_items)];
559 	char content[HNS3_DBG_INFO_LEN];
560 	u32 i, j;
561 
562 	if (!tx_spare) {
563 		*pos += scnprintf(buf + *pos, len - *pos,
564 				  "tx spare buffer is not enabled\n");
565 		return;
566 	}
567 
568 	for (i = 0; i < ARRAY_SIZE(tx_spare_info_items); i++)
569 		result[i] = &data_str[i][0];
570 
571 	*pos += scnprintf(buf + *pos, len - *pos, "tx spare buffer info\n");
572 	hns3_dbg_fill_content(content, sizeof(content), tx_spare_info_items,
573 			      NULL, ARRAY_SIZE(tx_spare_info_items));
574 	*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
575 
576 	for (i = 0; i < ring_num; i++) {
577 		j = 0;
578 		sprintf(result[j++], "%u", i);
579 		sprintf(result[j++], "%u", ring->tx_copybreak);
580 		sprintf(result[j++], "%u", tx_spare->len);
581 		sprintf(result[j++], "%u", tx_spare->next_to_use);
582 		sprintf(result[j++], "%u", tx_spare->next_to_clean);
583 		sprintf(result[j++], "%u", tx_spare->last_to_clean);
584 		sprintf(result[j++], "%pad", &tx_spare->dma);
585 		hns3_dbg_fill_content(content, sizeof(content),
586 				      tx_spare_info_items,
587 				      (const char **)result,
588 				      ARRAY_SIZE(tx_spare_info_items));
589 		*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
590 	}
591 }
592 
593 static const struct hns3_dbg_item rx_queue_info_items[] = {
594 	{ "QUEUE_ID", 2 },
595 	{ "BD_NUM", 2 },
596 	{ "BD_LEN", 2 },
597 	{ "TAIL", 2 },
598 	{ "HEAD", 2 },
599 	{ "FBDNUM", 2 },
600 	{ "PKTNUM", 5 },
601 	{ "COPYBREAK", 2 },
602 	{ "RING_EN", 2 },
603 	{ "RX_RING_EN", 2 },
604 	{ "BASE_ADDR", 10 },
605 };
606 
607 static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring,
608 				    struct hnae3_ae_dev *ae_dev, char **result,
609 				    u32 index)
610 {
611 	u32 base_add_l, base_add_h;
612 	u32 j = 0;
613 
614 	sprintf(result[j++], "%u", index);
615 
616 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
617 		HNS3_RING_RX_RING_BD_NUM_REG));
618 
619 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
620 		HNS3_RING_RX_RING_BD_LEN_REG));
621 
622 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
623 		HNS3_RING_RX_RING_TAIL_REG));
624 
625 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
626 		HNS3_RING_RX_RING_HEAD_REG));
627 
628 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
629 		HNS3_RING_RX_RING_FBDNUM_REG));
630 
631 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
632 		HNS3_RING_RX_RING_PKTNUM_RECORD_REG));
633 	sprintf(result[j++], "%u", ring->rx_copybreak);
634 
635 	sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +
636 		HNS3_RING_EN_REG) ? "on" : "off");
637 
638 	if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
639 		sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +
640 			HNS3_RING_RX_EN_REG) ? "on" : "off");
641 	else
642 		sprintf(result[j++], "%s", "NA");
643 
644 	base_add_h = readl_relaxed(ring->tqp->io_base +
645 					HNS3_RING_RX_RING_BASEADDR_H_REG);
646 	base_add_l = readl_relaxed(ring->tqp->io_base +
647 					HNS3_RING_RX_RING_BASEADDR_L_REG);
648 	sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l);
649 }
650 
651 static int hns3_dbg_rx_queue_info(struct hnae3_handle *h,
652 				  char *buf, int len)
653 {
654 	char data_str[ARRAY_SIZE(rx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];
655 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
656 	char *result[ARRAY_SIZE(rx_queue_info_items)];
657 	struct hns3_nic_priv *priv = h->priv;
658 	char content[HNS3_DBG_INFO_LEN];
659 	struct hns3_enet_ring *ring;
660 	int pos = 0;
661 	u32 i;
662 
663 	if (!priv->ring) {
664 		dev_err(&h->pdev->dev, "priv->ring is NULL\n");
665 		return -EFAULT;
666 	}
667 
668 	for (i = 0; i < ARRAY_SIZE(rx_queue_info_items); i++)
669 		result[i] = &data_str[i][0];
670 
671 	hns3_dbg_fill_content(content, sizeof(content), rx_queue_info_items,
672 			      NULL, ARRAY_SIZE(rx_queue_info_items));
673 	pos += scnprintf(buf + pos, len - pos, "%s", content);
674 	for (i = 0; i < h->kinfo.num_tqps; i++) {
675 		/* Each cycle needs to determine whether the instance is reset,
676 		 * to prevent reference to invalid memory. And need to ensure
677 		 * that the following code is executed within 100ms.
678 		 */
679 		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
680 		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
681 			return -EPERM;
682 
683 		ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];
684 		hns3_dump_rx_queue_info(ring, ae_dev, result, i);
685 		hns3_dbg_fill_content(content, sizeof(content),
686 				      rx_queue_info_items,
687 				      (const char **)result,
688 				      ARRAY_SIZE(rx_queue_info_items));
689 		pos += scnprintf(buf + pos, len - pos, "%s", content);
690 	}
691 
692 	return 0;
693 }
694 
695 static const struct hns3_dbg_item tx_queue_info_items[] = {
696 	{ "QUEUE_ID", 2 },
697 	{ "BD_NUM", 2 },
698 	{ "TC", 2 },
699 	{ "TAIL", 2 },
700 	{ "HEAD", 2 },
701 	{ "FBDNUM", 2 },
702 	{ "OFFSET", 2 },
703 	{ "PKTNUM", 5 },
704 	{ "RING_EN", 2 },
705 	{ "TX_RING_EN", 2 },
706 	{ "BASE_ADDR", 10 },
707 };
708 
709 static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring,
710 				    struct hnae3_ae_dev *ae_dev, char **result,
711 				    u32 index)
712 {
713 	u32 base_add_l, base_add_h;
714 	u32 j = 0;
715 
716 	sprintf(result[j++], "%u", index);
717 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
718 		HNS3_RING_TX_RING_BD_NUM_REG));
719 
720 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
721 		HNS3_RING_TX_RING_TC_REG));
722 
723 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
724 		HNS3_RING_TX_RING_TAIL_REG));
725 
726 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
727 		HNS3_RING_TX_RING_HEAD_REG));
728 
729 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
730 		HNS3_RING_TX_RING_FBDNUM_REG));
731 
732 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
733 		HNS3_RING_TX_RING_OFFSET_REG));
734 
735 	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
736 		HNS3_RING_TX_RING_PKTNUM_RECORD_REG));
737 
738 	sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +
739 		HNS3_RING_EN_REG) ? "on" : "off");
740 
741 	if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
742 		sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +
743 			HNS3_RING_TX_EN_REG) ? "on" : "off");
744 	else
745 		sprintf(result[j++], "%s", "NA");
746 
747 	base_add_h = readl_relaxed(ring->tqp->io_base +
748 					HNS3_RING_TX_RING_BASEADDR_H_REG);
749 	base_add_l = readl_relaxed(ring->tqp->io_base +
750 					HNS3_RING_TX_RING_BASEADDR_L_REG);
751 	sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l);
752 }
753 
754 static int hns3_dbg_tx_queue_info(struct hnae3_handle *h,
755 				  char *buf, int len)
756 {
757 	char data_str[ARRAY_SIZE(tx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];
758 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
759 	char *result[ARRAY_SIZE(tx_queue_info_items)];
760 	struct hns3_nic_priv *priv = h->priv;
761 	char content[HNS3_DBG_INFO_LEN];
762 	struct hns3_enet_ring *ring;
763 	int pos = 0;
764 	u32 i;
765 
766 	if (!priv->ring) {
767 		dev_err(&h->pdev->dev, "priv->ring is NULL\n");
768 		return -EFAULT;
769 	}
770 
771 	for (i = 0; i < ARRAY_SIZE(tx_queue_info_items); i++)
772 		result[i] = &data_str[i][0];
773 
774 	hns3_dbg_fill_content(content, sizeof(content), tx_queue_info_items,
775 			      NULL, ARRAY_SIZE(tx_queue_info_items));
776 	pos += scnprintf(buf + pos, len - pos, "%s", content);
777 
778 	for (i = 0; i < h->kinfo.num_tqps; i++) {
779 		/* Each cycle needs to determine whether the instance is reset,
780 		 * to prevent reference to invalid memory. And need to ensure
781 		 * that the following code is executed within 100ms.
782 		 */
783 		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
784 		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
785 			return -EPERM;
786 
787 		ring = &priv->ring[i];
788 		hns3_dump_tx_queue_info(ring, ae_dev, result, i);
789 		hns3_dbg_fill_content(content, sizeof(content),
790 				      tx_queue_info_items,
791 				      (const char **)result,
792 				      ARRAY_SIZE(tx_queue_info_items));
793 		pos += scnprintf(buf + pos, len - pos, "%s", content);
794 	}
795 
796 	hns3_dbg_tx_spare_info(ring, buf, len, h->kinfo.num_tqps, &pos);
797 
798 	return 0;
799 }
800 
801 static const struct hns3_dbg_item queue_map_items[] = {
802 	{ "local_queue_id", 2 },
803 	{ "global_queue_id", 2 },
804 	{ "vector_id", 2 },
805 };
806 
807 static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len)
808 {
809 	char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN];
810 	char *result[ARRAY_SIZE(queue_map_items)];
811 	struct hns3_nic_priv *priv = h->priv;
812 	char content[HNS3_DBG_INFO_LEN];
813 	int pos = 0;
814 	int j;
815 	u32 i;
816 
817 	if (!h->ae_algo->ops->get_global_queue_id)
818 		return -EOPNOTSUPP;
819 
820 	for (i = 0; i < ARRAY_SIZE(queue_map_items); i++)
821 		result[i] = &data_str[i][0];
822 
823 	hns3_dbg_fill_content(content, sizeof(content), queue_map_items,
824 			      NULL, ARRAY_SIZE(queue_map_items));
825 	pos += scnprintf(buf + pos, len - pos, "%s", content);
826 	for (i = 0; i < h->kinfo.num_tqps; i++) {
827 		if (!priv->ring || !priv->ring[i].tqp_vector)
828 			continue;
829 		j = 0;
830 		sprintf(result[j++], "%u", i);
831 		sprintf(result[j++], "%u",
832 			h->ae_algo->ops->get_global_queue_id(h, i));
833 		sprintf(result[j++], "%d",
834 			priv->ring[i].tqp_vector->vector_irq);
835 		hns3_dbg_fill_content(content, sizeof(content), queue_map_items,
836 				      (const char **)result,
837 				      ARRAY_SIZE(queue_map_items));
838 		pos += scnprintf(buf + pos, len - pos, "%s", content);
839 	}
840 
841 	return 0;
842 }
843 
844 static const struct hns3_dbg_item rx_bd_info_items[] = {
845 	{ "BD_IDX", 3 },
846 	{ "L234_INFO", 2 },
847 	{ "PKT_LEN", 3 },
848 	{ "SIZE", 4 },
849 	{ "RSS_HASH", 4 },
850 	{ "FD_ID", 2 },
851 	{ "VLAN_TAG", 2 },
852 	{ "O_DM_VLAN_ID_FB", 2 },
853 	{ "OT_VLAN_TAG", 2 },
854 	{ "BD_BASE_INFO", 2 },
855 	{ "PTYPE", 2 },
856 	{ "HW_CSUM", 2 },
857 };
858 
859 static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv,
860 				 struct hns3_desc *desc, char **result, int idx)
861 {
862 	unsigned int j = 0;
863 
864 	sprintf(result[j++], "%d", idx);
865 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info));
866 	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.pkt_len));
867 	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.size));
868 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash));
869 	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.fd_id));
870 	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.vlan_tag));
871 	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb));
872 	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.ot_vlan_tag));
873 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info));
874 	if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) {
875 		u32 ol_info = le32_to_cpu(desc->rx.ol_info);
876 
877 		sprintf(result[j++], "%5lu", hnae3_get_field(ol_info,
878 							     HNS3_RXD_PTYPE_M,
879 							     HNS3_RXD_PTYPE_S));
880 		sprintf(result[j++], "%7u", le16_to_cpu(desc->csum));
881 	} else {
882 		sprintf(result[j++], "NA");
883 		sprintf(result[j++], "NA");
884 	}
885 }
886 
887 static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
888 {
889 	char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];
890 	struct hns3_nic_priv *priv = d->handle->priv;
891 	char *result[ARRAY_SIZE(rx_bd_info_items)];
892 	char content[HNS3_DBG_INFO_LEN];
893 	struct hns3_enet_ring *ring;
894 	struct hns3_desc *desc;
895 	unsigned int i;
896 	int pos = 0;
897 
898 	if (d->qid >= d->handle->kinfo.num_tqps) {
899 		dev_err(&d->handle->pdev->dev,
900 			"queue%u is not in use\n", d->qid);
901 		return -EINVAL;
902 	}
903 
904 	for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++)
905 		result[i] = &data_str[i][0];
906 
907 	pos += scnprintf(buf + pos, len - pos,
908 			  "Queue %u rx bd info:\n", d->qid);
909 	hns3_dbg_fill_content(content, sizeof(content), rx_bd_info_items,
910 			      NULL, ARRAY_SIZE(rx_bd_info_items));
911 	pos += scnprintf(buf + pos, len - pos, "%s", content);
912 
913 	ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps];
914 	for (i = 0; i < ring->desc_num; i++) {
915 		desc = &ring->desc[i];
916 
917 		hns3_dump_rx_bd_info(priv, desc, result, i);
918 		hns3_dbg_fill_content(content, sizeof(content),
919 				      rx_bd_info_items, (const char **)result,
920 				      ARRAY_SIZE(rx_bd_info_items));
921 		pos += scnprintf(buf + pos, len - pos, "%s", content);
922 	}
923 
924 	return 0;
925 }
926 
927 static const struct hns3_dbg_item tx_bd_info_items[] = {
928 	{ "BD_IDX", 2 },
929 	{ "ADDRESS", 13 },
930 	{ "VLAN_TAG", 2 },
931 	{ "SIZE", 2 },
932 	{ "T_CS_VLAN_TSO", 2 },
933 	{ "OT_VLAN_TAG", 3 },
934 	{ "TV", 5 },
935 	{ "OLT_VLAN_LEN", 2 },
936 	{ "PAYLEN_OL4CS", 2 },
937 	{ "BD_FE_SC_VLD", 2 },
938 	{ "MSS_HW_CSUM", 0 },
939 };
940 
941 static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv,
942 				 struct hns3_desc *desc, char **result, int idx)
943 {
944 	unsigned int j = 0;
945 
946 	sprintf(result[j++], "%d", idx);
947 	sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr));
948 	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.vlan_tag));
949 	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.send_size));
950 	sprintf(result[j++], "%#x",
951 		le32_to_cpu(desc->tx.type_cs_vlan_tso_len));
952 	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.outer_vlan_tag));
953 	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.tv));
954 	sprintf(result[j++], "%u",
955 		le32_to_cpu(desc->tx.ol_type_vlan_len_msec));
956 	sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs));
957 	sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri));
958 	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.mss_hw_csum));
959 }
960 
961 static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
962 {
963 	char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];
964 	struct hns3_nic_priv *priv = d->handle->priv;
965 	char *result[ARRAY_SIZE(tx_bd_info_items)];
966 	char content[HNS3_DBG_INFO_LEN];
967 	struct hns3_enet_ring *ring;
968 	struct hns3_desc *desc;
969 	unsigned int i;
970 	int pos = 0;
971 
972 	if (d->qid >= d->handle->kinfo.num_tqps) {
973 		dev_err(&d->handle->pdev->dev,
974 			"queue%u is not in use\n", d->qid);
975 		return -EINVAL;
976 	}
977 
978 	for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++)
979 		result[i] = &data_str[i][0];
980 
981 	pos += scnprintf(buf + pos, len - pos,
982 			  "Queue %u tx bd info:\n", d->qid);
983 	hns3_dbg_fill_content(content, sizeof(content), tx_bd_info_items,
984 			      NULL, ARRAY_SIZE(tx_bd_info_items));
985 	pos += scnprintf(buf + pos, len - pos, "%s", content);
986 
987 	ring = &priv->ring[d->qid];
988 	for (i = 0; i < ring->desc_num; i++) {
989 		desc = &ring->desc[i];
990 
991 		hns3_dump_tx_bd_info(priv, desc, result, i);
992 		hns3_dbg_fill_content(content, sizeof(content),
993 				      tx_bd_info_items, (const char **)result,
994 				      ARRAY_SIZE(tx_bd_info_items));
995 		pos += scnprintf(buf + pos, len - pos, "%s", content);
996 	}
997 
998 	return 0;
999 }
1000 
1001 static void
1002 hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos)
1003 {
1004 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
1005 	const char * const str[] = {"no", "yes"};
1006 	unsigned long *caps = ae_dev->caps;
1007 	u32 i, state;
1008 
1009 	*pos += scnprintf(buf + *pos, len - *pos, "dev capability:\n");
1010 
1011 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) {
1012 		state = test_bit(hns3_dbg_cap[i].cap_bit, caps);
1013 		*pos += scnprintf(buf + *pos, len - *pos, "%s: %s\n",
1014 				  hns3_dbg_cap[i].name, str[state]);
1015 	}
1016 
1017 	*pos += scnprintf(buf + *pos, len - *pos, "\n");
1018 }
1019 
1020 static void
1021 hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos)
1022 {
1023 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
1024 	struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs;
1025 	struct hnae3_knic_private_info *kinfo = &h->kinfo;
1026 
1027 	*pos += scnprintf(buf + *pos, len - *pos, "dev_spec:\n");
1028 	*pos += scnprintf(buf + *pos, len - *pos, "MAC entry num: %u\n",
1029 			  dev_specs->mac_entry_num);
1030 	*pos += scnprintf(buf + *pos, len - *pos, "MNG entry num: %u\n",
1031 			  dev_specs->mng_entry_num);
1032 	*pos += scnprintf(buf + *pos, len - *pos, "MAX non tso bd num: %u\n",
1033 			  dev_specs->max_non_tso_bd_num);
1034 	*pos += scnprintf(buf + *pos, len - *pos, "RSS ind tbl size: %u\n",
1035 			  dev_specs->rss_ind_tbl_size);
1036 	*pos += scnprintf(buf + *pos, len - *pos, "RSS key size: %u\n",
1037 			  dev_specs->rss_key_size);
1038 	*pos += scnprintf(buf + *pos, len - *pos, "RSS size: %u\n",
1039 			  kinfo->rss_size);
1040 	*pos += scnprintf(buf + *pos, len - *pos, "Allocated RSS size: %u\n",
1041 			  kinfo->req_rss_size);
1042 	*pos += scnprintf(buf + *pos, len - *pos,
1043 			  "Task queue pairs numbers: %u\n",
1044 			  kinfo->num_tqps);
1045 	*pos += scnprintf(buf + *pos, len - *pos, "RX buffer length: %u\n",
1046 			  kinfo->rx_buf_len);
1047 	*pos += scnprintf(buf + *pos, len - *pos, "Desc num per TX queue: %u\n",
1048 			  kinfo->num_tx_desc);
1049 	*pos += scnprintf(buf + *pos, len - *pos, "Desc num per RX queue: %u\n",
1050 			  kinfo->num_rx_desc);
1051 	*pos += scnprintf(buf + *pos, len - *pos,
1052 			  "Total number of enabled TCs: %u\n",
1053 			  kinfo->tc_info.num_tc);
1054 	*pos += scnprintf(buf + *pos, len - *pos, "MAX INT QL: %u\n",
1055 			  dev_specs->int_ql_max);
1056 	*pos += scnprintf(buf + *pos, len - *pos, "MAX INT GL: %u\n",
1057 			  dev_specs->max_int_gl);
1058 	*pos += scnprintf(buf + *pos, len - *pos, "MAX TM RATE: %u\n",
1059 			  dev_specs->max_tm_rate);
1060 	*pos += scnprintf(buf + *pos, len - *pos, "MAX QSET number: %u\n",
1061 			  dev_specs->max_qset_num);
1062 	*pos += scnprintf(buf + *pos, len - *pos, "umv size: %u\n",
1063 			  dev_specs->umv_size);
1064 	*pos += scnprintf(buf + *pos, len - *pos, "mc mac size: %u\n",
1065 			  dev_specs->mc_mac_size);
1066 	*pos += scnprintf(buf + *pos, len - *pos, "MAC statistics number: %u\n",
1067 			  dev_specs->mac_stats_num);
1068 }
1069 
1070 static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len)
1071 {
1072 	int pos = 0;
1073 
1074 	hns3_dbg_dev_caps(h, buf, len, &pos);
1075 
1076 	hns3_dbg_dev_specs(h, buf, len, &pos);
1077 
1078 	return 0;
1079 }
1080 
1081 static const struct hns3_dbg_item page_pool_info_items[] = {
1082 	{ "QUEUE_ID", 2 },
1083 	{ "ALLOCATE_CNT", 2 },
1084 	{ "FREE_CNT", 6 },
1085 	{ "POOL_SIZE(PAGE_NUM)", 2 },
1086 	{ "ORDER", 2 },
1087 	{ "NUMA_ID", 2 },
1088 	{ "MAX_LEN", 2 },
1089 };
1090 
1091 static void hns3_dump_page_pool_info(struct hns3_enet_ring *ring,
1092 				     char **result, u32 index)
1093 {
1094 	u32 j = 0;
1095 
1096 	sprintf(result[j++], "%u", index);
1097 	sprintf(result[j++], "%u",
1098 		READ_ONCE(ring->page_pool->pages_state_hold_cnt));
1099 	sprintf(result[j++], "%d",
1100 		atomic_read(&ring->page_pool->pages_state_release_cnt));
1101 	sprintf(result[j++], "%u", ring->page_pool->p.pool_size);
1102 	sprintf(result[j++], "%u", ring->page_pool->p.order);
1103 	sprintf(result[j++], "%d", ring->page_pool->p.nid);
1104 	sprintf(result[j++], "%uK", ring->page_pool->p.max_len / 1024);
1105 }
1106 
1107 static int
1108 hns3_dbg_page_pool_info(struct hnae3_handle *h, char *buf, int len)
1109 {
1110 	char data_str[ARRAY_SIZE(page_pool_info_items)][HNS3_DBG_DATA_STR_LEN];
1111 	char *result[ARRAY_SIZE(page_pool_info_items)];
1112 	struct hns3_nic_priv *priv = h->priv;
1113 	char content[HNS3_DBG_INFO_LEN];
1114 	struct hns3_enet_ring *ring;
1115 	int pos = 0;
1116 	u32 i;
1117 
1118 	if (!priv->ring) {
1119 		dev_err(&h->pdev->dev, "priv->ring is NULL\n");
1120 		return -EFAULT;
1121 	}
1122 
1123 	if (!priv->ring[h->kinfo.num_tqps].page_pool) {
1124 		dev_err(&h->pdev->dev, "page pool is not initialized\n");
1125 		return -EFAULT;
1126 	}
1127 
1128 	for (i = 0; i < ARRAY_SIZE(page_pool_info_items); i++)
1129 		result[i] = &data_str[i][0];
1130 
1131 	hns3_dbg_fill_content(content, sizeof(content), page_pool_info_items,
1132 			      NULL, ARRAY_SIZE(page_pool_info_items));
1133 	pos += scnprintf(buf + pos, len - pos, "%s", content);
1134 	for (i = 0; i < h->kinfo.num_tqps; i++) {
1135 		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
1136 		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
1137 			return -EPERM;
1138 		ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];
1139 		hns3_dump_page_pool_info(ring, result, i);
1140 		hns3_dbg_fill_content(content, sizeof(content),
1141 				      page_pool_info_items,
1142 				      (const char **)result,
1143 				      ARRAY_SIZE(page_pool_info_items));
1144 		pos += scnprintf(buf + pos, len - pos, "%s", content);
1145 	}
1146 
1147 	return 0;
1148 }
1149 
1150 static int hns3_dbg_get_cmd_index(struct hns3_dbg_data *dbg_data, u32 *index)
1151 {
1152 	u32 i;
1153 
1154 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
1155 		if (hns3_dbg_cmd[i].cmd == dbg_data->cmd) {
1156 			*index = i;
1157 			return 0;
1158 		}
1159 	}
1160 
1161 	dev_err(&dbg_data->handle->pdev->dev, "unknown command(%d)\n",
1162 		dbg_data->cmd);
1163 	return -EINVAL;
1164 }
1165 
1166 static const struct hns3_dbg_func hns3_dbg_cmd_func[] = {
1167 	{
1168 		.cmd = HNAE3_DBG_CMD_QUEUE_MAP,
1169 		.dbg_dump = hns3_dbg_queue_map,
1170 	},
1171 	{
1172 		.cmd = HNAE3_DBG_CMD_DEV_INFO,
1173 		.dbg_dump = hns3_dbg_dev_info,
1174 	},
1175 	{
1176 		.cmd = HNAE3_DBG_CMD_TX_BD,
1177 		.dbg_dump_bd = hns3_dbg_tx_bd_info,
1178 	},
1179 	{
1180 		.cmd = HNAE3_DBG_CMD_RX_BD,
1181 		.dbg_dump_bd = hns3_dbg_rx_bd_info,
1182 	},
1183 	{
1184 		.cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,
1185 		.dbg_dump = hns3_dbg_rx_queue_info,
1186 	},
1187 	{
1188 		.cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,
1189 		.dbg_dump = hns3_dbg_tx_queue_info,
1190 	},
1191 	{
1192 		.cmd = HNAE3_DBG_CMD_PAGE_POOL_INFO,
1193 		.dbg_dump = hns3_dbg_page_pool_info,
1194 	},
1195 	{
1196 		.cmd = HNAE3_DBG_CMD_COAL_INFO,
1197 		.dbg_dump = hns3_dbg_coal_info,
1198 	},
1199 };
1200 
1201 static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data,
1202 			     enum hnae3_dbg_cmd cmd, char *buf, int len)
1203 {
1204 	const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops;
1205 	const struct hns3_dbg_func *cmd_func;
1206 	u32 i;
1207 
1208 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) {
1209 		if (cmd == hns3_dbg_cmd_func[i].cmd) {
1210 			cmd_func = &hns3_dbg_cmd_func[i];
1211 			if (cmd_func->dbg_dump)
1212 				return cmd_func->dbg_dump(dbg_data->handle, buf,
1213 							  len);
1214 			else
1215 				return cmd_func->dbg_dump_bd(dbg_data, buf,
1216 							     len);
1217 		}
1218 	}
1219 
1220 	if (!ops->dbg_read_cmd)
1221 		return -EOPNOTSUPP;
1222 
1223 	return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len);
1224 }
1225 
1226 static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
1227 			     size_t count, loff_t *ppos)
1228 {
1229 	struct hns3_dbg_data *dbg_data = filp->private_data;
1230 	struct hnae3_handle *handle = dbg_data->handle;
1231 	struct hns3_nic_priv *priv = handle->priv;
1232 	ssize_t size = 0;
1233 	char **save_buf;
1234 	char *read_buf;
1235 	u32 index;
1236 	int ret;
1237 
1238 	ret = hns3_dbg_get_cmd_index(dbg_data, &index);
1239 	if (ret)
1240 		return ret;
1241 
1242 	mutex_lock(&handle->dbgfs_lock);
1243 	save_buf = &handle->dbgfs_buf[index];
1244 
1245 	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
1246 	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) {
1247 		ret = -EBUSY;
1248 		goto out;
1249 	}
1250 
1251 	if (*save_buf) {
1252 		read_buf = *save_buf;
1253 	} else {
1254 		read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
1255 		if (!read_buf) {
1256 			ret = -ENOMEM;
1257 			goto out;
1258 		}
1259 
1260 		/* save the buffer addr until the last read operation */
1261 		*save_buf = read_buf;
1262 
1263 		/* get data ready for the first time to read */
1264 		ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
1265 					read_buf, hns3_dbg_cmd[index].buf_len);
1266 		if (ret)
1267 			goto out;
1268 	}
1269 
1270 	size = simple_read_from_buffer(buffer, count, ppos, read_buf,
1271 				       strlen(read_buf));
1272 	if (size > 0) {
1273 		mutex_unlock(&handle->dbgfs_lock);
1274 		return size;
1275 	}
1276 
1277 out:
1278 	/* free the buffer for the last read operation */
1279 	if (*save_buf) {
1280 		kvfree(*save_buf);
1281 		*save_buf = NULL;
1282 	}
1283 
1284 	mutex_unlock(&handle->dbgfs_lock);
1285 	return ret;
1286 }
1287 
1288 static const struct file_operations hns3_dbg_fops = {
1289 	.owner = THIS_MODULE,
1290 	.open  = simple_open,
1291 	.read  = hns3_dbg_read,
1292 };
1293 
1294 static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd)
1295 {
1296 	struct dentry *entry_dir;
1297 	struct hns3_dbg_data *data;
1298 	u16 max_queue_num;
1299 	unsigned int i;
1300 
1301 	entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
1302 	max_queue_num = hns3_get_max_available_channels(handle);
1303 	data = devm_kzalloc(&handle->pdev->dev, max_queue_num * sizeof(*data),
1304 			    GFP_KERNEL);
1305 	if (!data)
1306 		return -ENOMEM;
1307 
1308 	for (i = 0; i < max_queue_num; i++) {
1309 		char name[HNS3_DBG_FILE_NAME_LEN];
1310 
1311 		data[i].handle = handle;
1312 		data[i].cmd = hns3_dbg_cmd[cmd].cmd;
1313 		data[i].qid = i;
1314 		sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i);
1315 		debugfs_create_file(name, 0400, entry_dir, &data[i],
1316 				    &hns3_dbg_fops);
1317 	}
1318 
1319 	return 0;
1320 }
1321 
1322 static int
1323 hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd)
1324 {
1325 	struct hns3_dbg_data *data;
1326 	struct dentry *entry_dir;
1327 
1328 	data = devm_kzalloc(&handle->pdev->dev, sizeof(*data), GFP_KERNEL);
1329 	if (!data)
1330 		return -ENOMEM;
1331 
1332 	data->handle = handle;
1333 	data->cmd = hns3_dbg_cmd[cmd].cmd;
1334 	entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
1335 	debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir,
1336 			    data, &hns3_dbg_fops);
1337 
1338 	return 0;
1339 }
1340 
1341 int hns3_dbg_init(struct hnae3_handle *handle)
1342 {
1343 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
1344 	const char *name = pci_name(handle->pdev);
1345 	int ret;
1346 	u32 i;
1347 
1348 	handle->dbgfs_buf = devm_kcalloc(&handle->pdev->dev,
1349 					 ARRAY_SIZE(hns3_dbg_cmd),
1350 					 sizeof(*handle->dbgfs_buf),
1351 					 GFP_KERNEL);
1352 	if (!handle->dbgfs_buf)
1353 		return -ENOMEM;
1354 
1355 	hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry =
1356 				debugfs_create_dir(name, hns3_dbgfs_root);
1357 	handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry;
1358 
1359 	for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++)
1360 		hns3_dbg_dentry[i].dentry =
1361 			debugfs_create_dir(hns3_dbg_dentry[i].name,
1362 					   handle->hnae3_dbgfs);
1363 
1364 	mutex_init(&handle->dbgfs_lock);
1365 
1366 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
1367 		if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
1368 		     ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) ||
1369 		    (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_PTP_INFO &&
1370 		     !test_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps)))
1371 			continue;
1372 
1373 		if (!hns3_dbg_cmd[i].init) {
1374 			dev_err(&handle->pdev->dev,
1375 				"cmd %s lack of init func\n",
1376 				hns3_dbg_cmd[i].name);
1377 			ret = -EINVAL;
1378 			goto out;
1379 		}
1380 
1381 		ret = hns3_dbg_cmd[i].init(handle, i);
1382 		if (ret) {
1383 			dev_err(&handle->pdev->dev, "failed to init cmd %s\n",
1384 				hns3_dbg_cmd[i].name);
1385 			goto out;
1386 		}
1387 	}
1388 
1389 	return 0;
1390 
1391 out:
1392 	mutex_destroy(&handle->dbgfs_lock);
1393 	debugfs_remove_recursive(handle->hnae3_dbgfs);
1394 	handle->hnae3_dbgfs = NULL;
1395 	return ret;
1396 }
1397 
1398 void hns3_dbg_uninit(struct hnae3_handle *handle)
1399 {
1400 	u32 i;
1401 
1402 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++)
1403 		if (handle->dbgfs_buf[i]) {
1404 			kvfree(handle->dbgfs_buf[i]);
1405 			handle->dbgfs_buf[i] = NULL;
1406 		}
1407 
1408 	mutex_destroy(&handle->dbgfs_lock);
1409 	debugfs_remove_recursive(handle->hnae3_dbgfs);
1410 	handle->hnae3_dbgfs = NULL;
1411 }
1412 
1413 void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
1414 {
1415 	hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL);
1416 }
1417 
1418 void hns3_dbg_unregister_debugfs(void)
1419 {
1420 	debugfs_remove_recursive(hns3_dbgfs_root);
1421 	hns3_dbgfs_root = NULL;
1422 }
1423