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