net: hns3: Add "tc config" info query function
[linux-block.git] / drivers / net / ethernet / hisilicon / hns3 / hns3_debugfs.c
CommitLineData
b2292360 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
12static struct dentry *hns3_dbgfs_root;
13
57ceee2c 14static 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
b2292360 128static 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");
2849d4e7 133 dev_info(&h->pdev->dev, "dump tc\n");
b2292360 134}
135
136static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer,
137 size_t count, loff_t *ppos)
138{
139 int uncopy_bytes;
140 char *buf;
141 int len;
142
143 if (*ppos != 0)
144 return 0;
145
146 if (count < HNS3_DBG_READ_LEN)
147 return -ENOSPC;
148
149 buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL);
150 if (!buf)
151 return -ENOMEM;
152
153 len = snprintf(buf, HNS3_DBG_READ_LEN, "%s\n",
154 "Please echo help to cmd to get help information");
155 uncopy_bytes = copy_to_user(buffer, buf, len);
156
157 kfree(buf);
158
159 if (uncopy_bytes)
160 return -EFAULT;
161
162 return (*ppos = len);
163}
164
165static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
166 size_t count, loff_t *ppos)
167{
168 struct hnae3_handle *handle = filp->private_data;
57ceee2c 169 struct hns3_nic_priv *priv = handle->priv;
b2292360 170 char *cmd_buf, *cmd_buf_tmp;
171 int uncopied_bytes;
172 int ret = 0;
173
174 if (*ppos != 0)
175 return 0;
176
57ceee2c 177 /* Judge if the instance is being reset. */
178 if (test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
179 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
180 return 0;
181
b2292360 182 cmd_buf = kzalloc(count + 1, GFP_KERNEL);
183 if (!cmd_buf)
184 return count;
185
186 uncopied_bytes = copy_from_user(cmd_buf, buffer, count);
187 if (uncopied_bytes) {
188 kfree(cmd_buf);
189 return -EFAULT;
190 }
191
192 cmd_buf[count] = '\0';
193
194 cmd_buf_tmp = strchr(cmd_buf, '\n');
195 if (cmd_buf_tmp) {
196 *cmd_buf_tmp = '\0';
197 count = cmd_buf_tmp - cmd_buf + 1;
198 }
199
200 if (strncmp(cmd_buf, "help", 4) == 0)
201 hns3_dbg_help(handle);
57ceee2c 202 else if (strncmp(cmd_buf, "queue info", 10) == 0)
203 ret = hns3_dbg_queue_info(handle, cmd_buf);
3c666b58 204 else if (handle->ae_algo->ops->dbg_run_cmd)
205 ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);
b2292360 206
207 if (ret)
208 hns3_dbg_help(handle);
209
210 kfree(cmd_buf);
211 cmd_buf = NULL;
212
213 return count;
214}
215
216static const struct file_operations hns3_dbg_cmd_fops = {
217 .owner = THIS_MODULE,
218 .open = simple_open,
219 .read = hns3_dbg_cmd_read,
220 .write = hns3_dbg_cmd_write,
221};
222
223void hns3_dbg_init(struct hnae3_handle *handle)
224{
225 const char *name = pci_name(handle->pdev);
226 struct dentry *pfile;
227
228 handle->hnae3_dbgfs = debugfs_create_dir(name, hns3_dbgfs_root);
229 if (!handle->hnae3_dbgfs)
230 return;
231
232 pfile = debugfs_create_file("cmd", 0600, handle->hnae3_dbgfs, handle,
233 &hns3_dbg_cmd_fops);
234 if (!pfile) {
235 debugfs_remove_recursive(handle->hnae3_dbgfs);
236 handle->hnae3_dbgfs = NULL;
237 dev_warn(&handle->pdev->dev, "create file for %s fail\n",
238 name);
239 }
240}
241
242void hns3_dbg_uninit(struct hnae3_handle *handle)
243{
244 debugfs_remove_recursive(handle->hnae3_dbgfs);
245 handle->hnae3_dbgfs = NULL;
246}
247
248void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
249{
250 hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL);
251 if (!hns3_dbgfs_root) {
252 pr_warn("Register debugfs for %s fail\n", debugfs_dir_name);
253 return;
254 }
255}
256
257void hns3_dbg_unregister_debugfs(void)
258{
259 debugfs_remove_recursive(hns3_dbgfs_root);
260 hns3_dbgfs_root = NULL;
261}