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 | }, | |
b5a0b70d HC |
32 | { |
33 | .name = "fd" | |
34 | }, | |
5e69ea7e YM |
35 | /* keep common at the bottom and add new directory above */ |
36 | { | |
37 | .name = "common" | |
38 | }, | |
39 | }; | |
40 | ||
0c5c135c HC |
41 | static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd); |
42 | static int hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd); | |
5e69ea7e YM |
43 | |
44 | static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = { | |
45 | { | |
46 | .name = "tm_nodes", | |
47 | .cmd = HNAE3_DBG_CMD_TM_NODES, | |
48 | .dentry = HNS3_DBG_DENTRY_TM, | |
49 | .buf_len = HNS3_DBG_READ_LEN, | |
50 | .init = hns3_dbg_common_file_init, | |
51 | }, | |
52 | { | |
53 | .name = "tm_priority", | |
54 | .cmd = HNAE3_DBG_CMD_TM_PRI, | |
55 | .dentry = HNS3_DBG_DENTRY_TM, | |
56 | .buf_len = HNS3_DBG_READ_LEN, | |
57 | .init = hns3_dbg_common_file_init, | |
58 | }, | |
59 | { | |
60 | .name = "tm_qset", | |
61 | .cmd = HNAE3_DBG_CMD_TM_QSET, | |
62 | .dentry = HNS3_DBG_DENTRY_TM, | |
63 | .buf_len = HNS3_DBG_READ_LEN, | |
64 | .init = hns3_dbg_common_file_init, | |
65 | }, | |
7679f28e GH |
66 | { |
67 | .name = "tm_map", | |
68 | .cmd = HNAE3_DBG_CMD_TM_MAP, | |
69 | .dentry = HNS3_DBG_DENTRY_TM, | |
70 | .buf_len = HNS3_DBG_READ_LEN_1MB, | |
71 | .init = hns3_dbg_common_file_init, | |
72 | }, | |
cad7c215 GH |
73 | { |
74 | .name = "tm_pg", | |
75 | .cmd = HNAE3_DBG_CMD_TM_PG, | |
76 | .dentry = HNS3_DBG_DENTRY_TM, | |
77 | .buf_len = HNS3_DBG_READ_LEN, | |
78 | .init = hns3_dbg_common_file_init, | |
79 | }, | |
80 | { | |
81 | .name = "tm_port", | |
82 | .cmd = HNAE3_DBG_CMD_TM_PORT, | |
83 | .dentry = HNS3_DBG_DENTRY_TM, | |
84 | .buf_len = HNS3_DBG_READ_LEN, | |
85 | .init = hns3_dbg_common_file_init, | |
86 | }, | |
0e32038d GH |
87 | { |
88 | .name = "tc_sch_info", | |
89 | .cmd = HNAE3_DBG_CMD_TC_SCH_INFO, | |
90 | .dentry = HNS3_DBG_DENTRY_TM, | |
91 | .buf_len = HNS3_DBG_READ_LEN, | |
92 | .init = hns3_dbg_common_file_init, | |
93 | }, | |
6571ec2e GH |
94 | { |
95 | .name = "qos_pause_cfg", | |
96 | .cmd = HNAE3_DBG_CMD_QOS_PAUSE_CFG, | |
97 | .dentry = HNS3_DBG_DENTRY_TM, | |
98 | .buf_len = HNS3_DBG_READ_LEN, | |
99 | .init = hns3_dbg_common_file_init, | |
100 | }, | |
28d3bada GH |
101 | { |
102 | .name = "qos_pri_map", | |
103 | .cmd = HNAE3_DBG_CMD_QOS_PRI_MAP, | |
104 | .dentry = HNS3_DBG_DENTRY_TM, | |
105 | .buf_len = HNS3_DBG_READ_LEN, | |
106 | .init = hns3_dbg_common_file_init, | |
107 | }, | |
95b19586 GH |
108 | { |
109 | .name = "qos_buf_cfg", | |
110 | .cmd = HNAE3_DBG_CMD_QOS_BUF_CFG, | |
111 | .dentry = HNS3_DBG_DENTRY_TM, | |
112 | .buf_len = HNS3_DBG_READ_LEN, | |
113 | .init = hns3_dbg_common_file_init, | |
114 | }, | |
c929bc2a JZ |
115 | { |
116 | .name = "dev_info", | |
117 | .cmd = HNAE3_DBG_CMD_DEV_INFO, | |
118 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
119 | .buf_len = HNS3_DBG_READ_LEN, | |
120 | .init = hns3_dbg_common_file_init, | |
121 | }, | |
77e91848 HT |
122 | { |
123 | .name = "tx_bd_queue", | |
124 | .cmd = HNAE3_DBG_CMD_TX_BD, | |
125 | .dentry = HNS3_DBG_DENTRY_TX_BD, | |
126 | .buf_len = HNS3_DBG_READ_LEN_4MB, | |
127 | .init = hns3_dbg_bd_file_init, | |
128 | }, | |
129 | { | |
130 | .name = "rx_bd_queue", | |
131 | .cmd = HNAE3_DBG_CMD_RX_BD, | |
132 | .dentry = HNS3_DBG_DENTRY_RX_BD, | |
133 | .buf_len = HNS3_DBG_READ_LEN_4MB, | |
134 | .init = hns3_dbg_bd_file_init, | |
135 | }, | |
1556ea91 HT |
136 | { |
137 | .name = "uc", | |
138 | .cmd = HNAE3_DBG_CMD_MAC_UC, | |
139 | .dentry = HNS3_DBG_DENTRY_MAC, | |
140 | .buf_len = HNS3_DBG_READ_LEN, | |
141 | .init = hns3_dbg_common_file_init, | |
142 | }, | |
143 | { | |
144 | .name = "mc", | |
145 | .cmd = HNAE3_DBG_CMD_MAC_MC, | |
146 | .dentry = HNS3_DBG_DENTRY_MAC, | |
147 | .buf_len = HNS3_DBG_READ_LEN, | |
148 | .init = hns3_dbg_common_file_init, | |
149 | }, | |
8ddfd9c4 YM |
150 | { |
151 | .name = "mng_tbl", | |
152 | .cmd = HNAE3_DBG_CMD_MNG_TBL, | |
153 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
154 | .buf_len = HNS3_DBG_READ_LEN, | |
155 | .init = hns3_dbg_common_file_init, | |
156 | }, | |
d658ff34 YM |
157 | { |
158 | .name = "loopback", | |
159 | .cmd = HNAE3_DBG_CMD_LOOPBACK, | |
160 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
161 | .buf_len = HNS3_DBG_READ_LEN, | |
162 | .init = hns3_dbg_common_file_init, | |
163 | }, | |
9149ca0f JZ |
164 | { |
165 | .name = "interrupt_info", | |
166 | .cmd = HNAE3_DBG_CMD_INTERRUPT_INFO, | |
167 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
168 | .buf_len = HNS3_DBG_READ_LEN, | |
169 | .init = hns3_dbg_common_file_init, | |
170 | }, | |
1a7ff828 JZ |
171 | { |
172 | .name = "reset_info", | |
173 | .cmd = HNAE3_DBG_CMD_RESET_INFO, | |
174 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
175 | .buf_len = HNS3_DBG_READ_LEN, | |
176 | .init = hns3_dbg_common_file_init, | |
177 | }, | |
0b198b0d JZ |
178 | { |
179 | .name = "imp_info", | |
180 | .cmd = HNAE3_DBG_CMD_IMP_INFO, | |
181 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
182 | .buf_len = HNS3_DBG_READ_LEN, | |
183 | .init = hns3_dbg_common_file_init, | |
184 | }, | |
e76e6886 JZ |
185 | { |
186 | .name = "ncl_config", | |
187 | .cmd = HNAE3_DBG_CMD_NCL_CONFIG, | |
188 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
189 | .buf_len = HNS3_DBG_READ_LEN_128KB, | |
190 | .init = hns3_dbg_common_file_init, | |
191 | }, | |
7b07ab06 JZ |
192 | { |
193 | .name = "mac_tnl_status", | |
194 | .cmd = HNAE3_DBG_CMD_MAC_TNL_STATUS, | |
195 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
196 | .buf_len = HNS3_DBG_READ_LEN, | |
197 | .init = hns3_dbg_common_file_init, | |
198 | }, | |
d96b0e59 YM |
199 | { |
200 | .name = "bios_common", | |
201 | .cmd = HNAE3_DBG_CMD_REG_BIOS_COMMON, | |
202 | .dentry = HNS3_DBG_DENTRY_REG, | |
203 | .buf_len = HNS3_DBG_READ_LEN, | |
204 | .init = hns3_dbg_common_file_init, | |
205 | }, | |
206 | { | |
207 | .name = "ssu", | |
208 | .cmd = HNAE3_DBG_CMD_REG_SSU, | |
209 | .dentry = HNS3_DBG_DENTRY_REG, | |
210 | .buf_len = HNS3_DBG_READ_LEN, | |
211 | .init = hns3_dbg_common_file_init, | |
212 | }, | |
213 | { | |
214 | .name = "igu_egu", | |
215 | .cmd = HNAE3_DBG_CMD_REG_IGU_EGU, | |
216 | .dentry = HNS3_DBG_DENTRY_REG, | |
217 | .buf_len = HNS3_DBG_READ_LEN, | |
218 | .init = hns3_dbg_common_file_init, | |
219 | }, | |
220 | { | |
221 | .name = "rpu", | |
222 | .cmd = HNAE3_DBG_CMD_REG_RPU, | |
223 | .dentry = HNS3_DBG_DENTRY_REG, | |
224 | .buf_len = HNS3_DBG_READ_LEN, | |
225 | .init = hns3_dbg_common_file_init, | |
226 | }, | |
227 | { | |
228 | .name = "ncsi", | |
229 | .cmd = HNAE3_DBG_CMD_REG_NCSI, | |
230 | .dentry = HNS3_DBG_DENTRY_REG, | |
231 | .buf_len = HNS3_DBG_READ_LEN, | |
232 | .init = hns3_dbg_common_file_init, | |
233 | }, | |
234 | { | |
235 | .name = "rtc", | |
236 | .cmd = HNAE3_DBG_CMD_REG_RTC, | |
237 | .dentry = HNS3_DBG_DENTRY_REG, | |
238 | .buf_len = HNS3_DBG_READ_LEN, | |
239 | .init = hns3_dbg_common_file_init, | |
240 | }, | |
241 | { | |
242 | .name = "ppp", | |
243 | .cmd = HNAE3_DBG_CMD_REG_PPP, | |
244 | .dentry = HNS3_DBG_DENTRY_REG, | |
245 | .buf_len = HNS3_DBG_READ_LEN, | |
246 | .init = hns3_dbg_common_file_init, | |
247 | }, | |
248 | { | |
249 | .name = "rcb", | |
250 | .cmd = HNAE3_DBG_CMD_REG_RCB, | |
251 | .dentry = HNS3_DBG_DENTRY_REG, | |
252 | .buf_len = HNS3_DBG_READ_LEN, | |
253 | .init = hns3_dbg_common_file_init, | |
254 | }, | |
255 | { | |
256 | .name = "tqp", | |
257 | .cmd = HNAE3_DBG_CMD_REG_TQP, | |
258 | .dentry = HNS3_DBG_DENTRY_REG, | |
259 | .buf_len = HNS3_DBG_READ_LEN, | |
260 | .init = hns3_dbg_common_file_init, | |
261 | }, | |
262 | { | |
263 | .name = "mac", | |
264 | .cmd = HNAE3_DBG_CMD_REG_MAC, | |
265 | .dentry = HNS3_DBG_DENTRY_REG, | |
266 | .buf_len = HNS3_DBG_READ_LEN, | |
267 | .init = hns3_dbg_common_file_init, | |
268 | }, | |
365e860a YM |
269 | { |
270 | .name = "dcb", | |
271 | .cmd = HNAE3_DBG_CMD_REG_DCB, | |
272 | .dentry = HNS3_DBG_DENTRY_REG, | |
273 | .buf_len = HNS3_DBG_READ_LEN, | |
274 | .init = hns3_dbg_common_file_init, | |
275 | }, | |
d2f737cf HC |
276 | { |
277 | .name = "queue_map", | |
278 | .cmd = HNAE3_DBG_CMD_QUEUE_MAP, | |
279 | .dentry = HNS3_DBG_DENTRY_QUEUE, | |
280 | .buf_len = HNS3_DBG_READ_LEN, | |
281 | .init = hns3_dbg_common_file_init, | |
282 | }, | |
e44c495d HC |
283 | { |
284 | .name = "rx_queue_info", | |
285 | .cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO, | |
286 | .dentry = HNS3_DBG_DENTRY_QUEUE, | |
287 | .buf_len = HNS3_DBG_READ_LEN_1MB, | |
288 | .init = hns3_dbg_common_file_init, | |
289 | }, | |
290 | { | |
291 | .name = "tx_queue_info", | |
292 | .cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO, | |
293 | .dentry = HNS3_DBG_DENTRY_QUEUE, | |
294 | .buf_len = HNS3_DBG_READ_LEN_1MB, | |
295 | .init = hns3_dbg_common_file_init, | |
296 | }, | |
b5a0b70d HC |
297 | { |
298 | .name = "fd_tcam", | |
299 | .cmd = HNAE3_DBG_CMD_FD_TCAM, | |
300 | .dentry = HNS3_DBG_DENTRY_FD, | |
301 | .buf_len = HNS3_DBG_READ_LEN, | |
302 | .init = hns3_dbg_common_file_init, | |
303 | }, | |
058c3be9 YM |
304 | { |
305 | .name = "service_task_info", | |
306 | .cmd = HNAE3_DBG_CMD_SERV_INFO, | |
307 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
308 | .buf_len = HNS3_DBG_READ_LEN, | |
309 | .init = hns3_dbg_common_file_init, | |
310 | }, | |
0ca821da JS |
311 | { |
312 | .name = "vlan_config", | |
313 | .cmd = HNAE3_DBG_CMD_VLAN_CONFIG, | |
314 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
315 | .buf_len = HNS3_DBG_READ_LEN, | |
316 | .init = hns3_dbg_common_file_init, | |
317 | }, | |
b34c157f HT |
318 | { |
319 | .name = "ptp_info", | |
320 | .cmd = HNAE3_DBG_CMD_PTP_INFO, | |
321 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
322 | .buf_len = HNS3_DBG_READ_LEN, | |
323 | .init = hns3_dbg_common_file_init, | |
324 | }, | |
03a92fe8 JS |
325 | { |
326 | .name = "fd_counter", | |
327 | .cmd = HNAE3_DBG_CMD_FD_COUNTER, | |
328 | .dentry = HNS3_DBG_DENTRY_FD, | |
329 | .buf_len = HNS3_DBG_READ_LEN, | |
330 | .init = hns3_dbg_common_file_init, | |
331 | }, | |
d59daf6a JS |
332 | { |
333 | .name = "umv_info", | |
334 | .cmd = HNAE3_DBG_CMD_UMV_INFO, | |
335 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
336 | .buf_len = HNS3_DBG_READ_LEN, | |
337 | .init = hns3_dbg_common_file_init, | |
338 | }, | |
850bfb91 HC |
339 | { |
340 | .name = "page_pool_info", | |
341 | .cmd = HNAE3_DBG_CMD_PAGE_POOL_INFO, | |
342 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
343 | .buf_len = HNS3_DBG_READ_LEN, | |
344 | .init = hns3_dbg_common_file_init, | |
345 | }, | |
c99fead7 HT |
346 | { |
347 | .name = "coalesce_info", | |
348 | .cmd = HNAE3_DBG_CMD_COAL_INFO, | |
349 | .dentry = HNS3_DBG_DENTRY_COMMON, | |
350 | .buf_len = HNS3_DBG_READ_LEN_1MB, | |
351 | .init = hns3_dbg_common_file_init, | |
352 | }, | |
c929bc2a JZ |
353 | }; |
354 | ||
355 | static struct hns3_dbg_cap_info hns3_dbg_cap[] = { | |
356 | { | |
357 | .name = "support FD", | |
358 | .cap_bit = HNAE3_DEV_SUPPORT_FD_B, | |
359 | }, { | |
360 | .name = "support GRO", | |
361 | .cap_bit = HNAE3_DEV_SUPPORT_GRO_B, | |
362 | }, { | |
363 | .name = "support FEC", | |
364 | .cap_bit = HNAE3_DEV_SUPPORT_FEC_B, | |
365 | }, { | |
366 | .name = "support UDP GSO", | |
367 | .cap_bit = HNAE3_DEV_SUPPORT_UDP_GSO_B, | |
368 | }, { | |
369 | .name = "support PTP", | |
370 | .cap_bit = HNAE3_DEV_SUPPORT_PTP_B, | |
371 | }, { | |
372 | .name = "support INT QL", | |
373 | .cap_bit = HNAE3_DEV_SUPPORT_INT_QL_B, | |
374 | }, { | |
375 | .name = "support HW TX csum", | |
376 | .cap_bit = HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, | |
377 | }, { | |
378 | .name = "support UDP tunnel csum", | |
379 | .cap_bit = HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, | |
380 | }, { | |
381 | .name = "support TX push", | |
382 | .cap_bit = HNAE3_DEV_SUPPORT_TX_PUSH_B, | |
383 | }, { | |
384 | .name = "support imp-controlled PHY", | |
385 | .cap_bit = HNAE3_DEV_SUPPORT_PHY_IMP_B, | |
e65e9f5c JZ |
386 | }, { |
387 | .name = "support imp-controlled RAS", | |
388 | .cap_bit = HNAE3_DEV_SUPPORT_RAS_IMP_B, | |
c929bc2a JZ |
389 | }, { |
390 | .name = "support rxd advanced layout", | |
391 | .cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, | |
2ba30662 JS |
392 | }, { |
393 | .name = "support port vlan bypass", | |
394 | .cap_bit = HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, | |
395 | }, { | |
396 | .name = "support modify vlan filter state", | |
397 | .cap_bit = HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, | |
398 | } | |
5e69ea7e YM |
399 | }; |
400 | ||
c99fead7 HT |
401 | static const struct hns3_dbg_item coal_info_items[] = { |
402 | { "VEC_ID", 2 }, | |
403 | { "ALGO_STATE", 2 }, | |
404 | { "PROFILE_ID", 2 }, | |
405 | { "CQE_MODE", 2 }, | |
406 | { "TUNE_STATE", 2 }, | |
407 | { "STEPS_LEFT", 2 }, | |
408 | { "STEPS_RIGHT", 2 }, | |
409 | { "TIRED", 2 }, | |
410 | { "SW_GL", 2 }, | |
411 | { "SW_QL", 2 }, | |
412 | { "HW_GL", 2 }, | |
413 | { "HW_QL", 2 }, | |
414 | }; | |
415 | ||
416 | static const char * const dim_cqe_mode_str[] = { "EQE", "CQE" }; | |
417 | static const char * const dim_state_str[] = { "START", "IN_PROG", "APPLY" }; | |
418 | static const char * const | |
419 | dim_tune_stat_str[] = { "ON_TOP", "TIRED", "RIGHT", "LEFT" }; | |
420 | ||
77e91848 HT |
421 | static void hns3_dbg_fill_content(char *content, u16 len, |
422 | const struct hns3_dbg_item *items, | |
423 | const char **result, u16 size) | |
424 | { | |
425 | char *pos = content; | |
426 | u16 i; | |
427 | ||
428 | memset(content, ' ', len); | |
429 | for (i = 0; i < size; i++) { | |
430 | if (result) | |
431 | strncpy(pos, result[i], strlen(result[i])); | |
432 | else | |
433 | strncpy(pos, items[i].name, strlen(items[i].name)); | |
434 | ||
435 | pos += strlen(items[i].name) + items[i].interval; | |
436 | } | |
437 | ||
438 | *pos++ = '\n'; | |
439 | *pos++ = '\0'; | |
440 | } | |
441 | ||
c99fead7 HT |
442 | static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector, |
443 | char **result, int i, bool is_tx) | |
444 | { | |
445 | unsigned int gl_offset, ql_offset; | |
446 | struct hns3_enet_coalesce *coal; | |
447 | unsigned int reg_val; | |
448 | unsigned int j = 0; | |
449 | struct dim *dim; | |
450 | bool ql_enable; | |
451 | ||
452 | if (is_tx) { | |
453 | coal = &tqp_vector->tx_group.coal; | |
454 | dim = &tqp_vector->tx_group.dim; | |
455 | gl_offset = HNS3_VECTOR_GL1_OFFSET; | |
456 | ql_offset = HNS3_VECTOR_TX_QL_OFFSET; | |
457 | ql_enable = tqp_vector->tx_group.coal.ql_enable; | |
458 | } else { | |
459 | coal = &tqp_vector->rx_group.coal; | |
460 | dim = &tqp_vector->rx_group.dim; | |
461 | gl_offset = HNS3_VECTOR_GL0_OFFSET; | |
462 | ql_offset = HNS3_VECTOR_RX_QL_OFFSET; | |
463 | ql_enable = tqp_vector->rx_group.coal.ql_enable; | |
464 | } | |
465 | ||
466 | sprintf(result[j++], "%d", i); | |
467 | sprintf(result[j++], "%s", dim_state_str[dim->state]); | |
468 | sprintf(result[j++], "%u", dim->profile_ix); | |
469 | sprintf(result[j++], "%s", dim_cqe_mode_str[dim->mode]); | |
470 | sprintf(result[j++], "%s", | |
471 | dim_tune_stat_str[dim->tune_state]); | |
472 | sprintf(result[j++], "%u", dim->steps_left); | |
473 | sprintf(result[j++], "%u", dim->steps_right); | |
474 | sprintf(result[j++], "%u", dim->tired); | |
475 | sprintf(result[j++], "%u", coal->int_gl); | |
476 | sprintf(result[j++], "%u", coal->int_ql); | |
477 | reg_val = readl(tqp_vector->mask_addr + gl_offset) & | |
478 | HNS3_VECTOR_GL_MASK; | |
479 | sprintf(result[j++], "%u", reg_val); | |
480 | if (ql_enable) { | |
481 | reg_val = readl(tqp_vector->mask_addr + ql_offset) & | |
482 | HNS3_VECTOR_QL_MASK; | |
483 | sprintf(result[j++], "%u", reg_val); | |
484 | } else { | |
485 | sprintf(result[j++], "NA"); | |
486 | } | |
487 | } | |
488 | ||
489 | static void hns3_dump_coal_info(struct hnae3_handle *h, char *buf, int len, | |
490 | int *pos, bool is_tx) | |
491 | { | |
492 | char data_str[ARRAY_SIZE(coal_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
493 | char *result[ARRAY_SIZE(coal_info_items)]; | |
494 | struct hns3_enet_tqp_vector *tqp_vector; | |
495 | struct hns3_nic_priv *priv = h->priv; | |
496 | char content[HNS3_DBG_INFO_LEN]; | |
497 | unsigned int i; | |
498 | ||
499 | for (i = 0; i < ARRAY_SIZE(coal_info_items); i++) | |
500 | result[i] = &data_str[i][0]; | |
501 | ||
502 | *pos += scnprintf(buf + *pos, len - *pos, | |
503 | "%s interrupt coalesce info:\n", | |
504 | is_tx ? "tx" : "rx"); | |
505 | hns3_dbg_fill_content(content, sizeof(content), coal_info_items, | |
506 | NULL, ARRAY_SIZE(coal_info_items)); | |
507 | *pos += scnprintf(buf + *pos, len - *pos, "%s", content); | |
508 | ||
509 | for (i = 0; i < priv->vector_num; i++) { | |
510 | tqp_vector = &priv->tqp_vector[i]; | |
511 | hns3_get_coal_info(tqp_vector, result, i, is_tx); | |
512 | hns3_dbg_fill_content(content, sizeof(content), coal_info_items, | |
513 | (const char **)result, | |
514 | ARRAY_SIZE(coal_info_items)); | |
515 | *pos += scnprintf(buf + *pos, len - *pos, "%s", content); | |
516 | } | |
517 | } | |
518 | ||
519 | static int hns3_dbg_coal_info(struct hnae3_handle *h, char *buf, int len) | |
520 | { | |
521 | int pos = 0; | |
522 | ||
523 | hns3_dump_coal_info(h, buf, len, &pos, true); | |
524 | pos += scnprintf(buf + pos, len - pos, "\n"); | |
525 | hns3_dump_coal_info(h, buf, len, &pos, false); | |
526 | ||
527 | return 0; | |
528 | } | |
529 | ||
907676b1 YL |
530 | static const struct hns3_dbg_item tx_spare_info_items[] = { |
531 | { "QUEUE_ID", 2 }, | |
532 | { "COPYBREAK", 2 }, | |
533 | { "LEN", 7 }, | |
534 | { "NTU", 4 }, | |
535 | { "NTC", 4 }, | |
536 | { "LTC", 4 }, | |
537 | { "DMA", 17 }, | |
538 | }; | |
539 | ||
540 | static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf, | |
541 | int len, u32 ring_num, int *pos) | |
542 | { | |
543 | char data_str[ARRAY_SIZE(tx_spare_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
544 | struct hns3_tx_spare *tx_spare = ring->tx_spare; | |
545 | char *result[ARRAY_SIZE(tx_spare_info_items)]; | |
546 | char content[HNS3_DBG_INFO_LEN]; | |
547 | u32 i, j; | |
548 | ||
549 | if (!tx_spare) { | |
550 | *pos += scnprintf(buf + *pos, len - *pos, | |
551 | "tx spare buffer is not enabled\n"); | |
552 | return; | |
553 | } | |
554 | ||
555 | for (i = 0; i < ARRAY_SIZE(tx_spare_info_items); i++) | |
556 | result[i] = &data_str[i][0]; | |
557 | ||
558 | *pos += scnprintf(buf + *pos, len - *pos, "tx spare buffer info\n"); | |
559 | hns3_dbg_fill_content(content, sizeof(content), tx_spare_info_items, | |
560 | NULL, ARRAY_SIZE(tx_spare_info_items)); | |
561 | *pos += scnprintf(buf + *pos, len - *pos, "%s", content); | |
562 | ||
563 | for (i = 0; i < ring_num; i++) { | |
564 | j = 0; | |
565 | sprintf(result[j++], "%8u", i); | |
566 | sprintf(result[j++], "%9u", ring->tx_copybreak); | |
567 | sprintf(result[j++], "%3u", tx_spare->len); | |
568 | sprintf(result[j++], "%3u", tx_spare->next_to_use); | |
569 | sprintf(result[j++], "%3u", tx_spare->next_to_clean); | |
570 | sprintf(result[j++], "%3u", tx_spare->last_to_clean); | |
571 | sprintf(result[j++], "%pad", &tx_spare->dma); | |
572 | hns3_dbg_fill_content(content, sizeof(content), | |
573 | tx_spare_info_items, | |
574 | (const char **)result, | |
575 | ARRAY_SIZE(tx_spare_info_items)); | |
576 | *pos += scnprintf(buf + *pos, len - *pos, "%s", content); | |
577 | } | |
578 | } | |
579 | ||
e44c495d HC |
580 | static const struct hns3_dbg_item rx_queue_info_items[] = { |
581 | { "QUEUE_ID", 2 }, | |
582 | { "BD_NUM", 2 }, | |
583 | { "BD_LEN", 2 }, | |
584 | { "TAIL", 2 }, | |
585 | { "HEAD", 2 }, | |
586 | { "FBDNUM", 2 }, | |
587 | { "PKTNUM", 2 }, | |
99f6b5fb | 588 | { "COPYBREAK", 2 }, |
e44c495d HC |
589 | { "RING_EN", 2 }, |
590 | { "RX_RING_EN", 2 }, | |
591 | { "BASE_ADDR", 10 }, | |
592 | }; | |
593 | ||
594 | static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring, | |
595 | struct hnae3_ae_dev *ae_dev, char **result, | |
596 | u32 index) | |
57ceee2c | 597 | { |
e44c495d HC |
598 | u32 base_add_l, base_add_h; |
599 | u32 j = 0; | |
600 | ||
601 | sprintf(result[j++], "%8u", index); | |
602 | ||
603 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
604 | HNS3_RING_RX_RING_BD_NUM_REG)); | |
605 | ||
606 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
607 | HNS3_RING_RX_RING_BD_LEN_REG)); | |
608 | ||
609 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + | |
610 | HNS3_RING_RX_RING_TAIL_REG)); | |
611 | ||
612 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + | |
613 | HNS3_RING_RX_RING_HEAD_REG)); | |
614 | ||
615 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
616 | HNS3_RING_RX_RING_FBDNUM_REG)); | |
617 | ||
618 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
619 | HNS3_RING_RX_RING_PKTNUM_RECORD_REG)); | |
99f6b5fb | 620 | sprintf(result[j++], "%9u", ring->rx_copybreak); |
e44c495d HC |
621 | |
622 | sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + | |
623 | HNS3_RING_EN_REG) ? "on" : "off"); | |
624 | ||
625 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) | |
626 | sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base + | |
627 | HNS3_RING_RX_EN_REG) ? "on" : "off"); | |
628 | else | |
629 | sprintf(result[j++], "%10s", "NA"); | |
630 | ||
631 | base_add_h = readl_relaxed(ring->tqp->io_base + | |
632 | HNS3_RING_RX_RING_BASEADDR_H_REG); | |
633 | base_add_l = readl_relaxed(ring->tqp->io_base + | |
634 | HNS3_RING_RX_RING_BASEADDR_L_REG); | |
635 | sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l); | |
636 | } | |
637 | ||
638 | static int hns3_dbg_rx_queue_info(struct hnae3_handle *h, | |
639 | char *buf, int len) | |
640 | { | |
641 | char data_str[ARRAY_SIZE(rx_queue_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
dbaae5bb | 642 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); |
e44c495d | 643 | char *result[ARRAY_SIZE(rx_queue_info_items)]; |
57ceee2c | 644 | struct hns3_nic_priv *priv = h->priv; |
e44c495d | 645 | char content[HNS3_DBG_INFO_LEN]; |
57ceee2c | 646 | struct hns3_enet_ring *ring; |
e44c495d HC |
647 | int pos = 0; |
648 | u32 i; | |
57ceee2c | 649 | |
5f06b903 YL |
650 | if (!priv->ring) { |
651 | dev_err(&h->pdev->dev, "priv->ring is NULL\n"); | |
57ceee2c | 652 | return -EFAULT; |
653 | } | |
654 | ||
e44c495d HC |
655 | for (i = 0; i < ARRAY_SIZE(rx_queue_info_items); i++) |
656 | result[i] = &data_str[i][0]; | |
57ceee2c | 657 | |
e44c495d HC |
658 | hns3_dbg_fill_content(content, sizeof(content), rx_queue_info_items, |
659 | NULL, ARRAY_SIZE(rx_queue_info_items)); | |
660 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
661 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
57ceee2c | 662 | /* Each cycle needs to determine whether the instance is reset, |
663 | * to prevent reference to invalid memory. And need to ensure | |
664 | * that the following code is executed within 100ms. | |
665 | */ | |
7737f1fb | 666 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
57ceee2c | 667 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) |
668 | return -EPERM; | |
669 | ||
5f06b903 | 670 | ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)]; |
e44c495d HC |
671 | hns3_dump_rx_queue_info(ring, ae_dev, result, i); |
672 | hns3_dbg_fill_content(content, sizeof(content), | |
673 | rx_queue_info_items, | |
674 | (const char **)result, | |
675 | ARRAY_SIZE(rx_queue_info_items)); | |
676 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
677 | } | |
678 | ||
679 | return 0; | |
680 | } | |
681 | ||
682 | static const struct hns3_dbg_item tx_queue_info_items[] = { | |
683 | { "QUEUE_ID", 2 }, | |
684 | { "BD_NUM", 2 }, | |
685 | { "TC", 2 }, | |
686 | { "TAIL", 2 }, | |
687 | { "HEAD", 2 }, | |
688 | { "FBDNUM", 2 }, | |
689 | { "OFFSET", 2 }, | |
690 | { "PKTNUM", 2 }, | |
691 | { "RING_EN", 2 }, | |
692 | { "TX_RING_EN", 2 }, | |
693 | { "BASE_ADDR", 10 }, | |
694 | }; | |
695 | ||
696 | static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring, | |
697 | struct hnae3_ae_dev *ae_dev, char **result, | |
698 | u32 index) | |
699 | { | |
700 | u32 base_add_l, base_add_h; | |
701 | u32 j = 0; | |
57ceee2c | 702 | |
e44c495d HC |
703 | sprintf(result[j++], "%8u", index); |
704 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
705 | HNS3_RING_TX_RING_BD_NUM_REG)); | |
57ceee2c | 706 | |
e44c495d HC |
707 | sprintf(result[j++], "%2u", readl_relaxed(ring->tqp->io_base + |
708 | HNS3_RING_TX_RING_TC_REG)); | |
57ceee2c | 709 | |
e44c495d HC |
710 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + |
711 | HNS3_RING_TX_RING_TAIL_REG)); | |
57ceee2c | 712 | |
e44c495d HC |
713 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + |
714 | HNS3_RING_TX_RING_HEAD_REG)); | |
57ceee2c | 715 | |
e44c495d HC |
716 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + |
717 | HNS3_RING_TX_RING_FBDNUM_REG)); | |
57ceee2c | 718 | |
e44c495d HC |
719 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + |
720 | HNS3_RING_TX_RING_OFFSET_REG)); | |
57ceee2c | 721 | |
e44c495d HC |
722 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + |
723 | HNS3_RING_TX_RING_PKTNUM_RECORD_REG)); | |
dbaae5bb | 724 | |
e44c495d HC |
725 | sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + |
726 | HNS3_RING_EN_REG) ? "on" : "off"); | |
727 | ||
728 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) | |
729 | sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base + | |
730 | HNS3_RING_TX_EN_REG) ? "on" : "off"); | |
731 | else | |
732 | sprintf(result[j++], "%10s", "NA"); | |
733 | ||
734 | base_add_h = readl_relaxed(ring->tqp->io_base + | |
735 | HNS3_RING_TX_RING_BASEADDR_H_REG); | |
736 | base_add_l = readl_relaxed(ring->tqp->io_base + | |
737 | HNS3_RING_TX_RING_BASEADDR_L_REG); | |
738 | sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l); | |
739 | } | |
740 | ||
741 | static int hns3_dbg_tx_queue_info(struct hnae3_handle *h, | |
742 | char *buf, int len) | |
743 | { | |
744 | char data_str[ARRAY_SIZE(tx_queue_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
745 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
746 | char *result[ARRAY_SIZE(tx_queue_info_items)]; | |
747 | struct hns3_nic_priv *priv = h->priv; | |
748 | char content[HNS3_DBG_INFO_LEN]; | |
749 | struct hns3_enet_ring *ring; | |
750 | int pos = 0; | |
751 | u32 i; | |
752 | ||
753 | if (!priv->ring) { | |
754 | dev_err(&h->pdev->dev, "priv->ring is NULL\n"); | |
755 | return -EFAULT; | |
756 | } | |
757 | ||
758 | for (i = 0; i < ARRAY_SIZE(tx_queue_info_items); i++) | |
759 | result[i] = &data_str[i][0]; | |
760 | ||
761 | hns3_dbg_fill_content(content, sizeof(content), tx_queue_info_items, | |
762 | NULL, ARRAY_SIZE(tx_queue_info_items)); | |
763 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
764 | ||
765 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
766 | /* Each cycle needs to determine whether the instance is reset, | |
767 | * to prevent reference to invalid memory. And need to ensure | |
768 | * that the following code is executed within 100ms. | |
769 | */ | |
770 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || | |
771 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) | |
772 | return -EPERM; | |
773 | ||
774 | ring = &priv->ring[i]; | |
775 | hns3_dump_tx_queue_info(ring, ae_dev, result, i); | |
776 | hns3_dbg_fill_content(content, sizeof(content), | |
777 | tx_queue_info_items, | |
778 | (const char **)result, | |
779 | ARRAY_SIZE(tx_queue_info_items)); | |
780 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
57ceee2c | 781 | } |
782 | ||
907676b1 YL |
783 | hns3_dbg_tx_spare_info(ring, buf, len, h->kinfo.num_tqps, &pos); |
784 | ||
57ceee2c | 785 | return 0; |
786 | } | |
787 | ||
d2f737cf HC |
788 | static const struct hns3_dbg_item queue_map_items[] = { |
789 | { "local_queue_id", 2 }, | |
790 | { "global_queue_id", 2 }, | |
791 | { "vector_id", 2 }, | |
792 | }; | |
793 | ||
794 | static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len) | |
0c29d191 | 795 | { |
d2f737cf HC |
796 | char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN]; |
797 | char *result[ARRAY_SIZE(queue_map_items)]; | |
0c29d191 | 798 | struct hns3_nic_priv *priv = h->priv; |
d2f737cf HC |
799 | char content[HNS3_DBG_INFO_LEN]; |
800 | int pos = 0; | |
801 | int j; | |
802 | u32 i; | |
0c29d191 | 803 | |
804 | if (!h->ae_algo->ops->get_global_queue_id) | |
805 | return -EOPNOTSUPP; | |
806 | ||
d2f737cf HC |
807 | for (i = 0; i < ARRAY_SIZE(queue_map_items); i++) |
808 | result[i] = &data_str[i][0]; | |
0c29d191 | 809 | |
d2f737cf HC |
810 | hns3_dbg_fill_content(content, sizeof(content), queue_map_items, |
811 | NULL, ARRAY_SIZE(queue_map_items)); | |
812 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
813 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
5f06b903 | 814 | if (!priv->ring || !priv->ring[i].tqp_vector) |
0c29d191 | 815 | continue; |
d2f737cf HC |
816 | j = 0; |
817 | sprintf(result[j++], "%u", i); | |
818 | sprintf(result[j++], "%u", | |
819 | h->ae_algo->ops->get_global_queue_id(h, i)); | |
5aea2da5 | 820 | sprintf(result[j++], "%d", |
d2f737cf HC |
821 | priv->ring[i].tqp_vector->vector_irq); |
822 | hns3_dbg_fill_content(content, sizeof(content), queue_map_items, | |
823 | (const char **)result, | |
824 | ARRAY_SIZE(queue_map_items)); | |
825 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
0c29d191 | 826 | } |
827 | ||
828 | return 0; | |
829 | } | |
830 | ||
77e91848 HT |
831 | static const struct hns3_dbg_item rx_bd_info_items[] = { |
832 | { "BD_IDX", 3 }, | |
833 | { "L234_INFO", 2 }, | |
834 | { "PKT_LEN", 3 }, | |
835 | { "SIZE", 4 }, | |
836 | { "RSS_HASH", 4 }, | |
837 | { "FD_ID", 2 }, | |
838 | { "VLAN_TAG", 2 }, | |
839 | { "O_DM_VLAN_ID_FB", 2 }, | |
840 | { "OT_VLAN_TAG", 2 }, | |
841 | { "BD_BASE_INFO", 2 }, | |
842 | { "PTYPE", 2 }, | |
843 | { "HW_CSUM", 2 }, | |
844 | }; | |
845 | ||
846 | static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv, | |
847 | struct hns3_desc *desc, char **result, int idx) | |
122bedc5 | 848 | { |
77e91848 HT |
849 | unsigned int j = 0; |
850 | ||
851 | sprintf(result[j++], "%5d", idx); | |
852 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info)); | |
853 | sprintf(result[j++], "%7u", le16_to_cpu(desc->rx.pkt_len)); | |
854 | sprintf(result[j++], "%4u", le16_to_cpu(desc->rx.size)); | |
855 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash)); | |
856 | sprintf(result[j++], "%5u", le16_to_cpu(desc->rx.fd_id)); | |
857 | sprintf(result[j++], "%8u", le16_to_cpu(desc->rx.vlan_tag)); | |
858 | sprintf(result[j++], "%15u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb)); | |
859 | sprintf(result[j++], "%11u", le16_to_cpu(desc->rx.ot_vlan_tag)); | |
860 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info)); | |
861 | if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) { | |
862 | u32 ol_info = le32_to_cpu(desc->rx.ol_info); | |
863 | ||
864 | sprintf(result[j++], "%5lu", hnae3_get_field(ol_info, | |
865 | HNS3_RXD_PTYPE_M, | |
866 | HNS3_RXD_PTYPE_S)); | |
867 | sprintf(result[j++], "%7u", le16_to_cpu(desc->csum)); | |
868 | } else { | |
869 | sprintf(result[j++], "NA"); | |
870 | sprintf(result[j++], "NA"); | |
871 | } | |
872 | } | |
873 | ||
874 | static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len) | |
875 | { | |
876 | char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
877 | struct hns3_nic_priv *priv = d->handle->priv; | |
878 | char *result[ARRAY_SIZE(rx_bd_info_items)]; | |
879 | char content[HNS3_DBG_INFO_LEN]; | |
122bedc5 | 880 | struct hns3_enet_ring *ring; |
77e91848 HT |
881 | struct hns3_desc *desc; |
882 | unsigned int i; | |
883 | int pos = 0; | |
122bedc5 | 884 | |
77e91848 HT |
885 | if (d->qid >= d->handle->kinfo.num_tqps) { |
886 | dev_err(&d->handle->pdev->dev, | |
887 | "queue%u is not in use\n", d->qid); | |
122bedc5 | 888 | return -EINVAL; |
889 | } | |
890 | ||
77e91848 HT |
891 | for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++) |
892 | result[i] = &data_str[i][0]; | |
893 | ||
894 | pos += scnprintf(buf + pos, len - pos, | |
895 | "Queue %u rx bd info:\n", d->qid); | |
896 | hns3_dbg_fill_content(content, sizeof(content), rx_bd_info_items, | |
897 | NULL, ARRAY_SIZE(rx_bd_info_items)); | |
898 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
899 | ||
900 | ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps]; | |
901 | for (i = 0; i < ring->desc_num; i++) { | |
902 | desc = &ring->desc[i]; | |
903 | ||
904 | hns3_dump_rx_bd_info(priv, desc, result, i); | |
905 | hns3_dbg_fill_content(content, sizeof(content), | |
906 | rx_bd_info_items, (const char **)result, | |
907 | ARRAY_SIZE(rx_bd_info_items)); | |
908 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
122bedc5 | 909 | } |
910 | ||
77e91848 HT |
911 | return 0; |
912 | } | |
913 | ||
914 | static const struct hns3_dbg_item tx_bd_info_items[] = { | |
915 | { "BD_IDX", 5 }, | |
916 | { "ADDRESS", 2 }, | |
917 | { "VLAN_TAG", 2 }, | |
918 | { "SIZE", 2 }, | |
919 | { "T_CS_VLAN_TSO", 2 }, | |
920 | { "OT_VLAN_TAG", 3 }, | |
921 | { "TV", 2 }, | |
c74e5035 HC |
922 | { "OLT_VLAN_LEN", 2 }, |
923 | { "PAYLEN_OL4CS", 2 }, | |
924 | { "BD_FE_SC_VLD", 2 }, | |
925 | { "MSS_HW_CSUM", 0 }, | |
77e91848 | 926 | }; |
122bedc5 | 927 | |
77e91848 HT |
928 | static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv, |
929 | struct hns3_desc *desc, char **result, int idx) | |
930 | { | |
931 | unsigned int j = 0; | |
932 | ||
933 | sprintf(result[j++], "%6d", idx); | |
934 | sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr)); | |
935 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.vlan_tag)); | |
936 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.send_size)); | |
937 | sprintf(result[j++], "%#x", | |
938 | le32_to_cpu(desc->tx.type_cs_vlan_tso_len)); | |
939 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.outer_vlan_tag)); | |
940 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.tv)); | |
941 | sprintf(result[j++], "%10u", | |
942 | le32_to_cpu(desc->tx.ol_type_vlan_len_msec)); | |
943 | sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs)); | |
944 | sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri)); | |
945 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum)); | |
946 | } | |
947 | ||
948 | static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len) | |
949 | { | |
950 | char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
951 | struct hns3_nic_priv *priv = d->handle->priv; | |
952 | char *result[ARRAY_SIZE(tx_bd_info_items)]; | |
953 | char content[HNS3_DBG_INFO_LEN]; | |
954 | struct hns3_enet_ring *ring; | |
955 | struct hns3_desc *desc; | |
956 | unsigned int i; | |
957 | int pos = 0; | |
958 | ||
959 | if (d->qid >= d->handle->kinfo.num_tqps) { | |
960 | dev_err(&d->handle->pdev->dev, | |
961 | "queue%u is not in use\n", d->qid); | |
122bedc5 | 962 | return -EINVAL; |
963 | } | |
964 | ||
77e91848 HT |
965 | for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++) |
966 | result[i] = &data_str[i][0]; | |
967 | ||
968 | pos += scnprintf(buf + pos, len - pos, | |
969 | "Queue %u tx bd info:\n", d->qid); | |
970 | hns3_dbg_fill_content(content, sizeof(content), tx_bd_info_items, | |
971 | NULL, ARRAY_SIZE(tx_bd_info_items)); | |
972 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
b1533ada | 973 | |
77e91848 HT |
974 | ring = &priv->ring[d->qid]; |
975 | for (i = 0; i < ring->desc_num; i++) { | |
976 | desc = &ring->desc[i]; | |
977 | ||
978 | hns3_dump_tx_bd_info(priv, desc, result, i); | |
979 | hns3_dbg_fill_content(content, sizeof(content), | |
980 | tx_bd_info_items, (const char **)result, | |
981 | ARRAY_SIZE(tx_bd_info_items)); | |
982 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
983 | } | |
122bedc5 | 984 | |
985 | return 0; | |
986 | } | |
987 | ||
c929bc2a JZ |
988 | static void |
989 | hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos) | |
9484e337 GH |
990 | { |
991 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
1026b153 | 992 | const char * const str[] = {"no", "yes"}; |
c929bc2a JZ |
993 | unsigned long *caps = ae_dev->caps; |
994 | u32 i, state; | |
995 | ||
996 | *pos += scnprintf(buf + *pos, len - *pos, "dev capability:\n"); | |
997 | ||
998 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) { | |
999 | state = test_bit(hns3_dbg_cap[i].cap_bit, caps); | |
1000 | *pos += scnprintf(buf + *pos, len - *pos, "%s: %s\n", | |
1001 | hns3_dbg_cap[i].name, str[state]); | |
1002 | } | |
1003 | ||
1004 | *pos += scnprintf(buf + *pos, len - *pos, "\n"); | |
9484e337 GH |
1005 | } |
1006 | ||
c929bc2a JZ |
1007 | static void |
1008 | hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos) | |
b4442ec5 GH |
1009 | { |
1010 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
1011 | struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs; | |
1012 | struct hnae3_knic_private_info *kinfo = &h->kinfo; | |
c929bc2a JZ |
1013 | |
1014 | *pos += scnprintf(buf + *pos, len - *pos, "dev_spec:\n"); | |
1015 | *pos += scnprintf(buf + *pos, len - *pos, "MAC entry num: %u\n", | |
1016 | dev_specs->mac_entry_num); | |
1017 | *pos += scnprintf(buf + *pos, len - *pos, "MNG entry num: %u\n", | |
1018 | dev_specs->mng_entry_num); | |
1019 | *pos += scnprintf(buf + *pos, len - *pos, "MAX non tso bd num: %u\n", | |
1020 | dev_specs->max_non_tso_bd_num); | |
1021 | *pos += scnprintf(buf + *pos, len - *pos, "RSS ind tbl size: %u\n", | |
1022 | dev_specs->rss_ind_tbl_size); | |
1023 | *pos += scnprintf(buf + *pos, len - *pos, "RSS key size: %u\n", | |
1024 | dev_specs->rss_key_size); | |
1025 | *pos += scnprintf(buf + *pos, len - *pos, "RSS size: %u\n", | |
1026 | kinfo->rss_size); | |
1027 | *pos += scnprintf(buf + *pos, len - *pos, "Allocated RSS size: %u\n", | |
1028 | kinfo->req_rss_size); | |
1029 | *pos += scnprintf(buf + *pos, len - *pos, | |
1030 | "Task queue pairs numbers: %u\n", | |
1031 | kinfo->num_tqps); | |
1032 | *pos += scnprintf(buf + *pos, len - *pos, "RX buffer length: %u\n", | |
1033 | kinfo->rx_buf_len); | |
1034 | *pos += scnprintf(buf + *pos, len - *pos, "Desc num per TX queue: %u\n", | |
1035 | kinfo->num_tx_desc); | |
1036 | *pos += scnprintf(buf + *pos, len - *pos, "Desc num per RX queue: %u\n", | |
1037 | kinfo->num_rx_desc); | |
1038 | *pos += scnprintf(buf + *pos, len - *pos, | |
1039 | "Total number of enabled TCs: %u\n", | |
1040 | kinfo->tc_info.num_tc); | |
1041 | *pos += scnprintf(buf + *pos, len - *pos, "MAX INT QL: %u\n", | |
1042 | dev_specs->int_ql_max); | |
1043 | *pos += scnprintf(buf + *pos, len - *pos, "MAX INT GL: %u\n", | |
1044 | dev_specs->max_int_gl); | |
1045 | *pos += scnprintf(buf + *pos, len - *pos, "MAX TM RATE: %u\n", | |
1046 | dev_specs->max_tm_rate); | |
1047 | *pos += scnprintf(buf + *pos, len - *pos, "MAX QSET number: %u\n", | |
1048 | dev_specs->max_qset_num); | |
e435a6b5 GH |
1049 | *pos += scnprintf(buf + *pos, len - *pos, "umv size: %u\n", |
1050 | dev_specs->umv_size); | |
5c56ff48 GH |
1051 | *pos += scnprintf(buf + *pos, len - *pos, "mc mac size: %u\n", |
1052 | dev_specs->mc_mac_size); | |
c929bc2a JZ |
1053 | } |
1054 | ||
1055 | static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len) | |
1056 | { | |
1057 | int pos = 0; | |
1058 | ||
1059 | hns3_dbg_dev_caps(h, buf, len, &pos); | |
1060 | ||
1061 | hns3_dbg_dev_specs(h, buf, len, &pos); | |
1062 | ||
1063 | return 0; | |
b4442ec5 GH |
1064 | } |
1065 | ||
850bfb91 HC |
1066 | static const struct hns3_dbg_item page_pool_info_items[] = { |
1067 | { "QUEUE_ID", 2 }, | |
1068 | { "ALLOCATE_CNT", 2 }, | |
1069 | { "FREE_CNT", 6 }, | |
1070 | { "POOL_SIZE(PAGE_NUM)", 2 }, | |
1071 | { "ORDER", 2 }, | |
1072 | { "NUMA_ID", 2 }, | |
1073 | { "MAX_LEN", 2 }, | |
1074 | }; | |
1075 | ||
1076 | static void hns3_dump_page_pool_info(struct hns3_enet_ring *ring, | |
1077 | char **result, u32 index) | |
1078 | { | |
1079 | u32 j = 0; | |
1080 | ||
1081 | sprintf(result[j++], "%u", index); | |
1082 | sprintf(result[j++], "%u", ring->page_pool->pages_state_hold_cnt); | |
1083 | sprintf(result[j++], "%u", | |
1084 | atomic_read(&ring->page_pool->pages_state_release_cnt)); | |
1085 | sprintf(result[j++], "%u", ring->page_pool->p.pool_size); | |
1086 | sprintf(result[j++], "%u", ring->page_pool->p.order); | |
1087 | sprintf(result[j++], "%d", ring->page_pool->p.nid); | |
1088 | sprintf(result[j++], "%uK", ring->page_pool->p.max_len / 1024); | |
1089 | } | |
1090 | ||
1091 | static int | |
1092 | hns3_dbg_page_pool_info(struct hnae3_handle *h, char *buf, int len) | |
1093 | { | |
1094 | char data_str[ARRAY_SIZE(page_pool_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
1095 | char *result[ARRAY_SIZE(page_pool_info_items)]; | |
1096 | struct hns3_nic_priv *priv = h->priv; | |
1097 | char content[HNS3_DBG_INFO_LEN]; | |
1098 | struct hns3_enet_ring *ring; | |
1099 | int pos = 0; | |
1100 | u32 i; | |
1101 | ||
1102 | if (!priv->ring) { | |
1103 | dev_err(&h->pdev->dev, "priv->ring is NULL\n"); | |
1104 | return -EFAULT; | |
1105 | } | |
1106 | ||
1107 | for (i = 0; i < ARRAY_SIZE(page_pool_info_items); i++) | |
1108 | result[i] = &data_str[i][0]; | |
1109 | ||
1110 | hns3_dbg_fill_content(content, sizeof(content), page_pool_info_items, | |
1111 | NULL, ARRAY_SIZE(page_pool_info_items)); | |
1112 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
1113 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
1114 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || | |
1115 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) | |
1116 | return -EPERM; | |
1117 | ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)]; | |
1118 | hns3_dump_page_pool_info(ring, result, i); | |
1119 | hns3_dbg_fill_content(content, sizeof(content), | |
1120 | page_pool_info_items, | |
1121 | (const char **)result, | |
1122 | ARRAY_SIZE(page_pool_info_items)); | |
1123 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
1124 | } | |
1125 | ||
1126 | return 0; | |
1127 | } | |
1128 | ||
55649d56 | 1129 | static int hns3_dbg_get_cmd_index(struct hns3_dbg_data *dbg_data, u32 *index) |
5e69ea7e YM |
1130 | { |
1131 | u32 i; | |
1132 | ||
1133 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { | |
55649d56 | 1134 | if (hns3_dbg_cmd[i].cmd == dbg_data->cmd) { |
5e69ea7e YM |
1135 | *index = i; |
1136 | return 0; | |
1137 | } | |
1138 | } | |
1139 | ||
55649d56 YM |
1140 | dev_err(&dbg_data->handle->pdev->dev, "unknown command(%d)\n", |
1141 | dbg_data->cmd); | |
5e69ea7e YM |
1142 | return -EINVAL; |
1143 | } | |
1144 | ||
c929bc2a | 1145 | static const struct hns3_dbg_func hns3_dbg_cmd_func[] = { |
d2f737cf HC |
1146 | { |
1147 | .cmd = HNAE3_DBG_CMD_QUEUE_MAP, | |
1148 | .dbg_dump = hns3_dbg_queue_map, | |
1149 | }, | |
c929bc2a JZ |
1150 | { |
1151 | .cmd = HNAE3_DBG_CMD_DEV_INFO, | |
1152 | .dbg_dump = hns3_dbg_dev_info, | |
1153 | }, | |
77e91848 HT |
1154 | { |
1155 | .cmd = HNAE3_DBG_CMD_TX_BD, | |
1156 | .dbg_dump_bd = hns3_dbg_tx_bd_info, | |
1157 | }, | |
1158 | { | |
1159 | .cmd = HNAE3_DBG_CMD_RX_BD, | |
1160 | .dbg_dump_bd = hns3_dbg_rx_bd_info, | |
1161 | }, | |
e44c495d HC |
1162 | { |
1163 | .cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO, | |
1164 | .dbg_dump = hns3_dbg_rx_queue_info, | |
1165 | }, | |
1166 | { | |
1167 | .cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO, | |
1168 | .dbg_dump = hns3_dbg_tx_queue_info, | |
1169 | }, | |
850bfb91 HC |
1170 | { |
1171 | .cmd = HNAE3_DBG_CMD_PAGE_POOL_INFO, | |
1172 | .dbg_dump = hns3_dbg_page_pool_info, | |
1173 | }, | |
c99fead7 HT |
1174 | { |
1175 | .cmd = HNAE3_DBG_CMD_COAL_INFO, | |
1176 | .dbg_dump = hns3_dbg_coal_info, | |
1177 | }, | |
c929bc2a JZ |
1178 | }; |
1179 | ||
77e91848 | 1180 | static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data, |
5e69ea7e YM |
1181 | enum hnae3_dbg_cmd cmd, char *buf, int len) |
1182 | { | |
77e91848 HT |
1183 | const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops; |
1184 | const struct hns3_dbg_func *cmd_func; | |
c929bc2a JZ |
1185 | u32 i; |
1186 | ||
1187 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) { | |
77e91848 HT |
1188 | if (cmd == hns3_dbg_cmd_func[i].cmd) { |
1189 | cmd_func = &hns3_dbg_cmd_func[i]; | |
1190 | if (cmd_func->dbg_dump) | |
1191 | return cmd_func->dbg_dump(dbg_data->handle, buf, | |
1192 | len); | |
1193 | else | |
1194 | return cmd_func->dbg_dump_bd(dbg_data, buf, | |
1195 | len); | |
1196 | } | |
c929bc2a | 1197 | } |
5e69ea7e YM |
1198 | |
1199 | if (!ops->dbg_read_cmd) | |
1200 | return -EOPNOTSUPP; | |
1201 | ||
77e91848 | 1202 | return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len); |
5e69ea7e YM |
1203 | } |
1204 | ||
04987ca1 GH |
1205 | static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, |
1206 | size_t count, loff_t *ppos) | |
1207 | { | |
77e91848 HT |
1208 | struct hns3_dbg_data *dbg_data = filp->private_data; |
1209 | struct hnae3_handle *handle = dbg_data->handle; | |
04987ca1 | 1210 | struct hns3_nic_priv *priv = handle->priv; |
04987ca1 | 1211 | ssize_t size = 0; |
5e69ea7e YM |
1212 | char **save_buf; |
1213 | char *read_buf; | |
1214 | u32 index; | |
1215 | int ret; | |
04987ca1 | 1216 | |
55649d56 | 1217 | ret = hns3_dbg_get_cmd_index(dbg_data, &index); |
5e69ea7e YM |
1218 | if (ret) |
1219 | return ret; | |
04987ca1 | 1220 | |
5e69ea7e | 1221 | save_buf = &hns3_dbg_cmd[index].buf; |
04987ca1 | 1222 | |
5e69ea7e YM |
1223 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
1224 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { | |
1225 | ret = -EBUSY; | |
04987ca1 GH |
1226 | goto out; |
1227 | } | |
1228 | ||
5e69ea7e YM |
1229 | if (*save_buf) { |
1230 | read_buf = *save_buf; | |
1231 | } else { | |
1232 | read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL); | |
1233 | if (!read_buf) | |
1234 | return -ENOMEM; | |
1235 | ||
1236 | /* save the buffer addr until the last read operation */ | |
1237 | *save_buf = read_buf; | |
1238 | } | |
1239 | ||
1240 | /* get data ready for the first time to read */ | |
1241 | if (!*ppos) { | |
77e91848 | 1242 | ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, |
5e69ea7e YM |
1243 | read_buf, hns3_dbg_cmd[index].buf_len); |
1244 | if (ret) | |
1245 | goto out; | |
1246 | } | |
1247 | ||
04987ca1 GH |
1248 | size = simple_read_from_buffer(buffer, count, ppos, read_buf, |
1249 | strlen(read_buf)); | |
5e69ea7e YM |
1250 | if (size > 0) |
1251 | return size; | |
04987ca1 GH |
1252 | |
1253 | out: | |
5e69ea7e YM |
1254 | /* free the buffer for the last read operation */ |
1255 | if (*save_buf) { | |
1256 | kvfree(*save_buf); | |
1257 | *save_buf = NULL; | |
1258 | } | |
1259 | ||
1260 | return ret; | |
04987ca1 GH |
1261 | } |
1262 | ||
04987ca1 GH |
1263 | static const struct file_operations hns3_dbg_fops = { |
1264 | .owner = THIS_MODULE, | |
1265 | .open = simple_open, | |
1266 | .read = hns3_dbg_read, | |
1267 | }; | |
1268 | ||
77e91848 HT |
1269 | static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd) |
1270 | { | |
1271 | struct dentry *entry_dir; | |
1272 | struct hns3_dbg_data *data; | |
1273 | u16 max_queue_num; | |
1274 | unsigned int i; | |
1275 | ||
1276 | entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry; | |
1277 | max_queue_num = hns3_get_max_available_channels(handle); | |
1278 | data = devm_kzalloc(&handle->pdev->dev, max_queue_num * sizeof(*data), | |
1279 | GFP_KERNEL); | |
1280 | if (!data) | |
1281 | return -ENOMEM; | |
1282 | ||
1283 | for (i = 0; i < max_queue_num; i++) { | |
1284 | char name[HNS3_DBG_FILE_NAME_LEN]; | |
1285 | ||
1286 | data[i].handle = handle; | |
55649d56 | 1287 | data[i].cmd = hns3_dbg_cmd[cmd].cmd; |
77e91848 HT |
1288 | data[i].qid = i; |
1289 | sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i); | |
1290 | debugfs_create_file(name, 0400, entry_dir, &data[i], | |
1291 | &hns3_dbg_fops); | |
1292 | } | |
1293 | ||
1294 | return 0; | |
1295 | } | |
1296 | ||
5e69ea7e YM |
1297 | static int |
1298 | hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd) | |
1299 | { | |
77e91848 | 1300 | struct hns3_dbg_data *data; |
5e69ea7e YM |
1301 | struct dentry *entry_dir; |
1302 | ||
77e91848 HT |
1303 | data = devm_kzalloc(&handle->pdev->dev, sizeof(*data), GFP_KERNEL); |
1304 | if (!data) | |
1305 | return -ENOMEM; | |
1306 | ||
1307 | data->handle = handle; | |
55649d56 | 1308 | data->cmd = hns3_dbg_cmd[cmd].cmd; |
5e69ea7e YM |
1309 | entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry; |
1310 | debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir, | |
77e91848 | 1311 | data, &hns3_dbg_fops); |
5e69ea7e YM |
1312 | |
1313 | return 0; | |
1314 | } | |
1315 | ||
1316 | int hns3_dbg_init(struct hnae3_handle *handle) | |
b2292360 | 1317 | { |
04987ca1 | 1318 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); |
b2292360 | 1319 | const char *name = pci_name(handle->pdev); |
5e69ea7e YM |
1320 | int ret; |
1321 | u32 i; | |
b2292360 | 1322 | |
5e69ea7e YM |
1323 | hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry = |
1324 | debugfs_create_dir(name, hns3_dbgfs_root); | |
1325 | handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry; | |
b2292360 | 1326 | |
5e69ea7e YM |
1327 | for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++) |
1328 | hns3_dbg_dentry[i].dentry = | |
1329 | debugfs_create_dir(hns3_dbg_dentry[i].name, | |
1330 | handle->hnae3_dbgfs); | |
1331 | ||
1332 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { | |
b34c157f HT |
1333 | if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES && |
1334 | ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) || | |
1335 | (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_PTP_INFO && | |
1336 | !test_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps))) | |
5e69ea7e YM |
1337 | continue; |
1338 | ||
1339 | if (!hns3_dbg_cmd[i].init) { | |
1340 | dev_err(&handle->pdev->dev, | |
1341 | "cmd %s lack of init func\n", | |
1342 | hns3_dbg_cmd[i].name); | |
1343 | ret = -EINVAL; | |
1344 | goto out; | |
1345 | } | |
1346 | ||
1347 | ret = hns3_dbg_cmd[i].init(handle, i); | |
1348 | if (ret) { | |
1349 | dev_err(&handle->pdev->dev, "failed to init cmd %s\n", | |
1350 | hns3_dbg_cmd[i].name); | |
1351 | goto out; | |
1352 | } | |
1353 | } | |
1354 | ||
1355 | return 0; | |
1356 | ||
1357 | out: | |
1358 | debugfs_remove_recursive(handle->hnae3_dbgfs); | |
1359 | handle->hnae3_dbgfs = NULL; | |
1360 | return ret; | |
b2292360 | 1361 | } |
1362 | ||
1363 | void hns3_dbg_uninit(struct hnae3_handle *handle) | |
1364 | { | |
5e69ea7e YM |
1365 | u32 i; |
1366 | ||
1367 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) | |
1368 | if (hns3_dbg_cmd[i].buf) { | |
1369 | kvfree(hns3_dbg_cmd[i].buf); | |
1370 | hns3_dbg_cmd[i].buf = NULL; | |
1371 | } | |
1372 | ||
b2292360 | 1373 | debugfs_remove_recursive(handle->hnae3_dbgfs); |
1374 | handle->hnae3_dbgfs = NULL; | |
1375 | } | |
1376 | ||
1377 | void hns3_dbg_register_debugfs(const char *debugfs_dir_name) | |
1378 | { | |
1379 | hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL); | |
b2292360 | 1380 | } |
1381 | ||
1382 | void hns3_dbg_unregister_debugfs(void) | |
1383 | { | |
1384 | debugfs_remove_recursive(hns3_dbgfs_root); | |
1385 | hns3_dbgfs_root = NULL; | |
1386 | } |