1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018-2021 HiSilicon Limited.
5 #include <ethdev_pci.h>
8 #include "hns3_ethdev.h"
10 #include "hns3_rxtx.h"
11 #include "hns3_regs.h"
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))
18 static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *length);
20 static 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};
35 static 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,
43 static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
47 static 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,
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,
64 HNS3_RING_TX_PRIORITY_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,
76 static 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};
82 static 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,
94 HNS3_OPC_DFX_SSU_REG_2
98 hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
99 uint32_t *regs_num_64_bit)
101 struct hns3_cmd_desc desc;
104 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_REG_NUM, true);
105 ret = hns3_cmd_send(hw, &desc, 1);
107 hns3_err(hw, "Query register number cmd failed, ret = %d",
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]);
119 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
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;
128 cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
131 sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
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;
137 len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
138 tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
141 ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit);
143 hns3_err(hw, "fail to get the number of registers, "
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;
152 ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
154 hns3_err(hw, "fail to get the number of dfx registers, "
158 len += dfx_reg_lines * REG_NUM_PER_LINE;
166 hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
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;
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);
185 hns3_err(hw, "Failed to allocate %zx bytes needed to "
187 sizeof(struct hns3_cmd_desc) * cmd_num);
191 hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_QUERY_32_BIT_REG, true);
192 ret = hns3_cmd_send(hw, desc, cmd_num);
194 hns3_err(hw, "Query 32 bit register cmd failed, ret = %d",
200 for (i = 0; i < cmd_num; i++) {
202 desc_data = &desc[i].data[0];
203 n = HNS3_32_BIT_REG_RTN_DATANUM -
204 HNS3_32_BIT_DESC_NODATA_LEN;
206 desc_data = (uint32_t *)(&desc[i]);
207 n = HNS3_32_BIT_REG_RTN_DATANUM;
209 for (k = 0; k < n; k++) {
210 *reg_val++ = rte_le_to_cpu_32(*desc_data++);
223 hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
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;
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);
242 hns3_err(hw, "Failed to allocate %zx bytes needed to "
244 sizeof(struct hns3_cmd_desc) * cmd_num);
248 hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_QUERY_64_BIT_REG, true);
249 ret = hns3_cmd_send(hw, desc, cmd_num);
251 hns3_err(hw, "Query 64 bit register cmd failed, ret = %d",
257 for (i = 0; i < cmd_num; i++) {
259 desc_data = (uint64_t *)(&desc[i].data[0]);
260 n = HNS3_64_BIT_REG_RTN_DATANUM -
261 HNS3_64_BIT_DESC_NODATA_LEN;
263 desc_data = (uint64_t *)(&desc[i]);
264 n = HNS3_64_BIT_REG_RTN_DATANUM;
266 for (k = 0; k < n; k++) {
267 *reg_val++ = rte_le_to_cpu_64(*desc_data++);
280 hns3_insert_reg_separator(int reg_num, uint32_t *data)
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;
292 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
294 struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
295 uint32_t *origin_data_ptr = data;
300 /* fetching per-PF registers values from PF PCIe register space */
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);
307 reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
309 reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
310 for (i = 0; i < reg_num; i++)
312 *data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
314 *data++ = hns3_read_dev(hw, common_reg_addrs[i]);
315 data += hns3_insert_reg_separator(reg_num, data);
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);
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] +
332 data += hns3_insert_reg_separator(reg_num, data);
334 return data - origin_data_ptr;
338 hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
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;
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);
352 /* The last BD does not need a next flag */
353 hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
355 ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
357 hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
361 /* The first data in the first BD is a reserved field */
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;
373 hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
374 int bd_num, uint32_t opcode)
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);
383 /* The last BD does not need a next flag */
384 hns3_cmd_setup_basic_desc(&desc[i], opcode, true);
386 ret = hns3_cmd_send(hw, desc, bd_num);
388 hns3_err(hw, "fail to query dfx registers, opcode = 0x%04X, "
389 "ret = %d.\n", opcode, ret);
396 hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
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];
409 reg_num += hns3_insert_reg_separator(reg_num, reg);
415 hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
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;
423 ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
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;
437 hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
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;
447 ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
452 for (i = 0; i < opcode_num; i++)
453 max_bd_num = RTE_MAX(bd_num_list[i], max_bd_num);
455 cmd_descs = rte_zmalloc(NULL, sizeof(*cmd_descs) * max_bd_num, 0);
456 if (cmd_descs == NULL)
459 for (i = 0; i < opcode_num; i++) {
460 opcode = hns3_dfx_reg_opcode_list[i];
461 bd_num = bd_num_list[i];
464 ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
467 reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
470 *data = (void *)reg_val;
476 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
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;
487 ret = hns3_get_regs_length(hw, &length);
493 regs->length = length;
494 regs->width = sizeof(uint32_t);
498 /* Only full register dump is supported */
499 if (regs->length && regs->length != length)
502 regs->version = hw->fw_version;
504 /* fetching per-PF registers values from PF PCIe register space */
505 data += hns3_direct_access_regs(hw, data);
510 ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit);
512 hns3_err(hw, "Get register number failed, ret = %d", ret);
516 /* fetching PF common registers values from firmware */
517 ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
519 hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
522 data += regs_num_32_bit;
523 data += hns3_insert_reg_separator(regs_num_32_bit, data);
525 ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
527 hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
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);
534 return hns3_get_dfx_regs(hw, (void **)&data);