1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018-2019 Hisilicon Limited. 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 18 static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *length); 19 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}; 34 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, 40 HNS3_FUN_RST_ING, 41 HNS3_GRO_EN_REG}; 42 43 static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE, 44 HNS3_FUN_RST_ING, 45 HNS3_GRO_EN_REG}; 46 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, 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 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}; 81 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, 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 97 static int 98 hns3_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 118 static int 119 hns3_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 165 static int 166 hns3_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 222 static int 223 hns3_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 279 static int 280 hns3_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 291 static int 292 hns3_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 /* 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); 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 337 static int 338 hns3_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 /* The last BD does not need a next flag */ 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 /* 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; 367 } 368 369 return 0; 370 } 371 372 static int 373 hns3_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 /* The last BD does not need a next flag */ 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 395 static int 396 hns3_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 414 static int 415 hns3_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 436 static int 437 hns3_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 475 int 476 hns3_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 if (regs == NULL) { 488 hns3_err(hw, "the input parameter regs is NULL!"); 489 return -EINVAL; 490 } 491 492 ret = hns3_get_regs_length(hw, &length); 493 if (ret) 494 return ret; 495 496 data = regs->data; 497 if (data == NULL) { 498 regs->length = length; 499 regs->width = sizeof(uint32_t); 500 return 0; 501 } 502 503 /* Only full register dump is supported */ 504 if (regs->length && regs->length != length) 505 return -ENOTSUP; 506 507 /* fetching per-PF registers values from PF PCIe register space */ 508 data += hns3_direct_access_regs(hw, data); 509 510 if (hns->is_vf) 511 return 0; 512 513 ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); 514 if (ret) { 515 hns3_err(hw, "Get register number failed, ret = %d", ret); 516 return ret; 517 } 518 519 /* fetching PF common registers values from firmware */ 520 ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data); 521 if (ret) { 522 hns3_err(hw, "Get 32 bit register failed, ret = %d", ret); 523 return ret; 524 } 525 data += regs_num_32_bit; 526 data += hns3_insert_reg_separator(regs_num_32_bit, data); 527 528 ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data); 529 if (ret) { 530 hns3_err(hw, "Get 64 bit register failed, ret = %d", ret); 531 return ret; 532 } 533 data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE; 534 data += hns3_insert_reg_separator(regs_num_64_bit * 535 HNS3_64_BIT_REG_SIZE, data); 536 537 return hns3_get_dfx_regs(hw, (void **)&data); 538 } 539