1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2022 HiSilicon Limited 3 */ 4 5 #include <rte_kvargs.h> 6 #include <rte_bus_pci.h> 7 #include <ethdev_pci.h> 8 #include <rte_pci.h> 9 10 #include "hns3_common.h" 11 #include "hns3_logs.h" 12 #include "hns3_regs.h" 13 #include "hns3_rxtx.h" 14 15 static const char * 16 get_adapter_state_name(uint32_t state) 17 { 18 static const char * const state_name[] = { 19 "UNINITIALIZED", 20 "INITIALIZED", 21 "CONFIGURING", 22 "CONFIGURED", 23 "STARTING", 24 "STARTED", 25 "STOPPING", 26 "CLOSING", 27 "CLOSED", 28 "REMOVED", 29 "NSTATES" 30 }; 31 32 if (state < RTE_DIM(state_name)) 33 return state_name[state]; 34 else 35 return "unknown"; 36 } 37 38 static const char * 39 get_io_func_hint_name(uint32_t hint) 40 { 41 switch (hint) { 42 case HNS3_IO_FUNC_HINT_NONE: 43 return "none"; 44 case HNS3_IO_FUNC_HINT_VEC: 45 return "vec"; 46 case HNS3_IO_FUNC_HINT_SVE: 47 return "sve"; 48 case HNS3_IO_FUNC_HINT_SIMPLE: 49 return "simple"; 50 case HNS3_IO_FUNC_HINT_COMMON: 51 return "common"; 52 default: 53 return "unknown"; 54 } 55 } 56 57 static void 58 get_dev_mac_info(FILE *file, struct hns3_adapter *hns) 59 { 60 struct hns3_hw *hw = &hns->hw; 61 struct hns3_pf *pf = &hns->pf; 62 63 fprintf(file, " - MAC Info:\n"); 64 fprintf(file, 65 "\t -- query_type=%u\n" 66 "\t -- supported_speed=0x%x\n" 67 "\t -- advertising=0x%x\n" 68 "\t -- lp_advertising=0x%x\n" 69 "\t -- support_autoneg=%s\n" 70 "\t -- support_fc_autoneg=%s\n", 71 hw->mac.query_type, 72 hw->mac.supported_speed, 73 hw->mac.advertising, 74 hw->mac.lp_advertising, 75 hw->mac.support_autoneg != 0 ? "Yes" : "No", 76 pf->support_fc_autoneg ? "Yes" : "No"); 77 } 78 79 static void 80 get_dev_feature_capability(FILE *file, struct hns3_hw *hw) 81 { 82 const char * const caps_name[] = { 83 "DCB", 84 "COPPER", 85 "FD QUEUE REGION", 86 "PTP", 87 "TX PUSH", 88 "INDEP TXRX", 89 "STASH", 90 "SIMPLE BD", 91 "RXD Advanced Layout", 92 "OUTER UDP CKSUM", 93 "RAS IMP", 94 "TM", 95 "VF VLAN FILTER MOD", 96 }; 97 uint32_t i; 98 99 fprintf(file, " - Dev Capability:\n"); 100 for (i = 0; i < RTE_DIM(caps_name); i++) 101 fprintf(file, "\t -- support %s: %s\n", caps_name[i], 102 hw->capability & BIT(i) ? "yes" : "no"); 103 } 104 105 static const char * 106 get_fdir_tuple_name(uint32_t index) 107 { 108 static const char * const tuple_name[] = { 109 "outer_dst_mac", 110 "outer_src_mac", 111 "outer_vlan_1st_tag", 112 "outer_vlan_2nd_tag", 113 "outer_eth_type", 114 "outer_l2_rsv", 115 "outer_ip_tos", 116 "outer_ip_proto", 117 "outer_src_ip", 118 "outer_dst_ip", 119 "outer_l3_rsv", 120 "outer_src_port", 121 "outer_dst_port", 122 "outer_l4_rsv", 123 "outer_tun_vni", 124 "outer_tun_flow_id", 125 "inner_dst_mac", 126 "inner_src_mac", 127 "inner_vlan_tag1", 128 "inner_vlan_tag2", 129 "inner_eth_type", 130 "inner_l2_rsv", 131 "inner_ip_tos", 132 "inner_ip_proto", 133 "inner_src_ip", 134 "inner_dst_ip", 135 "inner_l3_rsv", 136 "inner_src_port", 137 "inner_dst_port", 138 "inner_sctp_tag", 139 }; 140 if (index < RTE_DIM(tuple_name)) 141 return tuple_name[index]; 142 else 143 return "unknown"; 144 } 145 146 static void 147 get_fdir_basic_info(FILE *file, struct hns3_pf *pf) 148 { 149 #define TMPBUF_SIZE 2048 150 #define PERLINE_TUPLE_NAMES 4 151 struct hns3_fd_cfg *fdcfg = &pf->fdir.fd_cfg; 152 char tmpbuf[TMPBUF_SIZE] = {0}; 153 uint32_t i, count = 0; 154 155 fprintf(file, " - Fdir Info:\n"); 156 fprintf(file, 157 "\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n" 158 "\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n" 159 "\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n" 160 "\t -- active_tuples:\n", 161 fdcfg->fd_mode, fdcfg->max_key_length, 162 fdcfg->rule_num[HNS3_FD_STAGE_1], 163 fdcfg->cnt_num[HNS3_FD_STAGE_1], 164 fdcfg->key_cfg[HNS3_FD_STAGE_1].key_sel, 165 fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active, 166 fdcfg->key_cfg[HNS3_FD_STAGE_1].meta_data_active, 167 fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_sipv6_word_en, 168 fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en, 169 fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en, 170 fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en); 171 172 for (i = 0; i < MAX_TUPLE; i++) { 173 if (!(fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active & BIT(i))) 174 continue; 175 if (count % PERLINE_TUPLE_NAMES == 0) 176 fprintf(file, "\t "); 177 fprintf(file, " %s", get_fdir_tuple_name(i)); 178 count++; 179 if (count % PERLINE_TUPLE_NAMES == 0) 180 fprintf(file, "\n"); 181 } 182 if (count % PERLINE_TUPLE_NAMES) 183 fprintf(file, "\n"); 184 185 fprintf(file, "%s", tmpbuf); 186 } 187 188 static void 189 get_device_basic_info(FILE *file, struct rte_eth_dev *dev) 190 { 191 struct hns3_adapter *hns = dev->data->dev_private; 192 struct hns3_hw *hw = &hns->hw; 193 194 fprintf(file, 195 " - Device Base Info:\n" 196 "\t -- name: %s\n" 197 "\t -- adapter_state=%s\n" 198 "\t -- nb_rx_queues=%u nb_tx_queues=%u\n" 199 "\t -- total_tqps_num=%u tqps_num=%u intr_tqps_num=%u\n" 200 "\t -- rss_size_max=%u alloc_rss_size=%u tx_qnum_per_tc=%u\n" 201 "\t -- min_tx_pkt_len=%u intr_mapping_mode=%u vlan_mode=%u\n" 202 "\t -- tso_mode=%u max_non_tso_bd_num=%u\n" 203 "\t -- max_tm_rate=%u Mbps\n" 204 "\t -- set link down: %s\n" 205 "\t -- rx_func_hint=%s tx_func_hint=%s\n" 206 "\t -- dev_flags: lsc=%d\n" 207 "\t -- intr_conf: lsc=%u rxq=%u\n", 208 dev->data->name, 209 get_adapter_state_name(hw->adapter_state), 210 dev->data->nb_rx_queues, dev->data->nb_tx_queues, 211 hw->total_tqps_num, hw->tqps_num, hw->intr_tqps_num, 212 hw->rss_size_max, hw->alloc_rss_size, hw->tx_qnum_per_tc, 213 hw->min_tx_pkt_len, hw->intr.mapping_mode, hw->vlan_mode, 214 hw->tso_mode, hw->max_non_tso_bd_num, 215 hw->max_tm_rate, 216 hw->set_link_down ? "Yes" : "No", 217 get_io_func_hint_name(hns->rx_func_hint), 218 get_io_func_hint_name(hns->tx_func_hint), 219 !!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC), 220 dev->data->dev_conf.intr_conf.lsc, 221 dev->data->dev_conf.intr_conf.rxq); 222 } 223 224 /* 225 * Note: caller must make sure queue_id < nb_queues 226 * nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues, 227 * eth_dev->data->nb_tx_queues) 228 */ 229 static struct hns3_rx_queue * 230 get_rx_queue(struct rte_eth_dev *dev, unsigned int queue_id) 231 { 232 struct hns3_adapter *hns = dev->data->dev_private; 233 struct hns3_hw *hw = &hns->hw; 234 unsigned int offset; 235 void **rx_queues; 236 237 if (queue_id < dev->data->nb_rx_queues) { 238 rx_queues = dev->data->rx_queues; 239 offset = queue_id; 240 } else { 241 /* 242 * For kunpeng930, fake queue is not exist. But since the queues 243 * are usually accessd in pairs, this branch may still exist. 244 */ 245 if (hns3_dev_get_support(hw, INDEP_TXRX)) 246 return NULL; 247 248 rx_queues = hw->fkq_data.rx_queues; 249 offset = queue_id - dev->data->nb_rx_queues; 250 } 251 252 if (rx_queues != NULL && rx_queues[offset] != NULL) 253 return rx_queues[offset]; 254 255 hns3_err(hw, "Detect rx_queues is NULL!\n"); 256 return NULL; 257 } 258 259 /* 260 * Note: caller must make sure queue_id < nb_queues 261 * nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues, 262 * eth_dev->data->nb_tx_queues) 263 */ 264 static struct hns3_tx_queue * 265 get_tx_queue(struct rte_eth_dev *dev, unsigned int queue_id) 266 { 267 struct hns3_adapter *hns = dev->data->dev_private; 268 struct hns3_hw *hw = &hns->hw; 269 unsigned int offset; 270 void **tx_queues; 271 272 if (queue_id < dev->data->nb_tx_queues) { 273 tx_queues = dev->data->tx_queues; 274 offset = queue_id; 275 } else { 276 /* 277 * For kunpeng930, fake queue is not exist. But since the queues 278 * are usually accessd in pairs, this branch may still exist. 279 */ 280 if (hns3_dev_get_support(hw, INDEP_TXRX)) 281 return NULL; 282 tx_queues = hw->fkq_data.tx_queues; 283 offset = queue_id - dev->data->nb_tx_queues; 284 } 285 286 if (tx_queues != NULL && tx_queues[offset] != NULL) 287 return tx_queues[offset]; 288 289 hns3_err(hw, "Detect tx_queues is NULL!\n"); 290 return NULL; 291 } 292 293 static void 294 get_rxtx_fake_queue_info(FILE *file, struct rte_eth_dev *dev) 295 { 296 struct hns3_adapter *hns = dev->data->dev_private; 297 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns); 298 struct hns3_rx_queue *rxq; 299 struct hns3_tx_queue *txq; 300 unsigned int queue_id; 301 302 if (dev->data->nb_rx_queues != dev->data->nb_tx_queues && 303 !hns3_dev_get_support(hw, INDEP_TXRX)) { 304 queue_id = RTE_MIN(dev->data->nb_rx_queues, 305 dev->data->nb_tx_queues); 306 rxq = get_rx_queue(dev, queue_id); 307 if (rxq == NULL) 308 return; 309 txq = get_tx_queue(dev, queue_id); 310 if (txq == NULL) 311 return; 312 fprintf(file, 313 "\t -- first fake_queue rxtx info:\n" 314 "\t rx: port=%u nb_desc=%u free_thresh=%u\n" 315 "\t tx: port=%u nb_desc=%u\n", 316 rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh, 317 txq->port_id, txq->nb_tx_desc); 318 } 319 } 320 321 static void 322 get_queue_enable_state(struct hns3_hw *hw, uint32_t *queue_state, 323 uint32_t nb_queues, bool is_rxq) 324 { 325 #define STATE_SIZE (sizeof(*queue_state) * CHAR_BIT) 326 uint32_t queue_en_reg; 327 uint32_t reg_offset; 328 uint32_t state; 329 uint32_t i; 330 331 queue_en_reg = is_rxq ? HNS3_RING_RX_EN_REG : HNS3_RING_TX_EN_REG; 332 for (i = 0; i < nb_queues; i++) { 333 reg_offset = hns3_get_tqp_reg_offset(i); 334 state = hns3_read_dev(hw, reg_offset + HNS3_RING_EN_REG); 335 if (hns3_dev_get_support(hw, INDEP_TXRX)) 336 state = state && hns3_read_dev(hw, reg_offset + 337 queue_en_reg); 338 hns3_set_bit(queue_state[i / STATE_SIZE], 339 i % STATE_SIZE, state); 340 } 341 } 342 343 static void 344 print_queue_state_perline(FILE *file, const uint32_t *queue_state, 345 uint32_t nb_queues, uint32_t line_num) 346 { 347 #define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT) 348 uint32_t qid = line_num * NUM_QUEUE_PER_LINE; 349 uint32_t j; 350 351 for (j = 0; j < NUM_QUEUE_PER_LINE; j++) { 352 fprintf(file, "%1lx", hns3_get_bit(queue_state[line_num], j)); 353 354 if (qid % CHAR_BIT == CHAR_BIT - 1) { 355 fprintf(file, "%s", 356 j == NUM_QUEUE_PER_LINE - 1 ? "\n" : ":"); 357 } 358 qid++; 359 if (qid >= nb_queues) { 360 fprintf(file, "\n"); 361 break; 362 } 363 } 364 } 365 366 static void 367 display_queue_enable_state(FILE *file, const uint32_t *queue_state, 368 uint32_t nb_queues, bool is_rxq) 369 { 370 #define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT) 371 uint32_t i; 372 373 if (nb_queues == 0) { 374 fprintf(file, "\t %s queue number is 0\n", 375 is_rxq ? "Rx" : "Tx"); 376 return; 377 } 378 379 fprintf(file, "\t %s queue id | enable state bitMap\n", 380 is_rxq ? "rx" : "tx"); 381 382 for (i = 0; i < (nb_queues - 1) / NUM_QUEUE_PER_LINE + 1; i++) { 383 uint32_t line_end = (i + 1) * NUM_QUEUE_PER_LINE - 1; 384 uint32_t line_start = i * NUM_QUEUE_PER_LINE; 385 fprintf(file, "\t %04u - %04u | ", line_start, 386 nb_queues - 1 > line_end ? line_end : nb_queues - 1); 387 388 389 print_queue_state_perline(file, queue_state, nb_queues, i); 390 } 391 } 392 393 static void 394 get_rxtx_queue_enable_state(FILE *file, struct rte_eth_dev *dev) 395 { 396 #define MAX_TQP_NUM 1280 397 #define QUEUE_BITMAP_SIZE (MAX_TQP_NUM / 32) 398 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); 399 uint32_t rx_queue_state[QUEUE_BITMAP_SIZE] = {0}; 400 uint32_t tx_queue_state[QUEUE_BITMAP_SIZE] = {0}; 401 uint32_t nb_rx_queues; 402 uint32_t nb_tx_queues; 403 404 nb_rx_queues = dev->data->nb_rx_queues; 405 nb_tx_queues = dev->data->nb_tx_queues; 406 407 fprintf(file, "\t -- enable state:\n"); 408 get_queue_enable_state(hw, rx_queue_state, nb_rx_queues, true); 409 display_queue_enable_state(file, rx_queue_state, nb_rx_queues, 410 true); 411 412 get_queue_enable_state(hw, tx_queue_state, nb_tx_queues, false); 413 display_queue_enable_state(file, tx_queue_state, nb_tx_queues, 414 false); 415 } 416 417 static void 418 get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev) 419 { 420 struct hns3_rx_queue *rxq; 421 struct hns3_tx_queue *txq; 422 unsigned int queue_id = 0; 423 424 rxq = get_rx_queue(dev, queue_id); 425 if (rxq == NULL) 426 return; 427 txq = get_tx_queue(dev, queue_id); 428 if (txq == NULL) 429 return; 430 fprintf(file, " - Rx/Tx Queue Info:\n"); 431 fprintf(file, 432 "\t -- nb_rx_queues=%u nb_tx_queues=%u, " 433 "first queue rxtx info:\n" 434 "\t rx: port=%u nb_desc=%u free_thresh=%u\n" 435 "\t tx: port=%u nb_desc=%u\n" 436 "\t -- tx push: %s\n", 437 dev->data->nb_rx_queues, 438 dev->data->nb_tx_queues, 439 rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh, 440 txq->port_id, txq->nb_tx_desc, 441 txq->tx_push_enable ? "enabled" : "disabled"); 442 443 get_rxtx_fake_queue_info(file, dev); 444 get_rxtx_queue_enable_state(file, dev); 445 } 446 447 static int 448 get_vlan_filter_cfg(FILE *file, struct hns3_hw *hw) 449 { 450 #define HNS3_FILTER_TYPE_VF 0 451 #define HNS3_FILTER_TYPE_PORT 1 452 #define HNS3_FILTER_FE_NIC_INGRESS_B BIT(0) 453 #define HNS3_FILTER_FE_NIC_EGRESS_B BIT(1) 454 struct hns3_vlan_filter_ctrl_cmd *req; 455 struct hns3_cmd_desc desc; 456 uint8_t i; 457 int ret; 458 459 static const uint32_t vlan_filter_type[] = { 460 HNS3_FILTER_TYPE_PORT, 461 HNS3_FILTER_TYPE_VF 462 }; 463 464 for (i = 0; i < RTE_DIM(vlan_filter_type); i++) { 465 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_FILTER_CTRL, 466 true); 467 req = (struct hns3_vlan_filter_ctrl_cmd *)desc.data; 468 req->vlan_type = vlan_filter_type[i]; 469 req->vf_id = HNS3_PF_FUNC_ID; 470 ret = hns3_cmd_send(hw, &desc, 1); 471 if (ret != 0) { 472 hns3_err(hw, 473 "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!", 474 ret, 1, rte_le_to_cpu_16(desc.opcode)); 475 return ret; 476 } 477 fprintf(file, 478 "\t -- %s VLAN filter configuration\n" 479 "\t nic_ingress :%s\n" 480 "\t nic_egress :%s\n", 481 req->vlan_type == HNS3_FILTER_TYPE_PORT ? 482 "Port" : "VF", 483 req->vlan_fe & HNS3_FILTER_FE_NIC_INGRESS_B ? 484 "Enable" : "Disable", 485 req->vlan_fe & HNS3_FILTER_FE_NIC_EGRESS_B ? 486 "Enable" : "Disable"); 487 } 488 489 return 0; 490 } 491 492 static int 493 get_vlan_rx_offload_cfg(FILE *file, struct hns3_hw *hw) 494 { 495 struct hns3_vport_vtag_rx_cfg_cmd *req; 496 struct hns3_cmd_desc desc; 497 uint16_t vport_id; 498 uint8_t bitmap; 499 int ret; 500 501 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_RX_CFG, true); 502 req = (struct hns3_vport_vtag_rx_cfg_cmd *)desc.data; 503 vport_id = HNS3_PF_FUNC_ID; 504 req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD; 505 bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE); 506 req->vf_bitmap[req->vf_offset] = bitmap; 507 508 /* 509 * current version VF is not supported when PF is driven by DPDK driver, 510 * just need to configure rx parameters for PF vport. 511 */ 512 ret = hns3_cmd_send(hw, &desc, 1); 513 if (ret != 0) { 514 hns3_err(hw, 515 "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!", 516 ret, 1, rte_le_to_cpu_16(desc.opcode)); 517 return ret; 518 } 519 520 fprintf(file, 521 "\t -- RX VLAN configuration\n" 522 "\t vlan1_strip_en :%s\n" 523 "\t vlan2_strip_en :%s\n" 524 "\t vlan1_vlan_prionly :%s\n" 525 "\t vlan2_vlan_prionly :%s\n" 526 "\t vlan1_strip_discard :%s\n" 527 "\t vlan2_strip_discard :%s\n", 528 hns3_get_bit(req->vport_vlan_cfg, 529 HNS3_REM_TAG1_EN_B) ? "Enable" : "Disable", 530 hns3_get_bit(req->vport_vlan_cfg, 531 HNS3_REM_TAG2_EN_B) ? "Enable" : "Disable", 532 hns3_get_bit(req->vport_vlan_cfg, 533 HNS3_SHOW_TAG1_EN_B) ? "Enable" : "Disable", 534 hns3_get_bit(req->vport_vlan_cfg, 535 HNS3_SHOW_TAG2_EN_B) ? "Enable" : "Disable", 536 hns3_get_bit(req->vport_vlan_cfg, 537 HNS3_DISCARD_TAG1_EN_B) ? "Enable" : "Disable", 538 hns3_get_bit(req->vport_vlan_cfg, 539 HNS3_DISCARD_TAG2_EN_B) ? "Enable" : "Disable"); 540 541 return 0; 542 } 543 544 static void 545 parse_tx_vlan_cfg(FILE *file, struct hns3_vport_vtag_tx_cfg_cmd *req) 546 { 547 #define VLAN_VID_MASK 0x0fff 548 #define VLAN_PRIO_SHIFT 13 549 550 fprintf(file, 551 "\t -- TX VLAN configuration\n" 552 "\t accept_tag1 :%s\n" 553 "\t accept_untag1 :%s\n" 554 "\t insert_tag1_en :%s\n" 555 "\t default_vlan_tag1 = %d, qos = %d\n" 556 "\t accept_tag2 :%s\n" 557 "\t accept_untag2 :%s\n" 558 "\t insert_tag2_en :%s\n" 559 "\t default_vlan_tag2 = %d, qos = %d\n" 560 "\t vlan_shift_mode :%s\n", 561 hns3_get_bit(req->vport_vlan_cfg, 562 HNS3_ACCEPT_TAG1_B) ? "Enable" : "Disable", 563 hns3_get_bit(req->vport_vlan_cfg, 564 HNS3_ACCEPT_UNTAG1_B) ? "Enable" : "Disable", 565 hns3_get_bit(req->vport_vlan_cfg, 566 HNS3_PORT_INS_TAG1_EN_B) ? "Enable" : "Disable", 567 req->def_vlan_tag1 & VLAN_VID_MASK, 568 req->def_vlan_tag1 >> VLAN_PRIO_SHIFT, 569 hns3_get_bit(req->vport_vlan_cfg, 570 HNS3_ACCEPT_TAG2_B) ? "Enable" : "Disable", 571 hns3_get_bit(req->vport_vlan_cfg, 572 HNS3_ACCEPT_UNTAG2_B) ? "Enable" : "Disable", 573 hns3_get_bit(req->vport_vlan_cfg, 574 HNS3_PORT_INS_TAG2_EN_B) ? "Enable" : "Disable", 575 req->def_vlan_tag2 & VLAN_VID_MASK, 576 req->def_vlan_tag2 >> VLAN_PRIO_SHIFT, 577 hns3_get_bit(req->vport_vlan_cfg, 578 HNS3_TAG_SHIFT_MODE_EN_B) ? "Enable" : 579 "Disable"); 580 } 581 582 static int 583 get_vlan_tx_offload_cfg(FILE *file, struct hns3_hw *hw) 584 { 585 struct hns3_vport_vtag_tx_cfg_cmd *req; 586 struct hns3_cmd_desc desc; 587 uint16_t vport_id; 588 uint8_t bitmap; 589 int ret; 590 591 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_TX_CFG, true); 592 req = (struct hns3_vport_vtag_tx_cfg_cmd *)desc.data; 593 vport_id = HNS3_PF_FUNC_ID; 594 req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD; 595 bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE); 596 req->vf_bitmap[req->vf_offset] = bitmap; 597 /* 598 * current version VF is not supported when PF is driven by DPDK driver, 599 * just need to configure tx parameters for PF vport. 600 */ 601 ret = hns3_cmd_send(hw, &desc, 1); 602 if (ret != 0) { 603 hns3_err(hw, 604 "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!", 605 ret, 1, rte_le_to_cpu_16(desc.opcode)); 606 return ret; 607 } 608 609 parse_tx_vlan_cfg(file, req); 610 611 return 0; 612 } 613 614 static void 615 get_port_pvid_info(FILE *file, struct hns3_hw *hw) 616 { 617 fprintf(file, "\t -- pvid status: %s\n", 618 hw->port_base_vlan_cfg.state ? "on" : "off"); 619 } 620 621 static void 622 get_vlan_config_info(FILE *file, struct hns3_hw *hw) 623 { 624 int ret; 625 626 fprintf(file, " - VLAN Config Info:\n"); 627 ret = get_vlan_filter_cfg(file, hw); 628 if (ret < 0) 629 return; 630 631 ret = get_vlan_rx_offload_cfg(file, hw); 632 if (ret < 0) 633 return; 634 635 ret = get_vlan_tx_offload_cfg(file, hw); 636 if (ret < 0) 637 return; 638 639 get_port_pvid_info(file, hw); 640 } 641 642 static void 643 get_tm_conf_shaper_info(FILE *file, struct hns3_tm_conf *conf) 644 { 645 struct hns3_shaper_profile_list *shaper_profile_list = 646 &conf->shaper_profile_list; 647 struct hns3_tm_shaper_profile *shaper_profile; 648 649 if (!conf->nb_shaper_profile) 650 return; 651 652 fprintf(file, " shaper_profile:\n"); 653 TAILQ_FOREACH(shaper_profile, shaper_profile_list, node) { 654 fprintf(file, 655 " id=%u reference_count=%u peak_rate=%" PRIu64 "Bps\n", 656 shaper_profile->shaper_profile_id, 657 shaper_profile->reference_count, 658 shaper_profile->profile.peak.rate); 659 } 660 } 661 662 static void 663 get_tm_conf_port_node_info(FILE *file, struct hns3_tm_conf *conf) 664 { 665 if (!conf->root) 666 return; 667 668 fprintf(file, 669 " port_node:\n" 670 " node_id=%u reference_count=%u shaper_profile_id=%d\n", 671 conf->root->id, conf->root->reference_count, 672 conf->root->shaper_profile ? 673 (int)conf->root->shaper_profile->shaper_profile_id : -1); 674 } 675 676 static void 677 get_tm_conf_tc_node_info(FILE *file, struct hns3_tm_conf *conf) 678 { 679 struct hns3_tm_node_list *tc_list = &conf->tc_list; 680 struct hns3_tm_node *tc_node[HNS3_MAX_TC_NUM]; 681 struct hns3_tm_node *tm_node; 682 uint32_t tidx; 683 684 if (!conf->nb_tc_node) 685 return; 686 687 fprintf(file, " tc_node:\n"); 688 memset(tc_node, 0, sizeof(tc_node)); 689 TAILQ_FOREACH(tm_node, tc_list, node) { 690 tidx = hns3_tm_calc_node_tc_no(conf, tm_node->id); 691 if (tidx < HNS3_MAX_TC_NUM) 692 tc_node[tidx] = tm_node; 693 } 694 695 for (tidx = 0; tidx < HNS3_MAX_TC_NUM; tidx++) { 696 tm_node = tc_node[tidx]; 697 if (tm_node == NULL) 698 continue; 699 fprintf(file, 700 " id=%u TC%u reference_count=%u parent_id=%d " 701 "shaper_profile_id=%d\n", 702 tm_node->id, hns3_tm_calc_node_tc_no(conf, tm_node->id), 703 tm_node->reference_count, 704 tm_node->parent ? (int)tm_node->parent->id : -1, 705 tm_node->shaper_profile ? 706 (int)tm_node->shaper_profile->shaper_profile_id : -1); 707 } 708 } 709 710 static void 711 get_tm_conf_queue_format_info(FILE *file, struct hns3_tm_node **queue_node, 712 uint32_t *queue_node_tc, uint32_t nb_tx_queues) 713 { 714 #define PERLINE_QUEUES 32 715 #define PERLINE_STRIDE 8 716 #define LINE_BUF_SIZE 1024 717 uint32_t i, j, line_num, start_queue, end_queue; 718 char tmpbuf[LINE_BUF_SIZE] = {0}; 719 720 line_num = (nb_tx_queues + PERLINE_QUEUES - 1) / PERLINE_QUEUES; 721 for (i = 0; i < line_num; i++) { 722 start_queue = i * PERLINE_QUEUES; 723 end_queue = (i + 1) * PERLINE_QUEUES - 1; 724 if (end_queue > nb_tx_queues - 1) 725 end_queue = nb_tx_queues - 1; 726 fprintf(file, " %04u - %04u | ", start_queue, end_queue); 727 for (j = start_queue; j < nb_tx_queues; j++) { 728 if (j >= end_queue + 1) 729 break; 730 if (j > start_queue && j % PERLINE_STRIDE == 0) 731 fprintf(file, ":"); 732 fprintf(file, "%u", 733 queue_node[j] ? queue_node_tc[j] : 734 HNS3_MAX_TC_NUM); 735 } 736 fprintf(file, "%s\n", tmpbuf); 737 } 738 } 739 740 static void 741 get_tm_conf_queue_node_info(FILE *file, struct hns3_tm_conf *conf, 742 uint32_t nb_tx_queues) 743 { 744 struct hns3_tm_node_list *queue_list = &conf->queue_list; 745 uint32_t nb_queue_node = conf->nb_leaf_nodes_max + 1; 746 struct hns3_tm_node *queue_node[nb_queue_node]; 747 uint32_t queue_node_tc[nb_queue_node]; 748 struct hns3_tm_node *tm_node; 749 750 if (!conf->nb_queue_node) 751 return; 752 753 fprintf(file, 754 " queue_node:\n" 755 " tx queue id | mapped tc (8 mean node not exist)\n"); 756 757 memset(queue_node, 0, sizeof(queue_node)); 758 memset(queue_node_tc, 0, sizeof(queue_node_tc)); 759 nb_tx_queues = RTE_MIN(nb_tx_queues, nb_queue_node); 760 TAILQ_FOREACH(tm_node, queue_list, node) { 761 if (tm_node->id >= nb_queue_node) 762 continue; 763 queue_node[tm_node->id] = tm_node; 764 queue_node_tc[tm_node->id] = tm_node->parent ? 765 hns3_tm_calc_node_tc_no(conf, tm_node->parent->id) : 0; 766 nb_tx_queues = RTE_MAX(nb_tx_queues, tm_node->id + 1); 767 } 768 769 get_tm_conf_queue_format_info(file, queue_node, queue_node_tc, 770 nb_tx_queues); 771 } 772 773 static void 774 get_tm_conf_info(FILE *file, struct rte_eth_dev *dev) 775 { 776 struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); 777 struct hns3_tm_conf *conf = &pf->tm_conf; 778 779 fprintf(file, " - TM config info:\n"); 780 fprintf(file, 781 "\t -- nb_leaf_nodes_max=%u nb_nodes_max=%u\n" 782 "\t -- nb_shaper_profile=%u nb_tc_node=%u nb_queue_node=%u\n" 783 "\t -- committed=%u\n", 784 conf->nb_leaf_nodes_max, conf->nb_nodes_max, 785 conf->nb_shaper_profile, conf->nb_tc_node, conf->nb_queue_node, 786 conf->committed); 787 788 get_tm_conf_shaper_info(file, conf); 789 get_tm_conf_port_node_info(file, conf); 790 get_tm_conf_tc_node_info(file, conf); 791 get_tm_conf_queue_node_info(file, conf, dev->data->nb_tx_queues); 792 } 793 794 static void 795 hns3_fc_mode_to_rxtx_pause(enum hns3_fc_mode fc_mode, bool *rx_pause, 796 bool *tx_pause) 797 { 798 switch (fc_mode) { 799 case HNS3_FC_NONE: 800 *tx_pause = false; 801 *rx_pause = false; 802 break; 803 case HNS3_FC_RX_PAUSE: 804 *rx_pause = true; 805 *tx_pause = false; 806 break; 807 case HNS3_FC_TX_PAUSE: 808 *rx_pause = false; 809 *tx_pause = true; 810 break; 811 case HNS3_FC_FULL: 812 *rx_pause = true; 813 *tx_pause = true; 814 break; 815 default: 816 *rx_pause = false; 817 *tx_pause = false; 818 break; 819 } 820 } 821 822 static bool 823 is_link_fc_mode(struct hns3_adapter *hns) 824 { 825 struct hns3_hw *hw = &hns->hw; 826 struct hns3_pf *pf = &hns->pf; 827 828 if (hw->current_fc_status == HNS3_FC_STATUS_PFC) 829 return false; 830 831 if (hw->num_tc > 1 && !pf->support_multi_tc_pause) 832 return false; 833 834 return true; 835 } 836 837 static void 838 get_link_fc_info(FILE *file, struct rte_eth_dev *dev) 839 { 840 struct hns3_adapter *hns = dev->data->dev_private; 841 struct hns3_hw *hw = &hns->hw; 842 struct rte_eth_fc_conf fc_conf; 843 bool rx_pause1; 844 bool tx_pause1; 845 bool rx_pause2; 846 bool tx_pause2; 847 int ret; 848 849 if (!is_link_fc_mode(hns)) 850 return; 851 852 ret = hns3_flow_ctrl_get(dev, &fc_conf); 853 if (ret) { 854 fprintf(file, "get device flow control info fail!\n"); 855 return; 856 } 857 858 hns3_fc_mode_to_rxtx_pause(hw->requested_fc_mode, 859 &rx_pause1, &tx_pause1); 860 hns3_fc_mode_to_rxtx_pause((enum hns3_fc_mode)fc_conf.mode, 861 &rx_pause2, &tx_pause2); 862 863 fprintf(file, 864 "\t -- link_fc_info:\n" 865 "\t Requested fc:\n" 866 "\t Rx: %s\n" 867 "\t Tx: %s\n" 868 "\t Current fc:\n" 869 "\t Rx: %s\n" 870 "\t Tx: %s\n" 871 "\t Autonegotiate: %s\n" 872 "\t Pause time: 0x%x\n", 873 rx_pause1 ? "On" : "Off", tx_pause1 ? "On" : "Off", 874 rx_pause2 ? "On" : "Off", tx_pause2 ? "On" : "Off", 875 fc_conf.autoneg == RTE_ETH_LINK_AUTONEG ? "On" : "Off", 876 fc_conf.pause_time); 877 } 878 879 static void 880 get_flow_ctrl_info(FILE *file, struct rte_eth_dev *dev) 881 { 882 struct hns3_adapter *hns = dev->data->dev_private; 883 struct hns3_hw *hw = &hns->hw; 884 885 fprintf(file, " - Flow Ctrl Info:\n"); 886 fprintf(file, 887 "\t -- fc_common_info:\n" 888 "\t current_fc_status=%u\n" 889 "\t requested_fc_mode=%u\n", 890 hw->current_fc_status, 891 hw->requested_fc_mode); 892 893 get_link_fc_info(file, dev); 894 } 895 896 int 897 hns3_eth_dev_priv_dump(struct rte_eth_dev *dev, FILE *file) 898 { 899 struct hns3_adapter *hns = dev->data->dev_private; 900 struct hns3_hw *hw = &hns->hw; 901 902 get_device_basic_info(file, dev); 903 get_dev_feature_capability(file, hw); 904 905 /* VF only supports dumping basic info and feaure capability */ 906 if (hns->is_vf) 907 return 0; 908 909 get_dev_mac_info(file, hns); 910 get_rxtx_queue_info(file, dev); 911 get_vlan_config_info(file, hw); 912 get_fdir_basic_info(file, &hns->pf); 913 get_tm_conf_info(file, dev); 914 get_flow_ctrl_info(file, dev); 915 916 return 0; 917 } 918