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" | |
5e69ea7e | 8 | #include "hns3_debugfs.h" |
b2292360 | 9 | #include "hns3_enet.h" |
10 | ||
b2292360 | 11 | static struct dentry *hns3_dbgfs_root; |
12 | ||
5e69ea7e YM |
13 | static struct hns3_dbg_dentry_info hns3_dbg_dentry[] = { |
14 | { | |
15 | .name = "tm" | |
16 | }, | |
77e91848 HT |
17 | { |
18 | .name = "tx_bd_info" | |
19 | }, | |
20 | { | |
21 | .name = "rx_bd_info" | |
22 | }, | |
1556ea91 HT |
23 | { |
24 | .name = "mac_list" | |
25 | }, | |
d96b0e59 YM |
26 | { |
27 | .name = "reg" | |
28 | }, | |
d2f737cf HC |
29 | { |
30 | .name = "queue" | |
31 | }, | |
5e69ea7e YM |
32 | /* keep common at the bottom and add new directory above */ |
33 | { | |
34 | .name = "common" | |
35 | }, | |
36 | }; | |
37 | ||
77e91848 | 38 | static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, unsigned int cmd); |
5e69ea7e YM |
39 | static int hns3_dbg_common_file_init(struct hnae3_handle *handle, |
40 | unsigned int cmd); | |
41 | ||
42 | static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = { | |
43 | { | |
44 | .name = "tm_nodes", | |
45 | .cmd = HNAE3_DBG_CMD_TM_NODES, | |
46 | .dentry = HNS3_DBG_DENTRY_TM, | |
47 | .buf_len = HNS3_DBG_READ_LEN, | |
48 | .init = hns3_dbg_common_file_init, | |
49 | }, | |
50 | { | |
51 | .name = "tm_priority", | |
52 | .cmd = HNAE3_DBG_CMD_TM_PRI, | |
53 | .dentry = HNS3_DBG_DENTRY_TM, | |
54 | .buf_len = HNS3_DBG_READ_LEN, | |
55 | .init = hns3_dbg_common_file_init, | |
56 | }, | |
57 | { | |
58 | .name = "tm_qset", | |
59 | .cmd = HNAE3_DBG_CMD_TM_QSET, | |
60 | .dentry = HNS3_DBG_DENTRY_TM, | |
61 | .buf_len = HNS3_DBG_READ_LEN, | |
62 | .init = hns3_dbg_common_file_init, | |
63 | }, | |
c929bc2a JZ |
64 | { |
65 | .name = "dev_info", | |
66 | .cmd = HNAE3_DBG_CMD_DEV_INFO, | |
67 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
68 | .buf_len = HNS3_DBG_READ_LEN, | |
69 | .init = hns3_dbg_common_file_init, | |
70 | }, | |
77e91848 HT |
71 | { |
72 | .name = "tx_bd_queue", | |
73 | .cmd = HNAE3_DBG_CMD_TX_BD, | |
74 | .dentry = HNS3_DBG_DENTRY_TX_BD, | |
75 | .buf_len = HNS3_DBG_READ_LEN_4MB, | |
76 | .init = hns3_dbg_bd_file_init, | |
77 | }, | |
78 | { | |
79 | .name = "rx_bd_queue", | |
80 | .cmd = HNAE3_DBG_CMD_RX_BD, | |
81 | .dentry = HNS3_DBG_DENTRY_RX_BD, | |
82 | .buf_len = HNS3_DBG_READ_LEN_4MB, | |
83 | .init = hns3_dbg_bd_file_init, | |
84 | }, | |
1556ea91 HT |
85 | { |
86 | .name = "uc", | |
87 | .cmd = HNAE3_DBG_CMD_MAC_UC, | |
88 | .dentry = HNS3_DBG_DENTRY_MAC, | |
89 | .buf_len = HNS3_DBG_READ_LEN, | |
90 | .init = hns3_dbg_common_file_init, | |
91 | }, | |
92 | { | |
93 | .name = "mc", | |
94 | .cmd = HNAE3_DBG_CMD_MAC_MC, | |
95 | .dentry = HNS3_DBG_DENTRY_MAC, | |
96 | .buf_len = HNS3_DBG_READ_LEN, | |
97 | .init = hns3_dbg_common_file_init, | |
98 | }, | |
8ddfd9c4 YM |
99 | { |
100 | .name = "mng_tbl", | |
101 | .cmd = HNAE3_DBG_CMD_MNG_TBL, | |
102 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
103 | .buf_len = HNS3_DBG_READ_LEN, | |
104 | .init = hns3_dbg_common_file_init, | |
105 | }, | |
d658ff34 YM |
106 | { |
107 | .name = "loopback", | |
108 | .cmd = HNAE3_DBG_CMD_LOOPBACK, | |
109 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
110 | .buf_len = HNS3_DBG_READ_LEN, | |
111 | .init = hns3_dbg_common_file_init, | |
112 | }, | |
9149ca0f JZ |
113 | { |
114 | .name = "interrupt_info", | |
115 | .cmd = HNAE3_DBG_CMD_INTERRUPT_INFO, | |
116 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
117 | .buf_len = HNS3_DBG_READ_LEN, | |
118 | .init = hns3_dbg_common_file_init, | |
119 | }, | |
1a7ff828 JZ |
120 | { |
121 | .name = "reset_info", | |
122 | .cmd = HNAE3_DBG_CMD_RESET_INFO, | |
123 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
124 | .buf_len = HNS3_DBG_READ_LEN, | |
125 | .init = hns3_dbg_common_file_init, | |
126 | }, | |
0b198b0d JZ |
127 | { |
128 | .name = "imp_info", | |
129 | .cmd = HNAE3_DBG_CMD_IMP_INFO, | |
130 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
131 | .buf_len = HNS3_DBG_READ_LEN, | |
132 | .init = hns3_dbg_common_file_init, | |
133 | }, | |
e76e6886 JZ |
134 | { |
135 | .name = "ncl_config", | |
136 | .cmd = HNAE3_DBG_CMD_NCL_CONFIG, | |
137 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
138 | .buf_len = HNS3_DBG_READ_LEN_128KB, | |
139 | .init = hns3_dbg_common_file_init, | |
140 | }, | |
d96b0e59 YM |
141 | { |
142 | .name = "bios_common", | |
143 | .cmd = HNAE3_DBG_CMD_REG_BIOS_COMMON, | |
144 | .dentry = HNS3_DBG_DENTRY_REG, | |
145 | .buf_len = HNS3_DBG_READ_LEN, | |
146 | .init = hns3_dbg_common_file_init, | |
147 | }, | |
148 | { | |
149 | .name = "ssu", | |
150 | .cmd = HNAE3_DBG_CMD_REG_SSU, | |
151 | .dentry = HNS3_DBG_DENTRY_REG, | |
152 | .buf_len = HNS3_DBG_READ_LEN, | |
153 | .init = hns3_dbg_common_file_init, | |
154 | }, | |
155 | { | |
156 | .name = "igu_egu", | |
157 | .cmd = HNAE3_DBG_CMD_REG_IGU_EGU, | |
158 | .dentry = HNS3_DBG_DENTRY_REG, | |
159 | .buf_len = HNS3_DBG_READ_LEN, | |
160 | .init = hns3_dbg_common_file_init, | |
161 | }, | |
162 | { | |
163 | .name = "rpu", | |
164 | .cmd = HNAE3_DBG_CMD_REG_RPU, | |
165 | .dentry = HNS3_DBG_DENTRY_REG, | |
166 | .buf_len = HNS3_DBG_READ_LEN, | |
167 | .init = hns3_dbg_common_file_init, | |
168 | }, | |
169 | { | |
170 | .name = "ncsi", | |
171 | .cmd = HNAE3_DBG_CMD_REG_NCSI, | |
172 | .dentry = HNS3_DBG_DENTRY_REG, | |
173 | .buf_len = HNS3_DBG_READ_LEN, | |
174 | .init = hns3_dbg_common_file_init, | |
175 | }, | |
176 | { | |
177 | .name = "rtc", | |
178 | .cmd = HNAE3_DBG_CMD_REG_RTC, | |
179 | .dentry = HNS3_DBG_DENTRY_REG, | |
180 | .buf_len = HNS3_DBG_READ_LEN, | |
181 | .init = hns3_dbg_common_file_init, | |
182 | }, | |
183 | { | |
184 | .name = "ppp", | |
185 | .cmd = HNAE3_DBG_CMD_REG_PPP, | |
186 | .dentry = HNS3_DBG_DENTRY_REG, | |
187 | .buf_len = HNS3_DBG_READ_LEN, | |
188 | .init = hns3_dbg_common_file_init, | |
189 | }, | |
190 | { | |
191 | .name = "rcb", | |
192 | .cmd = HNAE3_DBG_CMD_REG_RCB, | |
193 | .dentry = HNS3_DBG_DENTRY_REG, | |
194 | .buf_len = HNS3_DBG_READ_LEN, | |
195 | .init = hns3_dbg_common_file_init, | |
196 | }, | |
197 | { | |
198 | .name = "tqp", | |
199 | .cmd = HNAE3_DBG_CMD_REG_TQP, | |
200 | .dentry = HNS3_DBG_DENTRY_REG, | |
201 | .buf_len = HNS3_DBG_READ_LEN, | |
202 | .init = hns3_dbg_common_file_init, | |
203 | }, | |
204 | { | |
205 | .name = "mac", | |
206 | .cmd = HNAE3_DBG_CMD_REG_MAC, | |
207 | .dentry = HNS3_DBG_DENTRY_REG, | |
208 | .buf_len = HNS3_DBG_READ_LEN, | |
209 | .init = hns3_dbg_common_file_init, | |
210 | }, | |
365e860a YM |
211 | { |
212 | .name = "dcb", | |
213 | .cmd = HNAE3_DBG_CMD_REG_DCB, | |
214 | .dentry = HNS3_DBG_DENTRY_REG, | |
215 | .buf_len = HNS3_DBG_READ_LEN, | |
216 | .init = hns3_dbg_common_file_init, | |
217 | }, | |
d2f737cf HC |
218 | { |
219 | .name = "queue_map", | |
220 | .cmd = HNAE3_DBG_CMD_QUEUE_MAP, | |
221 | .dentry = HNS3_DBG_DENTRY_QUEUE, | |
222 | .buf_len = HNS3_DBG_READ_LEN, | |
223 | .init = hns3_dbg_common_file_init, | |
224 | }, | |
c929bc2a JZ |
225 | }; |
226 | ||
227 | static struct hns3_dbg_cap_info hns3_dbg_cap[] = { | |
228 | { | |
229 | .name = "support FD", | |
230 | .cap_bit = HNAE3_DEV_SUPPORT_FD_B, | |
231 | }, { | |
232 | .name = "support GRO", | |
233 | .cap_bit = HNAE3_DEV_SUPPORT_GRO_B, | |
234 | }, { | |
235 | .name = "support FEC", | |
236 | .cap_bit = HNAE3_DEV_SUPPORT_FEC_B, | |
237 | }, { | |
238 | .name = "support UDP GSO", | |
239 | .cap_bit = HNAE3_DEV_SUPPORT_UDP_GSO_B, | |
240 | }, { | |
241 | .name = "support PTP", | |
242 | .cap_bit = HNAE3_DEV_SUPPORT_PTP_B, | |
243 | }, { | |
244 | .name = "support INT QL", | |
245 | .cap_bit = HNAE3_DEV_SUPPORT_INT_QL_B, | |
246 | }, { | |
247 | .name = "support HW TX csum", | |
248 | .cap_bit = HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, | |
249 | }, { | |
250 | .name = "support UDP tunnel csum", | |
251 | .cap_bit = HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, | |
252 | }, { | |
253 | .name = "support TX push", | |
254 | .cap_bit = HNAE3_DEV_SUPPORT_TX_PUSH_B, | |
255 | }, { | |
256 | .name = "support imp-controlled PHY", | |
257 | .cap_bit = HNAE3_DEV_SUPPORT_PHY_IMP_B, | |
258 | }, { | |
259 | .name = "support rxd advanced layout", | |
260 | .cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, | |
261 | }, | |
5e69ea7e YM |
262 | }; |
263 | ||
77e91848 HT |
264 | static void hns3_dbg_fill_content(char *content, u16 len, |
265 | const struct hns3_dbg_item *items, | |
266 | const char **result, u16 size) | |
267 | { | |
268 | char *pos = content; | |
269 | u16 i; | |
270 | ||
271 | memset(content, ' ', len); | |
272 | for (i = 0; i < size; i++) { | |
273 | if (result) | |
274 | strncpy(pos, result[i], strlen(result[i])); | |
275 | else | |
276 | strncpy(pos, items[i].name, strlen(items[i].name)); | |
277 | ||
278 | pos += strlen(items[i].name) + items[i].interval; | |
279 | } | |
280 | ||
281 | *pos++ = '\n'; | |
282 | *pos++ = '\0'; | |
283 | } | |
284 | ||
ebaf1908 WL |
285 | static int hns3_dbg_queue_info(struct hnae3_handle *h, |
286 | const char *cmd_buf) | |
57ceee2c | 287 | { |
dbaae5bb | 288 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); |
57ceee2c | 289 | struct hns3_nic_priv *priv = h->priv; |
57ceee2c | 290 | struct hns3_enet_ring *ring; |
291 | u32 base_add_l, base_add_h; | |
292 | u32 queue_num, queue_max; | |
9d8d5a36 | 293 | u32 value, i; |
57ceee2c | 294 | int cnt; |
295 | ||
5f06b903 YL |
296 | if (!priv->ring) { |
297 | dev_err(&h->pdev->dev, "priv->ring is NULL\n"); | |
57ceee2c | 298 | return -EFAULT; |
299 | } | |
300 | ||
301 | queue_max = h->kinfo.num_tqps; | |
302 | cnt = kstrtouint(&cmd_buf[11], 0, &queue_num); | |
303 | if (cnt) | |
304 | queue_num = 0; | |
305 | else | |
306 | queue_max = queue_num + 1; | |
307 | ||
308 | dev_info(&h->pdev->dev, "queue info\n"); | |
309 | ||
310 | if (queue_num >= h->kinfo.num_tqps) { | |
311 | dev_err(&h->pdev->dev, | |
ed5b255b | 312 | "Queue number(%u) is out of range(0-%u)\n", queue_num, |
57ceee2c | 313 | h->kinfo.num_tqps - 1); |
314 | return -EINVAL; | |
315 | } | |
316 | ||
57ceee2c | 317 | for (i = queue_num; i < queue_max; i++) { |
318 | /* Each cycle needs to determine whether the instance is reset, | |
319 | * to prevent reference to invalid memory. And need to ensure | |
320 | * that the following code is executed within 100ms. | |
321 | */ | |
7737f1fb | 322 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
57ceee2c | 323 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) |
324 | return -EPERM; | |
325 | ||
5f06b903 | 326 | ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)]; |
57ceee2c | 327 | base_add_h = readl_relaxed(ring->tqp->io_base + |
328 | HNS3_RING_RX_RING_BASEADDR_H_REG); | |
329 | base_add_l = readl_relaxed(ring->tqp->io_base + | |
330 | HNS3_RING_RX_RING_BASEADDR_L_REG); | |
adcf738b | 331 | dev_info(&h->pdev->dev, "RX(%u) BASE ADD: 0x%08x%08x\n", i, |
57ceee2c | 332 | base_add_h, base_add_l); |
333 | ||
334 | value = readl_relaxed(ring->tqp->io_base + | |
335 | HNS3_RING_RX_RING_BD_NUM_REG); | |
adcf738b | 336 | dev_info(&h->pdev->dev, "RX(%u) RING BD NUM: %u\n", i, value); |
57ceee2c | 337 | |
338 | value = readl_relaxed(ring->tqp->io_base + | |
339 | HNS3_RING_RX_RING_BD_LEN_REG); | |
adcf738b | 340 | dev_info(&h->pdev->dev, "RX(%u) RING BD LEN: %u\n", i, value); |
57ceee2c | 341 | |
342 | value = readl_relaxed(ring->tqp->io_base + | |
343 | HNS3_RING_RX_RING_TAIL_REG); | |
adcf738b | 344 | dev_info(&h->pdev->dev, "RX(%u) RING TAIL: %u\n", i, value); |
57ceee2c | 345 | |
346 | value = readl_relaxed(ring->tqp->io_base + | |
347 | HNS3_RING_RX_RING_HEAD_REG); | |
adcf738b | 348 | dev_info(&h->pdev->dev, "RX(%u) RING HEAD: %u\n", i, value); |
57ceee2c | 349 | |
350 | value = readl_relaxed(ring->tqp->io_base + | |
351 | HNS3_RING_RX_RING_FBDNUM_REG); | |
adcf738b | 352 | dev_info(&h->pdev->dev, "RX(%u) RING FBDNUM: %u\n", i, value); |
57ceee2c | 353 | |
354 | value = readl_relaxed(ring->tqp->io_base + | |
355 | HNS3_RING_RX_RING_PKTNUM_RECORD_REG); | |
adcf738b | 356 | dev_info(&h->pdev->dev, "RX(%u) RING PKTNUM: %u\n", i, value); |
57ceee2c | 357 | |
5f06b903 | 358 | ring = &priv->ring[i]; |
57ceee2c | 359 | base_add_h = readl_relaxed(ring->tqp->io_base + |
360 | HNS3_RING_TX_RING_BASEADDR_H_REG); | |
361 | base_add_l = readl_relaxed(ring->tqp->io_base + | |
362 | HNS3_RING_TX_RING_BASEADDR_L_REG); | |
adcf738b | 363 | dev_info(&h->pdev->dev, "TX(%u) BASE ADD: 0x%08x%08x\n", i, |
57ceee2c | 364 | base_add_h, base_add_l); |
365 | ||
366 | value = readl_relaxed(ring->tqp->io_base + | |
367 | HNS3_RING_TX_RING_BD_NUM_REG); | |
adcf738b | 368 | dev_info(&h->pdev->dev, "TX(%u) RING BD NUM: %u\n", i, value); |
57ceee2c | 369 | |
370 | value = readl_relaxed(ring->tqp->io_base + | |
371 | HNS3_RING_TX_RING_TC_REG); | |
adcf738b | 372 | dev_info(&h->pdev->dev, "TX(%u) RING TC: %u\n", i, value); |
57ceee2c | 373 | |
374 | value = readl_relaxed(ring->tqp->io_base + | |
375 | HNS3_RING_TX_RING_TAIL_REG); | |
adcf738b | 376 | dev_info(&h->pdev->dev, "TX(%u) RING TAIL: %u\n", i, value); |
57ceee2c | 377 | |
378 | value = readl_relaxed(ring->tqp->io_base + | |
379 | HNS3_RING_TX_RING_HEAD_REG); | |
adcf738b | 380 | dev_info(&h->pdev->dev, "TX(%u) RING HEAD: %u\n", i, value); |
57ceee2c | 381 | |
382 | value = readl_relaxed(ring->tqp->io_base + | |
383 | HNS3_RING_TX_RING_FBDNUM_REG); | |
adcf738b | 384 | dev_info(&h->pdev->dev, "TX(%u) RING FBDNUM: %u\n", i, value); |
57ceee2c | 385 | |
386 | value = readl_relaxed(ring->tqp->io_base + | |
387 | HNS3_RING_TX_RING_OFFSET_REG); | |
adcf738b | 388 | dev_info(&h->pdev->dev, "TX(%u) RING OFFSET: %u\n", i, value); |
57ceee2c | 389 | |
390 | value = readl_relaxed(ring->tqp->io_base + | |
391 | HNS3_RING_TX_RING_PKTNUM_RECORD_REG); | |
dbaae5bb GH |
392 | dev_info(&h->pdev->dev, "TX(%u) RING PKTNUM: %u\n", i, value); |
393 | ||
394 | value = readl_relaxed(ring->tqp->io_base + HNS3_RING_EN_REG); | |
395 | dev_info(&h->pdev->dev, "TX/RX(%u) RING EN: %s\n", i, | |
396 | value ? "enable" : "disable"); | |
397 | ||
398 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) { | |
399 | value = readl_relaxed(ring->tqp->io_base + | |
400 | HNS3_RING_TX_EN_REG); | |
401 | dev_info(&h->pdev->dev, "TX(%u) RING EN: %s\n", i, | |
402 | value ? "enable" : "disable"); | |
403 | ||
404 | value = readl_relaxed(ring->tqp->io_base + | |
405 | HNS3_RING_RX_EN_REG); | |
406 | dev_info(&h->pdev->dev, "RX(%u) RING EN: %s\n", i, | |
407 | value ? "enable" : "disable"); | |
408 | } | |
409 | ||
410 | dev_info(&h->pdev->dev, "\n"); | |
57ceee2c | 411 | } |
412 | ||
413 | return 0; | |
414 | } | |
415 | ||
d2f737cf HC |
416 | static const struct hns3_dbg_item queue_map_items[] = { |
417 | { "local_queue_id", 2 }, | |
418 | { "global_queue_id", 2 }, | |
419 | { "vector_id", 2 }, | |
420 | }; | |
421 | ||
422 | static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len) | |
0c29d191 | 423 | { |
d2f737cf HC |
424 | char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN]; |
425 | char *result[ARRAY_SIZE(queue_map_items)]; | |
0c29d191 | 426 | struct hns3_nic_priv *priv = h->priv; |
d2f737cf HC |
427 | char content[HNS3_DBG_INFO_LEN]; |
428 | int pos = 0; | |
429 | int j; | |
430 | u32 i; | |
0c29d191 | 431 | |
432 | if (!h->ae_algo->ops->get_global_queue_id) | |
433 | return -EOPNOTSUPP; | |
434 | ||
d2f737cf HC |
435 | for (i = 0; i < ARRAY_SIZE(queue_map_items); i++) |
436 | result[i] = &data_str[i][0]; | |
0c29d191 | 437 | |
d2f737cf HC |
438 | hns3_dbg_fill_content(content, sizeof(content), queue_map_items, |
439 | NULL, ARRAY_SIZE(queue_map_items)); | |
440 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
441 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
5f06b903 | 442 | if (!priv->ring || !priv->ring[i].tqp_vector) |
0c29d191 | 443 | continue; |
d2f737cf HC |
444 | j = 0; |
445 | sprintf(result[j++], "%u", i); | |
446 | sprintf(result[j++], "%u", | |
447 | h->ae_algo->ops->get_global_queue_id(h, i)); | |
448 | sprintf(result[j++], "%u", | |
449 | priv->ring[i].tqp_vector->vector_irq); | |
450 | hns3_dbg_fill_content(content, sizeof(content), queue_map_items, | |
451 | (const char **)result, | |
452 | ARRAY_SIZE(queue_map_items)); | |
453 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
0c29d191 | 454 | } |
455 | ||
456 | return 0; | |
457 | } | |
458 | ||
77e91848 HT |
459 | static const struct hns3_dbg_item rx_bd_info_items[] = { |
460 | { "BD_IDX", 3 }, | |
461 | { "L234_INFO", 2 }, | |
462 | { "PKT_LEN", 3 }, | |
463 | { "SIZE", 4 }, | |
464 | { "RSS_HASH", 4 }, | |
465 | { "FD_ID", 2 }, | |
466 | { "VLAN_TAG", 2 }, | |
467 | { "O_DM_VLAN_ID_FB", 2 }, | |
468 | { "OT_VLAN_TAG", 2 }, | |
469 | { "BD_BASE_INFO", 2 }, | |
470 | { "PTYPE", 2 }, | |
471 | { "HW_CSUM", 2 }, | |
472 | }; | |
473 | ||
474 | static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv, | |
475 | struct hns3_desc *desc, char **result, int idx) | |
122bedc5 | 476 | { |
77e91848 HT |
477 | unsigned int j = 0; |
478 | ||
479 | sprintf(result[j++], "%5d", idx); | |
480 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info)); | |
481 | sprintf(result[j++], "%7u", le16_to_cpu(desc->rx.pkt_len)); | |
482 | sprintf(result[j++], "%4u", le16_to_cpu(desc->rx.size)); | |
483 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash)); | |
484 | sprintf(result[j++], "%5u", le16_to_cpu(desc->rx.fd_id)); | |
485 | sprintf(result[j++], "%8u", le16_to_cpu(desc->rx.vlan_tag)); | |
486 | sprintf(result[j++], "%15u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb)); | |
487 | sprintf(result[j++], "%11u", le16_to_cpu(desc->rx.ot_vlan_tag)); | |
488 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info)); | |
489 | if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) { | |
490 | u32 ol_info = le32_to_cpu(desc->rx.ol_info); | |
491 | ||
492 | sprintf(result[j++], "%5lu", hnae3_get_field(ol_info, | |
493 | HNS3_RXD_PTYPE_M, | |
494 | HNS3_RXD_PTYPE_S)); | |
495 | sprintf(result[j++], "%7u", le16_to_cpu(desc->csum)); | |
496 | } else { | |
497 | sprintf(result[j++], "NA"); | |
498 | sprintf(result[j++], "NA"); | |
499 | } | |
500 | } | |
501 | ||
502 | static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len) | |
503 | { | |
504 | char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
505 | struct hns3_nic_priv *priv = d->handle->priv; | |
506 | char *result[ARRAY_SIZE(rx_bd_info_items)]; | |
507 | char content[HNS3_DBG_INFO_LEN]; | |
122bedc5 | 508 | struct hns3_enet_ring *ring; |
77e91848 HT |
509 | struct hns3_desc *desc; |
510 | unsigned int i; | |
511 | int pos = 0; | |
122bedc5 | 512 | |
77e91848 HT |
513 | if (d->qid >= d->handle->kinfo.num_tqps) { |
514 | dev_err(&d->handle->pdev->dev, | |
515 | "queue%u is not in use\n", d->qid); | |
122bedc5 | 516 | return -EINVAL; |
517 | } | |
518 | ||
77e91848 HT |
519 | for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++) |
520 | result[i] = &data_str[i][0]; | |
521 | ||
522 | pos += scnprintf(buf + pos, len - pos, | |
523 | "Queue %u rx bd info:\n", d->qid); | |
524 | hns3_dbg_fill_content(content, sizeof(content), rx_bd_info_items, | |
525 | NULL, ARRAY_SIZE(rx_bd_info_items)); | |
526 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
527 | ||
528 | ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps]; | |
529 | for (i = 0; i < ring->desc_num; i++) { | |
530 | desc = &ring->desc[i]; | |
531 | ||
532 | hns3_dump_rx_bd_info(priv, desc, result, i); | |
533 | hns3_dbg_fill_content(content, sizeof(content), | |
534 | rx_bd_info_items, (const char **)result, | |
535 | ARRAY_SIZE(rx_bd_info_items)); | |
536 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
122bedc5 | 537 | } |
538 | ||
77e91848 HT |
539 | return 0; |
540 | } | |
541 | ||
542 | static const struct hns3_dbg_item tx_bd_info_items[] = { | |
543 | { "BD_IDX", 5 }, | |
544 | { "ADDRESS", 2 }, | |
545 | { "VLAN_TAG", 2 }, | |
546 | { "SIZE", 2 }, | |
547 | { "T_CS_VLAN_TSO", 2 }, | |
548 | { "OT_VLAN_TAG", 3 }, | |
549 | { "TV", 2 }, | |
550 | { "OLT_VLAN_LEN", 2}, | |
551 | { "PAYLEN_OL4CS", 2}, | |
552 | { "BD_FE_SC_VLD", 2}, | |
553 | { "MSS_HW_CSUM", 0}, | |
554 | }; | |
122bedc5 | 555 | |
77e91848 HT |
556 | static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv, |
557 | struct hns3_desc *desc, char **result, int idx) | |
558 | { | |
559 | unsigned int j = 0; | |
560 | ||
561 | sprintf(result[j++], "%6d", idx); | |
562 | sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr)); | |
563 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.vlan_tag)); | |
564 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.send_size)); | |
565 | sprintf(result[j++], "%#x", | |
566 | le32_to_cpu(desc->tx.type_cs_vlan_tso_len)); | |
567 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.outer_vlan_tag)); | |
568 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.tv)); | |
569 | sprintf(result[j++], "%10u", | |
570 | le32_to_cpu(desc->tx.ol_type_vlan_len_msec)); | |
571 | sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs)); | |
572 | sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri)); | |
573 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum)); | |
574 | } | |
575 | ||
576 | static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len) | |
577 | { | |
578 | char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
579 | struct hns3_nic_priv *priv = d->handle->priv; | |
580 | char *result[ARRAY_SIZE(tx_bd_info_items)]; | |
581 | char content[HNS3_DBG_INFO_LEN]; | |
582 | struct hns3_enet_ring *ring; | |
583 | struct hns3_desc *desc; | |
584 | unsigned int i; | |
585 | int pos = 0; | |
586 | ||
587 | if (d->qid >= d->handle->kinfo.num_tqps) { | |
588 | dev_err(&d->handle->pdev->dev, | |
589 | "queue%u is not in use\n", d->qid); | |
122bedc5 | 590 | return -EINVAL; |
591 | } | |
592 | ||
77e91848 HT |
593 | for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++) |
594 | result[i] = &data_str[i][0]; | |
595 | ||
596 | pos += scnprintf(buf + pos, len - pos, | |
597 | "Queue %u tx bd info:\n", d->qid); | |
598 | hns3_dbg_fill_content(content, sizeof(content), tx_bd_info_items, | |
599 | NULL, ARRAY_SIZE(tx_bd_info_items)); | |
600 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
b1533ada | 601 | |
77e91848 HT |
602 | ring = &priv->ring[d->qid]; |
603 | for (i = 0; i < ring->desc_num; i++) { | |
604 | desc = &ring->desc[i]; | |
605 | ||
606 | hns3_dump_tx_bd_info(priv, desc, result, i); | |
607 | hns3_dbg_fill_content(content, sizeof(content), | |
608 | tx_bd_info_items, (const char **)result, | |
609 | ARRAY_SIZE(tx_bd_info_items)); | |
610 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
611 | } | |
122bedc5 | 612 | |
613 | return 0; | |
614 | } | |
615 | ||
b2292360 | 616 | static void hns3_dbg_help(struct hnae3_handle *h) |
617 | { | |
618 | dev_info(&h->pdev->dev, "available commands\n"); | |
ed5b255b | 619 | dev_info(&h->pdev->dev, "queue info <number>\n"); |
97afd47b YM |
620 | |
621 | if (!hns3_is_phys_func(h->pdev)) | |
622 | return; | |
623 | ||
b2292360 | 624 | dev_info(&h->pdev->dev, "dump fd tcam\n"); |
2849d4e7 | 625 | dev_info(&h->pdev->dev, "dump tc\n"); |
ed5b255b | 626 | dev_info(&h->pdev->dev, "dump tm map <q_num>\n"); |
96227f4c | 627 | dev_info(&h->pdev->dev, "dump tm\n"); |
d958919d | 628 | dev_info(&h->pdev->dev, "dump qos pause cfg\n"); |
6fc22440 | 629 | dev_info(&h->pdev->dev, "dump qos pri map\n"); |
7d9d7f88 | 630 | dev_info(&h->pdev->dev, "dump qos buf cfg\n"); |
a6345787 | 631 | dev_info(&h->pdev->dev, "dump mac tnl status\n"); |
89ec9485 | 632 | dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); |
b2292360 | 633 | } |
634 | ||
c929bc2a JZ |
635 | static void |
636 | hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos) | |
9484e337 GH |
637 | { |
638 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
c929bc2a JZ |
639 | static const char * const str[] = {"no", "yes"}; |
640 | unsigned long *caps = ae_dev->caps; | |
641 | u32 i, state; | |
642 | ||
643 | *pos += scnprintf(buf + *pos, len - *pos, "dev capability:\n"); | |
644 | ||
645 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) { | |
646 | state = test_bit(hns3_dbg_cap[i].cap_bit, caps); | |
647 | *pos += scnprintf(buf + *pos, len - *pos, "%s: %s\n", | |
648 | hns3_dbg_cap[i].name, str[state]); | |
649 | } | |
650 | ||
651 | *pos += scnprintf(buf + *pos, len - *pos, "\n"); | |
9484e337 GH |
652 | } |
653 | ||
c929bc2a JZ |
654 | static void |
655 | hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos) | |
b4442ec5 GH |
656 | { |
657 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
658 | struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs; | |
659 | struct hnae3_knic_private_info *kinfo = &h->kinfo; | |
c929bc2a JZ |
660 | |
661 | *pos += scnprintf(buf + *pos, len - *pos, "dev_spec:\n"); | |
662 | *pos += scnprintf(buf + *pos, len - *pos, "MAC entry num: %u\n", | |
663 | dev_specs->mac_entry_num); | |
664 | *pos += scnprintf(buf + *pos, len - *pos, "MNG entry num: %u\n", | |
665 | dev_specs->mng_entry_num); | |
666 | *pos += scnprintf(buf + *pos, len - *pos, "MAX non tso bd num: %u\n", | |
667 | dev_specs->max_non_tso_bd_num); | |
668 | *pos += scnprintf(buf + *pos, len - *pos, "RSS ind tbl size: %u\n", | |
669 | dev_specs->rss_ind_tbl_size); | |
670 | *pos += scnprintf(buf + *pos, len - *pos, "RSS key size: %u\n", | |
671 | dev_specs->rss_key_size); | |
672 | *pos += scnprintf(buf + *pos, len - *pos, "RSS size: %u\n", | |
673 | kinfo->rss_size); | |
674 | *pos += scnprintf(buf + *pos, len - *pos, "Allocated RSS size: %u\n", | |
675 | kinfo->req_rss_size); | |
676 | *pos += scnprintf(buf + *pos, len - *pos, | |
677 | "Task queue pairs numbers: %u\n", | |
678 | kinfo->num_tqps); | |
679 | *pos += scnprintf(buf + *pos, len - *pos, "RX buffer length: %u\n", | |
680 | kinfo->rx_buf_len); | |
681 | *pos += scnprintf(buf + *pos, len - *pos, "Desc num per TX queue: %u\n", | |
682 | kinfo->num_tx_desc); | |
683 | *pos += scnprintf(buf + *pos, len - *pos, "Desc num per RX queue: %u\n", | |
684 | kinfo->num_rx_desc); | |
685 | *pos += scnprintf(buf + *pos, len - *pos, | |
686 | "Total number of enabled TCs: %u\n", | |
687 | kinfo->tc_info.num_tc); | |
688 | *pos += scnprintf(buf + *pos, len - *pos, "MAX INT QL: %u\n", | |
689 | dev_specs->int_ql_max); | |
690 | *pos += scnprintf(buf + *pos, len - *pos, "MAX INT GL: %u\n", | |
691 | dev_specs->max_int_gl); | |
692 | *pos += scnprintf(buf + *pos, len - *pos, "MAX TM RATE: %u\n", | |
693 | dev_specs->max_tm_rate); | |
694 | *pos += scnprintf(buf + *pos, len - *pos, "MAX QSET number: %u\n", | |
695 | dev_specs->max_qset_num); | |
696 | } | |
697 | ||
698 | static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len) | |
699 | { | |
700 | int pos = 0; | |
701 | ||
702 | hns3_dbg_dev_caps(h, buf, len, &pos); | |
703 | ||
704 | hns3_dbg_dev_specs(h, buf, len, &pos); | |
705 | ||
706 | return 0; | |
b4442ec5 GH |
707 | } |
708 | ||
b2292360 | 709 | static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer, |
710 | size_t count, loff_t *ppos) | |
711 | { | |
712 | int uncopy_bytes; | |
713 | char *buf; | |
714 | int len; | |
715 | ||
716 | if (*ppos != 0) | |
717 | return 0; | |
718 | ||
719 | if (count < HNS3_DBG_READ_LEN) | |
720 | return -ENOSPC; | |
721 | ||
722 | buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL); | |
723 | if (!buf) | |
724 | return -ENOMEM; | |
725 | ||
49e211c0 CZ |
726 | len = scnprintf(buf, HNS3_DBG_READ_LEN, "%s\n", |
727 | "Please echo help to cmd to get help information"); | |
b2292360 | 728 | uncopy_bytes = copy_to_user(buffer, buf, len); |
729 | ||
730 | kfree(buf); | |
731 | ||
732 | if (uncopy_bytes) | |
733 | return -EFAULT; | |
734 | ||
735 | return (*ppos = len); | |
736 | } | |
737 | ||
c318af3f PL |
738 | static int hns3_dbg_check_cmd(struct hnae3_handle *handle, char *cmd_buf) |
739 | { | |
740 | int ret = 0; | |
741 | ||
742 | if (strncmp(cmd_buf, "help", 4) == 0) | |
743 | hns3_dbg_help(handle); | |
744 | else if (strncmp(cmd_buf, "queue info", 10) == 0) | |
745 | ret = hns3_dbg_queue_info(handle, cmd_buf); | |
c318af3f PL |
746 | else if (handle->ae_algo->ops->dbg_run_cmd) |
747 | ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf); | |
748 | else | |
749 | ret = -EOPNOTSUPP; | |
750 | ||
751 | return ret; | |
752 | } | |
753 | ||
b2292360 | 754 | static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer, |
755 | size_t count, loff_t *ppos) | |
756 | { | |
757 | struct hnae3_handle *handle = filp->private_data; | |
57ceee2c | 758 | struct hns3_nic_priv *priv = handle->priv; |
b2292360 | 759 | char *cmd_buf, *cmd_buf_tmp; |
760 | int uncopied_bytes; | |
c318af3f | 761 | int ret; |
b2292360 | 762 | |
763 | if (*ppos != 0) | |
764 | return 0; | |
765 | ||
57ceee2c | 766 | /* Judge if the instance is being reset. */ |
7737f1fb | 767 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
57ceee2c | 768 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) |
769 | return 0; | |
770 | ||
7ac243f9 YM |
771 | if (count > HNS3_DBG_WRITE_LEN) |
772 | return -ENOSPC; | |
773 | ||
b2292360 | 774 | cmd_buf = kzalloc(count + 1, GFP_KERNEL); |
775 | if (!cmd_buf) | |
776 | return count; | |
777 | ||
778 | uncopied_bytes = copy_from_user(cmd_buf, buffer, count); | |
779 | if (uncopied_bytes) { | |
780 | kfree(cmd_buf); | |
781 | return -EFAULT; | |
782 | } | |
783 | ||
784 | cmd_buf[count] = '\0'; | |
785 | ||
786 | cmd_buf_tmp = strchr(cmd_buf, '\n'); | |
787 | if (cmd_buf_tmp) { | |
788 | *cmd_buf_tmp = '\0'; | |
789 | count = cmd_buf_tmp - cmd_buf + 1; | |
790 | } | |
791 | ||
c318af3f | 792 | ret = hns3_dbg_check_cmd(handle, cmd_buf); |
b2292360 | 793 | if (ret) |
794 | hns3_dbg_help(handle); | |
795 | ||
796 | kfree(cmd_buf); | |
797 | cmd_buf = NULL; | |
798 | ||
799 | return count; | |
800 | } | |
801 | ||
5e69ea7e YM |
802 | static int hns3_dbg_get_cmd_index(struct hnae3_handle *handle, |
803 | const unsigned char *name, u32 *index) | |
804 | { | |
805 | u32 i; | |
806 | ||
807 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { | |
808 | if (!strncmp(name, hns3_dbg_cmd[i].name, | |
809 | strlen(hns3_dbg_cmd[i].name))) { | |
810 | *index = i; | |
811 | return 0; | |
812 | } | |
813 | } | |
814 | ||
815 | dev_err(&handle->pdev->dev, "unknown command(%s)\n", name); | |
816 | return -EINVAL; | |
817 | } | |
818 | ||
c929bc2a | 819 | static const struct hns3_dbg_func hns3_dbg_cmd_func[] = { |
d2f737cf HC |
820 | { |
821 | .cmd = HNAE3_DBG_CMD_QUEUE_MAP, | |
822 | .dbg_dump = hns3_dbg_queue_map, | |
823 | }, | |
c929bc2a JZ |
824 | { |
825 | .cmd = HNAE3_DBG_CMD_DEV_INFO, | |
826 | .dbg_dump = hns3_dbg_dev_info, | |
827 | }, | |
77e91848 HT |
828 | { |
829 | .cmd = HNAE3_DBG_CMD_TX_BD, | |
830 | .dbg_dump_bd = hns3_dbg_tx_bd_info, | |
831 | }, | |
832 | { | |
833 | .cmd = HNAE3_DBG_CMD_RX_BD, | |
834 | .dbg_dump_bd = hns3_dbg_rx_bd_info, | |
835 | }, | |
c929bc2a JZ |
836 | }; |
837 | ||
77e91848 | 838 | static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data, |
5e69ea7e YM |
839 | enum hnae3_dbg_cmd cmd, char *buf, int len) |
840 | { | |
77e91848 HT |
841 | const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops; |
842 | const struct hns3_dbg_func *cmd_func; | |
c929bc2a JZ |
843 | u32 i; |
844 | ||
845 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) { | |
77e91848 HT |
846 | if (cmd == hns3_dbg_cmd_func[i].cmd) { |
847 | cmd_func = &hns3_dbg_cmd_func[i]; | |
848 | if (cmd_func->dbg_dump) | |
849 | return cmd_func->dbg_dump(dbg_data->handle, buf, | |
850 | len); | |
851 | else | |
852 | return cmd_func->dbg_dump_bd(dbg_data, buf, | |
853 | len); | |
854 | } | |
c929bc2a | 855 | } |
5e69ea7e YM |
856 | |
857 | if (!ops->dbg_read_cmd) | |
858 | return -EOPNOTSUPP; | |
859 | ||
77e91848 | 860 | return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len); |
5e69ea7e YM |
861 | } |
862 | ||
04987ca1 GH |
863 | static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, |
864 | size_t count, loff_t *ppos) | |
865 | { | |
77e91848 HT |
866 | struct hns3_dbg_data *dbg_data = filp->private_data; |
867 | struct hnae3_handle *handle = dbg_data->handle; | |
04987ca1 | 868 | struct hns3_nic_priv *priv = handle->priv; |
04987ca1 | 869 | ssize_t size = 0; |
5e69ea7e YM |
870 | char **save_buf; |
871 | char *read_buf; | |
872 | u32 index; | |
873 | int ret; | |
04987ca1 | 874 | |
5e69ea7e YM |
875 | ret = hns3_dbg_get_cmd_index(handle, filp->f_path.dentry->d_iname, |
876 | &index); | |
877 | if (ret) | |
878 | return ret; | |
04987ca1 | 879 | |
5e69ea7e | 880 | save_buf = &hns3_dbg_cmd[index].buf; |
04987ca1 | 881 | |
5e69ea7e YM |
882 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
883 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { | |
884 | ret = -EBUSY; | |
04987ca1 GH |
885 | goto out; |
886 | } | |
887 | ||
5e69ea7e YM |
888 | if (*save_buf) { |
889 | read_buf = *save_buf; | |
890 | } else { | |
891 | read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL); | |
892 | if (!read_buf) | |
893 | return -ENOMEM; | |
894 | ||
895 | /* save the buffer addr until the last read operation */ | |
896 | *save_buf = read_buf; | |
897 | } | |
898 | ||
899 | /* get data ready for the first time to read */ | |
900 | if (!*ppos) { | |
77e91848 | 901 | ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, |
5e69ea7e YM |
902 | read_buf, hns3_dbg_cmd[index].buf_len); |
903 | if (ret) | |
904 | goto out; | |
905 | } | |
906 | ||
04987ca1 GH |
907 | size = simple_read_from_buffer(buffer, count, ppos, read_buf, |
908 | strlen(read_buf)); | |
5e69ea7e YM |
909 | if (size > 0) |
910 | return size; | |
04987ca1 GH |
911 | |
912 | out: | |
5e69ea7e YM |
913 | /* free the buffer for the last read operation */ |
914 | if (*save_buf) { | |
915 | kvfree(*save_buf); | |
916 | *save_buf = NULL; | |
917 | } | |
918 | ||
919 | return ret; | |
04987ca1 GH |
920 | } |
921 | ||
b2292360 | 922 | static const struct file_operations hns3_dbg_cmd_fops = { |
923 | .owner = THIS_MODULE, | |
924 | .open = simple_open, | |
925 | .read = hns3_dbg_cmd_read, | |
926 | .write = hns3_dbg_cmd_write, | |
927 | }; | |
928 | ||
04987ca1 GH |
929 | static const struct file_operations hns3_dbg_fops = { |
930 | .owner = THIS_MODULE, | |
931 | .open = simple_open, | |
932 | .read = hns3_dbg_read, | |
933 | }; | |
934 | ||
77e91848 HT |
935 | static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd) |
936 | { | |
937 | struct dentry *entry_dir; | |
938 | struct hns3_dbg_data *data; | |
939 | u16 max_queue_num; | |
940 | unsigned int i; | |
941 | ||
942 | entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry; | |
943 | max_queue_num = hns3_get_max_available_channels(handle); | |
944 | data = devm_kzalloc(&handle->pdev->dev, max_queue_num * sizeof(*data), | |
945 | GFP_KERNEL); | |
946 | if (!data) | |
947 | return -ENOMEM; | |
948 | ||
949 | for (i = 0; i < max_queue_num; i++) { | |
950 | char name[HNS3_DBG_FILE_NAME_LEN]; | |
951 | ||
952 | data[i].handle = handle; | |
953 | data[i].qid = i; | |
954 | sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i); | |
955 | debugfs_create_file(name, 0400, entry_dir, &data[i], | |
956 | &hns3_dbg_fops); | |
957 | } | |
958 | ||
959 | return 0; | |
960 | } | |
961 | ||
5e69ea7e YM |
962 | static int |
963 | hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd) | |
964 | { | |
77e91848 | 965 | struct hns3_dbg_data *data; |
5e69ea7e YM |
966 | struct dentry *entry_dir; |
967 | ||
77e91848 HT |
968 | data = devm_kzalloc(&handle->pdev->dev, sizeof(*data), GFP_KERNEL); |
969 | if (!data) | |
970 | return -ENOMEM; | |
971 | ||
972 | data->handle = handle; | |
5e69ea7e YM |
973 | entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry; |
974 | debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir, | |
77e91848 | 975 | data, &hns3_dbg_fops); |
5e69ea7e YM |
976 | |
977 | return 0; | |
978 | } | |
979 | ||
980 | int hns3_dbg_init(struct hnae3_handle *handle) | |
b2292360 | 981 | { |
04987ca1 | 982 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); |
b2292360 | 983 | const char *name = pci_name(handle->pdev); |
5e69ea7e YM |
984 | int ret; |
985 | u32 i; | |
b2292360 | 986 | |
5e69ea7e YM |
987 | hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry = |
988 | debugfs_create_dir(name, hns3_dbgfs_root); | |
989 | handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry; | |
b2292360 | 990 | |
11ab11e6 GKH |
991 | debugfs_create_file("cmd", 0600, handle->hnae3_dbgfs, handle, |
992 | &hns3_dbg_cmd_fops); | |
04987ca1 | 993 | |
5e69ea7e YM |
994 | for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++) |
995 | hns3_dbg_dentry[i].dentry = | |
996 | debugfs_create_dir(hns3_dbg_dentry[i].name, | |
997 | handle->hnae3_dbgfs); | |
998 | ||
999 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { | |
1000 | if (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES && | |
1001 | ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) | |
1002 | continue; | |
1003 | ||
1004 | if (!hns3_dbg_cmd[i].init) { | |
1005 | dev_err(&handle->pdev->dev, | |
1006 | "cmd %s lack of init func\n", | |
1007 | hns3_dbg_cmd[i].name); | |
1008 | ret = -EINVAL; | |
1009 | goto out; | |
1010 | } | |
1011 | ||
1012 | ret = hns3_dbg_cmd[i].init(handle, i); | |
1013 | if (ret) { | |
1014 | dev_err(&handle->pdev->dev, "failed to init cmd %s\n", | |
1015 | hns3_dbg_cmd[i].name); | |
1016 | goto out; | |
1017 | } | |
1018 | } | |
1019 | ||
1020 | return 0; | |
1021 | ||
1022 | out: | |
1023 | debugfs_remove_recursive(handle->hnae3_dbgfs); | |
1024 | handle->hnae3_dbgfs = NULL; | |
1025 | return ret; | |
b2292360 | 1026 | } |
1027 | ||
1028 | void hns3_dbg_uninit(struct hnae3_handle *handle) | |
1029 | { | |
5e69ea7e YM |
1030 | u32 i; |
1031 | ||
1032 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) | |
1033 | if (hns3_dbg_cmd[i].buf) { | |
1034 | kvfree(hns3_dbg_cmd[i].buf); | |
1035 | hns3_dbg_cmd[i].buf = NULL; | |
1036 | } | |
1037 | ||
b2292360 | 1038 | debugfs_remove_recursive(handle->hnae3_dbgfs); |
1039 | handle->hnae3_dbgfs = NULL; | |
1040 | } | |
1041 | ||
1042 | void hns3_dbg_register_debugfs(const char *debugfs_dir_name) | |
1043 | { | |
1044 | hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL); | |
b2292360 | 1045 | } |
1046 | ||
1047 | void hns3_dbg_unregister_debugfs(void) | |
1048 | { | |
1049 | debugfs_remove_recursive(hns3_dbgfs_root); | |
1050 | hns3_dbgfs_root = NULL; | |
1051 | } |