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, | |
c7a6e397 | 140 | .buf_len = HNS3_DBG_READ_LEN_128KB, |
1556ea91 HT |
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, | |
c7a6e397 | 259 | .buf_len = HNS3_DBG_READ_LEN_128KB, |
d96b0e59 YM |
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, | |
c7a6e397 | 301 | .buf_len = HNS3_DBG_READ_LEN_1MB, |
b5a0b70d HC |
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 | }, | |
c929bc2a JZ |
339 | }; |
340 | ||
341 | static struct hns3_dbg_cap_info hns3_dbg_cap[] = { | |
342 | { | |
343 | .name = "support FD", | |
344 | .cap_bit = HNAE3_DEV_SUPPORT_FD_B, | |
345 | }, { | |
346 | .name = "support GRO", | |
347 | .cap_bit = HNAE3_DEV_SUPPORT_GRO_B, | |
348 | }, { | |
349 | .name = "support FEC", | |
350 | .cap_bit = HNAE3_DEV_SUPPORT_FEC_B, | |
351 | }, { | |
352 | .name = "support UDP GSO", | |
353 | .cap_bit = HNAE3_DEV_SUPPORT_UDP_GSO_B, | |
354 | }, { | |
355 | .name = "support PTP", | |
356 | .cap_bit = HNAE3_DEV_SUPPORT_PTP_B, | |
357 | }, { | |
358 | .name = "support INT QL", | |
359 | .cap_bit = HNAE3_DEV_SUPPORT_INT_QL_B, | |
360 | }, { | |
361 | .name = "support HW TX csum", | |
362 | .cap_bit = HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, | |
363 | }, { | |
364 | .name = "support UDP tunnel csum", | |
365 | .cap_bit = HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, | |
366 | }, { | |
367 | .name = "support TX push", | |
368 | .cap_bit = HNAE3_DEV_SUPPORT_TX_PUSH_B, | |
369 | }, { | |
370 | .name = "support imp-controlled PHY", | |
371 | .cap_bit = HNAE3_DEV_SUPPORT_PHY_IMP_B, | |
e65e9f5c JZ |
372 | }, { |
373 | .name = "support imp-controlled RAS", | |
374 | .cap_bit = HNAE3_DEV_SUPPORT_RAS_IMP_B, | |
c929bc2a JZ |
375 | }, { |
376 | .name = "support rxd advanced layout", | |
377 | .cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, | |
2ba30662 JS |
378 | }, { |
379 | .name = "support port vlan bypass", | |
380 | .cap_bit = HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, | |
381 | }, { | |
382 | .name = "support modify vlan filter state", | |
383 | .cap_bit = HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, | |
384 | } | |
5e69ea7e YM |
385 | }; |
386 | ||
77e91848 HT |
387 | static void hns3_dbg_fill_content(char *content, u16 len, |
388 | const struct hns3_dbg_item *items, | |
389 | const char **result, u16 size) | |
390 | { | |
391 | char *pos = content; | |
392 | u16 i; | |
393 | ||
394 | memset(content, ' ', len); | |
395 | for (i = 0; i < size; i++) { | |
396 | if (result) | |
397 | strncpy(pos, result[i], strlen(result[i])); | |
398 | else | |
399 | strncpy(pos, items[i].name, strlen(items[i].name)); | |
400 | ||
401 | pos += strlen(items[i].name) + items[i].interval; | |
402 | } | |
403 | ||
404 | *pos++ = '\n'; | |
405 | *pos++ = '\0'; | |
406 | } | |
407 | ||
907676b1 YL |
408 | static const struct hns3_dbg_item tx_spare_info_items[] = { |
409 | { "QUEUE_ID", 2 }, | |
410 | { "COPYBREAK", 2 }, | |
411 | { "LEN", 7 }, | |
412 | { "NTU", 4 }, | |
413 | { "NTC", 4 }, | |
414 | { "LTC", 4 }, | |
415 | { "DMA", 17 }, | |
416 | }; | |
417 | ||
418 | static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf, | |
419 | int len, u32 ring_num, int *pos) | |
420 | { | |
421 | char data_str[ARRAY_SIZE(tx_spare_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
422 | struct hns3_tx_spare *tx_spare = ring->tx_spare; | |
423 | char *result[ARRAY_SIZE(tx_spare_info_items)]; | |
424 | char content[HNS3_DBG_INFO_LEN]; | |
425 | u32 i, j; | |
426 | ||
427 | if (!tx_spare) { | |
428 | *pos += scnprintf(buf + *pos, len - *pos, | |
429 | "tx spare buffer is not enabled\n"); | |
430 | return; | |
431 | } | |
432 | ||
433 | for (i = 0; i < ARRAY_SIZE(tx_spare_info_items); i++) | |
434 | result[i] = &data_str[i][0]; | |
435 | ||
436 | *pos += scnprintf(buf + *pos, len - *pos, "tx spare buffer info\n"); | |
437 | hns3_dbg_fill_content(content, sizeof(content), tx_spare_info_items, | |
438 | NULL, ARRAY_SIZE(tx_spare_info_items)); | |
439 | *pos += scnprintf(buf + *pos, len - *pos, "%s", content); | |
440 | ||
441 | for (i = 0; i < ring_num; i++) { | |
442 | j = 0; | |
443 | sprintf(result[j++], "%8u", i); | |
444 | sprintf(result[j++], "%9u", ring->tx_copybreak); | |
445 | sprintf(result[j++], "%3u", tx_spare->len); | |
446 | sprintf(result[j++], "%3u", tx_spare->next_to_use); | |
447 | sprintf(result[j++], "%3u", tx_spare->next_to_clean); | |
448 | sprintf(result[j++], "%3u", tx_spare->last_to_clean); | |
449 | sprintf(result[j++], "%pad", &tx_spare->dma); | |
450 | hns3_dbg_fill_content(content, sizeof(content), | |
451 | tx_spare_info_items, | |
452 | (const char **)result, | |
453 | ARRAY_SIZE(tx_spare_info_items)); | |
454 | *pos += scnprintf(buf + *pos, len - *pos, "%s", content); | |
455 | } | |
456 | } | |
457 | ||
e44c495d HC |
458 | static const struct hns3_dbg_item rx_queue_info_items[] = { |
459 | { "QUEUE_ID", 2 }, | |
460 | { "BD_NUM", 2 }, | |
461 | { "BD_LEN", 2 }, | |
462 | { "TAIL", 2 }, | |
463 | { "HEAD", 2 }, | |
464 | { "FBDNUM", 2 }, | |
6754614a | 465 | { "PKTNUM", 5 }, |
99f6b5fb | 466 | { "COPYBREAK", 2 }, |
e44c495d HC |
467 | { "RING_EN", 2 }, |
468 | { "RX_RING_EN", 2 }, | |
469 | { "BASE_ADDR", 10 }, | |
470 | }; | |
471 | ||
472 | static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring, | |
473 | struct hnae3_ae_dev *ae_dev, char **result, | |
474 | u32 index) | |
57ceee2c | 475 | { |
e44c495d HC |
476 | u32 base_add_l, base_add_h; |
477 | u32 j = 0; | |
478 | ||
479 | sprintf(result[j++], "%8u", index); | |
480 | ||
481 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
482 | HNS3_RING_RX_RING_BD_NUM_REG)); | |
483 | ||
484 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
485 | HNS3_RING_RX_RING_BD_LEN_REG)); | |
486 | ||
487 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + | |
488 | HNS3_RING_RX_RING_TAIL_REG)); | |
489 | ||
490 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + | |
491 | HNS3_RING_RX_RING_HEAD_REG)); | |
492 | ||
493 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
494 | HNS3_RING_RX_RING_FBDNUM_REG)); | |
495 | ||
496 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
497 | HNS3_RING_RX_RING_PKTNUM_RECORD_REG)); | |
99f6b5fb | 498 | sprintf(result[j++], "%9u", ring->rx_copybreak); |
e44c495d HC |
499 | |
500 | sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + | |
501 | HNS3_RING_EN_REG) ? "on" : "off"); | |
502 | ||
503 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) | |
504 | sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base + | |
505 | HNS3_RING_RX_EN_REG) ? "on" : "off"); | |
506 | else | |
507 | sprintf(result[j++], "%10s", "NA"); | |
508 | ||
509 | base_add_h = readl_relaxed(ring->tqp->io_base + | |
510 | HNS3_RING_RX_RING_BASEADDR_H_REG); | |
511 | base_add_l = readl_relaxed(ring->tqp->io_base + | |
512 | HNS3_RING_RX_RING_BASEADDR_L_REG); | |
513 | sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l); | |
514 | } | |
515 | ||
516 | static int hns3_dbg_rx_queue_info(struct hnae3_handle *h, | |
517 | char *buf, int len) | |
518 | { | |
519 | char data_str[ARRAY_SIZE(rx_queue_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
dbaae5bb | 520 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); |
e44c495d | 521 | char *result[ARRAY_SIZE(rx_queue_info_items)]; |
57ceee2c | 522 | struct hns3_nic_priv *priv = h->priv; |
e44c495d | 523 | char content[HNS3_DBG_INFO_LEN]; |
57ceee2c | 524 | struct hns3_enet_ring *ring; |
e44c495d HC |
525 | int pos = 0; |
526 | u32 i; | |
57ceee2c | 527 | |
5f06b903 YL |
528 | if (!priv->ring) { |
529 | dev_err(&h->pdev->dev, "priv->ring is NULL\n"); | |
57ceee2c | 530 | return -EFAULT; |
531 | } | |
532 | ||
e44c495d HC |
533 | for (i = 0; i < ARRAY_SIZE(rx_queue_info_items); i++) |
534 | result[i] = &data_str[i][0]; | |
57ceee2c | 535 | |
e44c495d HC |
536 | hns3_dbg_fill_content(content, sizeof(content), rx_queue_info_items, |
537 | NULL, ARRAY_SIZE(rx_queue_info_items)); | |
538 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
539 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
57ceee2c | 540 | /* Each cycle needs to determine whether the instance is reset, |
541 | * to prevent reference to invalid memory. And need to ensure | |
542 | * that the following code is executed within 100ms. | |
543 | */ | |
7737f1fb | 544 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
57ceee2c | 545 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) |
546 | return -EPERM; | |
547 | ||
5f06b903 | 548 | ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)]; |
e44c495d HC |
549 | hns3_dump_rx_queue_info(ring, ae_dev, result, i); |
550 | hns3_dbg_fill_content(content, sizeof(content), | |
551 | rx_queue_info_items, | |
552 | (const char **)result, | |
553 | ARRAY_SIZE(rx_queue_info_items)); | |
554 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
555 | } | |
556 | ||
557 | return 0; | |
558 | } | |
559 | ||
560 | static const struct hns3_dbg_item tx_queue_info_items[] = { | |
561 | { "QUEUE_ID", 2 }, | |
562 | { "BD_NUM", 2 }, | |
563 | { "TC", 2 }, | |
564 | { "TAIL", 2 }, | |
565 | { "HEAD", 2 }, | |
566 | { "FBDNUM", 2 }, | |
567 | { "OFFSET", 2 }, | |
6754614a | 568 | { "PKTNUM", 5 }, |
e44c495d HC |
569 | { "RING_EN", 2 }, |
570 | { "TX_RING_EN", 2 }, | |
571 | { "BASE_ADDR", 10 }, | |
572 | }; | |
573 | ||
574 | static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring, | |
575 | struct hnae3_ae_dev *ae_dev, char **result, | |
576 | u32 index) | |
577 | { | |
578 | u32 base_add_l, base_add_h; | |
579 | u32 j = 0; | |
57ceee2c | 580 | |
e44c495d HC |
581 | sprintf(result[j++], "%8u", index); |
582 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | |
583 | HNS3_RING_TX_RING_BD_NUM_REG)); | |
57ceee2c | 584 | |
e44c495d HC |
585 | sprintf(result[j++], "%2u", readl_relaxed(ring->tqp->io_base + |
586 | HNS3_RING_TX_RING_TC_REG)); | |
57ceee2c | 587 | |
e44c495d HC |
588 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + |
589 | HNS3_RING_TX_RING_TAIL_REG)); | |
57ceee2c | 590 | |
e44c495d HC |
591 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + |
592 | HNS3_RING_TX_RING_HEAD_REG)); | |
57ceee2c | 593 | |
e44c495d HC |
594 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + |
595 | HNS3_RING_TX_RING_FBDNUM_REG)); | |
57ceee2c | 596 | |
e44c495d HC |
597 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + |
598 | HNS3_RING_TX_RING_OFFSET_REG)); | |
57ceee2c | 599 | |
e44c495d HC |
600 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + |
601 | HNS3_RING_TX_RING_PKTNUM_RECORD_REG)); | |
dbaae5bb | 602 | |
e44c495d HC |
603 | sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + |
604 | HNS3_RING_EN_REG) ? "on" : "off"); | |
605 | ||
606 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) | |
607 | sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base + | |
608 | HNS3_RING_TX_EN_REG) ? "on" : "off"); | |
609 | else | |
610 | sprintf(result[j++], "%10s", "NA"); | |
611 | ||
612 | base_add_h = readl_relaxed(ring->tqp->io_base + | |
613 | HNS3_RING_TX_RING_BASEADDR_H_REG); | |
614 | base_add_l = readl_relaxed(ring->tqp->io_base + | |
615 | HNS3_RING_TX_RING_BASEADDR_L_REG); | |
616 | sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l); | |
617 | } | |
618 | ||
619 | static int hns3_dbg_tx_queue_info(struct hnae3_handle *h, | |
620 | char *buf, int len) | |
621 | { | |
622 | char data_str[ARRAY_SIZE(tx_queue_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
623 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
624 | char *result[ARRAY_SIZE(tx_queue_info_items)]; | |
625 | struct hns3_nic_priv *priv = h->priv; | |
626 | char content[HNS3_DBG_INFO_LEN]; | |
627 | struct hns3_enet_ring *ring; | |
628 | int pos = 0; | |
629 | u32 i; | |
630 | ||
631 | if (!priv->ring) { | |
632 | dev_err(&h->pdev->dev, "priv->ring is NULL\n"); | |
633 | return -EFAULT; | |
634 | } | |
635 | ||
636 | for (i = 0; i < ARRAY_SIZE(tx_queue_info_items); i++) | |
637 | result[i] = &data_str[i][0]; | |
638 | ||
639 | hns3_dbg_fill_content(content, sizeof(content), tx_queue_info_items, | |
640 | NULL, ARRAY_SIZE(tx_queue_info_items)); | |
641 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
642 | ||
643 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
644 | /* Each cycle needs to determine whether the instance is reset, | |
645 | * to prevent reference to invalid memory. And need to ensure | |
646 | * that the following code is executed within 100ms. | |
647 | */ | |
648 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || | |
649 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) | |
650 | return -EPERM; | |
651 | ||
652 | ring = &priv->ring[i]; | |
653 | hns3_dump_tx_queue_info(ring, ae_dev, result, i); | |
654 | hns3_dbg_fill_content(content, sizeof(content), | |
655 | tx_queue_info_items, | |
656 | (const char **)result, | |
657 | ARRAY_SIZE(tx_queue_info_items)); | |
658 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
57ceee2c | 659 | } |
660 | ||
907676b1 YL |
661 | hns3_dbg_tx_spare_info(ring, buf, len, h->kinfo.num_tqps, &pos); |
662 | ||
57ceee2c | 663 | return 0; |
664 | } | |
665 | ||
d2f737cf HC |
666 | static const struct hns3_dbg_item queue_map_items[] = { |
667 | { "local_queue_id", 2 }, | |
668 | { "global_queue_id", 2 }, | |
669 | { "vector_id", 2 }, | |
670 | }; | |
671 | ||
672 | static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len) | |
0c29d191 | 673 | { |
d2f737cf HC |
674 | char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN]; |
675 | char *result[ARRAY_SIZE(queue_map_items)]; | |
0c29d191 | 676 | struct hns3_nic_priv *priv = h->priv; |
d2f737cf HC |
677 | char content[HNS3_DBG_INFO_LEN]; |
678 | int pos = 0; | |
679 | int j; | |
680 | u32 i; | |
0c29d191 | 681 | |
682 | if (!h->ae_algo->ops->get_global_queue_id) | |
683 | return -EOPNOTSUPP; | |
684 | ||
d2f737cf HC |
685 | for (i = 0; i < ARRAY_SIZE(queue_map_items); i++) |
686 | result[i] = &data_str[i][0]; | |
0c29d191 | 687 | |
d2f737cf HC |
688 | hns3_dbg_fill_content(content, sizeof(content), queue_map_items, |
689 | NULL, ARRAY_SIZE(queue_map_items)); | |
690 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
691 | for (i = 0; i < h->kinfo.num_tqps; i++) { | |
5f06b903 | 692 | if (!priv->ring || !priv->ring[i].tqp_vector) |
0c29d191 | 693 | continue; |
d2f737cf HC |
694 | j = 0; |
695 | sprintf(result[j++], "%u", i); | |
696 | sprintf(result[j++], "%u", | |
697 | h->ae_algo->ops->get_global_queue_id(h, i)); | |
5aea2da5 | 698 | sprintf(result[j++], "%d", |
d2f737cf HC |
699 | priv->ring[i].tqp_vector->vector_irq); |
700 | hns3_dbg_fill_content(content, sizeof(content), queue_map_items, | |
701 | (const char **)result, | |
702 | ARRAY_SIZE(queue_map_items)); | |
703 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
0c29d191 | 704 | } |
705 | ||
706 | return 0; | |
707 | } | |
708 | ||
77e91848 HT |
709 | static const struct hns3_dbg_item rx_bd_info_items[] = { |
710 | { "BD_IDX", 3 }, | |
711 | { "L234_INFO", 2 }, | |
712 | { "PKT_LEN", 3 }, | |
713 | { "SIZE", 4 }, | |
714 | { "RSS_HASH", 4 }, | |
715 | { "FD_ID", 2 }, | |
716 | { "VLAN_TAG", 2 }, | |
717 | { "O_DM_VLAN_ID_FB", 2 }, | |
718 | { "OT_VLAN_TAG", 2 }, | |
719 | { "BD_BASE_INFO", 2 }, | |
720 | { "PTYPE", 2 }, | |
721 | { "HW_CSUM", 2 }, | |
722 | }; | |
723 | ||
724 | static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv, | |
725 | struct hns3_desc *desc, char **result, int idx) | |
122bedc5 | 726 | { |
77e91848 HT |
727 | unsigned int j = 0; |
728 | ||
729 | sprintf(result[j++], "%5d", idx); | |
730 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info)); | |
731 | sprintf(result[j++], "%7u", le16_to_cpu(desc->rx.pkt_len)); | |
732 | sprintf(result[j++], "%4u", le16_to_cpu(desc->rx.size)); | |
733 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash)); | |
734 | sprintf(result[j++], "%5u", le16_to_cpu(desc->rx.fd_id)); | |
735 | sprintf(result[j++], "%8u", le16_to_cpu(desc->rx.vlan_tag)); | |
736 | sprintf(result[j++], "%15u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb)); | |
737 | sprintf(result[j++], "%11u", le16_to_cpu(desc->rx.ot_vlan_tag)); | |
738 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info)); | |
739 | if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) { | |
740 | u32 ol_info = le32_to_cpu(desc->rx.ol_info); | |
741 | ||
742 | sprintf(result[j++], "%5lu", hnae3_get_field(ol_info, | |
743 | HNS3_RXD_PTYPE_M, | |
744 | HNS3_RXD_PTYPE_S)); | |
745 | sprintf(result[j++], "%7u", le16_to_cpu(desc->csum)); | |
746 | } else { | |
747 | sprintf(result[j++], "NA"); | |
748 | sprintf(result[j++], "NA"); | |
749 | } | |
750 | } | |
751 | ||
752 | static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len) | |
753 | { | |
754 | char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
755 | struct hns3_nic_priv *priv = d->handle->priv; | |
756 | char *result[ARRAY_SIZE(rx_bd_info_items)]; | |
757 | char content[HNS3_DBG_INFO_LEN]; | |
122bedc5 | 758 | struct hns3_enet_ring *ring; |
77e91848 HT |
759 | struct hns3_desc *desc; |
760 | unsigned int i; | |
761 | int pos = 0; | |
122bedc5 | 762 | |
77e91848 HT |
763 | if (d->qid >= d->handle->kinfo.num_tqps) { |
764 | dev_err(&d->handle->pdev->dev, | |
765 | "queue%u is not in use\n", d->qid); | |
122bedc5 | 766 | return -EINVAL; |
767 | } | |
768 | ||
77e91848 HT |
769 | for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++) |
770 | result[i] = &data_str[i][0]; | |
771 | ||
772 | pos += scnprintf(buf + pos, len - pos, | |
773 | "Queue %u rx bd info:\n", d->qid); | |
774 | hns3_dbg_fill_content(content, sizeof(content), rx_bd_info_items, | |
775 | NULL, ARRAY_SIZE(rx_bd_info_items)); | |
776 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
777 | ||
778 | ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps]; | |
779 | for (i = 0; i < ring->desc_num; i++) { | |
780 | desc = &ring->desc[i]; | |
781 | ||
782 | hns3_dump_rx_bd_info(priv, desc, result, i); | |
783 | hns3_dbg_fill_content(content, sizeof(content), | |
784 | rx_bd_info_items, (const char **)result, | |
785 | ARRAY_SIZE(rx_bd_info_items)); | |
786 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
122bedc5 | 787 | } |
788 | ||
77e91848 HT |
789 | return 0; |
790 | } | |
791 | ||
792 | static const struct hns3_dbg_item tx_bd_info_items[] = { | |
793 | { "BD_IDX", 5 }, | |
794 | { "ADDRESS", 2 }, | |
795 | { "VLAN_TAG", 2 }, | |
796 | { "SIZE", 2 }, | |
797 | { "T_CS_VLAN_TSO", 2 }, | |
798 | { "OT_VLAN_TAG", 3 }, | |
799 | { "TV", 2 }, | |
c74e5035 HC |
800 | { "OLT_VLAN_LEN", 2 }, |
801 | { "PAYLEN_OL4CS", 2 }, | |
802 | { "BD_FE_SC_VLD", 2 }, | |
803 | { "MSS_HW_CSUM", 0 }, | |
77e91848 | 804 | }; |
122bedc5 | 805 | |
77e91848 HT |
806 | static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv, |
807 | struct hns3_desc *desc, char **result, int idx) | |
808 | { | |
809 | unsigned int j = 0; | |
810 | ||
811 | sprintf(result[j++], "%6d", idx); | |
812 | sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr)); | |
813 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.vlan_tag)); | |
814 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.send_size)); | |
815 | sprintf(result[j++], "%#x", | |
816 | le32_to_cpu(desc->tx.type_cs_vlan_tso_len)); | |
817 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.outer_vlan_tag)); | |
818 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.tv)); | |
819 | sprintf(result[j++], "%10u", | |
820 | le32_to_cpu(desc->tx.ol_type_vlan_len_msec)); | |
821 | sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs)); | |
822 | sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri)); | |
823 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum)); | |
824 | } | |
825 | ||
826 | static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len) | |
827 | { | |
828 | char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN]; | |
829 | struct hns3_nic_priv *priv = d->handle->priv; | |
830 | char *result[ARRAY_SIZE(tx_bd_info_items)]; | |
831 | char content[HNS3_DBG_INFO_LEN]; | |
832 | struct hns3_enet_ring *ring; | |
833 | struct hns3_desc *desc; | |
834 | unsigned int i; | |
835 | int pos = 0; | |
836 | ||
837 | if (d->qid >= d->handle->kinfo.num_tqps) { | |
838 | dev_err(&d->handle->pdev->dev, | |
839 | "queue%u is not in use\n", d->qid); | |
122bedc5 | 840 | return -EINVAL; |
841 | } | |
842 | ||
77e91848 HT |
843 | for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++) |
844 | result[i] = &data_str[i][0]; | |
845 | ||
846 | pos += scnprintf(buf + pos, len - pos, | |
847 | "Queue %u tx bd info:\n", d->qid); | |
848 | hns3_dbg_fill_content(content, sizeof(content), tx_bd_info_items, | |
849 | NULL, ARRAY_SIZE(tx_bd_info_items)); | |
850 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
b1533ada | 851 | |
77e91848 HT |
852 | ring = &priv->ring[d->qid]; |
853 | for (i = 0; i < ring->desc_num; i++) { | |
854 | desc = &ring->desc[i]; | |
855 | ||
856 | hns3_dump_tx_bd_info(priv, desc, result, i); | |
857 | hns3_dbg_fill_content(content, sizeof(content), | |
858 | tx_bd_info_items, (const char **)result, | |
859 | ARRAY_SIZE(tx_bd_info_items)); | |
860 | pos += scnprintf(buf + pos, len - pos, "%s", content); | |
861 | } | |
122bedc5 | 862 | |
863 | return 0; | |
864 | } | |
865 | ||
c929bc2a JZ |
866 | static void |
867 | hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos) | |
9484e337 GH |
868 | { |
869 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
1026b153 | 870 | const char * const str[] = {"no", "yes"}; |
c929bc2a JZ |
871 | unsigned long *caps = ae_dev->caps; |
872 | u32 i, state; | |
873 | ||
874 | *pos += scnprintf(buf + *pos, len - *pos, "dev capability:\n"); | |
875 | ||
876 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) { | |
877 | state = test_bit(hns3_dbg_cap[i].cap_bit, caps); | |
878 | *pos += scnprintf(buf + *pos, len - *pos, "%s: %s\n", | |
879 | hns3_dbg_cap[i].name, str[state]); | |
880 | } | |
881 | ||
882 | *pos += scnprintf(buf + *pos, len - *pos, "\n"); | |
9484e337 GH |
883 | } |
884 | ||
c929bc2a JZ |
885 | static void |
886 | hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos) | |
b4442ec5 GH |
887 | { |
888 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); | |
889 | struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs; | |
890 | struct hnae3_knic_private_info *kinfo = &h->kinfo; | |
c929bc2a JZ |
891 | |
892 | *pos += scnprintf(buf + *pos, len - *pos, "dev_spec:\n"); | |
893 | *pos += scnprintf(buf + *pos, len - *pos, "MAC entry num: %u\n", | |
894 | dev_specs->mac_entry_num); | |
895 | *pos += scnprintf(buf + *pos, len - *pos, "MNG entry num: %u\n", | |
896 | dev_specs->mng_entry_num); | |
897 | *pos += scnprintf(buf + *pos, len - *pos, "MAX non tso bd num: %u\n", | |
898 | dev_specs->max_non_tso_bd_num); | |
899 | *pos += scnprintf(buf + *pos, len - *pos, "RSS ind tbl size: %u\n", | |
900 | dev_specs->rss_ind_tbl_size); | |
901 | *pos += scnprintf(buf + *pos, len - *pos, "RSS key size: %u\n", | |
902 | dev_specs->rss_key_size); | |
903 | *pos += scnprintf(buf + *pos, len - *pos, "RSS size: %u\n", | |
904 | kinfo->rss_size); | |
905 | *pos += scnprintf(buf + *pos, len - *pos, "Allocated RSS size: %u\n", | |
906 | kinfo->req_rss_size); | |
907 | *pos += scnprintf(buf + *pos, len - *pos, | |
908 | "Task queue pairs numbers: %u\n", | |
909 | kinfo->num_tqps); | |
910 | *pos += scnprintf(buf + *pos, len - *pos, "RX buffer length: %u\n", | |
911 | kinfo->rx_buf_len); | |
912 | *pos += scnprintf(buf + *pos, len - *pos, "Desc num per TX queue: %u\n", | |
913 | kinfo->num_tx_desc); | |
914 | *pos += scnprintf(buf + *pos, len - *pos, "Desc num per RX queue: %u\n", | |
915 | kinfo->num_rx_desc); | |
916 | *pos += scnprintf(buf + *pos, len - *pos, | |
917 | "Total number of enabled TCs: %u\n", | |
918 | kinfo->tc_info.num_tc); | |
919 | *pos += scnprintf(buf + *pos, len - *pos, "MAX INT QL: %u\n", | |
920 | dev_specs->int_ql_max); | |
921 | *pos += scnprintf(buf + *pos, len - *pos, "MAX INT GL: %u\n", | |
922 | dev_specs->max_int_gl); | |
923 | *pos += scnprintf(buf + *pos, len - *pos, "MAX TM RATE: %u\n", | |
924 | dev_specs->max_tm_rate); | |
925 | *pos += scnprintf(buf + *pos, len - *pos, "MAX QSET number: %u\n", | |
926 | dev_specs->max_qset_num); | |
927 | } | |
928 | ||
929 | static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len) | |
930 | { | |
931 | int pos = 0; | |
932 | ||
933 | hns3_dbg_dev_caps(h, buf, len, &pos); | |
934 | ||
935 | hns3_dbg_dev_specs(h, buf, len, &pos); | |
936 | ||
937 | return 0; | |
b4442ec5 GH |
938 | } |
939 | ||
55649d56 | 940 | static int hns3_dbg_get_cmd_index(struct hns3_dbg_data *dbg_data, u32 *index) |
5e69ea7e YM |
941 | { |
942 | u32 i; | |
943 | ||
944 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { | |
55649d56 | 945 | if (hns3_dbg_cmd[i].cmd == dbg_data->cmd) { |
5e69ea7e YM |
946 | *index = i; |
947 | return 0; | |
948 | } | |
949 | } | |
950 | ||
55649d56 YM |
951 | dev_err(&dbg_data->handle->pdev->dev, "unknown command(%d)\n", |
952 | dbg_data->cmd); | |
5e69ea7e YM |
953 | return -EINVAL; |
954 | } | |
955 | ||
c929bc2a | 956 | static const struct hns3_dbg_func hns3_dbg_cmd_func[] = { |
d2f737cf HC |
957 | { |
958 | .cmd = HNAE3_DBG_CMD_QUEUE_MAP, | |
959 | .dbg_dump = hns3_dbg_queue_map, | |
960 | }, | |
c929bc2a JZ |
961 | { |
962 | .cmd = HNAE3_DBG_CMD_DEV_INFO, | |
963 | .dbg_dump = hns3_dbg_dev_info, | |
964 | }, | |
77e91848 HT |
965 | { |
966 | .cmd = HNAE3_DBG_CMD_TX_BD, | |
967 | .dbg_dump_bd = hns3_dbg_tx_bd_info, | |
968 | }, | |
969 | { | |
970 | .cmd = HNAE3_DBG_CMD_RX_BD, | |
971 | .dbg_dump_bd = hns3_dbg_rx_bd_info, | |
972 | }, | |
e44c495d HC |
973 | { |
974 | .cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO, | |
975 | .dbg_dump = hns3_dbg_rx_queue_info, | |
976 | }, | |
977 | { | |
978 | .cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO, | |
979 | .dbg_dump = hns3_dbg_tx_queue_info, | |
980 | }, | |
c929bc2a JZ |
981 | }; |
982 | ||
77e91848 | 983 | static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data, |
5e69ea7e YM |
984 | enum hnae3_dbg_cmd cmd, char *buf, int len) |
985 | { | |
77e91848 HT |
986 | const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops; |
987 | const struct hns3_dbg_func *cmd_func; | |
c929bc2a JZ |
988 | u32 i; |
989 | ||
990 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) { | |
77e91848 HT |
991 | if (cmd == hns3_dbg_cmd_func[i].cmd) { |
992 | cmd_func = &hns3_dbg_cmd_func[i]; | |
993 | if (cmd_func->dbg_dump) | |
994 | return cmd_func->dbg_dump(dbg_data->handle, buf, | |
995 | len); | |
996 | else | |
997 | return cmd_func->dbg_dump_bd(dbg_data, buf, | |
998 | len); | |
999 | } | |
c929bc2a | 1000 | } |
5e69ea7e YM |
1001 | |
1002 | if (!ops->dbg_read_cmd) | |
1003 | return -EOPNOTSUPP; | |
1004 | ||
77e91848 | 1005 | return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len); |
5e69ea7e YM |
1006 | } |
1007 | ||
04987ca1 GH |
1008 | static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, |
1009 | size_t count, loff_t *ppos) | |
1010 | { | |
77e91848 HT |
1011 | struct hns3_dbg_data *dbg_data = filp->private_data; |
1012 | struct hnae3_handle *handle = dbg_data->handle; | |
04987ca1 | 1013 | struct hns3_nic_priv *priv = handle->priv; |
04987ca1 | 1014 | ssize_t size = 0; |
5e69ea7e YM |
1015 | char **save_buf; |
1016 | char *read_buf; | |
1017 | u32 index; | |
1018 | int ret; | |
04987ca1 | 1019 | |
55649d56 | 1020 | ret = hns3_dbg_get_cmd_index(dbg_data, &index); |
5e69ea7e YM |
1021 | if (ret) |
1022 | return ret; | |
04987ca1 | 1023 | |
5e69ea7e | 1024 | save_buf = &hns3_dbg_cmd[index].buf; |
04987ca1 | 1025 | |
5e69ea7e YM |
1026 | if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || |
1027 | test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { | |
1028 | ret = -EBUSY; | |
04987ca1 GH |
1029 | goto out; |
1030 | } | |
1031 | ||
5e69ea7e YM |
1032 | if (*save_buf) { |
1033 | read_buf = *save_buf; | |
1034 | } else { | |
1035 | read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL); | |
1036 | if (!read_buf) | |
1037 | return -ENOMEM; | |
1038 | ||
1039 | /* save the buffer addr until the last read operation */ | |
1040 | *save_buf = read_buf; | |
1041 | } | |
1042 | ||
1043 | /* get data ready for the first time to read */ | |
1044 | if (!*ppos) { | |
77e91848 | 1045 | ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, |
5e69ea7e YM |
1046 | read_buf, hns3_dbg_cmd[index].buf_len); |
1047 | if (ret) | |
1048 | goto out; | |
1049 | } | |
1050 | ||
04987ca1 GH |
1051 | size = simple_read_from_buffer(buffer, count, ppos, read_buf, |
1052 | strlen(read_buf)); | |
5e69ea7e YM |
1053 | if (size > 0) |
1054 | return size; | |
04987ca1 GH |
1055 | |
1056 | out: | |
5e69ea7e YM |
1057 | /* free the buffer for the last read operation */ |
1058 | if (*save_buf) { | |
1059 | kvfree(*save_buf); | |
1060 | *save_buf = NULL; | |
1061 | } | |
1062 | ||
1063 | return ret; | |
04987ca1 GH |
1064 | } |
1065 | ||
04987ca1 GH |
1066 | static const struct file_operations hns3_dbg_fops = { |
1067 | .owner = THIS_MODULE, | |
1068 | .open = simple_open, | |
1069 | .read = hns3_dbg_read, | |
1070 | }; | |
1071 | ||
77e91848 HT |
1072 | static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd) |
1073 | { | |
1074 | struct dentry *entry_dir; | |
1075 | struct hns3_dbg_data *data; | |
1076 | u16 max_queue_num; | |
1077 | unsigned int i; | |
1078 | ||
1079 | entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry; | |
1080 | max_queue_num = hns3_get_max_available_channels(handle); | |
1081 | data = devm_kzalloc(&handle->pdev->dev, max_queue_num * sizeof(*data), | |
1082 | GFP_KERNEL); | |
1083 | if (!data) | |
1084 | return -ENOMEM; | |
1085 | ||
1086 | for (i = 0; i < max_queue_num; i++) { | |
1087 | char name[HNS3_DBG_FILE_NAME_LEN]; | |
1088 | ||
1089 | data[i].handle = handle; | |
55649d56 | 1090 | data[i].cmd = hns3_dbg_cmd[cmd].cmd; |
77e91848 HT |
1091 | data[i].qid = i; |
1092 | sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i); | |
1093 | debugfs_create_file(name, 0400, entry_dir, &data[i], | |
1094 | &hns3_dbg_fops); | |
1095 | } | |
1096 | ||
1097 | return 0; | |
1098 | } | |
1099 | ||
5e69ea7e YM |
1100 | static int |
1101 | hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd) | |
1102 | { | |
77e91848 | 1103 | struct hns3_dbg_data *data; |
5e69ea7e YM |
1104 | struct dentry *entry_dir; |
1105 | ||
77e91848 HT |
1106 | data = devm_kzalloc(&handle->pdev->dev, sizeof(*data), GFP_KERNEL); |
1107 | if (!data) | |
1108 | return -ENOMEM; | |
1109 | ||
1110 | data->handle = handle; | |
55649d56 | 1111 | data->cmd = hns3_dbg_cmd[cmd].cmd; |
5e69ea7e YM |
1112 | entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry; |
1113 | debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir, | |
77e91848 | 1114 | data, &hns3_dbg_fops); |
5e69ea7e YM |
1115 | |
1116 | return 0; | |
1117 | } | |
1118 | ||
1119 | int hns3_dbg_init(struct hnae3_handle *handle) | |
b2292360 | 1120 | { |
04987ca1 | 1121 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); |
b2292360 | 1122 | const char *name = pci_name(handle->pdev); |
5e69ea7e YM |
1123 | int ret; |
1124 | u32 i; | |
b2292360 | 1125 | |
5e69ea7e YM |
1126 | hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry = |
1127 | debugfs_create_dir(name, hns3_dbgfs_root); | |
1128 | handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry; | |
b2292360 | 1129 | |
5e69ea7e YM |
1130 | for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++) |
1131 | hns3_dbg_dentry[i].dentry = | |
1132 | debugfs_create_dir(hns3_dbg_dentry[i].name, | |
1133 | handle->hnae3_dbgfs); | |
1134 | ||
1135 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { | |
b34c157f HT |
1136 | if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES && |
1137 | ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) || | |
1138 | (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_PTP_INFO && | |
1139 | !test_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps))) | |
5e69ea7e YM |
1140 | continue; |
1141 | ||
1142 | if (!hns3_dbg_cmd[i].init) { | |
1143 | dev_err(&handle->pdev->dev, | |
1144 | "cmd %s lack of init func\n", | |
1145 | hns3_dbg_cmd[i].name); | |
1146 | ret = -EINVAL; | |
1147 | goto out; | |
1148 | } | |
1149 | ||
1150 | ret = hns3_dbg_cmd[i].init(handle, i); | |
1151 | if (ret) { | |
1152 | dev_err(&handle->pdev->dev, "failed to init cmd %s\n", | |
1153 | hns3_dbg_cmd[i].name); | |
1154 | goto out; | |
1155 | } | |
1156 | } | |
1157 | ||
1158 | return 0; | |
1159 | ||
1160 | out: | |
1161 | debugfs_remove_recursive(handle->hnae3_dbgfs); | |
1162 | handle->hnae3_dbgfs = NULL; | |
1163 | return ret; | |
b2292360 | 1164 | } |
1165 | ||
1166 | void hns3_dbg_uninit(struct hnae3_handle *handle) | |
1167 | { | |
5e69ea7e YM |
1168 | u32 i; |
1169 | ||
1170 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) | |
1171 | if (hns3_dbg_cmd[i].buf) { | |
1172 | kvfree(hns3_dbg_cmd[i].buf); | |
1173 | hns3_dbg_cmd[i].buf = NULL; | |
1174 | } | |
1175 | ||
b2292360 | 1176 | debugfs_remove_recursive(handle->hnae3_dbgfs); |
1177 | handle->hnae3_dbgfs = NULL; | |
1178 | } | |
1179 | ||
1180 | void hns3_dbg_register_debugfs(const char *debugfs_dir_name) | |
1181 | { | |
1182 | hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL); | |
b2292360 | 1183 | } |
1184 | ||
1185 | void hns3_dbg_unregister_debugfs(void) | |
1186 | { | |
1187 | debugfs_remove_recursive(hns3_dbgfs_root); | |
1188 | hns3_dbgfs_root = NULL; | |
1189 | } |