Commit | Line | Data |
---|---|---|
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 | |
7ac243f9 | 11 | #define HNS3_DBG_WRITE_LEN 1024 |
b2292360 | 12 | |
13 | static struct dentry *hns3_dbgfs_root; | |
14 | ||
ebaf1908 WL |
15 | static int hns3_dbg_queue_info(struct hnae3_handle *h, |
16 | const char *cmd_buf) | |
57ceee2c | 17 | { |
18 | struct hns3_nic_priv *priv = h->priv; | |
57ceee2c | 19 | struct hns3_enet_ring *ring; |
20 | u32 base_add_l, base_add_h; | |
21 | u32 queue_num, queue_max; | |
9d8d5a36 | 22 | u32 value, i; |
57ceee2c | 23 | int cnt; |
24 | ||
5f06b903 YL |
25 | if (!priv->ring) { |
26 | dev_err(&h->pdev->dev, "priv->ring is NULL\n"); | |
57ceee2c | 27 | return -EFAULT; |
28 | } | |
29 | ||
30 | queue_max = h->kinfo.num_tqps; | |
31 | cnt = kstrtouint(&cmd_buf[11], 0, &queue_num); | |
32 | if (cnt) | |
33 | queue_num = 0; | |
34 | else | |
35 | queue_max = queue_num + 1; | |
36 | ||
37 | dev_info(&h->pdev->dev, "queue info\n"); | |
38 | ||
39 | if (queue_num >= h->kinfo.num_tqps) { | |
40 | dev_err(&h->pdev->dev, | |
ed5b255b | 41 | "Queue number(%u) is out of range(0-%u)\n", queue_num, |
57ceee2c | 42 | h->kinfo.num_tqps - 1); |
43 | return -EINVAL; | |
44 | } | |
45 | ||
57ceee2c | 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 | */ | |
7737f1fb | 51 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
57ceee2c | 52 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) |
53 | return -EPERM; | |
54 | ||
5f06b903 | 55 | ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)]; |
57ceee2c | 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); | |
adcf738b | 60 | dev_info(&h->pdev->dev, "RX(%u) BASE ADD: 0x%08x%08x\n", i, |
57ceee2c | 61 | base_add_h, base_add_l); |
62 | ||
63 | value = readl_relaxed(ring->tqp->io_base + | |
64 | HNS3_RING_RX_RING_BD_NUM_REG); | |
adcf738b | 65 | dev_info(&h->pdev->dev, "RX(%u) RING BD NUM: %u\n", i, value); |
57ceee2c | 66 | |
67 | value = readl_relaxed(ring->tqp->io_base + | |
68 | HNS3_RING_RX_RING_BD_LEN_REG); | |
adcf738b | 69 | dev_info(&h->pdev->dev, "RX(%u) RING BD LEN: %u\n", i, value); |
57ceee2c | 70 | |
71 | value = readl_relaxed(ring->tqp->io_base + | |
72 | HNS3_RING_RX_RING_TAIL_REG); | |
adcf738b | 73 | dev_info(&h->pdev->dev, "RX(%u) RING TAIL: %u\n", i, value); |
57ceee2c | 74 | |
75 | value = readl_relaxed(ring->tqp->io_base + | |
76 | HNS3_RING_RX_RING_HEAD_REG); | |
adcf738b | 77 | dev_info(&h->pdev->dev, "RX(%u) RING HEAD: %u\n", i, value); |
57ceee2c | 78 | |
79 | value = readl_relaxed(ring->tqp->io_base + | |
80 | HNS3_RING_RX_RING_FBDNUM_REG); | |
adcf738b | 81 | dev_info(&h->pdev->dev, "RX(%u) RING FBDNUM: %u\n", i, value); |
57ceee2c | 82 | |
83 | value = readl_relaxed(ring->tqp->io_base + | |
84 | HNS3_RING_RX_RING_PKTNUM_RECORD_REG); | |
adcf738b | 85 | dev_info(&h->pdev->dev, "RX(%u) RING PKTNUM: %u\n", i, value); |
57ceee2c | 86 | |
5f06b903 | 87 | ring = &priv->ring[i]; |
57ceee2c | 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); | |
adcf738b | 92 | dev_info(&h->pdev->dev, "TX(%u) BASE ADD: 0x%08x%08x\n", i, |
57ceee2c | 93 | base_add_h, base_add_l); |
94 | ||
95 | value = readl_relaxed(ring->tqp->io_base + | |
96 | HNS3_RING_TX_RING_BD_NUM_REG); | |
adcf738b | 97 | dev_info(&h->pdev->dev, "TX(%u) RING BD NUM: %u\n", i, value); |
57ceee2c | 98 | |
99 | value = readl_relaxed(ring->tqp->io_base + | |
100 | HNS3_RING_TX_RING_TC_REG); | |
adcf738b | 101 | dev_info(&h->pdev->dev, "TX(%u) RING TC: %u\n", i, value); |
57ceee2c | 102 | |
103 | value = readl_relaxed(ring->tqp->io_base + | |
104 | HNS3_RING_TX_RING_TAIL_REG); | |
adcf738b | 105 | dev_info(&h->pdev->dev, "TX(%u) RING TAIL: %u\n", i, value); |
57ceee2c | 106 | |
107 | value = readl_relaxed(ring->tqp->io_base + | |
108 | HNS3_RING_TX_RING_HEAD_REG); | |
adcf738b | 109 | dev_info(&h->pdev->dev, "TX(%u) RING HEAD: %u\n", i, value); |
57ceee2c | 110 | |
111 | value = readl_relaxed(ring->tqp->io_base + | |
112 | HNS3_RING_TX_RING_FBDNUM_REG); | |
adcf738b | 113 | dev_info(&h->pdev->dev, "TX(%u) RING FBDNUM: %u\n", i, value); |
57ceee2c | 114 | |
115 | value = readl_relaxed(ring->tqp->io_base + | |
116 | HNS3_RING_TX_RING_OFFSET_REG); | |
adcf738b | 117 | dev_info(&h->pdev->dev, "TX(%u) RING OFFSET: %u\n", i, value); |
57ceee2c | 118 | |
119 | value = readl_relaxed(ring->tqp->io_base + | |
120 | HNS3_RING_TX_RING_PKTNUM_RECORD_REG); | |
adcf738b | 121 | dev_info(&h->pdev->dev, "TX(%u) RING PKTNUM: %u\n\n", i, |
57ceee2c | 122 | value); |
123 | } | |
124 | ||
125 | return 0; | |
126 | } | |
127 | ||
0c29d191 | 128 | static int hns3_dbg_queue_map(struct hnae3_handle *h) |
129 | { | |
130 | struct hns3_nic_priv *priv = h->priv; | |
0c29d191 | 131 | int i; |
132 | ||
133 | if (!h->ae_algo->ops->get_global_queue_id) | |
134 | return -EOPNOTSUPP; | |
135 | ||
136 | dev_info(&h->pdev->dev, "map info for queue id and vector id\n"); | |
137 | dev_info(&h->pdev->dev, | |
138 | "local queue id | global queue id | vector id\n"); | |
139 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
140 | u16 global_qid; | |
141 | ||
142 | global_qid = h->ae_algo->ops->get_global_queue_id(h, i); | |
5f06b903 | 143 | if (!priv->ring || !priv->ring[i].tqp_vector) |
0c29d191 | 144 | continue; |
145 | ||
146 | dev_info(&h->pdev->dev, | |
147 | " %4d %4d %4d\n", | |
5f06b903 | 148 | i, global_qid, priv->ring[i].tqp_vector->vector_irq); |
0c29d191 | 149 | } |
150 | ||
151 | return 0; | |
152 | } | |
153 | ||
ebaf1908 | 154 | static int hns3_dbg_bd_info(struct hnae3_handle *h, const char *cmd_buf) |
122bedc5 | 155 | { |
156 | struct hns3_nic_priv *priv = h->priv; | |
122bedc5 | 157 | struct hns3_desc *rx_desc, *tx_desc; |
158 | struct device *dev = &h->pdev->dev; | |
159 | struct hns3_enet_ring *ring; | |
160 | u32 tx_index, rx_index; | |
161 | u32 q_num, value; | |
96e65abb | 162 | dma_addr_t addr; |
122bedc5 | 163 | int cnt; |
164 | ||
165 | cnt = sscanf(&cmd_buf[8], "%u %u", &q_num, &tx_index); | |
166 | if (cnt == 2) { | |
167 | rx_index = tx_index; | |
168 | } else if (cnt != 1) { | |
169 | dev_err(dev, "bd info: bad command string, cnt=%d\n", cnt); | |
170 | return -EINVAL; | |
171 | } | |
172 | ||
173 | if (q_num >= h->kinfo.num_tqps) { | |
ed5b255b | 174 | dev_err(dev, "Queue number(%u) is out of range(0-%u)\n", q_num, |
122bedc5 | 175 | h->kinfo.num_tqps - 1); |
176 | return -EINVAL; | |
177 | } | |
178 | ||
e3105329 | 179 | ring = &priv->ring[q_num]; |
122bedc5 | 180 | value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG); |
181 | tx_index = (cnt == 1) ? value : tx_index; | |
182 | ||
183 | if (tx_index >= ring->desc_num) { | |
ed5b255b | 184 | dev_err(dev, "bd index(%u) is out of range(0-%u)\n", tx_index, |
122bedc5 | 185 | ring->desc_num - 1); |
186 | return -EINVAL; | |
187 | } | |
188 | ||
189 | tx_desc = &ring->desc[tx_index]; | |
96e65abb | 190 | addr = le64_to_cpu(tx_desc->addr); |
122bedc5 | 191 | dev_info(dev, "TX Queue Num: %u, BD Index: %u\n", q_num, tx_index); |
96e65abb | 192 | dev_info(dev, "(TX)addr: %pad\n", &addr); |
39edaf24 GL |
193 | dev_info(dev, "(TX)vlan_tag: %u\n", le16_to_cpu(tx_desc->tx.vlan_tag)); |
194 | dev_info(dev, "(TX)send_size: %u\n", | |
195 | le16_to_cpu(tx_desc->tx.send_size)); | |
122bedc5 | 196 | dev_info(dev, "(TX)vlan_tso: %u\n", tx_desc->tx.type_cs_vlan_tso); |
197 | dev_info(dev, "(TX)l2_len: %u\n", tx_desc->tx.l2_len); | |
198 | dev_info(dev, "(TX)l3_len: %u\n", tx_desc->tx.l3_len); | |
199 | dev_info(dev, "(TX)l4_len: %u\n", tx_desc->tx.l4_len); | |
39edaf24 GL |
200 | dev_info(dev, "(TX)vlan_tag: %u\n", |
201 | le16_to_cpu(tx_desc->tx.outer_vlan_tag)); | |
202 | dev_info(dev, "(TX)tv: %u\n", le16_to_cpu(tx_desc->tx.tv)); | |
122bedc5 | 203 | dev_info(dev, "(TX)vlan_msec: %u\n", tx_desc->tx.ol_type_vlan_msec); |
204 | dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len); | |
205 | dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len); | |
206 | dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len); | |
39edaf24 GL |
207 | dev_info(dev, "(TX)paylen: %u\n", le32_to_cpu(tx_desc->tx.paylen)); |
208 | dev_info(dev, "(TX)vld_ra_ri: %u\n", | |
209 | le16_to_cpu(tx_desc->tx.bdtp_fe_sc_vld_ra_ri)); | |
210 | dev_info(dev, "(TX)mss: %u\n", le16_to_cpu(tx_desc->tx.mss)); | |
122bedc5 | 211 | |
e3105329 | 212 | ring = &priv->ring[q_num + h->kinfo.num_tqps]; |
122bedc5 | 213 | value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_TAIL_REG); |
214 | rx_index = (cnt == 1) ? value : tx_index; | |
e3105329 | 215 | rx_desc = &ring->desc[rx_index]; |
122bedc5 | 216 | |
96e65abb | 217 | addr = le64_to_cpu(rx_desc->addr); |
122bedc5 | 218 | dev_info(dev, "RX Queue Num: %u, BD Index: %u\n", q_num, rx_index); |
96e65abb | 219 | dev_info(dev, "(RX)addr: %pad\n", &addr); |
39edaf24 GL |
220 | dev_info(dev, "(RX)l234_info: %u\n", |
221 | le32_to_cpu(rx_desc->rx.l234_info)); | |
222 | dev_info(dev, "(RX)pkt_len: %u\n", le16_to_cpu(rx_desc->rx.pkt_len)); | |
223 | dev_info(dev, "(RX)size: %u\n", le16_to_cpu(rx_desc->rx.size)); | |
224 | dev_info(dev, "(RX)rss_hash: %u\n", le32_to_cpu(rx_desc->rx.rss_hash)); | |
225 | dev_info(dev, "(RX)fd_id: %u\n", le16_to_cpu(rx_desc->rx.fd_id)); | |
226 | dev_info(dev, "(RX)vlan_tag: %u\n", le16_to_cpu(rx_desc->rx.vlan_tag)); | |
227 | dev_info(dev, "(RX)o_dm_vlan_id_fb: %u\n", | |
228 | le16_to_cpu(rx_desc->rx.o_dm_vlan_id_fb)); | |
229 | dev_info(dev, "(RX)ot_vlan_tag: %u\n", | |
230 | le16_to_cpu(rx_desc->rx.ot_vlan_tag)); | |
231 | dev_info(dev, "(RX)bd_base_info: %u\n", | |
232 | le32_to_cpu(rx_desc->rx.bd_base_info)); | |
122bedc5 | 233 | |
234 | return 0; | |
235 | } | |
236 | ||
b2292360 | 237 | static void hns3_dbg_help(struct hnae3_handle *h) |
238 | { | |
27cf979a | 239 | #define HNS3_DBG_BUF_LEN 256 |
240 | ||
241 | char printf_buf[HNS3_DBG_BUF_LEN]; | |
242 | ||
b2292360 | 243 | dev_info(&h->pdev->dev, "available commands\n"); |
ed5b255b | 244 | dev_info(&h->pdev->dev, "queue info <number>\n"); |
0c29d191 | 245 | dev_info(&h->pdev->dev, "queue map\n"); |
ed5b255b | 246 | dev_info(&h->pdev->dev, "bd info <q_num> <bd index>\n"); |
9484e337 | 247 | dev_info(&h->pdev->dev, "dev capability\n"); |
97afd47b YM |
248 | |
249 | if (!hns3_is_phys_func(h->pdev)) | |
250 | return; | |
251 | ||
b2292360 | 252 | dev_info(&h->pdev->dev, "dump fd tcam\n"); |
2849d4e7 | 253 | dev_info(&h->pdev->dev, "dump tc\n"); |
ed5b255b | 254 | dev_info(&h->pdev->dev, "dump tm map <q_num>\n"); |
96227f4c | 255 | dev_info(&h->pdev->dev, "dump tm\n"); |
d958919d | 256 | dev_info(&h->pdev->dev, "dump qos pause cfg\n"); |
6fc22440 | 257 | dev_info(&h->pdev->dev, "dump qos pri map\n"); |
7d9d7f88 | 258 | dev_info(&h->pdev->dev, "dump qos buf cfg\n"); |
7737f1fb | 259 | dev_info(&h->pdev->dev, "dump mng tbl\n"); |
f02eb82d | 260 | dev_info(&h->pdev->dev, "dump reset info\n"); |
33a90e2f | 261 | dev_info(&h->pdev->dev, "dump m7 info\n"); |
ffd140e2 | 262 | dev_info(&h->pdev->dev, "dump ncl_config <offset> <length>(in hex)\n"); |
a6345787 | 263 | dev_info(&h->pdev->dev, "dump mac tnl status\n"); |
ded45d40 | 264 | dev_info(&h->pdev->dev, "dump loopback\n"); |
89ec9485 | 265 | dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); |
f671237a JS |
266 | dev_info(&h->pdev->dev, "dump uc mac list <func id>\n"); |
267 | dev_info(&h->pdev->dev, "dump mc mac list <func id>\n"); | |
348775eb | 268 | dev_info(&h->pdev->dev, "dump intr\n"); |
27cf979a | 269 | |
270 | memset(printf_buf, 0, HNS3_DBG_BUF_LEN); | |
ed5b255b | 271 | strncat(printf_buf, "dump reg [[bios common] [ssu <port_id>]", |
27cf979a | 272 | HNS3_DBG_BUF_LEN - 1); |
273 | strncat(printf_buf + strlen(printf_buf), | |
ed5b255b | 274 | " [igu egu <port_id>] [rpu <tc_queue_num>]", |
27cf979a | 275 | HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1); |
276 | strncat(printf_buf + strlen(printf_buf), | |
5cb51cfe | 277 | " [rtc] [ppp] [rcb] [tqp <queue_num>] [mac]]\n", |
27cf979a | 278 | HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1); |
279 | dev_info(&h->pdev->dev, "%s", printf_buf); | |
c0ebebb9 | 280 | |
281 | memset(printf_buf, 0, HNS3_DBG_BUF_LEN); | |
ed5b255b | 282 | strncat(printf_buf, "dump reg dcb <port_id> <pri_id> <pg_id>", |
c0ebebb9 | 283 | HNS3_DBG_BUF_LEN - 1); |
ed5b255b | 284 | strncat(printf_buf + strlen(printf_buf), " <rq_id> <nq_id> <qset_id>\n", |
c0ebebb9 | 285 | HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1); |
286 | dev_info(&h->pdev->dev, "%s", printf_buf); | |
b2292360 | 287 | } |
288 | ||
9484e337 GH |
289 | static void hns3_dbg_dev_caps(struct hnae3_handle *h) |
290 | { | |
291 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
292 | unsigned long *caps; | |
293 | ||
294 | caps = ae_dev->caps; | |
295 | ||
296 | dev_info(&h->pdev->dev, "support FD: %s\n", | |
297 | test_bit(HNAE3_DEV_SUPPORT_FD_B, caps) ? "yes" : "no"); | |
298 | dev_info(&h->pdev->dev, "support GRO: %s\n", | |
299 | test_bit(HNAE3_DEV_SUPPORT_GRO_B, caps) ? "yes" : "no"); | |
300 | dev_info(&h->pdev->dev, "support FEC: %s\n", | |
301 | test_bit(HNAE3_DEV_SUPPORT_FEC_B, caps) ? "yes" : "no"); | |
302 | dev_info(&h->pdev->dev, "support UDP GSO: %s\n", | |
303 | test_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, caps) ? "yes" : "no"); | |
304 | dev_info(&h->pdev->dev, "support PTP: %s\n", | |
305 | test_bit(HNAE3_DEV_SUPPORT_PTP_B, caps) ? "yes" : "no"); | |
306 | dev_info(&h->pdev->dev, "support INT QL: %s\n", | |
307 | test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, caps) ? "yes" : "no"); | |
308 | } | |
309 | ||
b2292360 | 310 | static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer, |
311 | size_t count, loff_t *ppos) | |
312 | { | |
313 | int uncopy_bytes; | |
314 | char *buf; | |
315 | int len; | |
316 | ||
317 | if (*ppos != 0) | |
318 | return 0; | |
319 | ||
320 | if (count < HNS3_DBG_READ_LEN) | |
321 | return -ENOSPC; | |
322 | ||
323 | buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL); | |
324 | if (!buf) | |
325 | return -ENOMEM; | |
326 | ||
49e211c0 CZ |
327 | len = scnprintf(buf, HNS3_DBG_READ_LEN, "%s\n", |
328 | "Please echo help to cmd to get help information"); | |
b2292360 | 329 | uncopy_bytes = copy_to_user(buffer, buf, len); |
330 | ||
331 | kfree(buf); | |
332 | ||
333 | if (uncopy_bytes) | |
334 | return -EFAULT; | |
335 | ||
336 | return (*ppos = len); | |
337 | } | |
338 | ||
339 | static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer, | |
340 | size_t count, loff_t *ppos) | |
341 | { | |
342 | struct hnae3_handle *handle = filp->private_data; | |
57ceee2c | 343 | struct hns3_nic_priv *priv = handle->priv; |
b2292360 | 344 | char *cmd_buf, *cmd_buf_tmp; |
345 | int uncopied_bytes; | |
346 | int ret = 0; | |
347 | ||
348 | if (*ppos != 0) | |
349 | return 0; | |
350 | ||
57ceee2c | 351 | /* Judge if the instance is being reset. */ |
7737f1fb | 352 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
57ceee2c | 353 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) |
354 | return 0; | |
355 | ||
7ac243f9 YM |
356 | if (count > HNS3_DBG_WRITE_LEN) |
357 | return -ENOSPC; | |
358 | ||
b2292360 | 359 | cmd_buf = kzalloc(count + 1, GFP_KERNEL); |
360 | if (!cmd_buf) | |
361 | return count; | |
362 | ||
363 | uncopied_bytes = copy_from_user(cmd_buf, buffer, count); | |
364 | if (uncopied_bytes) { | |
365 | kfree(cmd_buf); | |
366 | return -EFAULT; | |
367 | } | |
368 | ||
369 | cmd_buf[count] = '\0'; | |
370 | ||
371 | cmd_buf_tmp = strchr(cmd_buf, '\n'); | |
372 | if (cmd_buf_tmp) { | |
373 | *cmd_buf_tmp = '\0'; | |
374 | count = cmd_buf_tmp - cmd_buf + 1; | |
375 | } | |
376 | ||
377 | if (strncmp(cmd_buf, "help", 4) == 0) | |
378 | hns3_dbg_help(handle); | |
57ceee2c | 379 | else if (strncmp(cmd_buf, "queue info", 10) == 0) |
380 | ret = hns3_dbg_queue_info(handle, cmd_buf); | |
0c29d191 | 381 | else if (strncmp(cmd_buf, "queue map", 9) == 0) |
382 | ret = hns3_dbg_queue_map(handle); | |
122bedc5 | 383 | else if (strncmp(cmd_buf, "bd info", 7) == 0) |
384 | ret = hns3_dbg_bd_info(handle, cmd_buf); | |
9484e337 GH |
385 | else if (strncmp(cmd_buf, "dev capability", 14) == 0) |
386 | hns3_dbg_dev_caps(handle); | |
3c666b58 | 387 | else if (handle->ae_algo->ops->dbg_run_cmd) |
388 | ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf); | |
97afd47b YM |
389 | else |
390 | ret = -EOPNOTSUPP; | |
b2292360 | 391 | |
392 | if (ret) | |
393 | hns3_dbg_help(handle); | |
394 | ||
395 | kfree(cmd_buf); | |
396 | cmd_buf = NULL; | |
397 | ||
398 | return count; | |
399 | } | |
400 | ||
401 | static const struct file_operations hns3_dbg_cmd_fops = { | |
402 | .owner = THIS_MODULE, | |
403 | .open = simple_open, | |
404 | .read = hns3_dbg_cmd_read, | |
405 | .write = hns3_dbg_cmd_write, | |
406 | }; | |
407 | ||
408 | void hns3_dbg_init(struct hnae3_handle *handle) | |
409 | { | |
410 | const char *name = pci_name(handle->pdev); | |
b2292360 | 411 | |
412 | handle->hnae3_dbgfs = debugfs_create_dir(name, hns3_dbgfs_root); | |
b2292360 | 413 | |
11ab11e6 GKH |
414 | debugfs_create_file("cmd", 0600, handle->hnae3_dbgfs, handle, |
415 | &hns3_dbg_cmd_fops); | |
b2292360 | 416 | } |
417 | ||
418 | void hns3_dbg_uninit(struct hnae3_handle *handle) | |
419 | { | |
420 | debugfs_remove_recursive(handle->hnae3_dbgfs); | |
421 | handle->hnae3_dbgfs = NULL; | |
422 | } | |
423 | ||
424 | void hns3_dbg_register_debugfs(const char *debugfs_dir_name) | |
425 | { | |
426 | hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL); | |
b2292360 | 427 | } |
428 | ||
429 | void hns3_dbg_unregister_debugfs(void) | |
430 | { | |
431 | debugfs_remove_recursive(hns3_dbgfs_root); | |
432 | hns3_dbgfs_root = NULL; | |
433 | } |