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"); |
b4442ec5 | 248 | dev_info(&h->pdev->dev, "dev spec\n"); |
97afd47b YM |
249 | |
250 | if (!hns3_is_phys_func(h->pdev)) | |
251 | return; | |
252 | ||
b2292360 | 253 | dev_info(&h->pdev->dev, "dump fd tcam\n"); |
2849d4e7 | 254 | dev_info(&h->pdev->dev, "dump tc\n"); |
ed5b255b | 255 | dev_info(&h->pdev->dev, "dump tm map <q_num>\n"); |
96227f4c | 256 | dev_info(&h->pdev->dev, "dump tm\n"); |
d958919d | 257 | dev_info(&h->pdev->dev, "dump qos pause cfg\n"); |
6fc22440 | 258 | dev_info(&h->pdev->dev, "dump qos pri map\n"); |
7d9d7f88 | 259 | dev_info(&h->pdev->dev, "dump qos buf cfg\n"); |
7737f1fb | 260 | dev_info(&h->pdev->dev, "dump mng tbl\n"); |
f02eb82d | 261 | dev_info(&h->pdev->dev, "dump reset info\n"); |
33a90e2f | 262 | dev_info(&h->pdev->dev, "dump m7 info\n"); |
ffd140e2 | 263 | dev_info(&h->pdev->dev, "dump ncl_config <offset> <length>(in hex)\n"); |
a6345787 | 264 | dev_info(&h->pdev->dev, "dump mac tnl status\n"); |
ded45d40 | 265 | dev_info(&h->pdev->dev, "dump loopback\n"); |
89ec9485 | 266 | dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); |
f671237a JS |
267 | dev_info(&h->pdev->dev, "dump uc mac list <func id>\n"); |
268 | dev_info(&h->pdev->dev, "dump mc mac list <func id>\n"); | |
348775eb | 269 | dev_info(&h->pdev->dev, "dump intr\n"); |
27cf979a | 270 | |
271 | memset(printf_buf, 0, HNS3_DBG_BUF_LEN); | |
ed5b255b | 272 | strncat(printf_buf, "dump reg [[bios common] [ssu <port_id>]", |
27cf979a | 273 | HNS3_DBG_BUF_LEN - 1); |
274 | strncat(printf_buf + strlen(printf_buf), | |
ed5b255b | 275 | " [igu egu <port_id>] [rpu <tc_queue_num>]", |
27cf979a | 276 | HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1); |
277 | strncat(printf_buf + strlen(printf_buf), | |
5cb51cfe | 278 | " [rtc] [ppp] [rcb] [tqp <queue_num>] [mac]]\n", |
27cf979a | 279 | HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1); |
280 | dev_info(&h->pdev->dev, "%s", printf_buf); | |
c0ebebb9 | 281 | |
282 | memset(printf_buf, 0, HNS3_DBG_BUF_LEN); | |
ed5b255b | 283 | strncat(printf_buf, "dump reg dcb <port_id> <pri_id> <pg_id>", |
c0ebebb9 | 284 | HNS3_DBG_BUF_LEN - 1); |
ed5b255b | 285 | strncat(printf_buf + strlen(printf_buf), " <rq_id> <nq_id> <qset_id>\n", |
c0ebebb9 | 286 | HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1); |
287 | dev_info(&h->pdev->dev, "%s", printf_buf); | |
b2292360 | 288 | } |
289 | ||
9484e337 GH |
290 | static void hns3_dbg_dev_caps(struct hnae3_handle *h) |
291 | { | |
292 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
293 | unsigned long *caps; | |
294 | ||
295 | caps = ae_dev->caps; | |
296 | ||
297 | dev_info(&h->pdev->dev, "support FD: %s\n", | |
298 | test_bit(HNAE3_DEV_SUPPORT_FD_B, caps) ? "yes" : "no"); | |
299 | dev_info(&h->pdev->dev, "support GRO: %s\n", | |
300 | test_bit(HNAE3_DEV_SUPPORT_GRO_B, caps) ? "yes" : "no"); | |
301 | dev_info(&h->pdev->dev, "support FEC: %s\n", | |
302 | test_bit(HNAE3_DEV_SUPPORT_FEC_B, caps) ? "yes" : "no"); | |
303 | dev_info(&h->pdev->dev, "support UDP GSO: %s\n", | |
304 | test_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, caps) ? "yes" : "no"); | |
305 | dev_info(&h->pdev->dev, "support PTP: %s\n", | |
306 | test_bit(HNAE3_DEV_SUPPORT_PTP_B, caps) ? "yes" : "no"); | |
307 | dev_info(&h->pdev->dev, "support INT QL: %s\n", | |
308 | test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, caps) ? "yes" : "no"); | |
309 | } | |
310 | ||
b4442ec5 GH |
311 | static void hns3_dbg_dev_specs(struct hnae3_handle *h) |
312 | { | |
313 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
314 | struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs; | |
315 | struct hnae3_knic_private_info *kinfo = &h->kinfo; | |
316 | struct hns3_nic_priv *priv = h->priv; | |
317 | ||
318 | dev_info(priv->dev, "MAC entry num: %u\n", dev_specs->mac_entry_num); | |
319 | dev_info(priv->dev, "MNG entry num: %u\n", dev_specs->mng_entry_num); | |
320 | dev_info(priv->dev, "MAX non tso bd num: %u\n", | |
321 | dev_specs->max_non_tso_bd_num); | |
322 | dev_info(priv->dev, "RSS ind tbl size: %u\n", | |
323 | dev_specs->rss_ind_tbl_size); | |
324 | dev_info(priv->dev, "RSS key size: %u\n", dev_specs->rss_key_size); | |
325 | dev_info(priv->dev, "RSS size: %u\n", kinfo->rss_size); | |
326 | dev_info(priv->dev, "Allocated RSS size: %u\n", kinfo->req_rss_size); | |
327 | dev_info(priv->dev, "Task queue pairs numbers: %u\n", kinfo->num_tqps); | |
328 | ||
329 | dev_info(priv->dev, "RX buffer length: %u\n", kinfo->rx_buf_len); | |
330 | dev_info(priv->dev, "Desc num per TX queue: %u\n", kinfo->num_tx_desc); | |
331 | dev_info(priv->dev, "Desc num per RX queue: %u\n", kinfo->num_rx_desc); | |
332 | dev_info(priv->dev, "Total number of enabled TCs: %u\n", kinfo->num_tc); | |
333 | dev_info(priv->dev, "MAX INT QL: %u\n", dev_specs->int_ql_max); | |
334 | } | |
335 | ||
b2292360 | 336 | static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer, |
337 | size_t count, loff_t *ppos) | |
338 | { | |
339 | int uncopy_bytes; | |
340 | char *buf; | |
341 | int len; | |
342 | ||
343 | if (*ppos != 0) | |
344 | return 0; | |
345 | ||
346 | if (count < HNS3_DBG_READ_LEN) | |
347 | return -ENOSPC; | |
348 | ||
349 | buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL); | |
350 | if (!buf) | |
351 | return -ENOMEM; | |
352 | ||
49e211c0 CZ |
353 | len = scnprintf(buf, HNS3_DBG_READ_LEN, "%s\n", |
354 | "Please echo help to cmd to get help information"); | |
b2292360 | 355 | uncopy_bytes = copy_to_user(buffer, buf, len); |
356 | ||
357 | kfree(buf); | |
358 | ||
359 | if (uncopy_bytes) | |
360 | return -EFAULT; | |
361 | ||
362 | return (*ppos = len); | |
363 | } | |
364 | ||
365 | static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer, | |
366 | size_t count, loff_t *ppos) | |
367 | { | |
368 | struct hnae3_handle *handle = filp->private_data; | |
57ceee2c | 369 | struct hns3_nic_priv *priv = handle->priv; |
b2292360 | 370 | char *cmd_buf, *cmd_buf_tmp; |
371 | int uncopied_bytes; | |
372 | int ret = 0; | |
373 | ||
374 | if (*ppos != 0) | |
375 | return 0; | |
376 | ||
57ceee2c | 377 | /* Judge if the instance is being reset. */ |
7737f1fb | 378 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
57ceee2c | 379 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) |
380 | return 0; | |
381 | ||
7ac243f9 YM |
382 | if (count > HNS3_DBG_WRITE_LEN) |
383 | return -ENOSPC; | |
384 | ||
b2292360 | 385 | cmd_buf = kzalloc(count + 1, GFP_KERNEL); |
386 | if (!cmd_buf) | |
387 | return count; | |
388 | ||
389 | uncopied_bytes = copy_from_user(cmd_buf, buffer, count); | |
390 | if (uncopied_bytes) { | |
391 | kfree(cmd_buf); | |
392 | return -EFAULT; | |
393 | } | |
394 | ||
395 | cmd_buf[count] = '\0'; | |
396 | ||
397 | cmd_buf_tmp = strchr(cmd_buf, '\n'); | |
398 | if (cmd_buf_tmp) { | |
399 | *cmd_buf_tmp = '\0'; | |
400 | count = cmd_buf_tmp - cmd_buf + 1; | |
401 | } | |
402 | ||
403 | if (strncmp(cmd_buf, "help", 4) == 0) | |
404 | hns3_dbg_help(handle); | |
57ceee2c | 405 | else if (strncmp(cmd_buf, "queue info", 10) == 0) |
406 | ret = hns3_dbg_queue_info(handle, cmd_buf); | |
0c29d191 | 407 | else if (strncmp(cmd_buf, "queue map", 9) == 0) |
408 | ret = hns3_dbg_queue_map(handle); | |
122bedc5 | 409 | else if (strncmp(cmd_buf, "bd info", 7) == 0) |
410 | ret = hns3_dbg_bd_info(handle, cmd_buf); | |
9484e337 GH |
411 | else if (strncmp(cmd_buf, "dev capability", 14) == 0) |
412 | hns3_dbg_dev_caps(handle); | |
b4442ec5 GH |
413 | else if (strncmp(cmd_buf, "dev spec", 8) == 0) |
414 | hns3_dbg_dev_specs(handle); | |
3c666b58 | 415 | else if (handle->ae_algo->ops->dbg_run_cmd) |
416 | ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf); | |
97afd47b YM |
417 | else |
418 | ret = -EOPNOTSUPP; | |
b2292360 | 419 | |
420 | if (ret) | |
421 | hns3_dbg_help(handle); | |
422 | ||
423 | kfree(cmd_buf); | |
424 | cmd_buf = NULL; | |
425 | ||
426 | return count; | |
427 | } | |
428 | ||
429 | static const struct file_operations hns3_dbg_cmd_fops = { | |
430 | .owner = THIS_MODULE, | |
431 | .open = simple_open, | |
432 | .read = hns3_dbg_cmd_read, | |
433 | .write = hns3_dbg_cmd_write, | |
434 | }; | |
435 | ||
436 | void hns3_dbg_init(struct hnae3_handle *handle) | |
437 | { | |
438 | const char *name = pci_name(handle->pdev); | |
b2292360 | 439 | |
440 | handle->hnae3_dbgfs = debugfs_create_dir(name, hns3_dbgfs_root); | |
b2292360 | 441 | |
11ab11e6 GKH |
442 | debugfs_create_file("cmd", 0600, handle->hnae3_dbgfs, handle, |
443 | &hns3_dbg_cmd_fops); | |
b2292360 | 444 | } |
445 | ||
446 | void hns3_dbg_uninit(struct hnae3_handle *handle) | |
447 | { | |
448 | debugfs_remove_recursive(handle->hnae3_dbgfs); | |
449 | handle->hnae3_dbgfs = NULL; | |
450 | } | |
451 | ||
452 | void hns3_dbg_register_debugfs(const char *debugfs_dir_name) | |
453 | { | |
454 | hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL); | |
b2292360 | 455 | } |
456 | ||
457 | void hns3_dbg_unregister_debugfs(void) | |
458 | { | |
459 | debugfs_remove_recursive(hns3_dbgfs_root); | |
460 | hns3_dbgfs_root = NULL; | |
461 | } |