1b2292360Sliuzhongzhu // SPDX-License-Identifier: GPL-2.0+
2b2292360Sliuzhongzhu /* Copyright (c) 2018-2019 Hisilicon Limited. */
3b2292360Sliuzhongzhu 
4b2292360Sliuzhongzhu #include <linux/debugfs.h>
5b2292360Sliuzhongzhu #include <linux/device.h>
6b2292360Sliuzhongzhu 
7b2292360Sliuzhongzhu #include "hnae3.h"
85e69ea7eSYufeng Mo #include "hns3_debugfs.h"
9b2292360Sliuzhongzhu #include "hns3_enet.h"
10b2292360Sliuzhongzhu 
11b2292360Sliuzhongzhu static struct dentry *hns3_dbgfs_root;
12b2292360Sliuzhongzhu 
135e69ea7eSYufeng Mo static struct hns3_dbg_dentry_info hns3_dbg_dentry[] = {
145e69ea7eSYufeng Mo 	{
155e69ea7eSYufeng Mo 		.name = "tm"
165e69ea7eSYufeng Mo 	},
1777e91848SHuazhong Tan 	{
1877e91848SHuazhong Tan 		.name = "tx_bd_info"
1977e91848SHuazhong Tan 	},
2077e91848SHuazhong Tan 	{
2177e91848SHuazhong Tan 		.name = "rx_bd_info"
2277e91848SHuazhong Tan 	},
231556ea91SHuazhong Tan 	{
241556ea91SHuazhong Tan 		.name = "mac_list"
251556ea91SHuazhong Tan 	},
26d96b0e59SYufeng Mo 	{
27d96b0e59SYufeng Mo 		.name = "reg"
28d96b0e59SYufeng Mo 	},
29d2f737cfSHao Chen 	{
30d2f737cfSHao Chen 		.name = "queue"
31d2f737cfSHao Chen 	},
32*b5a0b70dSHao Chen 	{
33*b5a0b70dSHao Chen 		.name = "fd"
34*b5a0b70dSHao Chen 	},
355e69ea7eSYufeng Mo 	/* keep common at the bottom and add new directory above */
365e69ea7eSYufeng Mo 	{
375e69ea7eSYufeng Mo 		.name = "common"
385e69ea7eSYufeng Mo 	},
395e69ea7eSYufeng Mo };
405e69ea7eSYufeng Mo 
4177e91848SHuazhong Tan static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, unsigned int cmd);
425e69ea7eSYufeng Mo static int hns3_dbg_common_file_init(struct hnae3_handle *handle,
435e69ea7eSYufeng Mo 				     unsigned int cmd);
445e69ea7eSYufeng Mo 
455e69ea7eSYufeng Mo static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
465e69ea7eSYufeng Mo 	{
475e69ea7eSYufeng Mo 		.name = "tm_nodes",
485e69ea7eSYufeng Mo 		.cmd = HNAE3_DBG_CMD_TM_NODES,
495e69ea7eSYufeng Mo 		.dentry = HNS3_DBG_DENTRY_TM,
505e69ea7eSYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
515e69ea7eSYufeng Mo 		.init = hns3_dbg_common_file_init,
525e69ea7eSYufeng Mo 	},
535e69ea7eSYufeng Mo 	{
545e69ea7eSYufeng Mo 		.name = "tm_priority",
555e69ea7eSYufeng Mo 		.cmd = HNAE3_DBG_CMD_TM_PRI,
565e69ea7eSYufeng Mo 		.dentry = HNS3_DBG_DENTRY_TM,
575e69ea7eSYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
585e69ea7eSYufeng Mo 		.init = hns3_dbg_common_file_init,
595e69ea7eSYufeng Mo 	},
605e69ea7eSYufeng Mo 	{
615e69ea7eSYufeng Mo 		.name = "tm_qset",
625e69ea7eSYufeng Mo 		.cmd = HNAE3_DBG_CMD_TM_QSET,
635e69ea7eSYufeng Mo 		.dentry = HNS3_DBG_DENTRY_TM,
645e69ea7eSYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
655e69ea7eSYufeng Mo 		.init = hns3_dbg_common_file_init,
665e69ea7eSYufeng Mo 	},
67c929bc2aSJiaran Zhang 	{
68c929bc2aSJiaran Zhang 		.name = "dev_info",
69c929bc2aSJiaran Zhang 		.cmd = HNAE3_DBG_CMD_DEV_INFO,
70c929bc2aSJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
71c929bc2aSJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN,
72c929bc2aSJiaran Zhang 		.init = hns3_dbg_common_file_init,
73c929bc2aSJiaran Zhang 	},
7477e91848SHuazhong Tan 	{
7577e91848SHuazhong Tan 		.name = "tx_bd_queue",
7677e91848SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_TX_BD,
7777e91848SHuazhong Tan 		.dentry = HNS3_DBG_DENTRY_TX_BD,
7877e91848SHuazhong Tan 		.buf_len = HNS3_DBG_READ_LEN_4MB,
7977e91848SHuazhong Tan 		.init = hns3_dbg_bd_file_init,
8077e91848SHuazhong Tan 	},
8177e91848SHuazhong Tan 	{
8277e91848SHuazhong Tan 		.name = "rx_bd_queue",
8377e91848SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_RX_BD,
8477e91848SHuazhong Tan 		.dentry = HNS3_DBG_DENTRY_RX_BD,
8577e91848SHuazhong Tan 		.buf_len = HNS3_DBG_READ_LEN_4MB,
8677e91848SHuazhong Tan 		.init = hns3_dbg_bd_file_init,
8777e91848SHuazhong Tan 	},
881556ea91SHuazhong Tan 	{
891556ea91SHuazhong Tan 		.name = "uc",
901556ea91SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_MAC_UC,
911556ea91SHuazhong Tan 		.dentry = HNS3_DBG_DENTRY_MAC,
921556ea91SHuazhong Tan 		.buf_len = HNS3_DBG_READ_LEN,
931556ea91SHuazhong Tan 		.init = hns3_dbg_common_file_init,
941556ea91SHuazhong Tan 	},
951556ea91SHuazhong Tan 	{
961556ea91SHuazhong Tan 		.name = "mc",
971556ea91SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_MAC_MC,
981556ea91SHuazhong Tan 		.dentry = HNS3_DBG_DENTRY_MAC,
991556ea91SHuazhong Tan 		.buf_len = HNS3_DBG_READ_LEN,
1001556ea91SHuazhong Tan 		.init = hns3_dbg_common_file_init,
1011556ea91SHuazhong Tan 	},
1028ddfd9c4SYufeng Mo 	{
1038ddfd9c4SYufeng Mo 		.name = "mng_tbl",
1048ddfd9c4SYufeng Mo 		.cmd = HNAE3_DBG_CMD_MNG_TBL,
1058ddfd9c4SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_COMMON,
1068ddfd9c4SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
1078ddfd9c4SYufeng Mo 		.init = hns3_dbg_common_file_init,
1088ddfd9c4SYufeng Mo 	},
109d658ff34SYufeng Mo 	{
110d658ff34SYufeng Mo 		.name = "loopback",
111d658ff34SYufeng Mo 		.cmd = HNAE3_DBG_CMD_LOOPBACK,
112d658ff34SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_COMMON,
113d658ff34SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
114d658ff34SYufeng Mo 		.init = hns3_dbg_common_file_init,
115d658ff34SYufeng Mo 	},
1169149ca0fSJiaran Zhang 	{
1179149ca0fSJiaran Zhang 		.name = "interrupt_info",
1189149ca0fSJiaran Zhang 		.cmd = HNAE3_DBG_CMD_INTERRUPT_INFO,
1199149ca0fSJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
1209149ca0fSJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN,
1219149ca0fSJiaran Zhang 		.init = hns3_dbg_common_file_init,
1229149ca0fSJiaran Zhang 	},
1231a7ff828SJiaran Zhang 	{
1241a7ff828SJiaran Zhang 		.name = "reset_info",
1251a7ff828SJiaran Zhang 		.cmd = HNAE3_DBG_CMD_RESET_INFO,
1261a7ff828SJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
1271a7ff828SJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN,
1281a7ff828SJiaran Zhang 		.init = hns3_dbg_common_file_init,
1291a7ff828SJiaran Zhang 	},
1300b198b0dSJiaran Zhang 	{
1310b198b0dSJiaran Zhang 		.name = "imp_info",
1320b198b0dSJiaran Zhang 		.cmd = HNAE3_DBG_CMD_IMP_INFO,
1330b198b0dSJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
1340b198b0dSJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN,
1350b198b0dSJiaran Zhang 		.init = hns3_dbg_common_file_init,
1360b198b0dSJiaran Zhang 	},
137e76e6886SJiaran Zhang 	{
138e76e6886SJiaran Zhang 		.name = "ncl_config",
139e76e6886SJiaran Zhang 		.cmd = HNAE3_DBG_CMD_NCL_CONFIG,
140e76e6886SJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
141e76e6886SJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN_128KB,
142e76e6886SJiaran Zhang 		.init = hns3_dbg_common_file_init,
143e76e6886SJiaran Zhang 	},
144d96b0e59SYufeng Mo 	{
145d96b0e59SYufeng Mo 		.name = "bios_common",
146d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_BIOS_COMMON,
147d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
148d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
149d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
150d96b0e59SYufeng Mo 	},
151d96b0e59SYufeng Mo 	{
152d96b0e59SYufeng Mo 		.name = "ssu",
153d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_SSU,
154d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
155d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
156d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
157d96b0e59SYufeng Mo 	},
158d96b0e59SYufeng Mo 	{
159d96b0e59SYufeng Mo 		.name = "igu_egu",
160d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_IGU_EGU,
161d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
162d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
163d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
164d96b0e59SYufeng Mo 	},
165d96b0e59SYufeng Mo 	{
166d96b0e59SYufeng Mo 		.name = "rpu",
167d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_RPU,
168d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
169d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
170d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
171d96b0e59SYufeng Mo 	},
172d96b0e59SYufeng Mo 	{
173d96b0e59SYufeng Mo 		.name = "ncsi",
174d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_NCSI,
175d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
176d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
177d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
178d96b0e59SYufeng Mo 	},
179d96b0e59SYufeng Mo 	{
180d96b0e59SYufeng Mo 		.name = "rtc",
181d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_RTC,
182d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
183d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
184d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
185d96b0e59SYufeng Mo 	},
186d96b0e59SYufeng Mo 	{
187d96b0e59SYufeng Mo 		.name = "ppp",
188d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_PPP,
189d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
190d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
191d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
192d96b0e59SYufeng Mo 	},
193d96b0e59SYufeng Mo 	{
194d96b0e59SYufeng Mo 		.name = "rcb",
195d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_RCB,
196d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
197d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
198d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
199d96b0e59SYufeng Mo 	},
200d96b0e59SYufeng Mo 	{
201d96b0e59SYufeng Mo 		.name = "tqp",
202d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_TQP,
203d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
204d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
205d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
206d96b0e59SYufeng Mo 	},
207d96b0e59SYufeng Mo 	{
208d96b0e59SYufeng Mo 		.name = "mac",
209d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_MAC,
210d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
211d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
212d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
213d96b0e59SYufeng Mo 	},
214365e860aSYufeng Mo 	{
215365e860aSYufeng Mo 		.name = "dcb",
216365e860aSYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_DCB,
217365e860aSYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
218365e860aSYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
219365e860aSYufeng Mo 		.init = hns3_dbg_common_file_init,
220365e860aSYufeng Mo 	},
221d2f737cfSHao Chen 	{
222d2f737cfSHao Chen 		.name = "queue_map",
223d2f737cfSHao Chen 		.cmd = HNAE3_DBG_CMD_QUEUE_MAP,
224d2f737cfSHao Chen 		.dentry = HNS3_DBG_DENTRY_QUEUE,
225d2f737cfSHao Chen 		.buf_len = HNS3_DBG_READ_LEN,
226d2f737cfSHao Chen 		.init = hns3_dbg_common_file_init,
227d2f737cfSHao Chen 	},
228e44c495dSHao Chen 	{
229e44c495dSHao Chen 		.name = "rx_queue_info",
230e44c495dSHao Chen 		.cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,
231e44c495dSHao Chen 		.dentry = HNS3_DBG_DENTRY_QUEUE,
232e44c495dSHao Chen 		.buf_len = HNS3_DBG_READ_LEN_1MB,
233e44c495dSHao Chen 		.init = hns3_dbg_common_file_init,
234e44c495dSHao Chen 	},
235e44c495dSHao Chen 	{
236e44c495dSHao Chen 		.name = "tx_queue_info",
237e44c495dSHao Chen 		.cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,
238e44c495dSHao Chen 		.dentry = HNS3_DBG_DENTRY_QUEUE,
239e44c495dSHao Chen 		.buf_len = HNS3_DBG_READ_LEN_1MB,
240e44c495dSHao Chen 		.init = hns3_dbg_common_file_init,
241e44c495dSHao Chen 	},
242*b5a0b70dSHao Chen 	{
243*b5a0b70dSHao Chen 		.name = "fd_tcam",
244*b5a0b70dSHao Chen 		.cmd = HNAE3_DBG_CMD_FD_TCAM,
245*b5a0b70dSHao Chen 		.dentry = HNS3_DBG_DENTRY_FD,
246*b5a0b70dSHao Chen 		.buf_len = HNS3_DBG_READ_LEN,
247*b5a0b70dSHao Chen 		.init = hns3_dbg_common_file_init,
248*b5a0b70dSHao Chen 	},
249c929bc2aSJiaran Zhang };
250c929bc2aSJiaran Zhang 
251c929bc2aSJiaran Zhang static struct hns3_dbg_cap_info hns3_dbg_cap[] = {
252c929bc2aSJiaran Zhang 	{
253c929bc2aSJiaran Zhang 		.name = "support FD",
254c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_FD_B,
255c929bc2aSJiaran Zhang 	}, {
256c929bc2aSJiaran Zhang 		.name = "support GRO",
257c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_GRO_B,
258c929bc2aSJiaran Zhang 	}, {
259c929bc2aSJiaran Zhang 		.name = "support FEC",
260c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_FEC_B,
261c929bc2aSJiaran Zhang 	}, {
262c929bc2aSJiaran Zhang 		.name = "support UDP GSO",
263c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_UDP_GSO_B,
264c929bc2aSJiaran Zhang 	}, {
265c929bc2aSJiaran Zhang 		.name = "support PTP",
266c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_PTP_B,
267c929bc2aSJiaran Zhang 	}, {
268c929bc2aSJiaran Zhang 		.name = "support INT QL",
269c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_INT_QL_B,
270c929bc2aSJiaran Zhang 	}, {
271c929bc2aSJiaran Zhang 		.name = "support HW TX csum",
272c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_HW_TX_CSUM_B,
273c929bc2aSJiaran Zhang 	}, {
274c929bc2aSJiaran Zhang 		.name = "support UDP tunnel csum",
275c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B,
276c929bc2aSJiaran Zhang 	}, {
277c929bc2aSJiaran Zhang 		.name = "support TX push",
278c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_TX_PUSH_B,
279c929bc2aSJiaran Zhang 	}, {
280c929bc2aSJiaran Zhang 		.name = "support imp-controlled PHY",
281c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_PHY_IMP_B,
282c929bc2aSJiaran Zhang 	}, {
283c929bc2aSJiaran Zhang 		.name = "support rxd advanced layout",
284c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
285c929bc2aSJiaran Zhang 	},
2865e69ea7eSYufeng Mo };
2875e69ea7eSYufeng Mo 
28877e91848SHuazhong Tan static void hns3_dbg_fill_content(char *content, u16 len,
28977e91848SHuazhong Tan 				  const struct hns3_dbg_item *items,
29077e91848SHuazhong Tan 				  const char **result, u16 size)
29177e91848SHuazhong Tan {
29277e91848SHuazhong Tan 	char *pos = content;
29377e91848SHuazhong Tan 	u16 i;
29477e91848SHuazhong Tan 
29577e91848SHuazhong Tan 	memset(content, ' ', len);
29677e91848SHuazhong Tan 	for (i = 0; i < size; i++) {
29777e91848SHuazhong Tan 		if (result)
29877e91848SHuazhong Tan 			strncpy(pos, result[i], strlen(result[i]));
29977e91848SHuazhong Tan 		else
30077e91848SHuazhong Tan 			strncpy(pos, items[i].name, strlen(items[i].name));
30177e91848SHuazhong Tan 
30277e91848SHuazhong Tan 		pos += strlen(items[i].name) + items[i].interval;
30377e91848SHuazhong Tan 	}
30477e91848SHuazhong Tan 
30577e91848SHuazhong Tan 	*pos++ = '\n';
30677e91848SHuazhong Tan 	*pos++ = '\0';
30777e91848SHuazhong Tan }
30877e91848SHuazhong Tan 
309e44c495dSHao Chen static const struct hns3_dbg_item rx_queue_info_items[] = {
310e44c495dSHao Chen 	{ "QUEUE_ID", 2 },
311e44c495dSHao Chen 	{ "BD_NUM", 2 },
312e44c495dSHao Chen 	{ "BD_LEN", 2 },
313e44c495dSHao Chen 	{ "TAIL", 2 },
314e44c495dSHao Chen 	{ "HEAD", 2 },
315e44c495dSHao Chen 	{ "FBDNUM", 2 },
316e44c495dSHao Chen 	{ "PKTNUM", 2 },
317e44c495dSHao Chen 	{ "RING_EN", 2 },
318e44c495dSHao Chen 	{ "RX_RING_EN", 2 },
319e44c495dSHao Chen 	{ "BASE_ADDR", 10 },
320e44c495dSHao Chen };
321e44c495dSHao Chen 
322e44c495dSHao Chen static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring,
323e44c495dSHao Chen 				    struct hnae3_ae_dev *ae_dev, char **result,
324e44c495dSHao Chen 				    u32 index)
32557ceee2cSliuzhongzhu {
32657ceee2cSliuzhongzhu 	u32 base_add_l, base_add_h;
327e44c495dSHao Chen 	u32 j = 0;
328e44c495dSHao Chen 
329e44c495dSHao Chen 	sprintf(result[j++], "%8u", index);
330e44c495dSHao Chen 
331e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
332e44c495dSHao Chen 		HNS3_RING_RX_RING_BD_NUM_REG));
333e44c495dSHao Chen 
334e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
335e44c495dSHao Chen 		HNS3_RING_RX_RING_BD_LEN_REG));
336e44c495dSHao Chen 
337e44c495dSHao Chen 	sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
338e44c495dSHao Chen 		HNS3_RING_RX_RING_TAIL_REG));
339e44c495dSHao Chen 
340e44c495dSHao Chen 	sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
341e44c495dSHao Chen 		HNS3_RING_RX_RING_HEAD_REG));
342e44c495dSHao Chen 
343e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
344e44c495dSHao Chen 		HNS3_RING_RX_RING_FBDNUM_REG));
345e44c495dSHao Chen 
346e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
347e44c495dSHao Chen 		HNS3_RING_RX_RING_PKTNUM_RECORD_REG));
348e44c495dSHao Chen 
349e44c495dSHao Chen 	sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base +
350e44c495dSHao Chen 		HNS3_RING_EN_REG) ? "on" : "off");
351e44c495dSHao Chen 
352e44c495dSHao Chen 	if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
353e44c495dSHao Chen 		sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base +
354e44c495dSHao Chen 			HNS3_RING_RX_EN_REG) ? "on" : "off");
355e44c495dSHao Chen 	else
356e44c495dSHao Chen 		sprintf(result[j++], "%10s", "NA");
357e44c495dSHao Chen 
358e44c495dSHao Chen 	base_add_h = readl_relaxed(ring->tqp->io_base +
359e44c495dSHao Chen 					HNS3_RING_RX_RING_BASEADDR_H_REG);
360e44c495dSHao Chen 	base_add_l = readl_relaxed(ring->tqp->io_base +
361e44c495dSHao Chen 					HNS3_RING_RX_RING_BASEADDR_L_REG);
362e44c495dSHao Chen 	sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l);
363e44c495dSHao Chen }
364e44c495dSHao Chen 
365e44c495dSHao Chen static int hns3_dbg_rx_queue_info(struct hnae3_handle *h,
366e44c495dSHao Chen 				  char *buf, int len)
367e44c495dSHao Chen {
368e44c495dSHao Chen 	char data_str[ARRAY_SIZE(rx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];
369e44c495dSHao Chen 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
370e44c495dSHao Chen 	char *result[ARRAY_SIZE(rx_queue_info_items)];
371e44c495dSHao Chen 	struct hns3_nic_priv *priv = h->priv;
372e44c495dSHao Chen 	char content[HNS3_DBG_INFO_LEN];
373e44c495dSHao Chen 	struct hns3_enet_ring *ring;
374e44c495dSHao Chen 	int pos = 0;
375e44c495dSHao Chen 	u32 i;
37657ceee2cSliuzhongzhu 
3775f06b903SYunsheng Lin 	if (!priv->ring) {
3785f06b903SYunsheng Lin 		dev_err(&h->pdev->dev, "priv->ring is NULL\n");
37957ceee2cSliuzhongzhu 		return -EFAULT;
38057ceee2cSliuzhongzhu 	}
38157ceee2cSliuzhongzhu 
382e44c495dSHao Chen 	for (i = 0; i < ARRAY_SIZE(rx_queue_info_items); i++)
383e44c495dSHao Chen 		result[i] = &data_str[i][0];
38457ceee2cSliuzhongzhu 
385e44c495dSHao Chen 	hns3_dbg_fill_content(content, sizeof(content), rx_queue_info_items,
386e44c495dSHao Chen 			      NULL, ARRAY_SIZE(rx_queue_info_items));
387e44c495dSHao Chen 	pos += scnprintf(buf + pos, len - pos, "%s", content);
388e44c495dSHao Chen 	for (i = 0; i < h->kinfo.num_tqps; i++) {
38957ceee2cSliuzhongzhu 		/* Each cycle needs to determine whether the instance is reset,
39057ceee2cSliuzhongzhu 		 * to prevent reference to invalid memory. And need to ensure
39157ceee2cSliuzhongzhu 		 * that the following code is executed within 100ms.
39257ceee2cSliuzhongzhu 		 */
3937737f1fbSliuzhongzhu 		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
39457ceee2cSliuzhongzhu 		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
39557ceee2cSliuzhongzhu 			return -EPERM;
39657ceee2cSliuzhongzhu 
3975f06b903SYunsheng Lin 		ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];
398e44c495dSHao Chen 		hns3_dump_rx_queue_info(ring, ae_dev, result, i);
399e44c495dSHao Chen 		hns3_dbg_fill_content(content, sizeof(content),
400e44c495dSHao Chen 				      rx_queue_info_items,
401e44c495dSHao Chen 				      (const char **)result,
402e44c495dSHao Chen 				      ARRAY_SIZE(rx_queue_info_items));
403e44c495dSHao Chen 		pos += scnprintf(buf + pos, len - pos, "%s", content);
404e44c495dSHao Chen 	}
40557ceee2cSliuzhongzhu 
406e44c495dSHao Chen 	return 0;
407e44c495dSHao Chen }
40857ceee2cSliuzhongzhu 
409e44c495dSHao Chen static const struct hns3_dbg_item tx_queue_info_items[] = {
410e44c495dSHao Chen 	{ "QUEUE_ID", 2 },
411e44c495dSHao Chen 	{ "BD_NUM", 2 },
412e44c495dSHao Chen 	{ "TC", 2 },
413e44c495dSHao Chen 	{ "TAIL", 2 },
414e44c495dSHao Chen 	{ "HEAD", 2 },
415e44c495dSHao Chen 	{ "FBDNUM", 2 },
416e44c495dSHao Chen 	{ "OFFSET", 2 },
417e44c495dSHao Chen 	{ "PKTNUM", 2 },
418e44c495dSHao Chen 	{ "RING_EN", 2 },
419e44c495dSHao Chen 	{ "TX_RING_EN", 2 },
420e44c495dSHao Chen 	{ "BASE_ADDR", 10 },
421e44c495dSHao Chen };
42257ceee2cSliuzhongzhu 
423e44c495dSHao Chen static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring,
424e44c495dSHao Chen 				    struct hnae3_ae_dev *ae_dev, char **result,
425e44c495dSHao Chen 				    u32 index)
426e44c495dSHao Chen {
427e44c495dSHao Chen 	u32 base_add_l, base_add_h;
428e44c495dSHao Chen 	u32 j = 0;
42957ceee2cSliuzhongzhu 
430e44c495dSHao Chen 	sprintf(result[j++], "%8u", index);
431e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
432e44c495dSHao Chen 		HNS3_RING_TX_RING_BD_NUM_REG));
43357ceee2cSliuzhongzhu 
434e44c495dSHao Chen 	sprintf(result[j++], "%2u", readl_relaxed(ring->tqp->io_base +
435e44c495dSHao Chen 		HNS3_RING_TX_RING_TC_REG));
43657ceee2cSliuzhongzhu 
437e44c495dSHao Chen 	sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
438e44c495dSHao Chen 		HNS3_RING_TX_RING_TAIL_REG));
43957ceee2cSliuzhongzhu 
440e44c495dSHao Chen 	sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
441e44c495dSHao Chen 		HNS3_RING_TX_RING_HEAD_REG));
442e44c495dSHao Chen 
443e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
444e44c495dSHao Chen 		HNS3_RING_TX_RING_FBDNUM_REG));
445e44c495dSHao Chen 
446e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
447e44c495dSHao Chen 		HNS3_RING_TX_RING_OFFSET_REG));
448e44c495dSHao Chen 
449e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
450e44c495dSHao Chen 		HNS3_RING_TX_RING_PKTNUM_RECORD_REG));
451e44c495dSHao Chen 
452e44c495dSHao Chen 	sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base +
453e44c495dSHao Chen 		HNS3_RING_EN_REG) ? "on" : "off");
454e44c495dSHao Chen 
455e44c495dSHao Chen 	if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
456e44c495dSHao Chen 		sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base +
457e44c495dSHao Chen 			HNS3_RING_TX_EN_REG) ? "on" : "off");
458e44c495dSHao Chen 	else
459e44c495dSHao Chen 		sprintf(result[j++], "%10s", "NA");
460e44c495dSHao Chen 
46157ceee2cSliuzhongzhu 	base_add_h = readl_relaxed(ring->tqp->io_base +
46257ceee2cSliuzhongzhu 					HNS3_RING_TX_RING_BASEADDR_H_REG);
46357ceee2cSliuzhongzhu 	base_add_l = readl_relaxed(ring->tqp->io_base +
46457ceee2cSliuzhongzhu 					HNS3_RING_TX_RING_BASEADDR_L_REG);
465e44c495dSHao Chen 	sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l);
466dbaae5bbSGuangbin Huang }
467dbaae5bbSGuangbin Huang 
468e44c495dSHao Chen static int hns3_dbg_tx_queue_info(struct hnae3_handle *h,
469e44c495dSHao Chen 				  char *buf, int len)
470e44c495dSHao Chen {
471e44c495dSHao Chen 	char data_str[ARRAY_SIZE(tx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];
472e44c495dSHao Chen 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
473e44c495dSHao Chen 	char *result[ARRAY_SIZE(tx_queue_info_items)];
474e44c495dSHao Chen 	struct hns3_nic_priv *priv = h->priv;
475e44c495dSHao Chen 	char content[HNS3_DBG_INFO_LEN];
476e44c495dSHao Chen 	struct hns3_enet_ring *ring;
477e44c495dSHao Chen 	int pos = 0;
478e44c495dSHao Chen 	u32 i;
479e44c495dSHao Chen 
480e44c495dSHao Chen 	if (!priv->ring) {
481e44c495dSHao Chen 		dev_err(&h->pdev->dev, "priv->ring is NULL\n");
482e44c495dSHao Chen 		return -EFAULT;
483e44c495dSHao Chen 	}
484e44c495dSHao Chen 
485e44c495dSHao Chen 	for (i = 0; i < ARRAY_SIZE(tx_queue_info_items); i++)
486e44c495dSHao Chen 		result[i] = &data_str[i][0];
487e44c495dSHao Chen 
488e44c495dSHao Chen 	hns3_dbg_fill_content(content, sizeof(content), tx_queue_info_items,
489e44c495dSHao Chen 			      NULL, ARRAY_SIZE(tx_queue_info_items));
490e44c495dSHao Chen 	pos += scnprintf(buf + pos, len - pos, "%s", content);
491e44c495dSHao Chen 
492e44c495dSHao Chen 	for (i = 0; i < h->kinfo.num_tqps; i++) {
493e44c495dSHao Chen 		/* Each cycle needs to determine whether the instance is reset,
494e44c495dSHao Chen 		 * to prevent reference to invalid memory. And need to ensure
495e44c495dSHao Chen 		 * that the following code is executed within 100ms.
496e44c495dSHao Chen 		 */
497e44c495dSHao Chen 		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
498e44c495dSHao Chen 		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
499e44c495dSHao Chen 			return -EPERM;
500e44c495dSHao Chen 
501e44c495dSHao Chen 		ring = &priv->ring[i];
502e44c495dSHao Chen 		hns3_dump_tx_queue_info(ring, ae_dev, result, i);
503e44c495dSHao Chen 		hns3_dbg_fill_content(content, sizeof(content),
504e44c495dSHao Chen 				      tx_queue_info_items,
505e44c495dSHao Chen 				      (const char **)result,
506e44c495dSHao Chen 				      ARRAY_SIZE(tx_queue_info_items));
507e44c495dSHao Chen 		pos += scnprintf(buf + pos, len - pos, "%s", content);
50857ceee2cSliuzhongzhu 	}
50957ceee2cSliuzhongzhu 
51057ceee2cSliuzhongzhu 	return 0;
51157ceee2cSliuzhongzhu }
51257ceee2cSliuzhongzhu 
513d2f737cfSHao Chen static const struct hns3_dbg_item queue_map_items[] = {
514d2f737cfSHao Chen 	{ "local_queue_id", 2 },
515d2f737cfSHao Chen 	{ "global_queue_id", 2 },
516d2f737cfSHao Chen 	{ "vector_id", 2 },
517d2f737cfSHao Chen };
518d2f737cfSHao Chen 
519d2f737cfSHao Chen static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len)
5200c29d191Sliuzhongzhu {
521d2f737cfSHao Chen 	char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN];
522d2f737cfSHao Chen 	char *result[ARRAY_SIZE(queue_map_items)];
5230c29d191Sliuzhongzhu 	struct hns3_nic_priv *priv = h->priv;
524d2f737cfSHao Chen 	char content[HNS3_DBG_INFO_LEN];
525d2f737cfSHao Chen 	int pos = 0;
526d2f737cfSHao Chen 	int j;
527d2f737cfSHao Chen 	u32 i;
5280c29d191Sliuzhongzhu 
5290c29d191Sliuzhongzhu 	if (!h->ae_algo->ops->get_global_queue_id)
5300c29d191Sliuzhongzhu 		return -EOPNOTSUPP;
5310c29d191Sliuzhongzhu 
532d2f737cfSHao Chen 	for (i = 0; i < ARRAY_SIZE(queue_map_items); i++)
533d2f737cfSHao Chen 		result[i] = &data_str[i][0];
5340c29d191Sliuzhongzhu 
535d2f737cfSHao Chen 	hns3_dbg_fill_content(content, sizeof(content), queue_map_items,
536d2f737cfSHao Chen 			      NULL, ARRAY_SIZE(queue_map_items));
537d2f737cfSHao Chen 	pos += scnprintf(buf + pos, len - pos, "%s", content);
538d2f737cfSHao Chen 	for (i = 0; i < h->kinfo.num_tqps; i++) {
5395f06b903SYunsheng Lin 		if (!priv->ring || !priv->ring[i].tqp_vector)
5400c29d191Sliuzhongzhu 			continue;
541d2f737cfSHao Chen 		j = 0;
542d2f737cfSHao Chen 		sprintf(result[j++], "%u", i);
543d2f737cfSHao Chen 		sprintf(result[j++], "%u",
544d2f737cfSHao Chen 			h->ae_algo->ops->get_global_queue_id(h, i));
545d2f737cfSHao Chen 		sprintf(result[j++], "%u",
546d2f737cfSHao Chen 			priv->ring[i].tqp_vector->vector_irq);
547d2f737cfSHao Chen 		hns3_dbg_fill_content(content, sizeof(content), queue_map_items,
548d2f737cfSHao Chen 				      (const char **)result,
549d2f737cfSHao Chen 				      ARRAY_SIZE(queue_map_items));
550d2f737cfSHao Chen 		pos += scnprintf(buf + pos, len - pos, "%s", content);
5510c29d191Sliuzhongzhu 	}
5520c29d191Sliuzhongzhu 
5530c29d191Sliuzhongzhu 	return 0;
5540c29d191Sliuzhongzhu }
5550c29d191Sliuzhongzhu 
55677e91848SHuazhong Tan static const struct hns3_dbg_item rx_bd_info_items[] = {
55777e91848SHuazhong Tan 	{ "BD_IDX", 3 },
55877e91848SHuazhong Tan 	{ "L234_INFO", 2 },
55977e91848SHuazhong Tan 	{ "PKT_LEN", 3 },
56077e91848SHuazhong Tan 	{ "SIZE", 4 },
56177e91848SHuazhong Tan 	{ "RSS_HASH", 4 },
56277e91848SHuazhong Tan 	{ "FD_ID", 2 },
56377e91848SHuazhong Tan 	{ "VLAN_TAG", 2 },
56477e91848SHuazhong Tan 	{ "O_DM_VLAN_ID_FB", 2 },
56577e91848SHuazhong Tan 	{ "OT_VLAN_TAG", 2 },
56677e91848SHuazhong Tan 	{ "BD_BASE_INFO", 2 },
56777e91848SHuazhong Tan 	{ "PTYPE", 2 },
56877e91848SHuazhong Tan 	{ "HW_CSUM", 2 },
56977e91848SHuazhong Tan };
57077e91848SHuazhong Tan 
57177e91848SHuazhong Tan static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv,
57277e91848SHuazhong Tan 				 struct hns3_desc *desc, char **result, int idx)
573122bedc5Sliuzhongzhu {
57477e91848SHuazhong Tan 	unsigned int j = 0;
575122bedc5Sliuzhongzhu 
57677e91848SHuazhong Tan 	sprintf(result[j++], "%5d", idx);
57777e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info));
57877e91848SHuazhong Tan 	sprintf(result[j++], "%7u", le16_to_cpu(desc->rx.pkt_len));
57977e91848SHuazhong Tan 	sprintf(result[j++], "%4u", le16_to_cpu(desc->rx.size));
58077e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash));
58177e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->rx.fd_id));
58277e91848SHuazhong Tan 	sprintf(result[j++], "%8u", le16_to_cpu(desc->rx.vlan_tag));
58377e91848SHuazhong Tan 	sprintf(result[j++], "%15u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb));
58477e91848SHuazhong Tan 	sprintf(result[j++], "%11u", le16_to_cpu(desc->rx.ot_vlan_tag));
58577e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info));
58677e91848SHuazhong Tan 	if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) {
58777e91848SHuazhong Tan 		u32 ol_info = le32_to_cpu(desc->rx.ol_info);
588122bedc5Sliuzhongzhu 
58977e91848SHuazhong Tan 		sprintf(result[j++], "%5lu", hnae3_get_field(ol_info,
59077e91848SHuazhong Tan 							     HNS3_RXD_PTYPE_M,
59177e91848SHuazhong Tan 							     HNS3_RXD_PTYPE_S));
59277e91848SHuazhong Tan 		sprintf(result[j++], "%7u", le16_to_cpu(desc->csum));
593b1533adaSHuazhong Tan 	} else {
59477e91848SHuazhong Tan 		sprintf(result[j++], "NA");
59577e91848SHuazhong Tan 		sprintf(result[j++], "NA");
59677e91848SHuazhong Tan 	}
597b1533adaSHuazhong Tan }
598b1533adaSHuazhong Tan 
59977e91848SHuazhong Tan static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
60077e91848SHuazhong Tan {
60177e91848SHuazhong Tan 	char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];
60277e91848SHuazhong Tan 	struct hns3_nic_priv *priv = d->handle->priv;
60377e91848SHuazhong Tan 	char *result[ARRAY_SIZE(rx_bd_info_items)];
60477e91848SHuazhong Tan 	char content[HNS3_DBG_INFO_LEN];
60577e91848SHuazhong Tan 	struct hns3_enet_ring *ring;
60677e91848SHuazhong Tan 	struct hns3_desc *desc;
60777e91848SHuazhong Tan 	unsigned int i;
60877e91848SHuazhong Tan 	int pos = 0;
609122bedc5Sliuzhongzhu 
61077e91848SHuazhong Tan 	if (d->qid >= d->handle->kinfo.num_tqps) {
61177e91848SHuazhong Tan 		dev_err(&d->handle->pdev->dev,
61277e91848SHuazhong Tan 			"queue%u is not in use\n", d->qid);
61377e91848SHuazhong Tan 		return -EINVAL;
61477e91848SHuazhong Tan 	}
615122bedc5Sliuzhongzhu 
61677e91848SHuazhong Tan 	for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++)
61777e91848SHuazhong Tan 		result[i] = &data_str[i][0];
618b1533adaSHuazhong Tan 
61977e91848SHuazhong Tan 	pos += scnprintf(buf + pos, len - pos,
62077e91848SHuazhong Tan 			  "Queue %u rx bd info:\n", d->qid);
62177e91848SHuazhong Tan 	hns3_dbg_fill_content(content, sizeof(content), rx_bd_info_items,
62277e91848SHuazhong Tan 			      NULL, ARRAY_SIZE(rx_bd_info_items));
62377e91848SHuazhong Tan 	pos += scnprintf(buf + pos, len - pos, "%s", content);
62477e91848SHuazhong Tan 
62577e91848SHuazhong Tan 	ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps];
62677e91848SHuazhong Tan 	for (i = 0; i < ring->desc_num; i++) {
62777e91848SHuazhong Tan 		desc = &ring->desc[i];
62877e91848SHuazhong Tan 
62977e91848SHuazhong Tan 		hns3_dump_rx_bd_info(priv, desc, result, i);
63077e91848SHuazhong Tan 		hns3_dbg_fill_content(content, sizeof(content),
63177e91848SHuazhong Tan 				      rx_bd_info_items, (const char **)result,
63277e91848SHuazhong Tan 				      ARRAY_SIZE(rx_bd_info_items));
63377e91848SHuazhong Tan 		pos += scnprintf(buf + pos, len - pos, "%s", content);
63477e91848SHuazhong Tan 	}
63577e91848SHuazhong Tan 
63677e91848SHuazhong Tan 	return 0;
63777e91848SHuazhong Tan }
63877e91848SHuazhong Tan 
63977e91848SHuazhong Tan static const struct hns3_dbg_item tx_bd_info_items[] = {
64077e91848SHuazhong Tan 	{ "BD_IDX", 5 },
64177e91848SHuazhong Tan 	{ "ADDRESS", 2 },
64277e91848SHuazhong Tan 	{ "VLAN_TAG", 2 },
64377e91848SHuazhong Tan 	{ "SIZE", 2 },
64477e91848SHuazhong Tan 	{ "T_CS_VLAN_TSO", 2 },
64577e91848SHuazhong Tan 	{ "OT_VLAN_TAG", 3 },
64677e91848SHuazhong Tan 	{ "TV", 2 },
64777e91848SHuazhong Tan 	{ "OLT_VLAN_LEN", 2},
64877e91848SHuazhong Tan 	{ "PAYLEN_OL4CS", 2},
64977e91848SHuazhong Tan 	{ "BD_FE_SC_VLD", 2},
65077e91848SHuazhong Tan 	{ "MSS_HW_CSUM", 0},
65177e91848SHuazhong Tan };
65277e91848SHuazhong Tan 
65377e91848SHuazhong Tan static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv,
65477e91848SHuazhong Tan 				 struct hns3_desc *desc, char **result, int idx)
65577e91848SHuazhong Tan {
65677e91848SHuazhong Tan 	unsigned int j = 0;
65777e91848SHuazhong Tan 
65877e91848SHuazhong Tan 	sprintf(result[j++], "%6d", idx);
65977e91848SHuazhong Tan 	sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr));
66077e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.vlan_tag));
66177e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.send_size));
66277e91848SHuazhong Tan 	sprintf(result[j++], "%#x",
66377e91848SHuazhong Tan 		le32_to_cpu(desc->tx.type_cs_vlan_tso_len));
66477e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.outer_vlan_tag));
66577e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.tv));
66677e91848SHuazhong Tan 	sprintf(result[j++], "%10u",
66777e91848SHuazhong Tan 		le32_to_cpu(desc->tx.ol_type_vlan_len_msec));
66877e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs));
66977e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri));
67077e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum));
67177e91848SHuazhong Tan }
67277e91848SHuazhong Tan 
67377e91848SHuazhong Tan static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
67477e91848SHuazhong Tan {
67577e91848SHuazhong Tan 	char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];
67677e91848SHuazhong Tan 	struct hns3_nic_priv *priv = d->handle->priv;
67777e91848SHuazhong Tan 	char *result[ARRAY_SIZE(tx_bd_info_items)];
67877e91848SHuazhong Tan 	char content[HNS3_DBG_INFO_LEN];
67977e91848SHuazhong Tan 	struct hns3_enet_ring *ring;
68077e91848SHuazhong Tan 	struct hns3_desc *desc;
68177e91848SHuazhong Tan 	unsigned int i;
68277e91848SHuazhong Tan 	int pos = 0;
68377e91848SHuazhong Tan 
68477e91848SHuazhong Tan 	if (d->qid >= d->handle->kinfo.num_tqps) {
68577e91848SHuazhong Tan 		dev_err(&d->handle->pdev->dev,
68677e91848SHuazhong Tan 			"queue%u is not in use\n", d->qid);
68777e91848SHuazhong Tan 		return -EINVAL;
68877e91848SHuazhong Tan 	}
68977e91848SHuazhong Tan 
69077e91848SHuazhong Tan 	for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++)
69177e91848SHuazhong Tan 		result[i] = &data_str[i][0];
69277e91848SHuazhong Tan 
69377e91848SHuazhong Tan 	pos += scnprintf(buf + pos, len - pos,
69477e91848SHuazhong Tan 			  "Queue %u tx bd info:\n", d->qid);
69577e91848SHuazhong Tan 	hns3_dbg_fill_content(content, sizeof(content), tx_bd_info_items,
69677e91848SHuazhong Tan 			      NULL, ARRAY_SIZE(tx_bd_info_items));
69777e91848SHuazhong Tan 	pos += scnprintf(buf + pos, len - pos, "%s", content);
69877e91848SHuazhong Tan 
69977e91848SHuazhong Tan 	ring = &priv->ring[d->qid];
70077e91848SHuazhong Tan 	for (i = 0; i < ring->desc_num; i++) {
70177e91848SHuazhong Tan 		desc = &ring->desc[i];
70277e91848SHuazhong Tan 
70377e91848SHuazhong Tan 		hns3_dump_tx_bd_info(priv, desc, result, i);
70477e91848SHuazhong Tan 		hns3_dbg_fill_content(content, sizeof(content),
70577e91848SHuazhong Tan 				      tx_bd_info_items, (const char **)result,
70677e91848SHuazhong Tan 				      ARRAY_SIZE(tx_bd_info_items));
70777e91848SHuazhong Tan 		pos += scnprintf(buf + pos, len - pos, "%s", content);
70877e91848SHuazhong Tan 	}
709122bedc5Sliuzhongzhu 
710122bedc5Sliuzhongzhu 	return 0;
711122bedc5Sliuzhongzhu }
712122bedc5Sliuzhongzhu 
713b2292360Sliuzhongzhu static void hns3_dbg_help(struct hnae3_handle *h)
714b2292360Sliuzhongzhu {
715b2292360Sliuzhongzhu 	dev_info(&h->pdev->dev, "available commands\n");
71697afd47bSYufeng Mo 
71797afd47bSYufeng Mo 	if (!hns3_is_phys_func(h->pdev))
71897afd47bSYufeng Mo 		return;
71997afd47bSYufeng Mo 
7202849d4e7Sliuzhongzhu 	dev_info(&h->pdev->dev, "dump tc\n");
721ed5b255bSYufeng Mo 	dev_info(&h->pdev->dev, "dump tm map <q_num>\n");
72296227f4cSliuzhongzhu 	dev_info(&h->pdev->dev, "dump tm\n");
723d958919dSliuzhongzhu 	dev_info(&h->pdev->dev, "dump qos pause cfg\n");
7246fc22440Sliuzhongzhu 	dev_info(&h->pdev->dev, "dump qos pri map\n");
7257d9d7f88Sliuzhongzhu 	dev_info(&h->pdev->dev, "dump qos buf cfg\n");
726a6345787SWeihang Li 	dev_info(&h->pdev->dev, "dump mac tnl status\n");
72789ec9485SYonglong Liu 	dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n");
728b2292360Sliuzhongzhu }
729b2292360Sliuzhongzhu 
730c929bc2aSJiaran Zhang static void
731c929bc2aSJiaran Zhang hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos)
7329484e337SGuangbin Huang {
7339484e337SGuangbin Huang 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
734c929bc2aSJiaran Zhang 	static const char * const str[] = {"no", "yes"};
735c929bc2aSJiaran Zhang 	unsigned long *caps = ae_dev->caps;
736c929bc2aSJiaran Zhang 	u32 i, state;
7379484e337SGuangbin Huang 
738c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "dev capability:\n");
7399484e337SGuangbin Huang 
740c929bc2aSJiaran Zhang 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) {
741c929bc2aSJiaran Zhang 		state = test_bit(hns3_dbg_cap[i].cap_bit, caps);
742c929bc2aSJiaran Zhang 		*pos += scnprintf(buf + *pos, len - *pos, "%s: %s\n",
743c929bc2aSJiaran Zhang 				  hns3_dbg_cap[i].name, str[state]);
7449484e337SGuangbin Huang 	}
7459484e337SGuangbin Huang 
746c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "\n");
747c929bc2aSJiaran Zhang }
748c929bc2aSJiaran Zhang 
749c929bc2aSJiaran Zhang static void
750c929bc2aSJiaran Zhang hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos)
751b4442ec5SGuangbin Huang {
752b4442ec5SGuangbin Huang 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
753b4442ec5SGuangbin Huang 	struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs;
754b4442ec5SGuangbin Huang 	struct hnae3_knic_private_info *kinfo = &h->kinfo;
755b4442ec5SGuangbin Huang 
756c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "dev_spec:\n");
757c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAC entry num: %u\n",
758c929bc2aSJiaran Zhang 			  dev_specs->mac_entry_num);
759c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MNG entry num: %u\n",
760c929bc2aSJiaran Zhang 			  dev_specs->mng_entry_num);
761c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX non tso bd num: %u\n",
762b4442ec5SGuangbin Huang 			  dev_specs->max_non_tso_bd_num);
763c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "RSS ind tbl size: %u\n",
764b4442ec5SGuangbin Huang 			  dev_specs->rss_ind_tbl_size);
765c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "RSS key size: %u\n",
766c929bc2aSJiaran Zhang 			  dev_specs->rss_key_size);
767c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "RSS size: %u\n",
768c929bc2aSJiaran Zhang 			  kinfo->rss_size);
769c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "Allocated RSS size: %u\n",
770c929bc2aSJiaran Zhang 			  kinfo->req_rss_size);
771c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos,
772c929bc2aSJiaran Zhang 			  "Task queue pairs numbers: %u\n",
773c929bc2aSJiaran Zhang 			  kinfo->num_tqps);
774c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "RX buffer length: %u\n",
775c929bc2aSJiaran Zhang 			  kinfo->rx_buf_len);
776c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "Desc num per TX queue: %u\n",
777c929bc2aSJiaran Zhang 			  kinfo->num_tx_desc);
778c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "Desc num per RX queue: %u\n",
779c929bc2aSJiaran Zhang 			  kinfo->num_rx_desc);
780c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos,
781c929bc2aSJiaran Zhang 			  "Total number of enabled TCs: %u\n",
78235244430SJian Shen 			  kinfo->tc_info.num_tc);
783c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX INT QL: %u\n",
784c929bc2aSJiaran Zhang 			  dev_specs->int_ql_max);
785c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX INT GL: %u\n",
786c929bc2aSJiaran Zhang 			  dev_specs->max_int_gl);
787c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX TM RATE: %u\n",
788c929bc2aSJiaran Zhang 			  dev_specs->max_tm_rate);
789c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX QSET number: %u\n",
790c929bc2aSJiaran Zhang 			  dev_specs->max_qset_num);
791c929bc2aSJiaran Zhang }
792c929bc2aSJiaran Zhang 
793c929bc2aSJiaran Zhang static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len)
794c929bc2aSJiaran Zhang {
795c929bc2aSJiaran Zhang 	int pos = 0;
796c929bc2aSJiaran Zhang 
797c929bc2aSJiaran Zhang 	hns3_dbg_dev_caps(h, buf, len, &pos);
798c929bc2aSJiaran Zhang 
799c929bc2aSJiaran Zhang 	hns3_dbg_dev_specs(h, buf, len, &pos);
800c929bc2aSJiaran Zhang 
801c929bc2aSJiaran Zhang 	return 0;
802b4442ec5SGuangbin Huang }
803b4442ec5SGuangbin Huang 
804b2292360Sliuzhongzhu static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer,
805b2292360Sliuzhongzhu 				 size_t count, loff_t *ppos)
806b2292360Sliuzhongzhu {
807b2292360Sliuzhongzhu 	int uncopy_bytes;
808b2292360Sliuzhongzhu 	char *buf;
809b2292360Sliuzhongzhu 	int len;
810b2292360Sliuzhongzhu 
811b2292360Sliuzhongzhu 	if (*ppos != 0)
812b2292360Sliuzhongzhu 		return 0;
813b2292360Sliuzhongzhu 
814b2292360Sliuzhongzhu 	if (count < HNS3_DBG_READ_LEN)
815b2292360Sliuzhongzhu 		return -ENOSPC;
816b2292360Sliuzhongzhu 
817b2292360Sliuzhongzhu 	buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL);
818b2292360Sliuzhongzhu 	if (!buf)
819b2292360Sliuzhongzhu 		return -ENOMEM;
820b2292360Sliuzhongzhu 
82149e211c0SChen Zhou 	len = scnprintf(buf, HNS3_DBG_READ_LEN, "%s\n",
822b2292360Sliuzhongzhu 			"Please echo help to cmd to get help information");
823b2292360Sliuzhongzhu 	uncopy_bytes = copy_to_user(buffer, buf, len);
824b2292360Sliuzhongzhu 
825b2292360Sliuzhongzhu 	kfree(buf);
826b2292360Sliuzhongzhu 
827b2292360Sliuzhongzhu 	if (uncopy_bytes)
828b2292360Sliuzhongzhu 		return -EFAULT;
829b2292360Sliuzhongzhu 
830b2292360Sliuzhongzhu 	return (*ppos = len);
831b2292360Sliuzhongzhu }
832b2292360Sliuzhongzhu 
833c318af3fSPeng Li static int hns3_dbg_check_cmd(struct hnae3_handle *handle, char *cmd_buf)
834c318af3fSPeng Li {
835c318af3fSPeng Li 	int ret = 0;
836c318af3fSPeng Li 
837c318af3fSPeng Li 	if (strncmp(cmd_buf, "help", 4) == 0)
838c318af3fSPeng Li 		hns3_dbg_help(handle);
839c318af3fSPeng Li 	else if (handle->ae_algo->ops->dbg_run_cmd)
840c318af3fSPeng Li 		ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);
841c318af3fSPeng Li 	else
842c318af3fSPeng Li 		ret = -EOPNOTSUPP;
843c318af3fSPeng Li 
844c318af3fSPeng Li 	return ret;
845c318af3fSPeng Li }
846c318af3fSPeng Li 
847b2292360Sliuzhongzhu static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
848b2292360Sliuzhongzhu 				  size_t count, loff_t *ppos)
849b2292360Sliuzhongzhu {
850b2292360Sliuzhongzhu 	struct hnae3_handle *handle = filp->private_data;
85157ceee2cSliuzhongzhu 	struct hns3_nic_priv *priv  = handle->priv;
852b2292360Sliuzhongzhu 	char *cmd_buf, *cmd_buf_tmp;
853b2292360Sliuzhongzhu 	int uncopied_bytes;
854c318af3fSPeng Li 	int ret;
855b2292360Sliuzhongzhu 
856b2292360Sliuzhongzhu 	if (*ppos != 0)
857b2292360Sliuzhongzhu 		return 0;
858b2292360Sliuzhongzhu 
85957ceee2cSliuzhongzhu 	/* Judge if the instance is being reset. */
8607737f1fbSliuzhongzhu 	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
86157ceee2cSliuzhongzhu 	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
86257ceee2cSliuzhongzhu 		return 0;
86357ceee2cSliuzhongzhu 
8647ac243f9SYufeng Mo 	if (count > HNS3_DBG_WRITE_LEN)
8657ac243f9SYufeng Mo 		return -ENOSPC;
8667ac243f9SYufeng Mo 
867b2292360Sliuzhongzhu 	cmd_buf = kzalloc(count + 1, GFP_KERNEL);
868b2292360Sliuzhongzhu 	if (!cmd_buf)
869b2292360Sliuzhongzhu 		return count;
870b2292360Sliuzhongzhu 
871b2292360Sliuzhongzhu 	uncopied_bytes = copy_from_user(cmd_buf, buffer, count);
872b2292360Sliuzhongzhu 	if (uncopied_bytes) {
873b2292360Sliuzhongzhu 		kfree(cmd_buf);
874b2292360Sliuzhongzhu 		return -EFAULT;
875b2292360Sliuzhongzhu 	}
876b2292360Sliuzhongzhu 
877b2292360Sliuzhongzhu 	cmd_buf[count] = '\0';
878b2292360Sliuzhongzhu 
879b2292360Sliuzhongzhu 	cmd_buf_tmp = strchr(cmd_buf, '\n');
880b2292360Sliuzhongzhu 	if (cmd_buf_tmp) {
881b2292360Sliuzhongzhu 		*cmd_buf_tmp = '\0';
882b2292360Sliuzhongzhu 		count = cmd_buf_tmp - cmd_buf + 1;
883b2292360Sliuzhongzhu 	}
884b2292360Sliuzhongzhu 
885c318af3fSPeng Li 	ret = hns3_dbg_check_cmd(handle, cmd_buf);
886b2292360Sliuzhongzhu 	if (ret)
887b2292360Sliuzhongzhu 		hns3_dbg_help(handle);
888b2292360Sliuzhongzhu 
889b2292360Sliuzhongzhu 	kfree(cmd_buf);
890b2292360Sliuzhongzhu 	cmd_buf = NULL;
891b2292360Sliuzhongzhu 
892b2292360Sliuzhongzhu 	return count;
893b2292360Sliuzhongzhu }
894b2292360Sliuzhongzhu 
8955e69ea7eSYufeng Mo static int hns3_dbg_get_cmd_index(struct hnae3_handle *handle,
8965e69ea7eSYufeng Mo 				  const unsigned char *name, u32 *index)
8975e69ea7eSYufeng Mo {
8985e69ea7eSYufeng Mo 	u32 i;
8995e69ea7eSYufeng Mo 
9005e69ea7eSYufeng Mo 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
9015e69ea7eSYufeng Mo 		if (!strncmp(name, hns3_dbg_cmd[i].name,
9025e69ea7eSYufeng Mo 			     strlen(hns3_dbg_cmd[i].name))) {
9035e69ea7eSYufeng Mo 			*index = i;
9045e69ea7eSYufeng Mo 			return 0;
9055e69ea7eSYufeng Mo 		}
9065e69ea7eSYufeng Mo 	}
9075e69ea7eSYufeng Mo 
9085e69ea7eSYufeng Mo 	dev_err(&handle->pdev->dev, "unknown command(%s)\n", name);
9095e69ea7eSYufeng Mo 	return -EINVAL;
9105e69ea7eSYufeng Mo }
9115e69ea7eSYufeng Mo 
912c929bc2aSJiaran Zhang static const struct hns3_dbg_func hns3_dbg_cmd_func[] = {
913c929bc2aSJiaran Zhang 	{
914d2f737cfSHao Chen 		.cmd = HNAE3_DBG_CMD_QUEUE_MAP,
915d2f737cfSHao Chen 		.dbg_dump = hns3_dbg_queue_map,
916d2f737cfSHao Chen 	},
917d2f737cfSHao Chen 	{
918c929bc2aSJiaran Zhang 		.cmd = HNAE3_DBG_CMD_DEV_INFO,
919c929bc2aSJiaran Zhang 		.dbg_dump = hns3_dbg_dev_info,
920c929bc2aSJiaran Zhang 	},
92177e91848SHuazhong Tan 	{
92277e91848SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_TX_BD,
92377e91848SHuazhong Tan 		.dbg_dump_bd = hns3_dbg_tx_bd_info,
92477e91848SHuazhong Tan 	},
92577e91848SHuazhong Tan 	{
92677e91848SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_RX_BD,
92777e91848SHuazhong Tan 		.dbg_dump_bd = hns3_dbg_rx_bd_info,
92877e91848SHuazhong Tan 	},
929e44c495dSHao Chen 	{
930e44c495dSHao Chen 		.cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,
931e44c495dSHao Chen 		.dbg_dump = hns3_dbg_rx_queue_info,
932e44c495dSHao Chen 	},
933e44c495dSHao Chen 	{
934e44c495dSHao Chen 		.cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,
935e44c495dSHao Chen 		.dbg_dump = hns3_dbg_tx_queue_info,
936e44c495dSHao Chen 	},
937c929bc2aSJiaran Zhang };
938c929bc2aSJiaran Zhang 
93977e91848SHuazhong Tan static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data,
9405e69ea7eSYufeng Mo 			     enum hnae3_dbg_cmd cmd, char *buf, int len)
9415e69ea7eSYufeng Mo {
94277e91848SHuazhong Tan 	const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops;
94377e91848SHuazhong Tan 	const struct hns3_dbg_func *cmd_func;
944c929bc2aSJiaran Zhang 	u32 i;
945c929bc2aSJiaran Zhang 
946c929bc2aSJiaran Zhang 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) {
94777e91848SHuazhong Tan 		if (cmd == hns3_dbg_cmd_func[i].cmd) {
94877e91848SHuazhong Tan 			cmd_func = &hns3_dbg_cmd_func[i];
94977e91848SHuazhong Tan 			if (cmd_func->dbg_dump)
95077e91848SHuazhong Tan 				return cmd_func->dbg_dump(dbg_data->handle, buf,
95177e91848SHuazhong Tan 							  len);
95277e91848SHuazhong Tan 			else
95377e91848SHuazhong Tan 				return cmd_func->dbg_dump_bd(dbg_data, buf,
95477e91848SHuazhong Tan 							     len);
95577e91848SHuazhong Tan 		}
956c929bc2aSJiaran Zhang 	}
9575e69ea7eSYufeng Mo 
9585e69ea7eSYufeng Mo 	if (!ops->dbg_read_cmd)
9595e69ea7eSYufeng Mo 		return -EOPNOTSUPP;
9605e69ea7eSYufeng Mo 
96177e91848SHuazhong Tan 	return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len);
9625e69ea7eSYufeng Mo }
9635e69ea7eSYufeng Mo 
96404987ca1SGuangbin Huang static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
96504987ca1SGuangbin Huang 			     size_t count, loff_t *ppos)
96604987ca1SGuangbin Huang {
96777e91848SHuazhong Tan 	struct hns3_dbg_data *dbg_data = filp->private_data;
96877e91848SHuazhong Tan 	struct hnae3_handle *handle = dbg_data->handle;
96904987ca1SGuangbin Huang 	struct hns3_nic_priv *priv = handle->priv;
97004987ca1SGuangbin Huang 	ssize_t size = 0;
9715e69ea7eSYufeng Mo 	char **save_buf;
9725e69ea7eSYufeng Mo 	char *read_buf;
9735e69ea7eSYufeng Mo 	u32 index;
9745e69ea7eSYufeng Mo 	int ret;
97504987ca1SGuangbin Huang 
9765e69ea7eSYufeng Mo 	ret = hns3_dbg_get_cmd_index(handle, filp->f_path.dentry->d_iname,
9775e69ea7eSYufeng Mo 				     &index);
9785e69ea7eSYufeng Mo 	if (ret)
9795e69ea7eSYufeng Mo 		return ret;
9805e69ea7eSYufeng Mo 
9815e69ea7eSYufeng Mo 	save_buf = &hns3_dbg_cmd[index].buf;
9825e69ea7eSYufeng Mo 
9835e69ea7eSYufeng Mo 	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
9845e69ea7eSYufeng Mo 	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) {
9855e69ea7eSYufeng Mo 		ret = -EBUSY;
9865e69ea7eSYufeng Mo 		goto out;
9875e69ea7eSYufeng Mo 	}
9885e69ea7eSYufeng Mo 
9895e69ea7eSYufeng Mo 	if (*save_buf) {
9905e69ea7eSYufeng Mo 		read_buf = *save_buf;
9915e69ea7eSYufeng Mo 	} else {
9925e69ea7eSYufeng Mo 		read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
99304987ca1SGuangbin Huang 		if (!read_buf)
99404987ca1SGuangbin Huang 			return -ENOMEM;
99504987ca1SGuangbin Huang 
9965e69ea7eSYufeng Mo 		/* save the buffer addr until the last read operation */
9975e69ea7eSYufeng Mo 		*save_buf = read_buf;
9985e69ea7eSYufeng Mo 	}
99904987ca1SGuangbin Huang 
10005e69ea7eSYufeng Mo 	/* get data ready for the first time to read */
10015e69ea7eSYufeng Mo 	if (!*ppos) {
100277e91848SHuazhong Tan 		ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
10035e69ea7eSYufeng Mo 					read_buf, hns3_dbg_cmd[index].buf_len);
10045e69ea7eSYufeng Mo 		if (ret)
100504987ca1SGuangbin Huang 			goto out;
100604987ca1SGuangbin Huang 	}
100704987ca1SGuangbin Huang 
100804987ca1SGuangbin Huang 	size = simple_read_from_buffer(buffer, count, ppos, read_buf,
100904987ca1SGuangbin Huang 				       strlen(read_buf));
10105e69ea7eSYufeng Mo 	if (size > 0)
10115e69ea7eSYufeng Mo 		return size;
101204987ca1SGuangbin Huang 
101304987ca1SGuangbin Huang out:
10145e69ea7eSYufeng Mo 	/* free the buffer for the last read operation */
10155e69ea7eSYufeng Mo 	if (*save_buf) {
10165e69ea7eSYufeng Mo 		kvfree(*save_buf);
10175e69ea7eSYufeng Mo 		*save_buf = NULL;
10185e69ea7eSYufeng Mo 	}
10195e69ea7eSYufeng Mo 
10205e69ea7eSYufeng Mo 	return ret;
102104987ca1SGuangbin Huang }
102204987ca1SGuangbin Huang 
1023b2292360Sliuzhongzhu static const struct file_operations hns3_dbg_cmd_fops = {
1024b2292360Sliuzhongzhu 	.owner = THIS_MODULE,
1025b2292360Sliuzhongzhu 	.open  = simple_open,
1026b2292360Sliuzhongzhu 	.read  = hns3_dbg_cmd_read,
1027b2292360Sliuzhongzhu 	.write = hns3_dbg_cmd_write,
1028b2292360Sliuzhongzhu };
1029b2292360Sliuzhongzhu 
103004987ca1SGuangbin Huang static const struct file_operations hns3_dbg_fops = {
103104987ca1SGuangbin Huang 	.owner = THIS_MODULE,
103204987ca1SGuangbin Huang 	.open  = simple_open,
103304987ca1SGuangbin Huang 	.read  = hns3_dbg_read,
103404987ca1SGuangbin Huang };
103504987ca1SGuangbin Huang 
103677e91848SHuazhong Tan static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd)
103777e91848SHuazhong Tan {
103877e91848SHuazhong Tan 	struct dentry *entry_dir;
103977e91848SHuazhong Tan 	struct hns3_dbg_data *data;
104077e91848SHuazhong Tan 	u16 max_queue_num;
104177e91848SHuazhong Tan 	unsigned int i;
104277e91848SHuazhong Tan 
104377e91848SHuazhong Tan 	entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
104477e91848SHuazhong Tan 	max_queue_num = hns3_get_max_available_channels(handle);
104577e91848SHuazhong Tan 	data = devm_kzalloc(&handle->pdev->dev, max_queue_num * sizeof(*data),
104677e91848SHuazhong Tan 			    GFP_KERNEL);
104777e91848SHuazhong Tan 	if (!data)
104877e91848SHuazhong Tan 		return -ENOMEM;
104977e91848SHuazhong Tan 
105077e91848SHuazhong Tan 	for (i = 0; i < max_queue_num; i++) {
105177e91848SHuazhong Tan 		char name[HNS3_DBG_FILE_NAME_LEN];
105277e91848SHuazhong Tan 
105377e91848SHuazhong Tan 		data[i].handle = handle;
105477e91848SHuazhong Tan 		data[i].qid = i;
105577e91848SHuazhong Tan 		sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i);
105677e91848SHuazhong Tan 		debugfs_create_file(name, 0400, entry_dir, &data[i],
105777e91848SHuazhong Tan 				    &hns3_dbg_fops);
105877e91848SHuazhong Tan 	}
105977e91848SHuazhong Tan 
106077e91848SHuazhong Tan 	return 0;
106177e91848SHuazhong Tan }
106277e91848SHuazhong Tan 
10635e69ea7eSYufeng Mo static int
10645e69ea7eSYufeng Mo hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd)
10655e69ea7eSYufeng Mo {
106677e91848SHuazhong Tan 	struct hns3_dbg_data *data;
10675e69ea7eSYufeng Mo 	struct dentry *entry_dir;
10685e69ea7eSYufeng Mo 
106977e91848SHuazhong Tan 	data = devm_kzalloc(&handle->pdev->dev, sizeof(*data), GFP_KERNEL);
107077e91848SHuazhong Tan 	if (!data)
107177e91848SHuazhong Tan 		return -ENOMEM;
107277e91848SHuazhong Tan 
107377e91848SHuazhong Tan 	data->handle = handle;
10745e69ea7eSYufeng Mo 	entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
10755e69ea7eSYufeng Mo 	debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir,
107677e91848SHuazhong Tan 			    data, &hns3_dbg_fops);
10775e69ea7eSYufeng Mo 
10785e69ea7eSYufeng Mo 	return 0;
10795e69ea7eSYufeng Mo }
10805e69ea7eSYufeng Mo 
10815e69ea7eSYufeng Mo int hns3_dbg_init(struct hnae3_handle *handle)
1082b2292360Sliuzhongzhu {
108304987ca1SGuangbin Huang 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
1084b2292360Sliuzhongzhu 	const char *name = pci_name(handle->pdev);
10855e69ea7eSYufeng Mo 	int ret;
10865e69ea7eSYufeng Mo 	u32 i;
1087b2292360Sliuzhongzhu 
10885e69ea7eSYufeng Mo 	hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry =
10895e69ea7eSYufeng Mo 				debugfs_create_dir(name, hns3_dbgfs_root);
10905e69ea7eSYufeng Mo 	handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry;
1091b2292360Sliuzhongzhu 
109211ab11e6SGreg Kroah-Hartman 	debugfs_create_file("cmd", 0600, handle->hnae3_dbgfs, handle,
1093b2292360Sliuzhongzhu 			    &hns3_dbg_cmd_fops);
109404987ca1SGuangbin Huang 
10955e69ea7eSYufeng Mo 	for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++)
10965e69ea7eSYufeng Mo 		hns3_dbg_dentry[i].dentry =
10975e69ea7eSYufeng Mo 			debugfs_create_dir(hns3_dbg_dentry[i].name,
10985e69ea7eSYufeng Mo 					   handle->hnae3_dbgfs);
10995e69ea7eSYufeng Mo 
11005e69ea7eSYufeng Mo 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
11015e69ea7eSYufeng Mo 		if (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
11025e69ea7eSYufeng Mo 		    ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2)
11035e69ea7eSYufeng Mo 			continue;
11045e69ea7eSYufeng Mo 
11055e69ea7eSYufeng Mo 		if (!hns3_dbg_cmd[i].init) {
11065e69ea7eSYufeng Mo 			dev_err(&handle->pdev->dev,
11075e69ea7eSYufeng Mo 				"cmd %s lack of init func\n",
11085e69ea7eSYufeng Mo 				hns3_dbg_cmd[i].name);
11095e69ea7eSYufeng Mo 			ret = -EINVAL;
11105e69ea7eSYufeng Mo 			goto out;
11115e69ea7eSYufeng Mo 		}
11125e69ea7eSYufeng Mo 
11135e69ea7eSYufeng Mo 		ret = hns3_dbg_cmd[i].init(handle, i);
11145e69ea7eSYufeng Mo 		if (ret) {
11155e69ea7eSYufeng Mo 			dev_err(&handle->pdev->dev, "failed to init cmd %s\n",
11165e69ea7eSYufeng Mo 				hns3_dbg_cmd[i].name);
11175e69ea7eSYufeng Mo 			goto out;
11185e69ea7eSYufeng Mo 		}
11195e69ea7eSYufeng Mo 	}
11205e69ea7eSYufeng Mo 
11215e69ea7eSYufeng Mo 	return 0;
11225e69ea7eSYufeng Mo 
11235e69ea7eSYufeng Mo out:
11245e69ea7eSYufeng Mo 	debugfs_remove_recursive(handle->hnae3_dbgfs);
11255e69ea7eSYufeng Mo 	handle->hnae3_dbgfs = NULL;
11265e69ea7eSYufeng Mo 	return ret;
1127b2292360Sliuzhongzhu }
1128b2292360Sliuzhongzhu 
1129b2292360Sliuzhongzhu void hns3_dbg_uninit(struct hnae3_handle *handle)
1130b2292360Sliuzhongzhu {
11315e69ea7eSYufeng Mo 	u32 i;
11325e69ea7eSYufeng Mo 
11335e69ea7eSYufeng Mo 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++)
11345e69ea7eSYufeng Mo 		if (hns3_dbg_cmd[i].buf) {
11355e69ea7eSYufeng Mo 			kvfree(hns3_dbg_cmd[i].buf);
11365e69ea7eSYufeng Mo 			hns3_dbg_cmd[i].buf = NULL;
11375e69ea7eSYufeng Mo 		}
11385e69ea7eSYufeng Mo 
1139b2292360Sliuzhongzhu 	debugfs_remove_recursive(handle->hnae3_dbgfs);
1140b2292360Sliuzhongzhu 	handle->hnae3_dbgfs = NULL;
1141b2292360Sliuzhongzhu }
1142b2292360Sliuzhongzhu 
1143b2292360Sliuzhongzhu void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
1144b2292360Sliuzhongzhu {
1145b2292360Sliuzhongzhu 	hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL);
1146b2292360Sliuzhongzhu }
1147b2292360Sliuzhongzhu 
1148b2292360Sliuzhongzhu void hns3_dbg_unregister_debugfs(void)
1149b2292360Sliuzhongzhu {
1150b2292360Sliuzhongzhu 	debugfs_remove_recursive(hns3_dbgfs_root);
1151b2292360Sliuzhongzhu 	hns3_dbgfs_root = NULL;
1152b2292360Sliuzhongzhu }
1153