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 	},
325e69ea7eSYufeng Mo 	/* keep common at the bottom and add new directory above */
335e69ea7eSYufeng Mo 	{
345e69ea7eSYufeng Mo 		.name = "common"
355e69ea7eSYufeng Mo 	},
365e69ea7eSYufeng Mo };
375e69ea7eSYufeng Mo 
3877e91848SHuazhong Tan static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, unsigned int cmd);
395e69ea7eSYufeng Mo static int hns3_dbg_common_file_init(struct hnae3_handle *handle,
405e69ea7eSYufeng Mo 				     unsigned int cmd);
415e69ea7eSYufeng Mo 
425e69ea7eSYufeng Mo static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
435e69ea7eSYufeng Mo 	{
445e69ea7eSYufeng Mo 		.name = "tm_nodes",
455e69ea7eSYufeng Mo 		.cmd = HNAE3_DBG_CMD_TM_NODES,
465e69ea7eSYufeng Mo 		.dentry = HNS3_DBG_DENTRY_TM,
475e69ea7eSYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
485e69ea7eSYufeng Mo 		.init = hns3_dbg_common_file_init,
495e69ea7eSYufeng Mo 	},
505e69ea7eSYufeng Mo 	{
515e69ea7eSYufeng Mo 		.name = "tm_priority",
525e69ea7eSYufeng Mo 		.cmd = HNAE3_DBG_CMD_TM_PRI,
535e69ea7eSYufeng Mo 		.dentry = HNS3_DBG_DENTRY_TM,
545e69ea7eSYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
555e69ea7eSYufeng Mo 		.init = hns3_dbg_common_file_init,
565e69ea7eSYufeng Mo 	},
575e69ea7eSYufeng Mo 	{
585e69ea7eSYufeng Mo 		.name = "tm_qset",
595e69ea7eSYufeng Mo 		.cmd = HNAE3_DBG_CMD_TM_QSET,
605e69ea7eSYufeng Mo 		.dentry = HNS3_DBG_DENTRY_TM,
615e69ea7eSYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
625e69ea7eSYufeng Mo 		.init = hns3_dbg_common_file_init,
635e69ea7eSYufeng Mo 	},
64c929bc2aSJiaran Zhang 	{
65c929bc2aSJiaran Zhang 		.name = "dev_info",
66c929bc2aSJiaran Zhang 		.cmd = HNAE3_DBG_CMD_DEV_INFO,
67c929bc2aSJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
68c929bc2aSJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN,
69c929bc2aSJiaran Zhang 		.init = hns3_dbg_common_file_init,
70c929bc2aSJiaran Zhang 	},
7177e91848SHuazhong Tan 	{
7277e91848SHuazhong Tan 		.name = "tx_bd_queue",
7377e91848SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_TX_BD,
7477e91848SHuazhong Tan 		.dentry = HNS3_DBG_DENTRY_TX_BD,
7577e91848SHuazhong Tan 		.buf_len = HNS3_DBG_READ_LEN_4MB,
7677e91848SHuazhong Tan 		.init = hns3_dbg_bd_file_init,
7777e91848SHuazhong Tan 	},
7877e91848SHuazhong Tan 	{
7977e91848SHuazhong Tan 		.name = "rx_bd_queue",
8077e91848SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_RX_BD,
8177e91848SHuazhong Tan 		.dentry = HNS3_DBG_DENTRY_RX_BD,
8277e91848SHuazhong Tan 		.buf_len = HNS3_DBG_READ_LEN_4MB,
8377e91848SHuazhong Tan 		.init = hns3_dbg_bd_file_init,
8477e91848SHuazhong Tan 	},
851556ea91SHuazhong Tan 	{
861556ea91SHuazhong Tan 		.name = "uc",
871556ea91SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_MAC_UC,
881556ea91SHuazhong Tan 		.dentry = HNS3_DBG_DENTRY_MAC,
891556ea91SHuazhong Tan 		.buf_len = HNS3_DBG_READ_LEN,
901556ea91SHuazhong Tan 		.init = hns3_dbg_common_file_init,
911556ea91SHuazhong Tan 	},
921556ea91SHuazhong Tan 	{
931556ea91SHuazhong Tan 		.name = "mc",
941556ea91SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_MAC_MC,
951556ea91SHuazhong Tan 		.dentry = HNS3_DBG_DENTRY_MAC,
961556ea91SHuazhong Tan 		.buf_len = HNS3_DBG_READ_LEN,
971556ea91SHuazhong Tan 		.init = hns3_dbg_common_file_init,
981556ea91SHuazhong Tan 	},
998ddfd9c4SYufeng Mo 	{
1008ddfd9c4SYufeng Mo 		.name = "mng_tbl",
1018ddfd9c4SYufeng Mo 		.cmd = HNAE3_DBG_CMD_MNG_TBL,
1028ddfd9c4SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_COMMON,
1038ddfd9c4SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
1048ddfd9c4SYufeng Mo 		.init = hns3_dbg_common_file_init,
1058ddfd9c4SYufeng Mo 	},
106d658ff34SYufeng Mo 	{
107d658ff34SYufeng Mo 		.name = "loopback",
108d658ff34SYufeng Mo 		.cmd = HNAE3_DBG_CMD_LOOPBACK,
109d658ff34SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_COMMON,
110d658ff34SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
111d658ff34SYufeng Mo 		.init = hns3_dbg_common_file_init,
112d658ff34SYufeng Mo 	},
1139149ca0fSJiaran Zhang 	{
1149149ca0fSJiaran Zhang 		.name = "interrupt_info",
1159149ca0fSJiaran Zhang 		.cmd = HNAE3_DBG_CMD_INTERRUPT_INFO,
1169149ca0fSJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
1179149ca0fSJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN,
1189149ca0fSJiaran Zhang 		.init = hns3_dbg_common_file_init,
1199149ca0fSJiaran Zhang 	},
1201a7ff828SJiaran Zhang 	{
1211a7ff828SJiaran Zhang 		.name = "reset_info",
1221a7ff828SJiaran Zhang 		.cmd = HNAE3_DBG_CMD_RESET_INFO,
1231a7ff828SJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
1241a7ff828SJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN,
1251a7ff828SJiaran Zhang 		.init = hns3_dbg_common_file_init,
1261a7ff828SJiaran Zhang 	},
1270b198b0dSJiaran Zhang 	{
1280b198b0dSJiaran Zhang 		.name = "imp_info",
1290b198b0dSJiaran Zhang 		.cmd = HNAE3_DBG_CMD_IMP_INFO,
1300b198b0dSJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
1310b198b0dSJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN,
1320b198b0dSJiaran Zhang 		.init = hns3_dbg_common_file_init,
1330b198b0dSJiaran Zhang 	},
134e76e6886SJiaran Zhang 	{
135e76e6886SJiaran Zhang 		.name = "ncl_config",
136e76e6886SJiaran Zhang 		.cmd = HNAE3_DBG_CMD_NCL_CONFIG,
137e76e6886SJiaran Zhang 		.dentry = HNS3_DBG_DENTRY_COMMON,
138e76e6886SJiaran Zhang 		.buf_len = HNS3_DBG_READ_LEN_128KB,
139e76e6886SJiaran Zhang 		.init = hns3_dbg_common_file_init,
140e76e6886SJiaran Zhang 	},
141d96b0e59SYufeng Mo 	{
142d96b0e59SYufeng Mo 		.name = "bios_common",
143d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_BIOS_COMMON,
144d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
145d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
146d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
147d96b0e59SYufeng Mo 	},
148d96b0e59SYufeng Mo 	{
149d96b0e59SYufeng Mo 		.name = "ssu",
150d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_SSU,
151d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
152d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
153d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
154d96b0e59SYufeng Mo 	},
155d96b0e59SYufeng Mo 	{
156d96b0e59SYufeng Mo 		.name = "igu_egu",
157d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_IGU_EGU,
158d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
159d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
160d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
161d96b0e59SYufeng Mo 	},
162d96b0e59SYufeng Mo 	{
163d96b0e59SYufeng Mo 		.name = "rpu",
164d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_RPU,
165d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
166d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
167d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
168d96b0e59SYufeng Mo 	},
169d96b0e59SYufeng Mo 	{
170d96b0e59SYufeng Mo 		.name = "ncsi",
171d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_NCSI,
172d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
173d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
174d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
175d96b0e59SYufeng Mo 	},
176d96b0e59SYufeng Mo 	{
177d96b0e59SYufeng Mo 		.name = "rtc",
178d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_RTC,
179d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
180d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
181d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
182d96b0e59SYufeng Mo 	},
183d96b0e59SYufeng Mo 	{
184d96b0e59SYufeng Mo 		.name = "ppp",
185d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_PPP,
186d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
187d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
188d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
189d96b0e59SYufeng Mo 	},
190d96b0e59SYufeng Mo 	{
191d96b0e59SYufeng Mo 		.name = "rcb",
192d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_RCB,
193d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
194d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
195d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
196d96b0e59SYufeng Mo 	},
197d96b0e59SYufeng Mo 	{
198d96b0e59SYufeng Mo 		.name = "tqp",
199d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_TQP,
200d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
201d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
202d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
203d96b0e59SYufeng Mo 	},
204d96b0e59SYufeng Mo 	{
205d96b0e59SYufeng Mo 		.name = "mac",
206d96b0e59SYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_MAC,
207d96b0e59SYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
208d96b0e59SYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
209d96b0e59SYufeng Mo 		.init = hns3_dbg_common_file_init,
210d96b0e59SYufeng Mo 	},
211365e860aSYufeng Mo 	{
212365e860aSYufeng Mo 		.name = "dcb",
213365e860aSYufeng Mo 		.cmd = HNAE3_DBG_CMD_REG_DCB,
214365e860aSYufeng Mo 		.dentry = HNS3_DBG_DENTRY_REG,
215365e860aSYufeng Mo 		.buf_len = HNS3_DBG_READ_LEN,
216365e860aSYufeng Mo 		.init = hns3_dbg_common_file_init,
217365e860aSYufeng Mo 	},
218d2f737cfSHao Chen 	{
219d2f737cfSHao Chen 		.name = "queue_map",
220d2f737cfSHao Chen 		.cmd = HNAE3_DBG_CMD_QUEUE_MAP,
221d2f737cfSHao Chen 		.dentry = HNS3_DBG_DENTRY_QUEUE,
222d2f737cfSHao Chen 		.buf_len = HNS3_DBG_READ_LEN,
223d2f737cfSHao Chen 		.init = hns3_dbg_common_file_init,
224d2f737cfSHao Chen 	},
225*e44c495dSHao Chen 	{
226*e44c495dSHao Chen 		.name = "rx_queue_info",
227*e44c495dSHao Chen 		.cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,
228*e44c495dSHao Chen 		.dentry = HNS3_DBG_DENTRY_QUEUE,
229*e44c495dSHao Chen 		.buf_len = HNS3_DBG_READ_LEN_1MB,
230*e44c495dSHao Chen 		.init = hns3_dbg_common_file_init,
231*e44c495dSHao Chen 	},
232*e44c495dSHao Chen 	{
233*e44c495dSHao Chen 		.name = "tx_queue_info",
234*e44c495dSHao Chen 		.cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,
235*e44c495dSHao Chen 		.dentry = HNS3_DBG_DENTRY_QUEUE,
236*e44c495dSHao Chen 		.buf_len = HNS3_DBG_READ_LEN_1MB,
237*e44c495dSHao Chen 		.init = hns3_dbg_common_file_init,
238*e44c495dSHao Chen 	},
239c929bc2aSJiaran Zhang };
240c929bc2aSJiaran Zhang 
241c929bc2aSJiaran Zhang static struct hns3_dbg_cap_info hns3_dbg_cap[] = {
242c929bc2aSJiaran Zhang 	{
243c929bc2aSJiaran Zhang 		.name = "support FD",
244c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_FD_B,
245c929bc2aSJiaran Zhang 	}, {
246c929bc2aSJiaran Zhang 		.name = "support GRO",
247c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_GRO_B,
248c929bc2aSJiaran Zhang 	}, {
249c929bc2aSJiaran Zhang 		.name = "support FEC",
250c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_FEC_B,
251c929bc2aSJiaran Zhang 	}, {
252c929bc2aSJiaran Zhang 		.name = "support UDP GSO",
253c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_UDP_GSO_B,
254c929bc2aSJiaran Zhang 	}, {
255c929bc2aSJiaran Zhang 		.name = "support PTP",
256c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_PTP_B,
257c929bc2aSJiaran Zhang 	}, {
258c929bc2aSJiaran Zhang 		.name = "support INT QL",
259c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_INT_QL_B,
260c929bc2aSJiaran Zhang 	}, {
261c929bc2aSJiaran Zhang 		.name = "support HW TX csum",
262c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_HW_TX_CSUM_B,
263c929bc2aSJiaran Zhang 	}, {
264c929bc2aSJiaran Zhang 		.name = "support UDP tunnel csum",
265c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B,
266c929bc2aSJiaran Zhang 	}, {
267c929bc2aSJiaran Zhang 		.name = "support TX push",
268c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_TX_PUSH_B,
269c929bc2aSJiaran Zhang 	}, {
270c929bc2aSJiaran Zhang 		.name = "support imp-controlled PHY",
271c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_PHY_IMP_B,
272c929bc2aSJiaran Zhang 	}, {
273c929bc2aSJiaran Zhang 		.name = "support rxd advanced layout",
274c929bc2aSJiaran Zhang 		.cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
275c929bc2aSJiaran Zhang 	},
2765e69ea7eSYufeng Mo };
2775e69ea7eSYufeng Mo 
27877e91848SHuazhong Tan static void hns3_dbg_fill_content(char *content, u16 len,
27977e91848SHuazhong Tan 				  const struct hns3_dbg_item *items,
28077e91848SHuazhong Tan 				  const char **result, u16 size)
28177e91848SHuazhong Tan {
28277e91848SHuazhong Tan 	char *pos = content;
28377e91848SHuazhong Tan 	u16 i;
28477e91848SHuazhong Tan 
28577e91848SHuazhong Tan 	memset(content, ' ', len);
28677e91848SHuazhong Tan 	for (i = 0; i < size; i++) {
28777e91848SHuazhong Tan 		if (result)
28877e91848SHuazhong Tan 			strncpy(pos, result[i], strlen(result[i]));
28977e91848SHuazhong Tan 		else
29077e91848SHuazhong Tan 			strncpy(pos, items[i].name, strlen(items[i].name));
29177e91848SHuazhong Tan 
29277e91848SHuazhong Tan 		pos += strlen(items[i].name) + items[i].interval;
29377e91848SHuazhong Tan 	}
29477e91848SHuazhong Tan 
29577e91848SHuazhong Tan 	*pos++ = '\n';
29677e91848SHuazhong Tan 	*pos++ = '\0';
29777e91848SHuazhong Tan }
29877e91848SHuazhong Tan 
299*e44c495dSHao Chen static const struct hns3_dbg_item rx_queue_info_items[] = {
300*e44c495dSHao Chen 	{ "QUEUE_ID", 2 },
301*e44c495dSHao Chen 	{ "BD_NUM", 2 },
302*e44c495dSHao Chen 	{ "BD_LEN", 2 },
303*e44c495dSHao Chen 	{ "TAIL", 2 },
304*e44c495dSHao Chen 	{ "HEAD", 2 },
305*e44c495dSHao Chen 	{ "FBDNUM", 2 },
306*e44c495dSHao Chen 	{ "PKTNUM", 2 },
307*e44c495dSHao Chen 	{ "RING_EN", 2 },
308*e44c495dSHao Chen 	{ "RX_RING_EN", 2 },
309*e44c495dSHao Chen 	{ "BASE_ADDR", 10 },
310*e44c495dSHao Chen };
311*e44c495dSHao Chen 
312*e44c495dSHao Chen static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring,
313*e44c495dSHao Chen 				    struct hnae3_ae_dev *ae_dev, char **result,
314*e44c495dSHao Chen 				    u32 index)
31557ceee2cSliuzhongzhu {
31657ceee2cSliuzhongzhu 	u32 base_add_l, base_add_h;
317*e44c495dSHao Chen 	u32 j = 0;
318*e44c495dSHao Chen 
319*e44c495dSHao Chen 	sprintf(result[j++], "%8u", index);
320*e44c495dSHao Chen 
321*e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
322*e44c495dSHao Chen 		HNS3_RING_RX_RING_BD_NUM_REG));
323*e44c495dSHao Chen 
324*e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
325*e44c495dSHao Chen 		HNS3_RING_RX_RING_BD_LEN_REG));
326*e44c495dSHao Chen 
327*e44c495dSHao Chen 	sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
328*e44c495dSHao Chen 		HNS3_RING_RX_RING_TAIL_REG));
329*e44c495dSHao Chen 
330*e44c495dSHao Chen 	sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
331*e44c495dSHao Chen 		HNS3_RING_RX_RING_HEAD_REG));
332*e44c495dSHao Chen 
333*e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
334*e44c495dSHao Chen 		HNS3_RING_RX_RING_FBDNUM_REG));
335*e44c495dSHao Chen 
336*e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
337*e44c495dSHao Chen 		HNS3_RING_RX_RING_PKTNUM_RECORD_REG));
338*e44c495dSHao Chen 
339*e44c495dSHao Chen 	sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base +
340*e44c495dSHao Chen 		HNS3_RING_EN_REG) ? "on" : "off");
341*e44c495dSHao Chen 
342*e44c495dSHao Chen 	if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
343*e44c495dSHao Chen 		sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base +
344*e44c495dSHao Chen 			HNS3_RING_RX_EN_REG) ? "on" : "off");
345*e44c495dSHao Chen 	else
346*e44c495dSHao Chen 		sprintf(result[j++], "%10s", "NA");
347*e44c495dSHao Chen 
348*e44c495dSHao Chen 	base_add_h = readl_relaxed(ring->tqp->io_base +
349*e44c495dSHao Chen 					HNS3_RING_RX_RING_BASEADDR_H_REG);
350*e44c495dSHao Chen 	base_add_l = readl_relaxed(ring->tqp->io_base +
351*e44c495dSHao Chen 					HNS3_RING_RX_RING_BASEADDR_L_REG);
352*e44c495dSHao Chen 	sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l);
353*e44c495dSHao Chen }
354*e44c495dSHao Chen 
355*e44c495dSHao Chen static int hns3_dbg_rx_queue_info(struct hnae3_handle *h,
356*e44c495dSHao Chen 				  char *buf, int len)
357*e44c495dSHao Chen {
358*e44c495dSHao Chen 	char data_str[ARRAY_SIZE(rx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];
359*e44c495dSHao Chen 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
360*e44c495dSHao Chen 	char *result[ARRAY_SIZE(rx_queue_info_items)];
361*e44c495dSHao Chen 	struct hns3_nic_priv *priv = h->priv;
362*e44c495dSHao Chen 	char content[HNS3_DBG_INFO_LEN];
363*e44c495dSHao Chen 	struct hns3_enet_ring *ring;
364*e44c495dSHao Chen 	int pos = 0;
365*e44c495dSHao Chen 	u32 i;
36657ceee2cSliuzhongzhu 
3675f06b903SYunsheng Lin 	if (!priv->ring) {
3685f06b903SYunsheng Lin 		dev_err(&h->pdev->dev, "priv->ring is NULL\n");
36957ceee2cSliuzhongzhu 		return -EFAULT;
37057ceee2cSliuzhongzhu 	}
37157ceee2cSliuzhongzhu 
372*e44c495dSHao Chen 	for (i = 0; i < ARRAY_SIZE(rx_queue_info_items); i++)
373*e44c495dSHao Chen 		result[i] = &data_str[i][0];
37457ceee2cSliuzhongzhu 
375*e44c495dSHao Chen 	hns3_dbg_fill_content(content, sizeof(content), rx_queue_info_items,
376*e44c495dSHao Chen 			      NULL, ARRAY_SIZE(rx_queue_info_items));
377*e44c495dSHao Chen 	pos += scnprintf(buf + pos, len - pos, "%s", content);
378*e44c495dSHao Chen 	for (i = 0; i < h->kinfo.num_tqps; i++) {
37957ceee2cSliuzhongzhu 		/* Each cycle needs to determine whether the instance is reset,
38057ceee2cSliuzhongzhu 		 * to prevent reference to invalid memory. And need to ensure
38157ceee2cSliuzhongzhu 		 * that the following code is executed within 100ms.
38257ceee2cSliuzhongzhu 		 */
3837737f1fbSliuzhongzhu 		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
38457ceee2cSliuzhongzhu 		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
38557ceee2cSliuzhongzhu 			return -EPERM;
38657ceee2cSliuzhongzhu 
3875f06b903SYunsheng Lin 		ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];
388*e44c495dSHao Chen 		hns3_dump_rx_queue_info(ring, ae_dev, result, i);
389*e44c495dSHao Chen 		hns3_dbg_fill_content(content, sizeof(content),
390*e44c495dSHao Chen 				      rx_queue_info_items,
391*e44c495dSHao Chen 				      (const char **)result,
392*e44c495dSHao Chen 				      ARRAY_SIZE(rx_queue_info_items));
393*e44c495dSHao Chen 		pos += scnprintf(buf + pos, len - pos, "%s", content);
394*e44c495dSHao Chen 	}
39557ceee2cSliuzhongzhu 
396*e44c495dSHao Chen 	return 0;
397*e44c495dSHao Chen }
39857ceee2cSliuzhongzhu 
399*e44c495dSHao Chen static const struct hns3_dbg_item tx_queue_info_items[] = {
400*e44c495dSHao Chen 	{ "QUEUE_ID", 2 },
401*e44c495dSHao Chen 	{ "BD_NUM", 2 },
402*e44c495dSHao Chen 	{ "TC", 2 },
403*e44c495dSHao Chen 	{ "TAIL", 2 },
404*e44c495dSHao Chen 	{ "HEAD", 2 },
405*e44c495dSHao Chen 	{ "FBDNUM", 2 },
406*e44c495dSHao Chen 	{ "OFFSET", 2 },
407*e44c495dSHao Chen 	{ "PKTNUM", 2 },
408*e44c495dSHao Chen 	{ "RING_EN", 2 },
409*e44c495dSHao Chen 	{ "TX_RING_EN", 2 },
410*e44c495dSHao Chen 	{ "BASE_ADDR", 10 },
411*e44c495dSHao Chen };
41257ceee2cSliuzhongzhu 
413*e44c495dSHao Chen static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring,
414*e44c495dSHao Chen 				    struct hnae3_ae_dev *ae_dev, char **result,
415*e44c495dSHao Chen 				    u32 index)
416*e44c495dSHao Chen {
417*e44c495dSHao Chen 	u32 base_add_l, base_add_h;
418*e44c495dSHao Chen 	u32 j = 0;
41957ceee2cSliuzhongzhu 
420*e44c495dSHao Chen 	sprintf(result[j++], "%8u", index);
421*e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
422*e44c495dSHao Chen 		HNS3_RING_TX_RING_BD_NUM_REG));
42357ceee2cSliuzhongzhu 
424*e44c495dSHao Chen 	sprintf(result[j++], "%2u", readl_relaxed(ring->tqp->io_base +
425*e44c495dSHao Chen 		HNS3_RING_TX_RING_TC_REG));
42657ceee2cSliuzhongzhu 
427*e44c495dSHao Chen 	sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
428*e44c495dSHao Chen 		HNS3_RING_TX_RING_TAIL_REG));
42957ceee2cSliuzhongzhu 
430*e44c495dSHao Chen 	sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
431*e44c495dSHao Chen 		HNS3_RING_TX_RING_HEAD_REG));
432*e44c495dSHao Chen 
433*e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
434*e44c495dSHao Chen 		HNS3_RING_TX_RING_FBDNUM_REG));
435*e44c495dSHao Chen 
436*e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
437*e44c495dSHao Chen 		HNS3_RING_TX_RING_OFFSET_REG));
438*e44c495dSHao Chen 
439*e44c495dSHao Chen 	sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
440*e44c495dSHao Chen 		HNS3_RING_TX_RING_PKTNUM_RECORD_REG));
441*e44c495dSHao Chen 
442*e44c495dSHao Chen 	sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base +
443*e44c495dSHao Chen 		HNS3_RING_EN_REG) ? "on" : "off");
444*e44c495dSHao Chen 
445*e44c495dSHao Chen 	if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
446*e44c495dSHao Chen 		sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base +
447*e44c495dSHao Chen 			HNS3_RING_TX_EN_REG) ? "on" : "off");
448*e44c495dSHao Chen 	else
449*e44c495dSHao Chen 		sprintf(result[j++], "%10s", "NA");
450*e44c495dSHao Chen 
45157ceee2cSliuzhongzhu 	base_add_h = readl_relaxed(ring->tqp->io_base +
45257ceee2cSliuzhongzhu 					HNS3_RING_TX_RING_BASEADDR_H_REG);
45357ceee2cSliuzhongzhu 	base_add_l = readl_relaxed(ring->tqp->io_base +
45457ceee2cSliuzhongzhu 					HNS3_RING_TX_RING_BASEADDR_L_REG);
455*e44c495dSHao Chen 	sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l);
456dbaae5bbSGuangbin Huang }
457dbaae5bbSGuangbin Huang 
458*e44c495dSHao Chen static int hns3_dbg_tx_queue_info(struct hnae3_handle *h,
459*e44c495dSHao Chen 				  char *buf, int len)
460*e44c495dSHao Chen {
461*e44c495dSHao Chen 	char data_str[ARRAY_SIZE(tx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];
462*e44c495dSHao Chen 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
463*e44c495dSHao Chen 	char *result[ARRAY_SIZE(tx_queue_info_items)];
464*e44c495dSHao Chen 	struct hns3_nic_priv *priv = h->priv;
465*e44c495dSHao Chen 	char content[HNS3_DBG_INFO_LEN];
466*e44c495dSHao Chen 	struct hns3_enet_ring *ring;
467*e44c495dSHao Chen 	int pos = 0;
468*e44c495dSHao Chen 	u32 i;
469*e44c495dSHao Chen 
470*e44c495dSHao Chen 	if (!priv->ring) {
471*e44c495dSHao Chen 		dev_err(&h->pdev->dev, "priv->ring is NULL\n");
472*e44c495dSHao Chen 		return -EFAULT;
473*e44c495dSHao Chen 	}
474*e44c495dSHao Chen 
475*e44c495dSHao Chen 	for (i = 0; i < ARRAY_SIZE(tx_queue_info_items); i++)
476*e44c495dSHao Chen 		result[i] = &data_str[i][0];
477*e44c495dSHao Chen 
478*e44c495dSHao Chen 	hns3_dbg_fill_content(content, sizeof(content), tx_queue_info_items,
479*e44c495dSHao Chen 			      NULL, ARRAY_SIZE(tx_queue_info_items));
480*e44c495dSHao Chen 	pos += scnprintf(buf + pos, len - pos, "%s", content);
481*e44c495dSHao Chen 
482*e44c495dSHao Chen 	for (i = 0; i < h->kinfo.num_tqps; i++) {
483*e44c495dSHao Chen 		/* Each cycle needs to determine whether the instance is reset,
484*e44c495dSHao Chen 		 * to prevent reference to invalid memory. And need to ensure
485*e44c495dSHao Chen 		 * that the following code is executed within 100ms.
486*e44c495dSHao Chen 		 */
487*e44c495dSHao Chen 		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
488*e44c495dSHao Chen 		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
489*e44c495dSHao Chen 			return -EPERM;
490*e44c495dSHao Chen 
491*e44c495dSHao Chen 		ring = &priv->ring[i];
492*e44c495dSHao Chen 		hns3_dump_tx_queue_info(ring, ae_dev, result, i);
493*e44c495dSHao Chen 		hns3_dbg_fill_content(content, sizeof(content),
494*e44c495dSHao Chen 				      tx_queue_info_items,
495*e44c495dSHao Chen 				      (const char **)result,
496*e44c495dSHao Chen 				      ARRAY_SIZE(tx_queue_info_items));
497*e44c495dSHao Chen 		pos += scnprintf(buf + pos, len - pos, "%s", content);
49857ceee2cSliuzhongzhu 	}
49957ceee2cSliuzhongzhu 
50057ceee2cSliuzhongzhu 	return 0;
50157ceee2cSliuzhongzhu }
50257ceee2cSliuzhongzhu 
503d2f737cfSHao Chen static const struct hns3_dbg_item queue_map_items[] = {
504d2f737cfSHao Chen 	{ "local_queue_id", 2 },
505d2f737cfSHao Chen 	{ "global_queue_id", 2 },
506d2f737cfSHao Chen 	{ "vector_id", 2 },
507d2f737cfSHao Chen };
508d2f737cfSHao Chen 
509d2f737cfSHao Chen static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len)
5100c29d191Sliuzhongzhu {
511d2f737cfSHao Chen 	char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN];
512d2f737cfSHao Chen 	char *result[ARRAY_SIZE(queue_map_items)];
5130c29d191Sliuzhongzhu 	struct hns3_nic_priv *priv = h->priv;
514d2f737cfSHao Chen 	char content[HNS3_DBG_INFO_LEN];
515d2f737cfSHao Chen 	int pos = 0;
516d2f737cfSHao Chen 	int j;
517d2f737cfSHao Chen 	u32 i;
5180c29d191Sliuzhongzhu 
5190c29d191Sliuzhongzhu 	if (!h->ae_algo->ops->get_global_queue_id)
5200c29d191Sliuzhongzhu 		return -EOPNOTSUPP;
5210c29d191Sliuzhongzhu 
522d2f737cfSHao Chen 	for (i = 0; i < ARRAY_SIZE(queue_map_items); i++)
523d2f737cfSHao Chen 		result[i] = &data_str[i][0];
5240c29d191Sliuzhongzhu 
525d2f737cfSHao Chen 	hns3_dbg_fill_content(content, sizeof(content), queue_map_items,
526d2f737cfSHao Chen 			      NULL, ARRAY_SIZE(queue_map_items));
527d2f737cfSHao Chen 	pos += scnprintf(buf + pos, len - pos, "%s", content);
528d2f737cfSHao Chen 	for (i = 0; i < h->kinfo.num_tqps; i++) {
5295f06b903SYunsheng Lin 		if (!priv->ring || !priv->ring[i].tqp_vector)
5300c29d191Sliuzhongzhu 			continue;
531d2f737cfSHao Chen 		j = 0;
532d2f737cfSHao Chen 		sprintf(result[j++], "%u", i);
533d2f737cfSHao Chen 		sprintf(result[j++], "%u",
534d2f737cfSHao Chen 			h->ae_algo->ops->get_global_queue_id(h, i));
535d2f737cfSHao Chen 		sprintf(result[j++], "%u",
536d2f737cfSHao Chen 			priv->ring[i].tqp_vector->vector_irq);
537d2f737cfSHao Chen 		hns3_dbg_fill_content(content, sizeof(content), queue_map_items,
538d2f737cfSHao Chen 				      (const char **)result,
539d2f737cfSHao Chen 				      ARRAY_SIZE(queue_map_items));
540d2f737cfSHao Chen 		pos += scnprintf(buf + pos, len - pos, "%s", content);
5410c29d191Sliuzhongzhu 	}
5420c29d191Sliuzhongzhu 
5430c29d191Sliuzhongzhu 	return 0;
5440c29d191Sliuzhongzhu }
5450c29d191Sliuzhongzhu 
54677e91848SHuazhong Tan static const struct hns3_dbg_item rx_bd_info_items[] = {
54777e91848SHuazhong Tan 	{ "BD_IDX", 3 },
54877e91848SHuazhong Tan 	{ "L234_INFO", 2 },
54977e91848SHuazhong Tan 	{ "PKT_LEN", 3 },
55077e91848SHuazhong Tan 	{ "SIZE", 4 },
55177e91848SHuazhong Tan 	{ "RSS_HASH", 4 },
55277e91848SHuazhong Tan 	{ "FD_ID", 2 },
55377e91848SHuazhong Tan 	{ "VLAN_TAG", 2 },
55477e91848SHuazhong Tan 	{ "O_DM_VLAN_ID_FB", 2 },
55577e91848SHuazhong Tan 	{ "OT_VLAN_TAG", 2 },
55677e91848SHuazhong Tan 	{ "BD_BASE_INFO", 2 },
55777e91848SHuazhong Tan 	{ "PTYPE", 2 },
55877e91848SHuazhong Tan 	{ "HW_CSUM", 2 },
55977e91848SHuazhong Tan };
56077e91848SHuazhong Tan 
56177e91848SHuazhong Tan static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv,
56277e91848SHuazhong Tan 				 struct hns3_desc *desc, char **result, int idx)
563122bedc5Sliuzhongzhu {
56477e91848SHuazhong Tan 	unsigned int j = 0;
565122bedc5Sliuzhongzhu 
56677e91848SHuazhong Tan 	sprintf(result[j++], "%5d", idx);
56777e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info));
56877e91848SHuazhong Tan 	sprintf(result[j++], "%7u", le16_to_cpu(desc->rx.pkt_len));
56977e91848SHuazhong Tan 	sprintf(result[j++], "%4u", le16_to_cpu(desc->rx.size));
57077e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash));
57177e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->rx.fd_id));
57277e91848SHuazhong Tan 	sprintf(result[j++], "%8u", le16_to_cpu(desc->rx.vlan_tag));
57377e91848SHuazhong Tan 	sprintf(result[j++], "%15u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb));
57477e91848SHuazhong Tan 	sprintf(result[j++], "%11u", le16_to_cpu(desc->rx.ot_vlan_tag));
57577e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info));
57677e91848SHuazhong Tan 	if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) {
57777e91848SHuazhong Tan 		u32 ol_info = le32_to_cpu(desc->rx.ol_info);
578122bedc5Sliuzhongzhu 
57977e91848SHuazhong Tan 		sprintf(result[j++], "%5lu", hnae3_get_field(ol_info,
58077e91848SHuazhong Tan 							     HNS3_RXD_PTYPE_M,
58177e91848SHuazhong Tan 							     HNS3_RXD_PTYPE_S));
58277e91848SHuazhong Tan 		sprintf(result[j++], "%7u", le16_to_cpu(desc->csum));
583b1533adaSHuazhong Tan 	} else {
58477e91848SHuazhong Tan 		sprintf(result[j++], "NA");
58577e91848SHuazhong Tan 		sprintf(result[j++], "NA");
58677e91848SHuazhong Tan 	}
587b1533adaSHuazhong Tan }
588b1533adaSHuazhong Tan 
58977e91848SHuazhong Tan static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
59077e91848SHuazhong Tan {
59177e91848SHuazhong Tan 	char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];
59277e91848SHuazhong Tan 	struct hns3_nic_priv *priv = d->handle->priv;
59377e91848SHuazhong Tan 	char *result[ARRAY_SIZE(rx_bd_info_items)];
59477e91848SHuazhong Tan 	char content[HNS3_DBG_INFO_LEN];
59577e91848SHuazhong Tan 	struct hns3_enet_ring *ring;
59677e91848SHuazhong Tan 	struct hns3_desc *desc;
59777e91848SHuazhong Tan 	unsigned int i;
59877e91848SHuazhong Tan 	int pos = 0;
599122bedc5Sliuzhongzhu 
60077e91848SHuazhong Tan 	if (d->qid >= d->handle->kinfo.num_tqps) {
60177e91848SHuazhong Tan 		dev_err(&d->handle->pdev->dev,
60277e91848SHuazhong Tan 			"queue%u is not in use\n", d->qid);
60377e91848SHuazhong Tan 		return -EINVAL;
60477e91848SHuazhong Tan 	}
605122bedc5Sliuzhongzhu 
60677e91848SHuazhong Tan 	for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++)
60777e91848SHuazhong Tan 		result[i] = &data_str[i][0];
608b1533adaSHuazhong Tan 
60977e91848SHuazhong Tan 	pos += scnprintf(buf + pos, len - pos,
61077e91848SHuazhong Tan 			  "Queue %u rx bd info:\n", d->qid);
61177e91848SHuazhong Tan 	hns3_dbg_fill_content(content, sizeof(content), rx_bd_info_items,
61277e91848SHuazhong Tan 			      NULL, ARRAY_SIZE(rx_bd_info_items));
61377e91848SHuazhong Tan 	pos += scnprintf(buf + pos, len - pos, "%s", content);
61477e91848SHuazhong Tan 
61577e91848SHuazhong Tan 	ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps];
61677e91848SHuazhong Tan 	for (i = 0; i < ring->desc_num; i++) {
61777e91848SHuazhong Tan 		desc = &ring->desc[i];
61877e91848SHuazhong Tan 
61977e91848SHuazhong Tan 		hns3_dump_rx_bd_info(priv, desc, result, i);
62077e91848SHuazhong Tan 		hns3_dbg_fill_content(content, sizeof(content),
62177e91848SHuazhong Tan 				      rx_bd_info_items, (const char **)result,
62277e91848SHuazhong Tan 				      ARRAY_SIZE(rx_bd_info_items));
62377e91848SHuazhong Tan 		pos += scnprintf(buf + pos, len - pos, "%s", content);
62477e91848SHuazhong Tan 	}
62577e91848SHuazhong Tan 
62677e91848SHuazhong Tan 	return 0;
62777e91848SHuazhong Tan }
62877e91848SHuazhong Tan 
62977e91848SHuazhong Tan static const struct hns3_dbg_item tx_bd_info_items[] = {
63077e91848SHuazhong Tan 	{ "BD_IDX", 5 },
63177e91848SHuazhong Tan 	{ "ADDRESS", 2 },
63277e91848SHuazhong Tan 	{ "VLAN_TAG", 2 },
63377e91848SHuazhong Tan 	{ "SIZE", 2 },
63477e91848SHuazhong Tan 	{ "T_CS_VLAN_TSO", 2 },
63577e91848SHuazhong Tan 	{ "OT_VLAN_TAG", 3 },
63677e91848SHuazhong Tan 	{ "TV", 2 },
63777e91848SHuazhong Tan 	{ "OLT_VLAN_LEN", 2},
63877e91848SHuazhong Tan 	{ "PAYLEN_OL4CS", 2},
63977e91848SHuazhong Tan 	{ "BD_FE_SC_VLD", 2},
64077e91848SHuazhong Tan 	{ "MSS_HW_CSUM", 0},
64177e91848SHuazhong Tan };
64277e91848SHuazhong Tan 
64377e91848SHuazhong Tan static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv,
64477e91848SHuazhong Tan 				 struct hns3_desc *desc, char **result, int idx)
64577e91848SHuazhong Tan {
64677e91848SHuazhong Tan 	unsigned int j = 0;
64777e91848SHuazhong Tan 
64877e91848SHuazhong Tan 	sprintf(result[j++], "%6d", idx);
64977e91848SHuazhong Tan 	sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr));
65077e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.vlan_tag));
65177e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.send_size));
65277e91848SHuazhong Tan 	sprintf(result[j++], "%#x",
65377e91848SHuazhong Tan 		le32_to_cpu(desc->tx.type_cs_vlan_tso_len));
65477e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.outer_vlan_tag));
65577e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.tv));
65677e91848SHuazhong Tan 	sprintf(result[j++], "%10u",
65777e91848SHuazhong Tan 		le32_to_cpu(desc->tx.ol_type_vlan_len_msec));
65877e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs));
65977e91848SHuazhong Tan 	sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri));
66077e91848SHuazhong Tan 	sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum));
66177e91848SHuazhong Tan }
66277e91848SHuazhong Tan 
66377e91848SHuazhong Tan static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
66477e91848SHuazhong Tan {
66577e91848SHuazhong Tan 	char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];
66677e91848SHuazhong Tan 	struct hns3_nic_priv *priv = d->handle->priv;
66777e91848SHuazhong Tan 	char *result[ARRAY_SIZE(tx_bd_info_items)];
66877e91848SHuazhong Tan 	char content[HNS3_DBG_INFO_LEN];
66977e91848SHuazhong Tan 	struct hns3_enet_ring *ring;
67077e91848SHuazhong Tan 	struct hns3_desc *desc;
67177e91848SHuazhong Tan 	unsigned int i;
67277e91848SHuazhong Tan 	int pos = 0;
67377e91848SHuazhong Tan 
67477e91848SHuazhong Tan 	if (d->qid >= d->handle->kinfo.num_tqps) {
67577e91848SHuazhong Tan 		dev_err(&d->handle->pdev->dev,
67677e91848SHuazhong Tan 			"queue%u is not in use\n", d->qid);
67777e91848SHuazhong Tan 		return -EINVAL;
67877e91848SHuazhong Tan 	}
67977e91848SHuazhong Tan 
68077e91848SHuazhong Tan 	for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++)
68177e91848SHuazhong Tan 		result[i] = &data_str[i][0];
68277e91848SHuazhong Tan 
68377e91848SHuazhong Tan 	pos += scnprintf(buf + pos, len - pos,
68477e91848SHuazhong Tan 			  "Queue %u tx bd info:\n", d->qid);
68577e91848SHuazhong Tan 	hns3_dbg_fill_content(content, sizeof(content), tx_bd_info_items,
68677e91848SHuazhong Tan 			      NULL, ARRAY_SIZE(tx_bd_info_items));
68777e91848SHuazhong Tan 	pos += scnprintf(buf + pos, len - pos, "%s", content);
68877e91848SHuazhong Tan 
68977e91848SHuazhong Tan 	ring = &priv->ring[d->qid];
69077e91848SHuazhong Tan 	for (i = 0; i < ring->desc_num; i++) {
69177e91848SHuazhong Tan 		desc = &ring->desc[i];
69277e91848SHuazhong Tan 
69377e91848SHuazhong Tan 		hns3_dump_tx_bd_info(priv, desc, result, i);
69477e91848SHuazhong Tan 		hns3_dbg_fill_content(content, sizeof(content),
69577e91848SHuazhong Tan 				      tx_bd_info_items, (const char **)result,
69677e91848SHuazhong Tan 				      ARRAY_SIZE(tx_bd_info_items));
69777e91848SHuazhong Tan 		pos += scnprintf(buf + pos, len - pos, "%s", content);
69877e91848SHuazhong Tan 	}
699122bedc5Sliuzhongzhu 
700122bedc5Sliuzhongzhu 	return 0;
701122bedc5Sliuzhongzhu }
702122bedc5Sliuzhongzhu 
703b2292360Sliuzhongzhu static void hns3_dbg_help(struct hnae3_handle *h)
704b2292360Sliuzhongzhu {
705b2292360Sliuzhongzhu 	dev_info(&h->pdev->dev, "available commands\n");
70697afd47bSYufeng Mo 
70797afd47bSYufeng Mo 	if (!hns3_is_phys_func(h->pdev))
70897afd47bSYufeng Mo 		return;
70997afd47bSYufeng Mo 
710b2292360Sliuzhongzhu 	dev_info(&h->pdev->dev, "dump fd tcam\n");
7112849d4e7Sliuzhongzhu 	dev_info(&h->pdev->dev, "dump tc\n");
712ed5b255bSYufeng Mo 	dev_info(&h->pdev->dev, "dump tm map <q_num>\n");
71396227f4cSliuzhongzhu 	dev_info(&h->pdev->dev, "dump tm\n");
714d958919dSliuzhongzhu 	dev_info(&h->pdev->dev, "dump qos pause cfg\n");
7156fc22440Sliuzhongzhu 	dev_info(&h->pdev->dev, "dump qos pri map\n");
7167d9d7f88Sliuzhongzhu 	dev_info(&h->pdev->dev, "dump qos buf cfg\n");
717a6345787SWeihang Li 	dev_info(&h->pdev->dev, "dump mac tnl status\n");
71889ec9485SYonglong Liu 	dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n");
719b2292360Sliuzhongzhu }
720b2292360Sliuzhongzhu 
721c929bc2aSJiaran Zhang static void
722c929bc2aSJiaran Zhang hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos)
7239484e337SGuangbin Huang {
7249484e337SGuangbin Huang 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
725c929bc2aSJiaran Zhang 	static const char * const str[] = {"no", "yes"};
726c929bc2aSJiaran Zhang 	unsigned long *caps = ae_dev->caps;
727c929bc2aSJiaran Zhang 	u32 i, state;
7289484e337SGuangbin Huang 
729c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "dev capability:\n");
7309484e337SGuangbin Huang 
731c929bc2aSJiaran Zhang 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) {
732c929bc2aSJiaran Zhang 		state = test_bit(hns3_dbg_cap[i].cap_bit, caps);
733c929bc2aSJiaran Zhang 		*pos += scnprintf(buf + *pos, len - *pos, "%s: %s\n",
734c929bc2aSJiaran Zhang 				  hns3_dbg_cap[i].name, str[state]);
7359484e337SGuangbin Huang 	}
7369484e337SGuangbin Huang 
737c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "\n");
738c929bc2aSJiaran Zhang }
739c929bc2aSJiaran Zhang 
740c929bc2aSJiaran Zhang static void
741c929bc2aSJiaran Zhang hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos)
742b4442ec5SGuangbin Huang {
743b4442ec5SGuangbin Huang 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
744b4442ec5SGuangbin Huang 	struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs;
745b4442ec5SGuangbin Huang 	struct hnae3_knic_private_info *kinfo = &h->kinfo;
746b4442ec5SGuangbin Huang 
747c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "dev_spec:\n");
748c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAC entry num: %u\n",
749c929bc2aSJiaran Zhang 			  dev_specs->mac_entry_num);
750c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MNG entry num: %u\n",
751c929bc2aSJiaran Zhang 			  dev_specs->mng_entry_num);
752c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX non tso bd num: %u\n",
753b4442ec5SGuangbin Huang 			  dev_specs->max_non_tso_bd_num);
754c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "RSS ind tbl size: %u\n",
755b4442ec5SGuangbin Huang 			  dev_specs->rss_ind_tbl_size);
756c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "RSS key size: %u\n",
757c929bc2aSJiaran Zhang 			  dev_specs->rss_key_size);
758c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "RSS size: %u\n",
759c929bc2aSJiaran Zhang 			  kinfo->rss_size);
760c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "Allocated RSS size: %u\n",
761c929bc2aSJiaran Zhang 			  kinfo->req_rss_size);
762c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos,
763c929bc2aSJiaran Zhang 			  "Task queue pairs numbers: %u\n",
764c929bc2aSJiaran Zhang 			  kinfo->num_tqps);
765c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "RX buffer length: %u\n",
766c929bc2aSJiaran Zhang 			  kinfo->rx_buf_len);
767c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "Desc num per TX queue: %u\n",
768c929bc2aSJiaran Zhang 			  kinfo->num_tx_desc);
769c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "Desc num per RX queue: %u\n",
770c929bc2aSJiaran Zhang 			  kinfo->num_rx_desc);
771c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos,
772c929bc2aSJiaran Zhang 			  "Total number of enabled TCs: %u\n",
77335244430SJian Shen 			  kinfo->tc_info.num_tc);
774c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX INT QL: %u\n",
775c929bc2aSJiaran Zhang 			  dev_specs->int_ql_max);
776c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX INT GL: %u\n",
777c929bc2aSJiaran Zhang 			  dev_specs->max_int_gl);
778c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX TM RATE: %u\n",
779c929bc2aSJiaran Zhang 			  dev_specs->max_tm_rate);
780c929bc2aSJiaran Zhang 	*pos += scnprintf(buf + *pos, len - *pos, "MAX QSET number: %u\n",
781c929bc2aSJiaran Zhang 			  dev_specs->max_qset_num);
782c929bc2aSJiaran Zhang }
783c929bc2aSJiaran Zhang 
784c929bc2aSJiaran Zhang static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len)
785c929bc2aSJiaran Zhang {
786c929bc2aSJiaran Zhang 	int pos = 0;
787c929bc2aSJiaran Zhang 
788c929bc2aSJiaran Zhang 	hns3_dbg_dev_caps(h, buf, len, &pos);
789c929bc2aSJiaran Zhang 
790c929bc2aSJiaran Zhang 	hns3_dbg_dev_specs(h, buf, len, &pos);
791c929bc2aSJiaran Zhang 
792c929bc2aSJiaran Zhang 	return 0;
793b4442ec5SGuangbin Huang }
794b4442ec5SGuangbin Huang 
795b2292360Sliuzhongzhu static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer,
796b2292360Sliuzhongzhu 				 size_t count, loff_t *ppos)
797b2292360Sliuzhongzhu {
798b2292360Sliuzhongzhu 	int uncopy_bytes;
799b2292360Sliuzhongzhu 	char *buf;
800b2292360Sliuzhongzhu 	int len;
801b2292360Sliuzhongzhu 
802b2292360Sliuzhongzhu 	if (*ppos != 0)
803b2292360Sliuzhongzhu 		return 0;
804b2292360Sliuzhongzhu 
805b2292360Sliuzhongzhu 	if (count < HNS3_DBG_READ_LEN)
806b2292360Sliuzhongzhu 		return -ENOSPC;
807b2292360Sliuzhongzhu 
808b2292360Sliuzhongzhu 	buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL);
809b2292360Sliuzhongzhu 	if (!buf)
810b2292360Sliuzhongzhu 		return -ENOMEM;
811b2292360Sliuzhongzhu 
81249e211c0SChen Zhou 	len = scnprintf(buf, HNS3_DBG_READ_LEN, "%s\n",
813b2292360Sliuzhongzhu 			"Please echo help to cmd to get help information");
814b2292360Sliuzhongzhu 	uncopy_bytes = copy_to_user(buffer, buf, len);
815b2292360Sliuzhongzhu 
816b2292360Sliuzhongzhu 	kfree(buf);
817b2292360Sliuzhongzhu 
818b2292360Sliuzhongzhu 	if (uncopy_bytes)
819b2292360Sliuzhongzhu 		return -EFAULT;
820b2292360Sliuzhongzhu 
821b2292360Sliuzhongzhu 	return (*ppos = len);
822b2292360Sliuzhongzhu }
823b2292360Sliuzhongzhu 
824c318af3fSPeng Li static int hns3_dbg_check_cmd(struct hnae3_handle *handle, char *cmd_buf)
825c318af3fSPeng Li {
826c318af3fSPeng Li 	int ret = 0;
827c318af3fSPeng Li 
828c318af3fSPeng Li 	if (strncmp(cmd_buf, "help", 4) == 0)
829c318af3fSPeng Li 		hns3_dbg_help(handle);
830c318af3fSPeng Li 	else if (handle->ae_algo->ops->dbg_run_cmd)
831c318af3fSPeng Li 		ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);
832c318af3fSPeng Li 	else
833c318af3fSPeng Li 		ret = -EOPNOTSUPP;
834c318af3fSPeng Li 
835c318af3fSPeng Li 	return ret;
836c318af3fSPeng Li }
837c318af3fSPeng Li 
838b2292360Sliuzhongzhu static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
839b2292360Sliuzhongzhu 				  size_t count, loff_t *ppos)
840b2292360Sliuzhongzhu {
841b2292360Sliuzhongzhu 	struct hnae3_handle *handle = filp->private_data;
84257ceee2cSliuzhongzhu 	struct hns3_nic_priv *priv  = handle->priv;
843b2292360Sliuzhongzhu 	char *cmd_buf, *cmd_buf_tmp;
844b2292360Sliuzhongzhu 	int uncopied_bytes;
845c318af3fSPeng Li 	int ret;
846b2292360Sliuzhongzhu 
847b2292360Sliuzhongzhu 	if (*ppos != 0)
848b2292360Sliuzhongzhu 		return 0;
849b2292360Sliuzhongzhu 
85057ceee2cSliuzhongzhu 	/* Judge if the instance is being reset. */
8517737f1fbSliuzhongzhu 	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
85257ceee2cSliuzhongzhu 	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
85357ceee2cSliuzhongzhu 		return 0;
85457ceee2cSliuzhongzhu 
8557ac243f9SYufeng Mo 	if (count > HNS3_DBG_WRITE_LEN)
8567ac243f9SYufeng Mo 		return -ENOSPC;
8577ac243f9SYufeng Mo 
858b2292360Sliuzhongzhu 	cmd_buf = kzalloc(count + 1, GFP_KERNEL);
859b2292360Sliuzhongzhu 	if (!cmd_buf)
860b2292360Sliuzhongzhu 		return count;
861b2292360Sliuzhongzhu 
862b2292360Sliuzhongzhu 	uncopied_bytes = copy_from_user(cmd_buf, buffer, count);
863b2292360Sliuzhongzhu 	if (uncopied_bytes) {
864b2292360Sliuzhongzhu 		kfree(cmd_buf);
865b2292360Sliuzhongzhu 		return -EFAULT;
866b2292360Sliuzhongzhu 	}
867b2292360Sliuzhongzhu 
868b2292360Sliuzhongzhu 	cmd_buf[count] = '\0';
869b2292360Sliuzhongzhu 
870b2292360Sliuzhongzhu 	cmd_buf_tmp = strchr(cmd_buf, '\n');
871b2292360Sliuzhongzhu 	if (cmd_buf_tmp) {
872b2292360Sliuzhongzhu 		*cmd_buf_tmp = '\0';
873b2292360Sliuzhongzhu 		count = cmd_buf_tmp - cmd_buf + 1;
874b2292360Sliuzhongzhu 	}
875b2292360Sliuzhongzhu 
876c318af3fSPeng Li 	ret = hns3_dbg_check_cmd(handle, cmd_buf);
877b2292360Sliuzhongzhu 	if (ret)
878b2292360Sliuzhongzhu 		hns3_dbg_help(handle);
879b2292360Sliuzhongzhu 
880b2292360Sliuzhongzhu 	kfree(cmd_buf);
881b2292360Sliuzhongzhu 	cmd_buf = NULL;
882b2292360Sliuzhongzhu 
883b2292360Sliuzhongzhu 	return count;
884b2292360Sliuzhongzhu }
885b2292360Sliuzhongzhu 
8865e69ea7eSYufeng Mo static int hns3_dbg_get_cmd_index(struct hnae3_handle *handle,
8875e69ea7eSYufeng Mo 				  const unsigned char *name, u32 *index)
8885e69ea7eSYufeng Mo {
8895e69ea7eSYufeng Mo 	u32 i;
8905e69ea7eSYufeng Mo 
8915e69ea7eSYufeng Mo 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
8925e69ea7eSYufeng Mo 		if (!strncmp(name, hns3_dbg_cmd[i].name,
8935e69ea7eSYufeng Mo 			     strlen(hns3_dbg_cmd[i].name))) {
8945e69ea7eSYufeng Mo 			*index = i;
8955e69ea7eSYufeng Mo 			return 0;
8965e69ea7eSYufeng Mo 		}
8975e69ea7eSYufeng Mo 	}
8985e69ea7eSYufeng Mo 
8995e69ea7eSYufeng Mo 	dev_err(&handle->pdev->dev, "unknown command(%s)\n", name);
9005e69ea7eSYufeng Mo 	return -EINVAL;
9015e69ea7eSYufeng Mo }
9025e69ea7eSYufeng Mo 
903c929bc2aSJiaran Zhang static const struct hns3_dbg_func hns3_dbg_cmd_func[] = {
904c929bc2aSJiaran Zhang 	{
905d2f737cfSHao Chen 		.cmd = HNAE3_DBG_CMD_QUEUE_MAP,
906d2f737cfSHao Chen 		.dbg_dump = hns3_dbg_queue_map,
907d2f737cfSHao Chen 	},
908d2f737cfSHao Chen 	{
909c929bc2aSJiaran Zhang 		.cmd = HNAE3_DBG_CMD_DEV_INFO,
910c929bc2aSJiaran Zhang 		.dbg_dump = hns3_dbg_dev_info,
911c929bc2aSJiaran Zhang 	},
91277e91848SHuazhong Tan 	{
91377e91848SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_TX_BD,
91477e91848SHuazhong Tan 		.dbg_dump_bd = hns3_dbg_tx_bd_info,
91577e91848SHuazhong Tan 	},
91677e91848SHuazhong Tan 	{
91777e91848SHuazhong Tan 		.cmd = HNAE3_DBG_CMD_RX_BD,
91877e91848SHuazhong Tan 		.dbg_dump_bd = hns3_dbg_rx_bd_info,
91977e91848SHuazhong Tan 	},
920*e44c495dSHao Chen 	{
921*e44c495dSHao Chen 		.cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,
922*e44c495dSHao Chen 		.dbg_dump = hns3_dbg_rx_queue_info,
923*e44c495dSHao Chen 	},
924*e44c495dSHao Chen 	{
925*e44c495dSHao Chen 		.cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,
926*e44c495dSHao Chen 		.dbg_dump = hns3_dbg_tx_queue_info,
927*e44c495dSHao Chen 	},
928c929bc2aSJiaran Zhang };
929c929bc2aSJiaran Zhang 
93077e91848SHuazhong Tan static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data,
9315e69ea7eSYufeng Mo 			     enum hnae3_dbg_cmd cmd, char *buf, int len)
9325e69ea7eSYufeng Mo {
93377e91848SHuazhong Tan 	const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops;
93477e91848SHuazhong Tan 	const struct hns3_dbg_func *cmd_func;
935c929bc2aSJiaran Zhang 	u32 i;
936c929bc2aSJiaran Zhang 
937c929bc2aSJiaran Zhang 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) {
93877e91848SHuazhong Tan 		if (cmd == hns3_dbg_cmd_func[i].cmd) {
93977e91848SHuazhong Tan 			cmd_func = &hns3_dbg_cmd_func[i];
94077e91848SHuazhong Tan 			if (cmd_func->dbg_dump)
94177e91848SHuazhong Tan 				return cmd_func->dbg_dump(dbg_data->handle, buf,
94277e91848SHuazhong Tan 							  len);
94377e91848SHuazhong Tan 			else
94477e91848SHuazhong Tan 				return cmd_func->dbg_dump_bd(dbg_data, buf,
94577e91848SHuazhong Tan 							     len);
94677e91848SHuazhong Tan 		}
947c929bc2aSJiaran Zhang 	}
9485e69ea7eSYufeng Mo 
9495e69ea7eSYufeng Mo 	if (!ops->dbg_read_cmd)
9505e69ea7eSYufeng Mo 		return -EOPNOTSUPP;
9515e69ea7eSYufeng Mo 
95277e91848SHuazhong Tan 	return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len);
9535e69ea7eSYufeng Mo }
9545e69ea7eSYufeng Mo 
95504987ca1SGuangbin Huang static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
95604987ca1SGuangbin Huang 			     size_t count, loff_t *ppos)
95704987ca1SGuangbin Huang {
95877e91848SHuazhong Tan 	struct hns3_dbg_data *dbg_data = filp->private_data;
95977e91848SHuazhong Tan 	struct hnae3_handle *handle = dbg_data->handle;
96004987ca1SGuangbin Huang 	struct hns3_nic_priv *priv = handle->priv;
96104987ca1SGuangbin Huang 	ssize_t size = 0;
9625e69ea7eSYufeng Mo 	char **save_buf;
9635e69ea7eSYufeng Mo 	char *read_buf;
9645e69ea7eSYufeng Mo 	u32 index;
9655e69ea7eSYufeng Mo 	int ret;
96604987ca1SGuangbin Huang 
9675e69ea7eSYufeng Mo 	ret = hns3_dbg_get_cmd_index(handle, filp->f_path.dentry->d_iname,
9685e69ea7eSYufeng Mo 				     &index);
9695e69ea7eSYufeng Mo 	if (ret)
9705e69ea7eSYufeng Mo 		return ret;
9715e69ea7eSYufeng Mo 
9725e69ea7eSYufeng Mo 	save_buf = &hns3_dbg_cmd[index].buf;
9735e69ea7eSYufeng Mo 
9745e69ea7eSYufeng Mo 	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
9755e69ea7eSYufeng Mo 	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) {
9765e69ea7eSYufeng Mo 		ret = -EBUSY;
9775e69ea7eSYufeng Mo 		goto out;
9785e69ea7eSYufeng Mo 	}
9795e69ea7eSYufeng Mo 
9805e69ea7eSYufeng Mo 	if (*save_buf) {
9815e69ea7eSYufeng Mo 		read_buf = *save_buf;
9825e69ea7eSYufeng Mo 	} else {
9835e69ea7eSYufeng Mo 		read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
98404987ca1SGuangbin Huang 		if (!read_buf)
98504987ca1SGuangbin Huang 			return -ENOMEM;
98604987ca1SGuangbin Huang 
9875e69ea7eSYufeng Mo 		/* save the buffer addr until the last read operation */
9885e69ea7eSYufeng Mo 		*save_buf = read_buf;
9895e69ea7eSYufeng Mo 	}
99004987ca1SGuangbin Huang 
9915e69ea7eSYufeng Mo 	/* get data ready for the first time to read */
9925e69ea7eSYufeng Mo 	if (!*ppos) {
99377e91848SHuazhong Tan 		ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
9945e69ea7eSYufeng Mo 					read_buf, hns3_dbg_cmd[index].buf_len);
9955e69ea7eSYufeng Mo 		if (ret)
99604987ca1SGuangbin Huang 			goto out;
99704987ca1SGuangbin Huang 	}
99804987ca1SGuangbin Huang 
99904987ca1SGuangbin Huang 	size = simple_read_from_buffer(buffer, count, ppos, read_buf,
100004987ca1SGuangbin Huang 				       strlen(read_buf));
10015e69ea7eSYufeng Mo 	if (size > 0)
10025e69ea7eSYufeng Mo 		return size;
100304987ca1SGuangbin Huang 
100404987ca1SGuangbin Huang out:
10055e69ea7eSYufeng Mo 	/* free the buffer for the last read operation */
10065e69ea7eSYufeng Mo 	if (*save_buf) {
10075e69ea7eSYufeng Mo 		kvfree(*save_buf);
10085e69ea7eSYufeng Mo 		*save_buf = NULL;
10095e69ea7eSYufeng Mo 	}
10105e69ea7eSYufeng Mo 
10115e69ea7eSYufeng Mo 	return ret;
101204987ca1SGuangbin Huang }
101304987ca1SGuangbin Huang 
1014b2292360Sliuzhongzhu static const struct file_operations hns3_dbg_cmd_fops = {
1015b2292360Sliuzhongzhu 	.owner = THIS_MODULE,
1016b2292360Sliuzhongzhu 	.open  = simple_open,
1017b2292360Sliuzhongzhu 	.read  = hns3_dbg_cmd_read,
1018b2292360Sliuzhongzhu 	.write = hns3_dbg_cmd_write,
1019b2292360Sliuzhongzhu };
1020b2292360Sliuzhongzhu 
102104987ca1SGuangbin Huang static const struct file_operations hns3_dbg_fops = {
102204987ca1SGuangbin Huang 	.owner = THIS_MODULE,
102304987ca1SGuangbin Huang 	.open  = simple_open,
102404987ca1SGuangbin Huang 	.read  = hns3_dbg_read,
102504987ca1SGuangbin Huang };
102604987ca1SGuangbin Huang 
102777e91848SHuazhong Tan static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd)
102877e91848SHuazhong Tan {
102977e91848SHuazhong Tan 	struct dentry *entry_dir;
103077e91848SHuazhong Tan 	struct hns3_dbg_data *data;
103177e91848SHuazhong Tan 	u16 max_queue_num;
103277e91848SHuazhong Tan 	unsigned int i;
103377e91848SHuazhong Tan 
103477e91848SHuazhong Tan 	entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
103577e91848SHuazhong Tan 	max_queue_num = hns3_get_max_available_channels(handle);
103677e91848SHuazhong Tan 	data = devm_kzalloc(&handle->pdev->dev, max_queue_num * sizeof(*data),
103777e91848SHuazhong Tan 			    GFP_KERNEL);
103877e91848SHuazhong Tan 	if (!data)
103977e91848SHuazhong Tan 		return -ENOMEM;
104077e91848SHuazhong Tan 
104177e91848SHuazhong Tan 	for (i = 0; i < max_queue_num; i++) {
104277e91848SHuazhong Tan 		char name[HNS3_DBG_FILE_NAME_LEN];
104377e91848SHuazhong Tan 
104477e91848SHuazhong Tan 		data[i].handle = handle;
104577e91848SHuazhong Tan 		data[i].qid = i;
104677e91848SHuazhong Tan 		sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i);
104777e91848SHuazhong Tan 		debugfs_create_file(name, 0400, entry_dir, &data[i],
104877e91848SHuazhong Tan 				    &hns3_dbg_fops);
104977e91848SHuazhong Tan 	}
105077e91848SHuazhong Tan 
105177e91848SHuazhong Tan 	return 0;
105277e91848SHuazhong Tan }
105377e91848SHuazhong Tan 
10545e69ea7eSYufeng Mo static int
10555e69ea7eSYufeng Mo hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd)
10565e69ea7eSYufeng Mo {
105777e91848SHuazhong Tan 	struct hns3_dbg_data *data;
10585e69ea7eSYufeng Mo 	struct dentry *entry_dir;
10595e69ea7eSYufeng Mo 
106077e91848SHuazhong Tan 	data = devm_kzalloc(&handle->pdev->dev, sizeof(*data), GFP_KERNEL);
106177e91848SHuazhong Tan 	if (!data)
106277e91848SHuazhong Tan 		return -ENOMEM;
106377e91848SHuazhong Tan 
106477e91848SHuazhong Tan 	data->handle = handle;
10655e69ea7eSYufeng Mo 	entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
10665e69ea7eSYufeng Mo 	debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir,
106777e91848SHuazhong Tan 			    data, &hns3_dbg_fops);
10685e69ea7eSYufeng Mo 
10695e69ea7eSYufeng Mo 	return 0;
10705e69ea7eSYufeng Mo }
10715e69ea7eSYufeng Mo 
10725e69ea7eSYufeng Mo int hns3_dbg_init(struct hnae3_handle *handle)
1073b2292360Sliuzhongzhu {
107404987ca1SGuangbin Huang 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
1075b2292360Sliuzhongzhu 	const char *name = pci_name(handle->pdev);
10765e69ea7eSYufeng Mo 	int ret;
10775e69ea7eSYufeng Mo 	u32 i;
1078b2292360Sliuzhongzhu 
10795e69ea7eSYufeng Mo 	hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry =
10805e69ea7eSYufeng Mo 				debugfs_create_dir(name, hns3_dbgfs_root);
10815e69ea7eSYufeng Mo 	handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry;
1082b2292360Sliuzhongzhu 
108311ab11e6SGreg Kroah-Hartman 	debugfs_create_file("cmd", 0600, handle->hnae3_dbgfs, handle,
1084b2292360Sliuzhongzhu 			    &hns3_dbg_cmd_fops);
108504987ca1SGuangbin Huang 
10865e69ea7eSYufeng Mo 	for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++)
10875e69ea7eSYufeng Mo 		hns3_dbg_dentry[i].dentry =
10885e69ea7eSYufeng Mo 			debugfs_create_dir(hns3_dbg_dentry[i].name,
10895e69ea7eSYufeng Mo 					   handle->hnae3_dbgfs);
10905e69ea7eSYufeng Mo 
10915e69ea7eSYufeng Mo 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
10925e69ea7eSYufeng Mo 		if (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
10935e69ea7eSYufeng Mo 		    ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2)
10945e69ea7eSYufeng Mo 			continue;
10955e69ea7eSYufeng Mo 
10965e69ea7eSYufeng Mo 		if (!hns3_dbg_cmd[i].init) {
10975e69ea7eSYufeng Mo 			dev_err(&handle->pdev->dev,
10985e69ea7eSYufeng Mo 				"cmd %s lack of init func\n",
10995e69ea7eSYufeng Mo 				hns3_dbg_cmd[i].name);
11005e69ea7eSYufeng Mo 			ret = -EINVAL;
11015e69ea7eSYufeng Mo 			goto out;
11025e69ea7eSYufeng Mo 		}
11035e69ea7eSYufeng Mo 
11045e69ea7eSYufeng Mo 		ret = hns3_dbg_cmd[i].init(handle, i);
11055e69ea7eSYufeng Mo 		if (ret) {
11065e69ea7eSYufeng Mo 			dev_err(&handle->pdev->dev, "failed to init cmd %s\n",
11075e69ea7eSYufeng Mo 				hns3_dbg_cmd[i].name);
11085e69ea7eSYufeng Mo 			goto out;
11095e69ea7eSYufeng Mo 		}
11105e69ea7eSYufeng Mo 	}
11115e69ea7eSYufeng Mo 
11125e69ea7eSYufeng Mo 	return 0;
11135e69ea7eSYufeng Mo 
11145e69ea7eSYufeng Mo out:
11155e69ea7eSYufeng Mo 	debugfs_remove_recursive(handle->hnae3_dbgfs);
11165e69ea7eSYufeng Mo 	handle->hnae3_dbgfs = NULL;
11175e69ea7eSYufeng Mo 	return ret;
1118b2292360Sliuzhongzhu }
1119b2292360Sliuzhongzhu 
1120b2292360Sliuzhongzhu void hns3_dbg_uninit(struct hnae3_handle *handle)
1121b2292360Sliuzhongzhu {
11225e69ea7eSYufeng Mo 	u32 i;
11235e69ea7eSYufeng Mo 
11245e69ea7eSYufeng Mo 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++)
11255e69ea7eSYufeng Mo 		if (hns3_dbg_cmd[i].buf) {
11265e69ea7eSYufeng Mo 			kvfree(hns3_dbg_cmd[i].buf);
11275e69ea7eSYufeng Mo 			hns3_dbg_cmd[i].buf = NULL;
11285e69ea7eSYufeng Mo 		}
11295e69ea7eSYufeng Mo 
1130b2292360Sliuzhongzhu 	debugfs_remove_recursive(handle->hnae3_dbgfs);
1131b2292360Sliuzhongzhu 	handle->hnae3_dbgfs = NULL;
1132b2292360Sliuzhongzhu }
1133b2292360Sliuzhongzhu 
1134b2292360Sliuzhongzhu void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
1135b2292360Sliuzhongzhu {
1136b2292360Sliuzhongzhu 	hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL);
1137b2292360Sliuzhongzhu }
1138b2292360Sliuzhongzhu 
1139b2292360Sliuzhongzhu void hns3_dbg_unregister_debugfs(void)
1140b2292360Sliuzhongzhu {
1141b2292360Sliuzhongzhu 	debugfs_remove_recursive(hns3_dbgfs_root);
1142b2292360Sliuzhongzhu 	hns3_dbgfs_root = NULL;
1143b2292360Sliuzhongzhu }
1144