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