xref: /linux/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c (revision cad4977344b35ea116ec5fefe91a76b1dfa113f5)
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Copyright (c) 2018-2019 Hisilicon Limited. */
3 
4 #include <linux/debugfs.h>
5 #include <linux/device.h>
6 
7 #include "hnae3.h"
8 #include "hns3_enet.h"
9 
10 #define HNS3_DBG_READ_LEN 256
11 
12 static struct dentry *hns3_dbgfs_root;
13 
14 static int hns3_dbg_queue_info(struct hnae3_handle *h, char *cmd_buf)
15 {
16 	struct hns3_nic_priv *priv = h->priv;
17 	struct hns3_nic_ring_data *ring_data;
18 	struct hns3_enet_ring *ring;
19 	u32 base_add_l, base_add_h;
20 	u32 queue_num, queue_max;
21 	u32 value, i = 0;
22 	int cnt;
23 
24 	if (!priv->ring_data) {
25 		dev_err(&h->pdev->dev, "ring_data is NULL\n");
26 		return -EFAULT;
27 	}
28 
29 	queue_max = h->kinfo.num_tqps;
30 	cnt = kstrtouint(&cmd_buf[11], 0, &queue_num);
31 	if (cnt)
32 		queue_num = 0;
33 	else
34 		queue_max = queue_num + 1;
35 
36 	dev_info(&h->pdev->dev, "queue info\n");
37 
38 	if (queue_num >= h->kinfo.num_tqps) {
39 		dev_err(&h->pdev->dev,
40 			"Queue number(%u) is out of range(%u)\n", queue_num,
41 			h->kinfo.num_tqps - 1);
42 		return -EINVAL;
43 	}
44 
45 	ring_data = priv->ring_data;
46 	for (i = queue_num; i < queue_max; i++) {
47 		/* Each cycle needs to determine whether the instance is reset,
48 		 * to prevent reference to invalid memory. And need to ensure
49 		 * that the following code is executed within 100ms.
50 		 */
51 		if (test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
52 		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
53 			return -EPERM;
54 
55 		ring = ring_data[i + h->kinfo.num_tqps].ring;
56 		base_add_h = readl_relaxed(ring->tqp->io_base +
57 					   HNS3_RING_RX_RING_BASEADDR_H_REG);
58 		base_add_l = readl_relaxed(ring->tqp->io_base +
59 					   HNS3_RING_RX_RING_BASEADDR_L_REG);
60 		dev_info(&h->pdev->dev, "RX(%d) BASE ADD: 0x%08x%08x\n", i,
61 			 base_add_h, base_add_l);
62 
63 		value = readl_relaxed(ring->tqp->io_base +
64 				      HNS3_RING_RX_RING_BD_NUM_REG);
65 		dev_info(&h->pdev->dev, "RX(%d) RING BD NUM: %u\n", i, value);
66 
67 		value = readl_relaxed(ring->tqp->io_base +
68 				      HNS3_RING_RX_RING_BD_LEN_REG);
69 		dev_info(&h->pdev->dev, "RX(%d) RING BD LEN: %u\n", i, value);
70 
71 		value = readl_relaxed(ring->tqp->io_base +
72 				      HNS3_RING_RX_RING_TAIL_REG);
73 		dev_info(&h->pdev->dev, "RX(%d) RING TAIL: %u\n", i, value);
74 
75 		value = readl_relaxed(ring->tqp->io_base +
76 				      HNS3_RING_RX_RING_HEAD_REG);
77 		dev_info(&h->pdev->dev, "RX(%d) RING HEAD: %u\n", i, value);
78 
79 		value = readl_relaxed(ring->tqp->io_base +
80 				      HNS3_RING_RX_RING_FBDNUM_REG);
81 		dev_info(&h->pdev->dev, "RX(%d) RING FBDNUM: %u\n", i, value);
82 
83 		value = readl_relaxed(ring->tqp->io_base +
84 				      HNS3_RING_RX_RING_PKTNUM_RECORD_REG);
85 		dev_info(&h->pdev->dev, "RX(%d) RING PKTNUM: %u\n", i, value);
86 
87 		ring = ring_data[i].ring;
88 		base_add_h = readl_relaxed(ring->tqp->io_base +
89 					   HNS3_RING_TX_RING_BASEADDR_H_REG);
90 		base_add_l = readl_relaxed(ring->tqp->io_base +
91 					   HNS3_RING_TX_RING_BASEADDR_L_REG);
92 		dev_info(&h->pdev->dev, "TX(%d) BASE ADD: 0x%08x%08x\n", i,
93 			 base_add_h, base_add_l);
94 
95 		value = readl_relaxed(ring->tqp->io_base +
96 				      HNS3_RING_TX_RING_BD_NUM_REG);
97 		dev_info(&h->pdev->dev, "TX(%d) RING BD NUM: %u\n", i, value);
98 
99 		value = readl_relaxed(ring->tqp->io_base +
100 				      HNS3_RING_TX_RING_TC_REG);
101 		dev_info(&h->pdev->dev, "TX(%d) RING TC: %u\n", i, value);
102 
103 		value = readl_relaxed(ring->tqp->io_base +
104 				      HNS3_RING_TX_RING_TAIL_REG);
105 		dev_info(&h->pdev->dev, "TX(%d) RING TAIL: %u\n", i, value);
106 
107 		value = readl_relaxed(ring->tqp->io_base +
108 				      HNS3_RING_TX_RING_HEAD_REG);
109 		dev_info(&h->pdev->dev, "TX(%d) RING HEAD: %u\n", i, value);
110 
111 		value = readl_relaxed(ring->tqp->io_base +
112 				      HNS3_RING_TX_RING_FBDNUM_REG);
113 		dev_info(&h->pdev->dev, "TX(%d) RING FBDNUM: %u\n", i, value);
114 
115 		value = readl_relaxed(ring->tqp->io_base +
116 				      HNS3_RING_TX_RING_OFFSET_REG);
117 		dev_info(&h->pdev->dev, "TX(%d) RING OFFSET: %u\n", i, value);
118 
119 		value = readl_relaxed(ring->tqp->io_base +
120 				      HNS3_RING_TX_RING_PKTNUM_RECORD_REG);
121 		dev_info(&h->pdev->dev, "TX(%d) RING PKTNUM: %u\n\n", i,
122 			 value);
123 	}
124 
125 	return 0;
126 }
127 
128 static void hns3_dbg_help(struct hnae3_handle *h)
129 {
130 	dev_info(&h->pdev->dev, "available commands\n");
131 	dev_info(&h->pdev->dev, "queue info [number]\n");
132 	dev_info(&h->pdev->dev, "dump fd tcam\n");
133 	dev_info(&h->pdev->dev, "dump tc\n");
134 	dev_info(&h->pdev->dev, "dump tm\n");
135 	dev_info(&h->pdev->dev, "dump qos pause cfg\n");
136 	dev_info(&h->pdev->dev, "dump qos pri map\n");
137 	dev_info(&h->pdev->dev, "dump qos buf cfg\n");
138 }
139 
140 static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer,
141 				 size_t count, loff_t *ppos)
142 {
143 	int uncopy_bytes;
144 	char *buf;
145 	int len;
146 
147 	if (*ppos != 0)
148 		return 0;
149 
150 	if (count < HNS3_DBG_READ_LEN)
151 		return -ENOSPC;
152 
153 	buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL);
154 	if (!buf)
155 		return -ENOMEM;
156 
157 	len = snprintf(buf, HNS3_DBG_READ_LEN, "%s\n",
158 		       "Please echo help to cmd to get help information");
159 	uncopy_bytes = copy_to_user(buffer, buf, len);
160 
161 	kfree(buf);
162 
163 	if (uncopy_bytes)
164 		return -EFAULT;
165 
166 	return (*ppos = len);
167 }
168 
169 static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
170 				  size_t count, loff_t *ppos)
171 {
172 	struct hnae3_handle *handle = filp->private_data;
173 	struct hns3_nic_priv *priv  = handle->priv;
174 	char *cmd_buf, *cmd_buf_tmp;
175 	int uncopied_bytes;
176 	int ret = 0;
177 
178 	if (*ppos != 0)
179 		return 0;
180 
181 	/* Judge if the instance is being reset. */
182 	if (test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
183 	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
184 		return 0;
185 
186 	cmd_buf = kzalloc(count + 1, GFP_KERNEL);
187 	if (!cmd_buf)
188 		return count;
189 
190 	uncopied_bytes = copy_from_user(cmd_buf, buffer, count);
191 	if (uncopied_bytes) {
192 		kfree(cmd_buf);
193 		return -EFAULT;
194 	}
195 
196 	cmd_buf[count] = '\0';
197 
198 	cmd_buf_tmp = strchr(cmd_buf, '\n');
199 	if (cmd_buf_tmp) {
200 		*cmd_buf_tmp = '\0';
201 		count = cmd_buf_tmp - cmd_buf + 1;
202 	}
203 
204 	if (strncmp(cmd_buf, "help", 4) == 0)
205 		hns3_dbg_help(handle);
206 	else if (strncmp(cmd_buf, "queue info", 10) == 0)
207 		ret = hns3_dbg_queue_info(handle, cmd_buf);
208 	else if (handle->ae_algo->ops->dbg_run_cmd)
209 		ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);
210 
211 	if (ret)
212 		hns3_dbg_help(handle);
213 
214 	kfree(cmd_buf);
215 	cmd_buf = NULL;
216 
217 	return count;
218 }
219 
220 static const struct file_operations hns3_dbg_cmd_fops = {
221 	.owner = THIS_MODULE,
222 	.open  = simple_open,
223 	.read  = hns3_dbg_cmd_read,
224 	.write = hns3_dbg_cmd_write,
225 };
226 
227 void hns3_dbg_init(struct hnae3_handle *handle)
228 {
229 	const char *name = pci_name(handle->pdev);
230 	struct dentry *pfile;
231 
232 	handle->hnae3_dbgfs = debugfs_create_dir(name, hns3_dbgfs_root);
233 	if (!handle->hnae3_dbgfs)
234 		return;
235 
236 	pfile = debugfs_create_file("cmd", 0600, handle->hnae3_dbgfs, handle,
237 				    &hns3_dbg_cmd_fops);
238 	if (!pfile) {
239 		debugfs_remove_recursive(handle->hnae3_dbgfs);
240 		handle->hnae3_dbgfs = NULL;
241 		dev_warn(&handle->pdev->dev, "create file for %s fail\n",
242 			 name);
243 	}
244 }
245 
246 void hns3_dbg_uninit(struct hnae3_handle *handle)
247 {
248 	debugfs_remove_recursive(handle->hnae3_dbgfs);
249 	handle->hnae3_dbgfs = NULL;
250 }
251 
252 void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
253 {
254 	hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL);
255 	if (!hns3_dbgfs_root) {
256 		pr_warn("Register debugfs for %s fail\n", debugfs_dir_name);
257 		return;
258 	}
259 }
260 
261 void hns3_dbg_unregister_debugfs(void)
262 {
263 	debugfs_remove_recursive(hns3_dbgfs_root);
264 	hns3_dbgfs_root = NULL;
265 }
266