1
2
3
4
5#include <ethdev_pci.h>
6#include <rte_io.h>
7
8#include "hns3_ethdev.h"
9#include "hns3_logs.h"
10#include "hns3_rxtx.h"
11#include "hns3_regs.h"
12
13#define MAX_SEPARATE_NUM 4
14#define SEPARATOR_VALUE 0xFFFFFFFF
15#define REG_NUM_PER_LINE 4
16#define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(uint32_t))
17
18static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *length);
19
20static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
21 HNS3_CMDQ_TX_ADDR_H_REG,
22 HNS3_CMDQ_TX_DEPTH_REG,
23 HNS3_CMDQ_TX_TAIL_REG,
24 HNS3_CMDQ_TX_HEAD_REG,
25 HNS3_CMDQ_RX_ADDR_L_REG,
26 HNS3_CMDQ_RX_ADDR_H_REG,
27 HNS3_CMDQ_RX_DEPTH_REG,
28 HNS3_CMDQ_RX_TAIL_REG,
29 HNS3_CMDQ_RX_HEAD_REG,
30 HNS3_VECTOR0_CMDQ_SRC_REG,
31 HNS3_CMDQ_INTR_STS_REG,
32 HNS3_CMDQ_INTR_EN_REG,
33 HNS3_CMDQ_INTR_GEN_REG};
34
35static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
36 HNS3_VECTOR0_OTER_EN_REG,
37 HNS3_MISC_RESET_STS_REG,
38 HNS3_VECTOR0_OTHER_INT_STS_REG,
39 HNS3_GLOBAL_RESET_REG,
40 HNS3_FUN_RST_ING,
41 HNS3_GRO_EN_REG};
42
43static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
44 HNS3_FUN_RST_ING,
45 HNS3_GRO_EN_REG};
46
47static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
48 HNS3_RING_RX_BASEADDR_H_REG,
49 HNS3_RING_RX_BD_NUM_REG,
50 HNS3_RING_RX_BD_LEN_REG,
51 HNS3_RING_RX_EN_REG,
52 HNS3_RING_RX_MERGE_EN_REG,
53 HNS3_RING_RX_TAIL_REG,
54 HNS3_RING_RX_HEAD_REG,
55 HNS3_RING_RX_FBDNUM_REG,
56 HNS3_RING_RX_OFFSET_REG,
57 HNS3_RING_RX_FBD_OFFSET_REG,
58 HNS3_RING_RX_STASH_REG,
59 HNS3_RING_RX_BD_ERR_REG,
60 HNS3_RING_TX_BASEADDR_L_REG,
61 HNS3_RING_TX_BASEADDR_H_REG,
62 HNS3_RING_TX_BD_NUM_REG,
63 HNS3_RING_TX_EN_REG,
64 HNS3_RING_TX_PRIORITY_REG,
65 HNS3_RING_TX_TC_REG,
66 HNS3_RING_TX_MERGE_EN_REG,
67 HNS3_RING_TX_TAIL_REG,
68 HNS3_RING_TX_HEAD_REG,
69 HNS3_RING_TX_FBDNUM_REG,
70 HNS3_RING_TX_OFFSET_REG,
71 HNS3_RING_TX_EBD_NUM_REG,
72 HNS3_RING_TX_EBD_OFFSET_REG,
73 HNS3_RING_TX_BD_ERR_REG,
74 HNS3_RING_EN_REG};
75
76static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
77 HNS3_TQP_INTR_GL0_REG,
78 HNS3_TQP_INTR_GL1_REG,
79 HNS3_TQP_INTR_GL2_REG,
80 HNS3_TQP_INTR_RL_REG};
81
82static const uint32_t hns3_dfx_reg_opcode_list[] = {
83 HNS3_OPC_DFX_BIOS_COMMON_REG,
84 HNS3_OPC_DFX_SSU_REG_0,
85 HNS3_OPC_DFX_SSU_REG_1,
86 HNS3_OPC_DFX_IGU_EGU_REG,
87 HNS3_OPC_DFX_RPU_REG_0,
88 HNS3_OPC_DFX_RPU_REG_1,
89 HNS3_OPC_DFX_NCSI_REG,
90 HNS3_OPC_DFX_RTC_REG,
91 HNS3_OPC_DFX_PPP_REG,
92 HNS3_OPC_DFX_RCB_REG,
93 HNS3_OPC_DFX_TQP_REG,
94 HNS3_OPC_DFX_SSU_REG_2
95};
96
97static int
98hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
99 uint32_t *regs_num_64_bit)
100{
101 struct hns3_cmd_desc desc;
102 int ret;
103
104 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_REG_NUM, true);
105 ret = hns3_cmd_send(hw, &desc, 1);
106 if (ret) {
107 hns3_err(hw, "Query register number cmd failed, ret = %d",
108 ret);
109 return ret;
110 }
111
112 *regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
113 *regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
114
115 return 0;
116}
117
118static int
119hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
120{
121 struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
122 uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
123 uint32_t regs_num_32_bit, regs_num_64_bit;
124 uint32_t dfx_reg_lines;
125 uint32_t len;
126 int ret;
127
128 cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
129 if (hns->is_vf)
130 common_lines =
131 sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
132 else
133 common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
134 ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
135 tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
136
137 len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
138 tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
139
140 if (!hns->is_vf) {
141 ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit);
142 if (ret) {
143 hns3_err(hw, "fail to get the number of registers, "
144 "ret = %d.", ret);
145 return ret;
146 }
147 dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
148 REG_LEN_PER_LINE + 1;
149 dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
150 REG_LEN_PER_LINE + 1;
151
152 ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
153 if (ret) {
154 hns3_err(hw, "fail to get the number of dfx registers, "
155 "ret = %d.", ret);
156 return ret;
157 }
158 len += dfx_reg_lines * REG_NUM_PER_LINE;
159 }
160
161 *length = len;
162 return 0;
163}
164
165static int
166hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
167{
168#define HNS3_32_BIT_REG_RTN_DATANUM 8
169#define HNS3_32_BIT_DESC_NODATA_LEN 2
170 struct hns3_cmd_desc *desc;
171 uint32_t *reg_val = data;
172 uint32_t *desc_data;
173 int cmd_num;
174 int i, k, n;
175 int ret;
176
177 if (regs_num == 0)
178 return 0;
179
180 cmd_num = DIV_ROUND_UP(regs_num + HNS3_32_BIT_DESC_NODATA_LEN,
181 HNS3_32_BIT_REG_RTN_DATANUM);
182 desc = rte_zmalloc("hns3-32bit-regs",
183 sizeof(struct hns3_cmd_desc) * cmd_num, 0);
184 if (desc == NULL) {
185 hns3_err(hw, "Failed to allocate %zx bytes needed to "
186 "store 32bit regs",
187 sizeof(struct hns3_cmd_desc) * cmd_num);
188 return -ENOMEM;
189 }
190
191 hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_QUERY_32_BIT_REG, true);
192 ret = hns3_cmd_send(hw, desc, cmd_num);
193 if (ret) {
194 hns3_err(hw, "Query 32 bit register cmd failed, ret = %d",
195 ret);
196 rte_free(desc);
197 return ret;
198 }
199
200 for (i = 0; i < cmd_num; i++) {
201 if (i == 0) {
202 desc_data = &desc[i].data[0];
203 n = HNS3_32_BIT_REG_RTN_DATANUM -
204 HNS3_32_BIT_DESC_NODATA_LEN;
205 } else {
206 desc_data = (uint32_t *)(&desc[i]);
207 n = HNS3_32_BIT_REG_RTN_DATANUM;
208 }
209 for (k = 0; k < n; k++) {
210 *reg_val++ = rte_le_to_cpu_32(*desc_data++);
211
212 regs_num--;
213 if (regs_num == 0)
214 break;
215 }
216 }
217
218 rte_free(desc);
219 return 0;
220}
221
222static int
223hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
224{
225#define HNS3_64_BIT_REG_RTN_DATANUM 4
226#define HNS3_64_BIT_DESC_NODATA_LEN 1
227 struct hns3_cmd_desc *desc;
228 uint64_t *reg_val = data;
229 uint64_t *desc_data;
230 int cmd_num;
231 int i, k, n;
232 int ret;
233
234 if (regs_num == 0)
235 return 0;
236
237 cmd_num = DIV_ROUND_UP(regs_num + HNS3_64_BIT_DESC_NODATA_LEN,
238 HNS3_64_BIT_REG_RTN_DATANUM);
239 desc = rte_zmalloc("hns3-64bit-regs",
240 sizeof(struct hns3_cmd_desc) * cmd_num, 0);
241 if (desc == NULL) {
242 hns3_err(hw, "Failed to allocate %zx bytes needed to "
243 "store 64bit regs",
244 sizeof(struct hns3_cmd_desc) * cmd_num);
245 return -ENOMEM;
246 }
247
248 hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_QUERY_64_BIT_REG, true);
249 ret = hns3_cmd_send(hw, desc, cmd_num);
250 if (ret) {
251 hns3_err(hw, "Query 64 bit register cmd failed, ret = %d",
252 ret);
253 rte_free(desc);
254 return ret;
255 }
256
257 for (i = 0; i < cmd_num; i++) {
258 if (i == 0) {
259 desc_data = (uint64_t *)(&desc[i].data[0]);
260 n = HNS3_64_BIT_REG_RTN_DATANUM -
261 HNS3_64_BIT_DESC_NODATA_LEN;
262 } else {
263 desc_data = (uint64_t *)(&desc[i]);
264 n = HNS3_64_BIT_REG_RTN_DATANUM;
265 }
266 for (k = 0; k < n; k++) {
267 *reg_val++ = rte_le_to_cpu_64(*desc_data++);
268
269 regs_num--;
270 if (!regs_num)
271 break;
272 }
273 }
274
275 rte_free(desc);
276 return 0;
277}
278
279static int
280hns3_insert_reg_separator(int reg_num, uint32_t *data)
281{
282 int separator_num;
283 int i;
284
285 separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
286 for (i = 0; i < separator_num; i++)
287 *data++ = SEPARATOR_VALUE;
288 return separator_num;
289}
290
291static int
292hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
293{
294 struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
295 uint32_t *origin_data_ptr = data;
296 uint32_t reg_offset;
297 int reg_num;
298 int i, j;
299
300
301 reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
302 for (i = 0; i < reg_num; i++)
303 *data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
304 data += hns3_insert_reg_separator(reg_num, data);
305
306 if (hns->is_vf)
307 reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
308 else
309 reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
310 for (i = 0; i < reg_num; i++)
311 if (hns->is_vf)
312 *data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
313 else
314 *data++ = hns3_read_dev(hw, common_reg_addrs[i]);
315 data += hns3_insert_reg_separator(reg_num, data);
316
317 reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
318 for (j = 0; j < hw->tqps_num; j++) {
319 reg_offset = hns3_get_tqp_reg_offset(j);
320 for (i = 0; i < reg_num; i++)
321 *data++ = hns3_read_dev(hw,
322 ring_reg_addrs[i] + reg_offset);
323 data += hns3_insert_reg_separator(reg_num, data);
324 }
325
326 reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
327 for (j = 0; j < hw->intr_tqps_num; j++) {
328 reg_offset = hns3_get_tqp_intr_reg_offset(j);
329 for (i = 0; i < reg_num; i++)
330 *data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
331 reg_offset);
332 data += hns3_insert_reg_separator(reg_num, data);
333 }
334 return data - origin_data_ptr;
335}
336
337static int
338hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
339 uint32_t list_size)
340{
341#define HNS3_GET_DFX_REG_BD_NUM_SIZE 4
342 struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
343 uint32_t index, desc_index;
344 uint32_t bd_num;
345 uint32_t i;
346 int ret;
347
348 for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
349 hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
350 desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
351 }
352
353 hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
354
355 ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
356 if (ret) {
357 hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
358 return ret;
359 }
360
361
362 for (i = 1; i <= list_size; i++) {
363 desc_index = i / HNS3_CMD_DESC_DATA_NUM;
364 index = i % HNS3_CMD_DESC_DATA_NUM;
365 bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
366 bd_num_list[i - 1] = bd_num;
367 }
368
369 return 0;
370}
371
372static int
373hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
374 int bd_num, uint32_t opcode)
375{
376 int ret;
377 int i;
378
379 for (i = 0; i < bd_num - 1; i++) {
380 hns3_cmd_setup_basic_desc(&desc[i], opcode, true);
381 desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
382 }
383
384 hns3_cmd_setup_basic_desc(&desc[i], opcode, true);
385
386 ret = hns3_cmd_send(hw, desc, bd_num);
387 if (ret) {
388 hns3_err(hw, "fail to query dfx registers, opcode = 0x%04X, "
389 "ret = %d.\n", opcode, ret);
390 }
391
392 return ret;
393}
394
395static int
396hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
397{
398 int desc_index;
399 int reg_num;
400 int index;
401 int i;
402
403 reg_num = bd_num * HNS3_CMD_DESC_DATA_NUM;
404 for (i = 0; i < reg_num; i++) {
405 desc_index = i / HNS3_CMD_DESC_DATA_NUM;
406 index = i % HNS3_CMD_DESC_DATA_NUM;
407 *reg++ = desc[desc_index].data[index];
408 }
409 reg_num += hns3_insert_reg_separator(reg_num, reg);
410
411 return reg_num;
412}
413
414static int
415hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
416{
417 int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
418 uint32_t bd_num_list[opcode_num];
419 uint32_t bd_num, data_len;
420 int ret;
421 int i;
422
423 ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
424 if (ret)
425 return ret;
426
427 for (i = 0; i < opcode_num; i++) {
428 bd_num = bd_num_list[i];
429 data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
430 *lines += data_len / REG_LEN_PER_LINE + 1;
431 }
432
433 return 0;
434}
435
436static int
437hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
438{
439 int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
440 uint32_t max_bd_num, bd_num, opcode;
441 uint32_t bd_num_list[opcode_num];
442 struct hns3_cmd_desc *cmd_descs;
443 uint32_t *reg_val = (uint32_t *)*data;
444 int ret;
445 int i;
446
447 ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
448 if (ret)
449 return ret;
450
451 max_bd_num = 0;
452 for (i = 0; i < opcode_num; i++)
453 max_bd_num = RTE_MAX(bd_num_list[i], max_bd_num);
454
455 cmd_descs = rte_zmalloc(NULL, sizeof(*cmd_descs) * max_bd_num, 0);
456 if (cmd_descs == NULL)
457 return -ENOMEM;
458
459 for (i = 0; i < opcode_num; i++) {
460 opcode = hns3_dfx_reg_opcode_list[i];
461 bd_num = bd_num_list[i];
462 if (bd_num == 0)
463 continue;
464 ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
465 if (ret)
466 break;
467 reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
468 }
469 rte_free(cmd_descs);
470 *data = (void *)reg_val;
471
472 return ret;
473}
474
475int
476hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
477{
478#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
479 struct hns3_adapter *hns = eth_dev->data->dev_private;
480 struct hns3_hw *hw = &hns->hw;
481 uint32_t regs_num_32_bit;
482 uint32_t regs_num_64_bit;
483 uint32_t length;
484 uint32_t *data;
485 int ret;
486
487 ret = hns3_get_regs_length(hw, &length);
488 if (ret)
489 return ret;
490
491 data = regs->data;
492 if (data == NULL) {
493 regs->length = length;
494 regs->width = sizeof(uint32_t);
495 return 0;
496 }
497
498
499 if (regs->length && regs->length != length)
500 return -ENOTSUP;
501
502 regs->version = hw->fw_version;
503
504
505 data += hns3_direct_access_regs(hw, data);
506
507 if (hns->is_vf)
508 return 0;
509
510 ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit);
511 if (ret) {
512 hns3_err(hw, "Get register number failed, ret = %d", ret);
513 return ret;
514 }
515
516
517 ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
518 if (ret) {
519 hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
520 return ret;
521 }
522 data += regs_num_32_bit;
523 data += hns3_insert_reg_separator(regs_num_32_bit, data);
524
525 ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
526 if (ret) {
527 hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
528 return ret;
529 }
530 data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
531 data += hns3_insert_reg_separator(regs_num_64_bit *
532 HNS3_64_BIT_REG_SIZE, data);
533
534 return hns3_get_dfx_regs(hw, (void **)&data);
535}
536