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 11 static struct dentry *hns3_dbgfs_root; 12 13 static 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 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); 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 }, 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_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 }, 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 }, 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 }, 136 { 137 .name = "uc", 138 .cmd = HNAE3_DBG_CMD_MAC_UC, 139 .dentry = HNS3_DBG_DENTRY_MAC, 140 .buf_len = HNS3_DBG_READ_LEN_128KB, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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, 259 .buf_len = HNS3_DBG_READ_LEN_128KB, 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 }, 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 }, 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 }, 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 }, 297 { 298 .name = "fd_tcam", 299 .cmd = HNAE3_DBG_CMD_FD_TCAM, 300 .dentry = HNS3_DBG_DENTRY_FD, 301 .buf_len = HNS3_DBG_READ_LEN_1MB, 302 .init = hns3_dbg_common_file_init, 303 }, 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 }, 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 }, 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 }, 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 }, 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 }, 339 { 340 .name = "page_pool_info", 341 .cmd = HNAE3_DBG_CMD_PAGE_POOL_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 = "coalesce_info", 348 .cmd = HNAE3_DBG_CMD_COAL_INFO, 349 .dentry = HNS3_DBG_DENTRY_COMMON, 350 .buf_len = HNS3_DBG_READ_LEN_1MB, 351 .init = hns3_dbg_common_file_init, 352 }, 353 }; 354 355 static struct hns3_dbg_cap_info hns3_dbg_cap[] = { 356 { 357 .name = "support FD", 358 .cap_bit = HNAE3_DEV_SUPPORT_FD_B, 359 }, { 360 .name = "support GRO", 361 .cap_bit = HNAE3_DEV_SUPPORT_GRO_B, 362 }, { 363 .name = "support FEC", 364 .cap_bit = HNAE3_DEV_SUPPORT_FEC_B, 365 }, { 366 .name = "support UDP GSO", 367 .cap_bit = HNAE3_DEV_SUPPORT_UDP_GSO_B, 368 }, { 369 .name = "support PTP", 370 .cap_bit = HNAE3_DEV_SUPPORT_PTP_B, 371 }, { 372 .name = "support INT QL", 373 .cap_bit = HNAE3_DEV_SUPPORT_INT_QL_B, 374 }, { 375 .name = "support HW TX csum", 376 .cap_bit = HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, 377 }, { 378 .name = "support UDP tunnel csum", 379 .cap_bit = HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, 380 }, { 381 .name = "support TX push", 382 .cap_bit = HNAE3_DEV_SUPPORT_TX_PUSH_B, 383 }, { 384 .name = "support imp-controlled PHY", 385 .cap_bit = HNAE3_DEV_SUPPORT_PHY_IMP_B, 386 }, { 387 .name = "support imp-controlled RAS", 388 .cap_bit = HNAE3_DEV_SUPPORT_RAS_IMP_B, 389 }, { 390 .name = "support rxd advanced layout", 391 .cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, 392 }, { 393 .name = "support port vlan bypass", 394 .cap_bit = HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, 395 }, { 396 .name = "support modify vlan filter state", 397 .cap_bit = HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, 398 } 399 }; 400 401 static const struct hns3_dbg_item coal_info_items[] = { 402 { "VEC_ID", 2 }, 403 { "ALGO_STATE", 2 }, 404 { "PROFILE_ID", 2 }, 405 { "CQE_MODE", 2 }, 406 { "TUNE_STATE", 2 }, 407 { "STEPS_LEFT", 2 }, 408 { "STEPS_RIGHT", 2 }, 409 { "TIRED", 2 }, 410 { "SW_GL", 2 }, 411 { "SW_QL", 2 }, 412 { "HW_GL", 2 }, 413 { "HW_QL", 2 }, 414 }; 415 416 static const char * const dim_cqe_mode_str[] = { "EQE", "CQE" }; 417 static const char * const dim_state_str[] = { "START", "IN_PROG", "APPLY" }; 418 static const char * const 419 dim_tune_stat_str[] = { "ON_TOP", "TIRED", "RIGHT", "LEFT" }; 420 421 static void hns3_dbg_fill_content(char *content, u16 len, 422 const struct hns3_dbg_item *items, 423 const char **result, u16 size) 424 { 425 char *pos = content; 426 u16 i; 427 428 memset(content, ' ', len); 429 for (i = 0; i < size; i++) { 430 if (result) 431 strncpy(pos, result[i], strlen(result[i])); 432 else 433 strncpy(pos, items[i].name, strlen(items[i].name)); 434 435 pos += strlen(items[i].name) + items[i].interval; 436 } 437 438 *pos++ = '\n'; 439 *pos++ = '\0'; 440 } 441 442 static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector, 443 char **result, int i, bool is_tx) 444 { 445 unsigned int gl_offset, ql_offset; 446 struct hns3_enet_coalesce *coal; 447 unsigned int reg_val; 448 unsigned int j = 0; 449 struct dim *dim; 450 bool ql_enable; 451 452 if (is_tx) { 453 coal = &tqp_vector->tx_group.coal; 454 dim = &tqp_vector->tx_group.dim; 455 gl_offset = HNS3_VECTOR_GL1_OFFSET; 456 ql_offset = HNS3_VECTOR_TX_QL_OFFSET; 457 ql_enable = tqp_vector->tx_group.coal.ql_enable; 458 } else { 459 coal = &tqp_vector->rx_group.coal; 460 dim = &tqp_vector->rx_group.dim; 461 gl_offset = HNS3_VECTOR_GL0_OFFSET; 462 ql_offset = HNS3_VECTOR_RX_QL_OFFSET; 463 ql_enable = tqp_vector->rx_group.coal.ql_enable; 464 } 465 466 sprintf(result[j++], "%d", i); 467 sprintf(result[j++], "%s", dim_state_str[dim->state]); 468 sprintf(result[j++], "%u", dim->profile_ix); 469 sprintf(result[j++], "%s", dim_cqe_mode_str[dim->mode]); 470 sprintf(result[j++], "%s", 471 dim_tune_stat_str[dim->tune_state]); 472 sprintf(result[j++], "%u", dim->steps_left); 473 sprintf(result[j++], "%u", dim->steps_right); 474 sprintf(result[j++], "%u", dim->tired); 475 sprintf(result[j++], "%u", coal->int_gl); 476 sprintf(result[j++], "%u", coal->int_ql); 477 reg_val = readl(tqp_vector->mask_addr + gl_offset) & 478 HNS3_VECTOR_GL_MASK; 479 sprintf(result[j++], "%u", reg_val); 480 if (ql_enable) { 481 reg_val = readl(tqp_vector->mask_addr + ql_offset) & 482 HNS3_VECTOR_QL_MASK; 483 sprintf(result[j++], "%u", reg_val); 484 } else { 485 sprintf(result[j++], "NA"); 486 } 487 } 488 489 static void hns3_dump_coal_info(struct hnae3_handle *h, char *buf, int len, 490 int *pos, bool is_tx) 491 { 492 char data_str[ARRAY_SIZE(coal_info_items)][HNS3_DBG_DATA_STR_LEN]; 493 char *result[ARRAY_SIZE(coal_info_items)]; 494 struct hns3_enet_tqp_vector *tqp_vector; 495 struct hns3_nic_priv *priv = h->priv; 496 char content[HNS3_DBG_INFO_LEN]; 497 unsigned int i; 498 499 for (i = 0; i < ARRAY_SIZE(coal_info_items); i++) 500 result[i] = &data_str[i][0]; 501 502 *pos += scnprintf(buf + *pos, len - *pos, 503 "%s interrupt coalesce info:\n", 504 is_tx ? "tx" : "rx"); 505 hns3_dbg_fill_content(content, sizeof(content), coal_info_items, 506 NULL, ARRAY_SIZE(coal_info_items)); 507 *pos += scnprintf(buf + *pos, len - *pos, "%s", content); 508 509 for (i = 0; i < priv->vector_num; i++) { 510 tqp_vector = &priv->tqp_vector[i]; 511 hns3_get_coal_info(tqp_vector, result, i, is_tx); 512 hns3_dbg_fill_content(content, sizeof(content), coal_info_items, 513 (const char **)result, 514 ARRAY_SIZE(coal_info_items)); 515 *pos += scnprintf(buf + *pos, len - *pos, "%s", content); 516 } 517 } 518 519 static int hns3_dbg_coal_info(struct hnae3_handle *h, char *buf, int len) 520 { 521 int pos = 0; 522 523 hns3_dump_coal_info(h, buf, len, &pos, true); 524 pos += scnprintf(buf + pos, len - pos, "\n"); 525 hns3_dump_coal_info(h, buf, len, &pos, false); 526 527 return 0; 528 } 529 530 static const struct hns3_dbg_item tx_spare_info_items[] = { 531 { "QUEUE_ID", 2 }, 532 { "COPYBREAK", 2 }, 533 { "LEN", 7 }, 534 { "NTU", 4 }, 535 { "NTC", 4 }, 536 { "LTC", 4 }, 537 { "DMA", 17 }, 538 }; 539 540 static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf, 541 int len, u32 ring_num, int *pos) 542 { 543 char data_str[ARRAY_SIZE(tx_spare_info_items)][HNS3_DBG_DATA_STR_LEN]; 544 struct hns3_tx_spare *tx_spare = ring->tx_spare; 545 char *result[ARRAY_SIZE(tx_spare_info_items)]; 546 char content[HNS3_DBG_INFO_LEN]; 547 u32 i, j; 548 549 if (!tx_spare) { 550 *pos += scnprintf(buf + *pos, len - *pos, 551 "tx spare buffer is not enabled\n"); 552 return; 553 } 554 555 for (i = 0; i < ARRAY_SIZE(tx_spare_info_items); i++) 556 result[i] = &data_str[i][0]; 557 558 *pos += scnprintf(buf + *pos, len - *pos, "tx spare buffer info\n"); 559 hns3_dbg_fill_content(content, sizeof(content), tx_spare_info_items, 560 NULL, ARRAY_SIZE(tx_spare_info_items)); 561 *pos += scnprintf(buf + *pos, len - *pos, "%s", content); 562 563 for (i = 0; i < ring_num; i++) { 564 j = 0; 565 sprintf(result[j++], "%8u", i); 566 sprintf(result[j++], "%9u", ring->tx_copybreak); 567 sprintf(result[j++], "%3u", tx_spare->len); 568 sprintf(result[j++], "%3u", tx_spare->next_to_use); 569 sprintf(result[j++], "%3u", tx_spare->next_to_clean); 570 sprintf(result[j++], "%3u", tx_spare->last_to_clean); 571 sprintf(result[j++], "%pad", &tx_spare->dma); 572 hns3_dbg_fill_content(content, sizeof(content), 573 tx_spare_info_items, 574 (const char **)result, 575 ARRAY_SIZE(tx_spare_info_items)); 576 *pos += scnprintf(buf + *pos, len - *pos, "%s", content); 577 } 578 } 579 580 static const struct hns3_dbg_item rx_queue_info_items[] = { 581 { "QUEUE_ID", 2 }, 582 { "BD_NUM", 2 }, 583 { "BD_LEN", 2 }, 584 { "TAIL", 2 }, 585 { "HEAD", 2 }, 586 { "FBDNUM", 2 }, 587 { "PKTNUM", 5 }, 588 { "COPYBREAK", 2 }, 589 { "RING_EN", 2 }, 590 { "RX_RING_EN", 2 }, 591 { "BASE_ADDR", 10 }, 592 }; 593 594 static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring, 595 struct hnae3_ae_dev *ae_dev, char **result, 596 u32 index) 597 { 598 u32 base_add_l, base_add_h; 599 u32 j = 0; 600 601 sprintf(result[j++], "%8u", index); 602 603 sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + 604 HNS3_RING_RX_RING_BD_NUM_REG)); 605 606 sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + 607 HNS3_RING_RX_RING_BD_LEN_REG)); 608 609 sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + 610 HNS3_RING_RX_RING_TAIL_REG)); 611 612 sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + 613 HNS3_RING_RX_RING_HEAD_REG)); 614 615 sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + 616 HNS3_RING_RX_RING_FBDNUM_REG)); 617 618 sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + 619 HNS3_RING_RX_RING_PKTNUM_RECORD_REG)); 620 sprintf(result[j++], "%9u", ring->rx_copybreak); 621 622 sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + 623 HNS3_RING_EN_REG) ? "on" : "off"); 624 625 if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) 626 sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base + 627 HNS3_RING_RX_EN_REG) ? "on" : "off"); 628 else 629 sprintf(result[j++], "%10s", "NA"); 630 631 base_add_h = readl_relaxed(ring->tqp->io_base + 632 HNS3_RING_RX_RING_BASEADDR_H_REG); 633 base_add_l = readl_relaxed(ring->tqp->io_base + 634 HNS3_RING_RX_RING_BASEADDR_L_REG); 635 sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l); 636 } 637 638 static int hns3_dbg_rx_queue_info(struct hnae3_handle *h, 639 char *buf, int len) 640 { 641 char data_str[ARRAY_SIZE(rx_queue_info_items)][HNS3_DBG_DATA_STR_LEN]; 642 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); 643 char *result[ARRAY_SIZE(rx_queue_info_items)]; 644 struct hns3_nic_priv *priv = h->priv; 645 char content[HNS3_DBG_INFO_LEN]; 646 struct hns3_enet_ring *ring; 647 int pos = 0; 648 u32 i; 649 650 if (!priv->ring) { 651 dev_err(&h->pdev->dev, "priv->ring is NULL\n"); 652 return -EFAULT; 653 } 654 655 for (i = 0; i < ARRAY_SIZE(rx_queue_info_items); i++) 656 result[i] = &data_str[i][0]; 657 658 hns3_dbg_fill_content(content, sizeof(content), rx_queue_info_items, 659 NULL, ARRAY_SIZE(rx_queue_info_items)); 660 pos += scnprintf(buf + pos, len - pos, "%s", content); 661 for (i = 0; i < h->kinfo.num_tqps; i++) { 662 /* Each cycle needs to determine whether the instance is reset, 663 * to prevent reference to invalid memory. And need to ensure 664 * that the following code is executed within 100ms. 665 */ 666 if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || 667 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) 668 return -EPERM; 669 670 ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)]; 671 hns3_dump_rx_queue_info(ring, ae_dev, result, i); 672 hns3_dbg_fill_content(content, sizeof(content), 673 rx_queue_info_items, 674 (const char **)result, 675 ARRAY_SIZE(rx_queue_info_items)); 676 pos += scnprintf(buf + pos, len - pos, "%s", content); 677 } 678 679 return 0; 680 } 681 682 static const struct hns3_dbg_item tx_queue_info_items[] = { 683 { "QUEUE_ID", 2 }, 684 { "BD_NUM", 2 }, 685 { "TC", 2 }, 686 { "TAIL", 2 }, 687 { "HEAD", 2 }, 688 { "FBDNUM", 2 }, 689 { "OFFSET", 2 }, 690 { "PKTNUM", 5 }, 691 { "RING_EN", 2 }, 692 { "TX_RING_EN", 2 }, 693 { "BASE_ADDR", 10 }, 694 }; 695 696 static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring, 697 struct hnae3_ae_dev *ae_dev, char **result, 698 u32 index) 699 { 700 u32 base_add_l, base_add_h; 701 u32 j = 0; 702 703 sprintf(result[j++], "%8u", index); 704 sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + 705 HNS3_RING_TX_RING_BD_NUM_REG)); 706 707 sprintf(result[j++], "%2u", readl_relaxed(ring->tqp->io_base + 708 HNS3_RING_TX_RING_TC_REG)); 709 710 sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + 711 HNS3_RING_TX_RING_TAIL_REG)); 712 713 sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + 714 HNS3_RING_TX_RING_HEAD_REG)); 715 716 sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + 717 HNS3_RING_TX_RING_FBDNUM_REG)); 718 719 sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + 720 HNS3_RING_TX_RING_OFFSET_REG)); 721 722 sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + 723 HNS3_RING_TX_RING_PKTNUM_RECORD_REG)); 724 725 sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + 726 HNS3_RING_EN_REG) ? "on" : "off"); 727 728 if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) 729 sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base + 730 HNS3_RING_TX_EN_REG) ? "on" : "off"); 731 else 732 sprintf(result[j++], "%10s", "NA"); 733 734 base_add_h = readl_relaxed(ring->tqp->io_base + 735 HNS3_RING_TX_RING_BASEADDR_H_REG); 736 base_add_l = readl_relaxed(ring->tqp->io_base + 737 HNS3_RING_TX_RING_BASEADDR_L_REG); 738 sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l); 739 } 740 741 static int hns3_dbg_tx_queue_info(struct hnae3_handle *h, 742 char *buf, int len) 743 { 744 char data_str[ARRAY_SIZE(tx_queue_info_items)][HNS3_DBG_DATA_STR_LEN]; 745 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); 746 char *result[ARRAY_SIZE(tx_queue_info_items)]; 747 struct hns3_nic_priv *priv = h->priv; 748 char content[HNS3_DBG_INFO_LEN]; 749 struct hns3_enet_ring *ring; 750 int pos = 0; 751 u32 i; 752 753 if (!priv->ring) { 754 dev_err(&h->pdev->dev, "priv->ring is NULL\n"); 755 return -EFAULT; 756 } 757 758 for (i = 0; i < ARRAY_SIZE(tx_queue_info_items); i++) 759 result[i] = &data_str[i][0]; 760 761 hns3_dbg_fill_content(content, sizeof(content), tx_queue_info_items, 762 NULL, ARRAY_SIZE(tx_queue_info_items)); 763 pos += scnprintf(buf + pos, len - pos, "%s", content); 764 765 for (i = 0; i < h->kinfo.num_tqps; i++) { 766 /* Each cycle needs to determine whether the instance is reset, 767 * to prevent reference to invalid memory. And need to ensure 768 * that the following code is executed within 100ms. 769 */ 770 if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || 771 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) 772 return -EPERM; 773 774 ring = &priv->ring[i]; 775 hns3_dump_tx_queue_info(ring, ae_dev, result, i); 776 hns3_dbg_fill_content(content, sizeof(content), 777 tx_queue_info_items, 778 (const char **)result, 779 ARRAY_SIZE(tx_queue_info_items)); 780 pos += scnprintf(buf + pos, len - pos, "%s", content); 781 } 782 783 hns3_dbg_tx_spare_info(ring, buf, len, h->kinfo.num_tqps, &pos); 784 785 return 0; 786 } 787 788 static const struct hns3_dbg_item queue_map_items[] = { 789 { "local_queue_id", 2 }, 790 { "global_queue_id", 2 }, 791 { "vector_id", 2 }, 792 }; 793 794 static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len) 795 { 796 char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN]; 797 char *result[ARRAY_SIZE(queue_map_items)]; 798 struct hns3_nic_priv *priv = h->priv; 799 char content[HNS3_DBG_INFO_LEN]; 800 int pos = 0; 801 int j; 802 u32 i; 803 804 if (!h->ae_algo->ops->get_global_queue_id) 805 return -EOPNOTSUPP; 806 807 for (i = 0; i < ARRAY_SIZE(queue_map_items); i++) 808 result[i] = &data_str[i][0]; 809 810 hns3_dbg_fill_content(content, sizeof(content), queue_map_items, 811 NULL, ARRAY_SIZE(queue_map_items)); 812 pos += scnprintf(buf + pos, len - pos, "%s", content); 813 for (i = 0; i < h->kinfo.num_tqps; i++) { 814 if (!priv->ring || !priv->ring[i].tqp_vector) 815 continue; 816 j = 0; 817 sprintf(result[j++], "%u", i); 818 sprintf(result[j++], "%u", 819 h->ae_algo->ops->get_global_queue_id(h, i)); 820 sprintf(result[j++], "%d", 821 priv->ring[i].tqp_vector->vector_irq); 822 hns3_dbg_fill_content(content, sizeof(content), queue_map_items, 823 (const char **)result, 824 ARRAY_SIZE(queue_map_items)); 825 pos += scnprintf(buf + pos, len - pos, "%s", content); 826 } 827 828 return 0; 829 } 830 831 static const struct hns3_dbg_item rx_bd_info_items[] = { 832 { "BD_IDX", 3 }, 833 { "L234_INFO", 2 }, 834 { "PKT_LEN", 3 }, 835 { "SIZE", 4 }, 836 { "RSS_HASH", 4 }, 837 { "FD_ID", 2 }, 838 { "VLAN_TAG", 2 }, 839 { "O_DM_VLAN_ID_FB", 2 }, 840 { "OT_VLAN_TAG", 2 }, 841 { "BD_BASE_INFO", 2 }, 842 { "PTYPE", 2 }, 843 { "HW_CSUM", 2 }, 844 }; 845 846 static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv, 847 struct hns3_desc *desc, char **result, int idx) 848 { 849 unsigned int j = 0; 850 851 sprintf(result[j++], "%5d", idx); 852 sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info)); 853 sprintf(result[j++], "%7u", le16_to_cpu(desc->rx.pkt_len)); 854 sprintf(result[j++], "%4u", le16_to_cpu(desc->rx.size)); 855 sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash)); 856 sprintf(result[j++], "%5u", le16_to_cpu(desc->rx.fd_id)); 857 sprintf(result[j++], "%8u", le16_to_cpu(desc->rx.vlan_tag)); 858 sprintf(result[j++], "%15u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb)); 859 sprintf(result[j++], "%11u", le16_to_cpu(desc->rx.ot_vlan_tag)); 860 sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info)); 861 if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) { 862 u32 ol_info = le32_to_cpu(desc->rx.ol_info); 863 864 sprintf(result[j++], "%5lu", hnae3_get_field(ol_info, 865 HNS3_RXD_PTYPE_M, 866 HNS3_RXD_PTYPE_S)); 867 sprintf(result[j++], "%7u", le16_to_cpu(desc->csum)); 868 } else { 869 sprintf(result[j++], "NA"); 870 sprintf(result[j++], "NA"); 871 } 872 } 873 874 static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len) 875 { 876 char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN]; 877 struct hns3_nic_priv *priv = d->handle->priv; 878 char *result[ARRAY_SIZE(rx_bd_info_items)]; 879 char content[HNS3_DBG_INFO_LEN]; 880 struct hns3_enet_ring *ring; 881 struct hns3_desc *desc; 882 unsigned int i; 883 int pos = 0; 884 885 if (d->qid >= d->handle->kinfo.num_tqps) { 886 dev_err(&d->handle->pdev->dev, 887 "queue%u is not in use\n", d->qid); 888 return -EINVAL; 889 } 890 891 for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++) 892 result[i] = &data_str[i][0]; 893 894 pos += scnprintf(buf + pos, len - pos, 895 "Queue %u rx bd info:\n", d->qid); 896 hns3_dbg_fill_content(content, sizeof(content), rx_bd_info_items, 897 NULL, ARRAY_SIZE(rx_bd_info_items)); 898 pos += scnprintf(buf + pos, len - pos, "%s", content); 899 900 ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps]; 901 for (i = 0; i < ring->desc_num; i++) { 902 desc = &ring->desc[i]; 903 904 hns3_dump_rx_bd_info(priv, desc, result, i); 905 hns3_dbg_fill_content(content, sizeof(content), 906 rx_bd_info_items, (const char **)result, 907 ARRAY_SIZE(rx_bd_info_items)); 908 pos += scnprintf(buf + pos, len - pos, "%s", content); 909 } 910 911 return 0; 912 } 913 914 static const struct hns3_dbg_item tx_bd_info_items[] = { 915 { "BD_IDX", 2 }, 916 { "ADDRESS", 13 }, 917 { "VLAN_TAG", 2 }, 918 { "SIZE", 2 }, 919 { "T_CS_VLAN_TSO", 2 }, 920 { "OT_VLAN_TAG", 3 }, 921 { "TV", 5 }, 922 { "OLT_VLAN_LEN", 2 }, 923 { "PAYLEN_OL4CS", 2 }, 924 { "BD_FE_SC_VLD", 2 }, 925 { "MSS_HW_CSUM", 0 }, 926 }; 927 928 static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv, 929 struct hns3_desc *desc, char **result, int idx) 930 { 931 unsigned int j = 0; 932 933 sprintf(result[j++], "%6d", idx); 934 sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr)); 935 sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.vlan_tag)); 936 sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.send_size)); 937 sprintf(result[j++], "%#x", 938 le32_to_cpu(desc->tx.type_cs_vlan_tso_len)); 939 sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.outer_vlan_tag)); 940 sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.tv)); 941 sprintf(result[j++], "%10u", 942 le32_to_cpu(desc->tx.ol_type_vlan_len_msec)); 943 sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs)); 944 sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri)); 945 sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum)); 946 } 947 948 static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len) 949 { 950 char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN]; 951 struct hns3_nic_priv *priv = d->handle->priv; 952 char *result[ARRAY_SIZE(tx_bd_info_items)]; 953 char content[HNS3_DBG_INFO_LEN]; 954 struct hns3_enet_ring *ring; 955 struct hns3_desc *desc; 956 unsigned int i; 957 int pos = 0; 958 959 if (d->qid >= d->handle->kinfo.num_tqps) { 960 dev_err(&d->handle->pdev->dev, 961 "queue%u is not in use\n", d->qid); 962 return -EINVAL; 963 } 964 965 for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++) 966 result[i] = &data_str[i][0]; 967 968 pos += scnprintf(buf + pos, len - pos, 969 "Queue %u tx bd info:\n", d->qid); 970 hns3_dbg_fill_content(content, sizeof(content), tx_bd_info_items, 971 NULL, ARRAY_SIZE(tx_bd_info_items)); 972 pos += scnprintf(buf + pos, len - pos, "%s", content); 973 974 ring = &priv->ring[d->qid]; 975 for (i = 0; i < ring->desc_num; i++) { 976 desc = &ring->desc[i]; 977 978 hns3_dump_tx_bd_info(priv, desc, result, i); 979 hns3_dbg_fill_content(content, sizeof(content), 980 tx_bd_info_items, (const char **)result, 981 ARRAY_SIZE(tx_bd_info_items)); 982 pos += scnprintf(buf + pos, len - pos, "%s", content); 983 } 984 985 return 0; 986 } 987 988 static void 989 hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos) 990 { 991 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); 992 const char * const str[] = {"no", "yes"}; 993 unsigned long *caps = ae_dev->caps; 994 u32 i, state; 995 996 *pos += scnprintf(buf + *pos, len - *pos, "dev capability:\n"); 997 998 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) { 999 state = test_bit(hns3_dbg_cap[i].cap_bit, caps); 1000 *pos += scnprintf(buf + *pos, len - *pos, "%s: %s\n", 1001 hns3_dbg_cap[i].name, str[state]); 1002 } 1003 1004 *pos += scnprintf(buf + *pos, len - *pos, "\n"); 1005 } 1006 1007 static void 1008 hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos) 1009 { 1010 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); 1011 struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs; 1012 struct hnae3_knic_private_info *kinfo = &h->kinfo; 1013 1014 *pos += scnprintf(buf + *pos, len - *pos, "dev_spec:\n"); 1015 *pos += scnprintf(buf + *pos, len - *pos, "MAC entry num: %u\n", 1016 dev_specs->mac_entry_num); 1017 *pos += scnprintf(buf + *pos, len - *pos, "MNG entry num: %u\n", 1018 dev_specs->mng_entry_num); 1019 *pos += scnprintf(buf + *pos, len - *pos, "MAX non tso bd num: %u\n", 1020 dev_specs->max_non_tso_bd_num); 1021 *pos += scnprintf(buf + *pos, len - *pos, "RSS ind tbl size: %u\n", 1022 dev_specs->rss_ind_tbl_size); 1023 *pos += scnprintf(buf + *pos, len - *pos, "RSS key size: %u\n", 1024 dev_specs->rss_key_size); 1025 *pos += scnprintf(buf + *pos, len - *pos, "RSS size: %u\n", 1026 kinfo->rss_size); 1027 *pos += scnprintf(buf + *pos, len - *pos, "Allocated RSS size: %u\n", 1028 kinfo->req_rss_size); 1029 *pos += scnprintf(buf + *pos, len - *pos, 1030 "Task queue pairs numbers: %u\n", 1031 kinfo->num_tqps); 1032 *pos += scnprintf(buf + *pos, len - *pos, "RX buffer length: %u\n", 1033 kinfo->rx_buf_len); 1034 *pos += scnprintf(buf + *pos, len - *pos, "Desc num per TX queue: %u\n", 1035 kinfo->num_tx_desc); 1036 *pos += scnprintf(buf + *pos, len - *pos, "Desc num per RX queue: %u\n", 1037 kinfo->num_rx_desc); 1038 *pos += scnprintf(buf + *pos, len - *pos, 1039 "Total number of enabled TCs: %u\n", 1040 kinfo->tc_info.num_tc); 1041 *pos += scnprintf(buf + *pos, len - *pos, "MAX INT QL: %u\n", 1042 dev_specs->int_ql_max); 1043 *pos += scnprintf(buf + *pos, len - *pos, "MAX INT GL: %u\n", 1044 dev_specs->max_int_gl); 1045 *pos += scnprintf(buf + *pos, len - *pos, "MAX TM RATE: %u\n", 1046 dev_specs->max_tm_rate); 1047 *pos += scnprintf(buf + *pos, len - *pos, "MAX QSET number: %u\n", 1048 dev_specs->max_qset_num); 1049 *pos += scnprintf(buf + *pos, len - *pos, "umv size: %u\n", 1050 dev_specs->umv_size); 1051 *pos += scnprintf(buf + *pos, len - *pos, "mc mac size: %u\n", 1052 dev_specs->mc_mac_size); 1053 *pos += scnprintf(buf + *pos, len - *pos, "MAC statistics number: %u\n", 1054 dev_specs->mac_stats_num); 1055 } 1056 1057 static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len) 1058 { 1059 int pos = 0; 1060 1061 hns3_dbg_dev_caps(h, buf, len, &pos); 1062 1063 hns3_dbg_dev_specs(h, buf, len, &pos); 1064 1065 return 0; 1066 } 1067 1068 static const struct hns3_dbg_item page_pool_info_items[] = { 1069 { "QUEUE_ID", 2 }, 1070 { "ALLOCATE_CNT", 2 }, 1071 { "FREE_CNT", 6 }, 1072 { "POOL_SIZE(PAGE_NUM)", 2 }, 1073 { "ORDER", 2 }, 1074 { "NUMA_ID", 2 }, 1075 { "MAX_LEN", 2 }, 1076 }; 1077 1078 static void hns3_dump_page_pool_info(struct hns3_enet_ring *ring, 1079 char **result, u32 index) 1080 { 1081 u32 j = 0; 1082 1083 sprintf(result[j++], "%u", index); 1084 sprintf(result[j++], "%u", 1085 READ_ONCE(ring->page_pool->pages_state_hold_cnt)); 1086 sprintf(result[j++], "%d", 1087 atomic_read(&ring->page_pool->pages_state_release_cnt)); 1088 sprintf(result[j++], "%u", ring->page_pool->p.pool_size); 1089 sprintf(result[j++], "%u", ring->page_pool->p.order); 1090 sprintf(result[j++], "%d", ring->page_pool->p.nid); 1091 sprintf(result[j++], "%uK", ring->page_pool->p.max_len / 1024); 1092 } 1093 1094 static int 1095 hns3_dbg_page_pool_info(struct hnae3_handle *h, char *buf, int len) 1096 { 1097 char data_str[ARRAY_SIZE(page_pool_info_items)][HNS3_DBG_DATA_STR_LEN]; 1098 char *result[ARRAY_SIZE(page_pool_info_items)]; 1099 struct hns3_nic_priv *priv = h->priv; 1100 char content[HNS3_DBG_INFO_LEN]; 1101 struct hns3_enet_ring *ring; 1102 int pos = 0; 1103 u32 i; 1104 1105 if (!priv->ring) { 1106 dev_err(&h->pdev->dev, "priv->ring is NULL\n"); 1107 return -EFAULT; 1108 } 1109 1110 if (!priv->ring[h->kinfo.num_tqps].page_pool) { 1111 dev_err(&h->pdev->dev, "page pool is not initialized\n"); 1112 return -EFAULT; 1113 } 1114 1115 for (i = 0; i < ARRAY_SIZE(page_pool_info_items); i++) 1116 result[i] = &data_str[i][0]; 1117 1118 hns3_dbg_fill_content(content, sizeof(content), page_pool_info_items, 1119 NULL, ARRAY_SIZE(page_pool_info_items)); 1120 pos += scnprintf(buf + pos, len - pos, "%s", content); 1121 for (i = 0; i < h->kinfo.num_tqps; i++) { 1122 if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || 1123 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) 1124 return -EPERM; 1125 ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)]; 1126 hns3_dump_page_pool_info(ring, result, i); 1127 hns3_dbg_fill_content(content, sizeof(content), 1128 page_pool_info_items, 1129 (const char **)result, 1130 ARRAY_SIZE(page_pool_info_items)); 1131 pos += scnprintf(buf + pos, len - pos, "%s", content); 1132 } 1133 1134 return 0; 1135 } 1136 1137 static int hns3_dbg_get_cmd_index(struct hns3_dbg_data *dbg_data, u32 *index) 1138 { 1139 u32 i; 1140 1141 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { 1142 if (hns3_dbg_cmd[i].cmd == dbg_data->cmd) { 1143 *index = i; 1144 return 0; 1145 } 1146 } 1147 1148 dev_err(&dbg_data->handle->pdev->dev, "unknown command(%d)\n", 1149 dbg_data->cmd); 1150 return -EINVAL; 1151 } 1152 1153 static const struct hns3_dbg_func hns3_dbg_cmd_func[] = { 1154 { 1155 .cmd = HNAE3_DBG_CMD_QUEUE_MAP, 1156 .dbg_dump = hns3_dbg_queue_map, 1157 }, 1158 { 1159 .cmd = HNAE3_DBG_CMD_DEV_INFO, 1160 .dbg_dump = hns3_dbg_dev_info, 1161 }, 1162 { 1163 .cmd = HNAE3_DBG_CMD_TX_BD, 1164 .dbg_dump_bd = hns3_dbg_tx_bd_info, 1165 }, 1166 { 1167 .cmd = HNAE3_DBG_CMD_RX_BD, 1168 .dbg_dump_bd = hns3_dbg_rx_bd_info, 1169 }, 1170 { 1171 .cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO, 1172 .dbg_dump = hns3_dbg_rx_queue_info, 1173 }, 1174 { 1175 .cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO, 1176 .dbg_dump = hns3_dbg_tx_queue_info, 1177 }, 1178 { 1179 .cmd = HNAE3_DBG_CMD_PAGE_POOL_INFO, 1180 .dbg_dump = hns3_dbg_page_pool_info, 1181 }, 1182 { 1183 .cmd = HNAE3_DBG_CMD_COAL_INFO, 1184 .dbg_dump = hns3_dbg_coal_info, 1185 }, 1186 }; 1187 1188 static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data, 1189 enum hnae3_dbg_cmd cmd, char *buf, int len) 1190 { 1191 const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops; 1192 const struct hns3_dbg_func *cmd_func; 1193 u32 i; 1194 1195 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) { 1196 if (cmd == hns3_dbg_cmd_func[i].cmd) { 1197 cmd_func = &hns3_dbg_cmd_func[i]; 1198 if (cmd_func->dbg_dump) 1199 return cmd_func->dbg_dump(dbg_data->handle, buf, 1200 len); 1201 else 1202 return cmd_func->dbg_dump_bd(dbg_data, buf, 1203 len); 1204 } 1205 } 1206 1207 if (!ops->dbg_read_cmd) 1208 return -EOPNOTSUPP; 1209 1210 return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len); 1211 } 1212 1213 static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, 1214 size_t count, loff_t *ppos) 1215 { 1216 struct hns3_dbg_data *dbg_data = filp->private_data; 1217 struct hnae3_handle *handle = dbg_data->handle; 1218 struct hns3_nic_priv *priv = handle->priv; 1219 ssize_t size = 0; 1220 char **save_buf; 1221 char *read_buf; 1222 u32 index; 1223 int ret; 1224 1225 ret = hns3_dbg_get_cmd_index(dbg_data, &index); 1226 if (ret) 1227 return ret; 1228 1229 mutex_lock(&handle->dbgfs_lock); 1230 save_buf = &hns3_dbg_cmd[index].buf; 1231 1232 if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || 1233 test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { 1234 ret = -EBUSY; 1235 goto out; 1236 } 1237 1238 if (*save_buf) { 1239 read_buf = *save_buf; 1240 } else { 1241 read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL); 1242 if (!read_buf) { 1243 ret = -ENOMEM; 1244 goto out; 1245 } 1246 1247 /* save the buffer addr until the last read operation */ 1248 *save_buf = read_buf; 1249 1250 /* get data ready for the first time to read */ 1251 ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, 1252 read_buf, hns3_dbg_cmd[index].buf_len); 1253 if (ret) 1254 goto out; 1255 } 1256 1257 size = simple_read_from_buffer(buffer, count, ppos, read_buf, 1258 strlen(read_buf)); 1259 if (size > 0) { 1260 mutex_unlock(&handle->dbgfs_lock); 1261 return size; 1262 } 1263 1264 out: 1265 /* free the buffer for the last read operation */ 1266 if (*save_buf) { 1267 kvfree(*save_buf); 1268 *save_buf = NULL; 1269 } 1270 1271 mutex_unlock(&handle->dbgfs_lock); 1272 return ret; 1273 } 1274 1275 static const struct file_operations hns3_dbg_fops = { 1276 .owner = THIS_MODULE, 1277 .open = simple_open, 1278 .read = hns3_dbg_read, 1279 }; 1280 1281 static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd) 1282 { 1283 struct dentry *entry_dir; 1284 struct hns3_dbg_data *data; 1285 u16 max_queue_num; 1286 unsigned int i; 1287 1288 entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry; 1289 max_queue_num = hns3_get_max_available_channels(handle); 1290 data = devm_kzalloc(&handle->pdev->dev, max_queue_num * sizeof(*data), 1291 GFP_KERNEL); 1292 if (!data) 1293 return -ENOMEM; 1294 1295 for (i = 0; i < max_queue_num; i++) { 1296 char name[HNS3_DBG_FILE_NAME_LEN]; 1297 1298 data[i].handle = handle; 1299 data[i].cmd = hns3_dbg_cmd[cmd].cmd; 1300 data[i].qid = i; 1301 sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i); 1302 debugfs_create_file(name, 0400, entry_dir, &data[i], 1303 &hns3_dbg_fops); 1304 } 1305 1306 return 0; 1307 } 1308 1309 static int 1310 hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd) 1311 { 1312 struct hns3_dbg_data *data; 1313 struct dentry *entry_dir; 1314 1315 data = devm_kzalloc(&handle->pdev->dev, sizeof(*data), GFP_KERNEL); 1316 if (!data) 1317 return -ENOMEM; 1318 1319 data->handle = handle; 1320 data->cmd = hns3_dbg_cmd[cmd].cmd; 1321 entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry; 1322 debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir, 1323 data, &hns3_dbg_fops); 1324 1325 return 0; 1326 } 1327 1328 int hns3_dbg_init(struct hnae3_handle *handle) 1329 { 1330 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); 1331 const char *name = pci_name(handle->pdev); 1332 int ret; 1333 u32 i; 1334 1335 hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry = 1336 debugfs_create_dir(name, hns3_dbgfs_root); 1337 handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry; 1338 1339 for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++) 1340 hns3_dbg_dentry[i].dentry = 1341 debugfs_create_dir(hns3_dbg_dentry[i].name, 1342 handle->hnae3_dbgfs); 1343 1344 mutex_init(&handle->dbgfs_lock); 1345 1346 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { 1347 if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES && 1348 ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) || 1349 (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_PTP_INFO && 1350 !test_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps))) 1351 continue; 1352 1353 if (!hns3_dbg_cmd[i].init) { 1354 dev_err(&handle->pdev->dev, 1355 "cmd %s lack of init func\n", 1356 hns3_dbg_cmd[i].name); 1357 ret = -EINVAL; 1358 goto out; 1359 } 1360 1361 ret = hns3_dbg_cmd[i].init(handle, i); 1362 if (ret) { 1363 dev_err(&handle->pdev->dev, "failed to init cmd %s\n", 1364 hns3_dbg_cmd[i].name); 1365 goto out; 1366 } 1367 } 1368 1369 return 0; 1370 1371 out: 1372 mutex_destroy(&handle->dbgfs_lock); 1373 debugfs_remove_recursive(handle->hnae3_dbgfs); 1374 handle->hnae3_dbgfs = NULL; 1375 return ret; 1376 } 1377 1378 void hns3_dbg_uninit(struct hnae3_handle *handle) 1379 { 1380 u32 i; 1381 1382 for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) 1383 if (hns3_dbg_cmd[i].buf) { 1384 kvfree(hns3_dbg_cmd[i].buf); 1385 hns3_dbg_cmd[i].buf = NULL; 1386 } 1387 1388 mutex_destroy(&handle->dbgfs_lock); 1389 debugfs_remove_recursive(handle->hnae3_dbgfs); 1390 handle->hnae3_dbgfs = NULL; 1391 } 1392 1393 void hns3_dbg_register_debugfs(const char *debugfs_dir_name) 1394 { 1395 hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL); 1396 } 1397 1398 void hns3_dbg_unregister_debugfs(void) 1399 { 1400 debugfs_remove_recursive(hns3_dbgfs_root); 1401 hns3_dbgfs_root = NULL; 1402 } 1403