get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/108524/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 108524,
    "url": "http://patches.dpdk.org/api/patches/108524/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220304012257.39247-3-humin29@huawei.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20220304012257.39247-3-humin29@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220304012257.39247-3-humin29@huawei.com",
    "date": "2022-03-04T01:22:54",
    "name": "dpdk: show dev basic info",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "archived": true,
    "hash": "a2fe478fedb35b1b7ade2210cb41be27fe1c9223",
    "submitter": {
        "id": 1944,
        "url": "http://patches.dpdk.org/api/people/1944/?format=api",
        "name": "humin (Q)",
        "email": "humin29@huawei.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220304012257.39247-3-humin29@huawei.com/mbox/",
    "series": [
        {
            "id": 22010,
            "url": "http://patches.dpdk.org/api/series/22010/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=22010",
            "date": "2022-03-04T01:22:54",
            "name": "dpdk: show dev basic info",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/22010/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/108524/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/108524/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 4638EA04A2;\n\tFri,  4 Mar 2022 02:23:34 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 4FCBF4279A;\n\tFri,  4 Mar 2022 02:23:24 +0100 (CET)",
            "from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187])\n by mails.dpdk.org (Postfix) with ESMTP id E307D42798\n for <dev@dpdk.org>; Fri,  4 Mar 2022 02:23:21 +0100 (CET)",
            "from dggeme756-chm.china.huawei.com (unknown [172.30.72.55])\n by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4K8qp227PczdZlG;\n Fri,  4 Mar 2022 09:22:02 +0800 (CST)",
            "from localhost.localdomain (10.69.192.56) by\n dggeme756-chm.china.huawei.com (10.3.19.102) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id\n 15.1.2308.21; Fri, 4 Mar 2022 09:23:20 +0800"
        ],
        "From": "\"Min Hu (Connor)\" <humin29@huawei.com>",
        "To": "<dev@dpdk.org>",
        "CC": "\"Min Hu (Connor)\" <humin29@huawei.com>, Maryam Tahhan\n <maryam.tahhan@intel.com>, Reshma Pattan <reshma.pattan@intel.com>, Yisen\n Zhuang <yisen.zhuang@huawei.com>, Lijun Ou <oulijun@huawei.com>, Thomas\n Monjalon <thomas@monjalon.net>, Ferruh Yigit <ferruh.yigit@intel.com>, Andrew\n Rybchenko <andrew.rybchenko@oktetlabs.ru>",
        "Subject": "[PATCH] dpdk: show dev basic info",
        "Date": "Fri, 4 Mar 2022 09:22:54 +0800",
        "Message-ID": "<20220304012257.39247-3-humin29@huawei.com>",
        "X-Mailer": "git-send-email 2.33.0",
        "In-Reply-To": "<20220304012257.39247-1-humin29@huawei.com>",
        "References": "<20220228032617.46618-1-humin29@huawei.com>\n <20220304012257.39247-1-humin29@huawei.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.69.192.56]",
        "X-ClientProxiedBy": "dggems706-chm.china.huawei.com (10.3.19.183) To\n dggeme756-chm.china.huawei.com (10.3.19.102)",
        "X-CFilter-Loop": "Reflected",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "version 1\n\nSigned-off-by: Min Hu (Connor) <humin29@huawei.com>\n---\n app/proc-info/main.c                | 254 ++++++++\n drivers/net/hns3/hns3_ethdev.c      |   3 +-\n drivers/net/hns3/hns3_ethdev.h      |   3 +\n drivers/net/hns3/hns3_ethdev_dump.c | 917 ++++++++++++++++++++++++++++\n drivers/net/hns3/hns3_ethdev_vf.c   |   1 +\n drivers/net/hns3/meson.build        |   1 +\n lib/ethdev/ethdev_driver.h          |  17 +\n lib/ethdev/rte_ethdev.c             |  15 +\n lib/ethdev/rte_ethdev.h             |  16 +\n 9 files changed, 1226 insertions(+), 1 deletion(-)\n create mode 100644 drivers/net/hns3/hns3_ethdev_dump.c",
    "diff": "diff --git a/app/proc-info/main.c b/app/proc-info/main.c\nindex a4271047e6..8644edfa7d 100644\n--- a/app/proc-info/main.c\n+++ b/app/proc-info/main.c\n@@ -47,6 +47,12 @@\n #define STATS_BDR_STR(w, s) printf(\"%.*s%s%.*s\\n\", w, \\\n \tSTATS_BDR_FMT, s, w, STATS_BDR_FMT)\n \n+/** Information for a given RSS type. */\n+struct rss_type_info {\n+\tconst char *str; /**< Type name. */\n+\tuint64_t rss_type; /**< Type value. */\n+};\n+\n /**< mask of enabled ports */\n static unsigned long enabled_port_mask;\n /**< Enable stats. */\n@@ -81,6 +87,8 @@ static char bdr_str[MAX_STRING_LEN];\n \n /**< Enable show port. */\n static uint32_t enable_shw_port;\n+/**< Enable show port. */\n+static uint32_t enable_shw_port_priv;\n /**< Enable show tm. */\n static uint32_t enable_shw_tm;\n /**< Enable show crypto. */\n@@ -98,6 +106,84 @@ static char *mempool_iter_name;\n static uint32_t enable_dump_regs;\n static char *dump_regs_file_prefix;\n \n+static const struct rss_type_info rss_type_table[] = {\n+\t{ \"all\", RTE_ETH_RSS_ETH | RTE_ETH_RSS_VLAN | RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP |\n+\t\tRTE_ETH_RSS_UDP | RTE_ETH_RSS_SCTP | RTE_ETH_RSS_L2_PAYLOAD |\n+\t\tRTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_ESP | RTE_ETH_RSS_AH | RTE_ETH_RSS_PFCP |\n+\t\tRTE_ETH_RSS_GTPU | RTE_ETH_RSS_ECPRI | RTE_ETH_RSS_MPLS},\n+\t{ \"none\", 0 },\n+\t{ \"eth\", RTE_ETH_RSS_ETH },\n+\t{ \"l2-src-only\", RTE_ETH_RSS_L2_SRC_ONLY },\n+\t{ \"l2-dst-only\", RTE_ETH_RSS_L2_DST_ONLY },\n+\t{ \"vlan\", RTE_ETH_RSS_VLAN },\n+\t{ \"s-vlan\", RTE_ETH_RSS_S_VLAN },\n+\t{ \"c-vlan\", RTE_ETH_RSS_C_VLAN },\n+\t{ \"ipv4\", RTE_ETH_RSS_IPV4 },\n+\t{ \"ipv4-frag\", RTE_ETH_RSS_FRAG_IPV4 },\n+\t{ \"ipv4-tcp\", RTE_ETH_RSS_NONFRAG_IPV4_TCP },\n+\t{ \"ipv4-udp\", RTE_ETH_RSS_NONFRAG_IPV4_UDP },\n+\t{ \"ipv4-sctp\", RTE_ETH_RSS_NONFRAG_IPV4_SCTP },\n+\t{ \"ipv4-other\", RTE_ETH_RSS_NONFRAG_IPV4_OTHER },\n+\t{ \"ipv6\", RTE_ETH_RSS_IPV6 },\n+\t{ \"ipv6-frag\", RTE_ETH_RSS_FRAG_IPV6 },\n+\t{ \"ipv6-tcp\", RTE_ETH_RSS_NONFRAG_IPV6_TCP },\n+\t{ \"ipv6-udp\", RTE_ETH_RSS_NONFRAG_IPV6_UDP },\n+\t{ \"ipv6-sctp\", RTE_ETH_RSS_NONFRAG_IPV6_SCTP },\n+\t{ \"ipv6-other\", RTE_ETH_RSS_NONFRAG_IPV6_OTHER },\n+\t{ \"l2-payload\", RTE_ETH_RSS_L2_PAYLOAD },\n+\t{ \"ipv6-ex\", RTE_ETH_RSS_IPV6_EX },\n+\t{ \"ipv6-tcp-ex\", RTE_ETH_RSS_IPV6_TCP_EX },\n+\t{ \"ipv6-udp-ex\", RTE_ETH_RSS_IPV6_UDP_EX },\n+\t{ \"port\", RTE_ETH_RSS_PORT },\n+\t{ \"vxlan\", RTE_ETH_RSS_VXLAN },\n+\t{ \"geneve\", RTE_ETH_RSS_GENEVE },\n+\t{ \"nvgre\", RTE_ETH_RSS_NVGRE },\n+\t{ \"ip\", RTE_ETH_RSS_IP },\n+\t{ \"udp\", RTE_ETH_RSS_UDP },\n+\t{ \"tcp\", RTE_ETH_RSS_TCP },\n+\t{ \"sctp\", RTE_ETH_RSS_SCTP },\n+\t{ \"tunnel\", RTE_ETH_RSS_TUNNEL },\n+\t{ \"l3-pre32\", RTE_ETH_RSS_L3_PRE32 },\n+\t{ \"l3-pre40\", RTE_ETH_RSS_L3_PRE40 },\n+\t{ \"l3-pre48\", RTE_ETH_RSS_L3_PRE48 },\n+\t{ \"l3-pre56\", RTE_ETH_RSS_L3_PRE56 },\n+\t{ \"l3-pre64\", RTE_ETH_RSS_L3_PRE64 },\n+\t{ \"l3-pre96\", RTE_ETH_RSS_L3_PRE96 },\n+\t{ \"l3-src-only\", RTE_ETH_RSS_L3_SRC_ONLY },\n+\t{ \"l3-dst-only\", RTE_ETH_RSS_L3_DST_ONLY },\n+\t{ \"l4-src-only\", RTE_ETH_RSS_L4_SRC_ONLY },\n+\t{ \"l4-dst-only\", RTE_ETH_RSS_L4_DST_ONLY },\n+\t{ \"esp\", RTE_ETH_RSS_ESP },\n+\t{ \"ah\", RTE_ETH_RSS_AH },\n+\t{ \"l2tpv3\", RTE_ETH_RSS_L2TPV3 },\n+\t{ \"pfcp\", RTE_ETH_RSS_PFCP },\n+\t{ \"pppoe\", RTE_ETH_RSS_PPPOE },\n+\t{ \"gtpu\", RTE_ETH_RSS_GTPU },\n+\t{ \"ecpri\", RTE_ETH_RSS_ECPRI },\n+\t{ \"mpls\", RTE_ETH_RSS_MPLS },\n+\t{ \"ipv4-chksum\", RTE_ETH_RSS_IPV4_CHKSUM },\n+\t{ \"l4-chksum\", RTE_ETH_RSS_L4_CHKSUM },\n+\t{ NULL, 0 },\n+};\n+\n+/** Information for a ethernet speed info. */\n+static const struct {\n+\tuint32_t speed;\n+\tconst char *str;\n+}eth_speed_table[] = {\n+\t{ ETH_LINK_SPEED_10M_HD, \"10Mbps-HD\" },\n+\t{ ETH_LINK_SPEED_10M, \"10Mbps\" },\n+\t{ ETH_LINK_SPEED_100M_HD, \"100Mbps-HD\" },\n+\t{ ETH_LINK_SPEED_100M, \"100Mbps\" },\n+\t{ ETH_LINK_SPEED_1G, \"1Gbps\" },\n+\t{ ETH_LINK_SPEED_10G, \"10Gbps\" },\n+\t{ ETH_LINK_SPEED_25G, \"25Gbps\" },\n+\t{ ETH_LINK_SPEED_40G, \"40Gbps\" },\n+\t{ ETH_LINK_SPEED_50G, \"50Gbps\" },\n+\t{ ETH_LINK_SPEED_100G, \"100Gbps\" },\n+\t{ ETH_LINK_SPEED_200G, \"200Gbps\" },\n+};\n+\n /**< display usage */\n static void\n proc_info_usage(const char *prgname)\n@@ -118,6 +204,7 @@ proc_info_usage(const char *prgname)\n \t\t\"  --collectd-format: to print statistics to STDOUT in expected by collectd format\\n\"\n \t\t\"  --host-id STRING: host id used to identify the system process is running on\\n\"\n \t\t\"  --show-port: to display ports information\\n\"\n+\t\t\"  --show-port-private: to display ports private information\\n\"\n \t\t\"  --show-tm: to display traffic manager information for ports\\n\"\n \t\t\"  --show-crypto: to display crypto information\\n\"\n \t\t\"  --show-ring[=name]: to display ring information\\n\"\n@@ -225,6 +312,7 @@ proc_info_parse_args(int argc, char **argv)\n \t\t{\"xstats-ids\", 1, NULL, 1},\n \t\t{\"host-id\", 0, NULL, 0},\n \t\t{\"show-port\", 0, NULL, 0},\n+\t\t{\"show-port-private\", 0, NULL, 0},\n \t\t{\"show-tm\", 0, NULL, 0},\n \t\t{\"show-crypto\", 0, NULL, 0},\n \t\t{\"show-ring\", optional_argument, NULL, 0},\n@@ -275,6 +363,9 @@ proc_info_parse_args(int argc, char **argv)\n \t\t\telse if (!strncmp(long_option[option_index].name,\n \t\t\t\t\t\"show-port\", MAX_LONG_OPT_SZ))\n \t\t\t\tenable_shw_port = 1;\n+\t\t\telse if (!strncmp(long_option[option_index].name,\n+\t\t\t\t\t\"show-port-private\", MAX_LONG_OPT_SZ))\n+\t\t\t\tenable_shw_port_priv = 1;\n \t\t\telse if (!strncmp(long_option[option_index].name,\n \t\t\t\t\t\"show-tm\", MAX_LONG_OPT_SZ))\n \t\t\t\tenable_shw_tm = 1;\n@@ -697,6 +788,119 @@ show_offloads(uint64_t offloads,\n \t}\n }\n \n+static void\n+show_dev_info(struct rte_eth_dev_info *dev_info)\n+{\n+\tprintf(\"  - device info\\n\");\n+\tprintf( \"\\t  -- maximum number of MAC addresses: %u\\n\"\n+\t\t\"\\t  -- maximum number of MAC addresses of hash filtering: %u\\n\"\n+\t\t\"\\t  -- hash key size in bytes: %u\\n\"\n+\t\t\"\\t  -- redirection table size: %u\\n\"\n+\t\t\"\\t  -- RSS offload flow type: 0x%\"PRIx64\"\\n\"\n+\t\t\"\\t  -- minimum size of RX buffer: %u\\n\"\n+\t\t\"\\t  -- maximum configurable length of RX packet: %u\\n\"\n+\t\t\"\\t  -- maximum number of VFs: %u\\n\"\n+\t\t\"\\t  -- maximum number of VMDq pools: %u\\n\"\n+\t\t\"\\t  -- current number of RX queues: %u\\n\"\n+\t\t\"\\t  -- max possible RX queues: %u\\n\"\n+\t\t\"\\t  -- current number of TX queues: %u\\n\"\n+\t\t\"\\t  -- max possible TX queues: %u\\n\"\n+\t\t\"\\t  -- max segment number per packet of TX: %u\\n\"\n+\t\t\"\\t  -- max segment number per MTU/TSO of TX: %u\\n\",\n+\t\tdev_info->max_mac_addrs, dev_info->max_hash_mac_addrs,\n+\t\tdev_info->hash_key_size, dev_info->reta_size,\n+\t\tdev_info->flow_type_rss_offloads,\n+\t\tdev_info->min_rx_bufsize, dev_info->max_rx_pktlen,\n+\t\tdev_info->max_vfs, dev_info->max_vmdq_pools,\n+\t\tdev_info->nb_rx_queues, dev_info->max_rx_queues,\n+\t\tdev_info->nb_tx_queues, dev_info->max_tx_queues,\n+\t\tdev_info->tx_desc_lim.nb_seg_max,\n+\t\tdev_info->tx_desc_lim.nb_mtu_seg_max);\n+}\n+\n+static void\n+show_port_rss_info(uint16_t port_id, struct rte_eth_dev_info *dev_info)\n+{\n+#define RSS_HASH_KEY_LENGTH 64\n+\tstruct rte_eth_rss_conf rss_conf = {0};\n+\tuint8_t rss_key[RSS_HASH_KEY_LENGTH];\n+\tuint8_t hash_key_size;\n+\tuint64_t rss_hf;\n+\tuint8_t i;\n+\tint ret;\n+\n+\tif (dev_info->hash_key_size > 0 &&\n+\t\t\tdev_info->hash_key_size <= sizeof(rss_key))\n+\t\thash_key_size = dev_info->hash_key_size;\n+\telse\n+\t\treturn;\n+\n+\trss_conf.rss_key = rss_key;\n+\trss_conf.rss_key_len = hash_key_size;\n+\tret = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);\n+\tif (ret != 0)\n+\t\treturn;\n+\n+\tprintf(\"  - RSS info\\n\");\n+\trss_hf = rss_conf.rss_hf;\n+\tif (rss_hf == 0) {\n+\t\tprintf( \"\\t  -- RSS disabled\");\n+\t\treturn;\n+\t}\n+\tret = printf(\"\\t  -- RSS functions: \");\n+\n+\tfor (i = 0; rss_type_table[i].str; i++)\n+\t\tif (rss_hf & rss_type_table[i].rss_type)\n+\t\t\tprintf(\"%s \", rss_type_table[i].str);\n+\tprintf(\"\\n\");\n+\tprintf(\"\\t  -- RSS key: \");\n+\n+\tfor (i = 0; i < rss_conf.rss_key_len; i++)\n+\t\tprintf(\"%02X\", rss_conf.rss_key[i]);\n+\tprintf(\"\\n\");\n+}\n+\n+static void\n+show_dev_speed_capability(uint32_t speed_capa)\n+{\n+\tint size = sizeof(eth_speed_table) / sizeof(eth_speed_table[0]);\n+\tint i;\n+\n+\tprintf(\"  - Device Speed Capability: \");\n+\tfor (i = 0; i < size; i++)\n+\t\tif (speed_capa & eth_speed_table[i].speed)\n+\t\t\tprintf(\"%s \", eth_speed_table[i].str);\n+\n+\tif (!(speed_capa & ETH_LINK_SPEED_FIXED)) {\n+\t\tprintf(\"auto\");\n+\t}\n+\n+\tprintf(\"\\n\");\n+}\n+\n+static void\n+show_dev_rxtx_burst_mode(uint16_t port_id)\n+{\n+\tstruct rte_eth_burst_mode rx_mode;\n+\tstruct rte_eth_burst_mode tx_mode;\n+\n+\tmemset(&rx_mode, 0, sizeof(rx_mode));\n+\tmemset(&tx_mode, 0, sizeof(tx_mode));\n+\n+\tif (rte_eth_rx_burst_mode_get(port_id, 0, &rx_mode) == 0 &&\n+\t\trte_eth_tx_burst_mode_get(port_id, 0, &tx_mode) == 0) {\n+\t\tprintf(\"  - Burst mode:\\n\");\n+\t\tprintf( \"\\t  -- Rx burst mode: %s%s\\n\"\n+\t\t\t\"\\t  -- Tx burst mode: %s%s\\n\",\n+\t\t\trx_mode.info,\n+\t\t\trx_mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?\n+\t\t\t\t\" (per queue)\" : \"\",\n+\t\t\ttx_mode.info,\n+\t\t\ttx_mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?\n+\t\t\t\t\" (per queue)\" : \"\");\n+\t}\n+}\n+\n static void\n show_port(void)\n {\n@@ -714,6 +918,7 @@ show_port(void)\n \t\tstruct rte_eth_fc_conf fc_conf;\n \t\tstruct rte_ether_addr mac;\n \t\tstruct rte_eth_dev_owner owner;\n+\t\tint vlan_offload;\n \n \t\t/* Skip if port is not in mask */\n \t\tif ((enabled_port_mask & (1ul << i)) == 0)\n@@ -792,6 +997,25 @@ show_port(void)\n \t\tif (ret == 0)\n \t\t\tprintf(\"\\t  -- mtu (%d)\\n\", mtu);\n \n+\t\tif (dev_info.rx_offload_capa != 0) {\n+\t\t\tprintf(\"  - device capability Rx\");\n+\t\t\tshow_offloads(dev_info.rx_offload_capa,\n+\t\t\t\t      rte_eth_dev_rx_offload_name);\n+\t\t\tprintf(\"\\n\");\n+\t\t}\n+\n+\t\tif (dev_info.tx_offload_capa != 0) {\n+\t\t\tprintf(\"  - device capability Tx\");\n+\t\t\tshow_offloads(dev_info.tx_offload_capa,\n+\t\t\t\t      rte_eth_dev_tx_offload_name);\n+\t\t\tprintf(\"\\n\");\n+\t\t}\n+\n+\t\tshow_dev_speed_capability(dev_info.speed_capa);\n+\t\tshow_dev_info(&dev_info);\n+\t\tshow_port_rss_info(i, &dev_info);\n+\t\tshow_dev_rxtx_burst_mode(i);\n+\n \t\tfor (j = 0; j < dev_info.nb_rx_queues; j++) {\n \t\t\tstruct rte_eth_rxq_info queue_info;\n \t\t\tint count;\n@@ -870,12 +1094,38 @@ show_port(void)\n \t\t\t}\n \t\t}\n \n+\t\tvlan_offload = rte_eth_dev_get_vlan_offload(i);\n+\t\tprintf(\"  - VLAN offload: 0x%x\\n\", vlan_offload);\n+\n #ifdef RTE_LIB_SECURITY\n \t\tshow_security_context(i, true);\n #endif\n \t}\n }\n \n+static void\n+show_port_private_info(void)\n+{\n+\tint i;\n+\n+\tsnprintf(bdr_str, MAX_STRING_LEN, \" show - Port PMD Private \");\n+\tSTATS_BDR_STR(10, bdr_str);\n+\n+\tfor (i = 0; i < RTE_MAX_ETHPORTS; i++) {\n+\t\t/* Skip if port is not in mask */\n+\t\tif ((enabled_port_mask & (1ul << i)) == 0)\n+\t\t\tcontinue;\n+\n+\t\t/* Skip if port is unused */\n+\t\tif (!rte_eth_dev_is_valid_port(i))\n+\t\t\tcontinue;\n+\n+\t\tsnprintf(bdr_str, MAX_STRING_LEN, \" Port %u \", i);\n+\t\tSTATS_BDR_STR(5, bdr_str);\n+\t\trte_eth_dev_priv_dump(stdout, i);\n+\t}\n+}\n+\n static void\n display_nodecap_info(int is_leaf, struct rte_tm_node_capabilities *cap)\n {\n@@ -1534,6 +1784,8 @@ main(int argc, char **argv)\n \t/* show information for PMD */\n \tif (enable_shw_port)\n \t\tshow_port();\n+\tif (enable_shw_port_priv)\n+\t\tshow_port_private_info();\n \tif (enable_shw_tm)\n \t\tshow_tm();\n \tif (enable_shw_crypto)\n@@ -1546,6 +1798,8 @@ main(int argc, char **argv)\n \t\titer_mempool(mempool_iter_name);\n \tif (enable_dump_regs)\n \t\tdump_regs(dump_regs_file_prefix);\n+\tif (enable_dump_regs)\n+\t\tdump_regs(dump_regs_file_prefix);\n \n \tRTE_ETH_FOREACH_DEV(i)\n \t\trte_eth_dev_close(i);\ndiff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c\nindex 0f5e9efb3c..a6d617a400 100644\n--- a/drivers/net/hns3/hns3_ethdev.c\n+++ b/drivers/net/hns3/hns3_ethdev.c\n@@ -5514,7 +5514,7 @@ hns3_get_current_fc_mode(struct rte_eth_dev *dev)\n \treturn hns3_get_autoneg_fc_mode(hw);\n }\n \n-static int\n+int\n hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)\n {\n \tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n@@ -6732,6 +6732,7 @@ static const struct eth_dev_ops hns3_eth_dev_ops = {\n \t.timesync_adjust_time       = hns3_timesync_adjust_time,\n \t.timesync_read_time         = hns3_timesync_read_time,\n \t.timesync_write_time        = hns3_timesync_write_time,\n+\t.eth_dev_priv_dump          = hns3_eth_dev_priv_dump,\n };\n \n static const struct hns3_reset_ops hns3_reset_ops = {\ndiff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h\nindex 678ee6cf97..24b39f1f1f 100644\n--- a/drivers/net/hns3/hns3_ethdev.h\n+++ b/drivers/net/hns3/hns3_ethdev.h\n@@ -1068,6 +1068,8 @@ hns3_test_and_clear_bit(unsigned int nr, volatile uint64_t *addr)\n \treturn __atomic_fetch_and(addr, ~mask, __ATOMIC_RELAXED) & mask;\n }\n \n+int\n+hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf);\n uint32_t hns3_get_speed_capa(struct hns3_hw *hw);\n \n int hns3_buffer_alloc(struct hns3_hw *hw);\n@@ -1093,6 +1095,7 @@ int hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts);\n int hns3_timesync_write_time(struct rte_eth_dev *dev,\n \t\t\tconst struct timespec *ts);\n int hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);\n+int hns3_eth_dev_priv_dump(FILE *file, struct rte_eth_dev *dev);\n \n static inline bool\n is_reset_pending(struct hns3_adapter *hns)\ndiff --git a/drivers/net/hns3/hns3_ethdev_dump.c b/drivers/net/hns3/hns3_ethdev_dump.c\nnew file mode 100644\nindex 0000000000..0d2b96f900\n--- /dev/null\n+++ b/drivers/net/hns3/hns3_ethdev_dump.c\n@@ -0,0 +1,917 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2021 HiSilicon Limited\n+ */\n+\n+#include <rte_kvargs.h>\n+#include <rte_bus_pci.h>\n+#include <ethdev_pci.h>\n+#include <rte_pci.h>\n+\n+#include \"hns3_common.h\"\n+#include \"hns3_logs.h\"\n+#include \"hns3_regs.h\"\n+#include \"hns3_rxtx.h\"\n+\n+static const char *\n+get_adapter_state_name(uint32_t state)\n+{\n+\tstatic const char *state_name[] = {\n+\t\t\"UNINITIALIZED\",\n+\t\t\"INITIALIZED\",\n+\t\t\"CONFIGURING\",\n+\t\t\"CONFIGURED\",\n+\t\t\"STARTING\",\n+\t\t\"STARTED\",\n+\t\t\"STOPPING\",\n+\t\t\"CLOSING\",\n+\t\t\"CLOSED\",\n+\t\t\"REMOVED\",\n+\t\t\"NSTATES\"\n+\t};\n+\n+\tif (state < RTE_DIM(state_name))\n+\t\treturn state_name[state];\n+\telse\n+\t\treturn \"unknown\";\n+}\n+\n+static const char *\n+get_io_func_hint_name(uint32_t hint)\n+{\n+\tswitch (hint) {\n+\tcase HNS3_IO_FUNC_HINT_NONE:\n+\t\treturn \"none\";\n+\tcase HNS3_IO_FUNC_HINT_VEC:\n+\t\treturn \"vec\";\n+\tcase HNS3_IO_FUNC_HINT_SVE:\n+\t\treturn \"sve\";\n+\tcase HNS3_IO_FUNC_HINT_SIMPLE:\n+\t\treturn \"simple\";\n+\tcase HNS3_IO_FUNC_HINT_COMMON:\n+\t\treturn \"common\";\n+\tdefault:\n+\t\treturn \"unknown\";\n+\t}\n+}\n+\n+static void\n+get_dev_mac_info(FILE *file, struct hns3_adapter *hns)\n+{\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tstruct hns3_pf *pf = &hns->pf;\n+\n+\tfprintf(file, \"  - MAC Info:\\n\");\n+\tfprintf(file,\n+\t\t\"\\t  -- query_type=%u\\n\"\n+\t\t\"\\t  -- supported_speed=0x%x\\n\"\n+\t\t\"\\t  -- advertising=0x%x\\n\"\n+\t\t\"\\t  -- lp_advertising=0x%x\\n\"\n+\t\t\"\\t  -- support_autoneg=%s\\n\"\n+\t\t\"\\t  -- support_fc_autoneg=%s\\n\",\n+\t\thw->mac.query_type,\n+\t\thw->mac.supported_speed,\n+\t\thw->mac.advertising,\n+\t\thw->mac.lp_advertising,\n+\t\thw->mac.support_autoneg != 0 ? \"Yes\" : \"No\",\n+\t\tpf->support_fc_autoneg ? \"Yes\" : \"No\");\n+}\n+\n+static void\n+get_dev_feature_capability(FILE *file, struct hns3_hw *hw)\n+{\n+\tconst char * const caps_name[] = {\n+\t\t\"DCB\",\n+\t\t\"COPPER\",\n+\t\t\"FD QUEUE REGION\",\n+\t\t\"PTP\",\n+\t\t\"TX PUSH\",\n+\t\t\"INDEP TXRX\",\n+\t\t\"STASH\",\n+\t\t\"SIMPLE BD\",\n+\t\t\"RXD Advanced Layout\",\n+\t\t\"OUTER UDP CKSUM\",\n+\t\t\"RAS IMP\",\n+\t\t\"TM\",\n+\t\t\"VF VLAN FILTER MOD\",\n+\t};\t\n+\tuint32_t i;\n+\n+\tfprintf(file, \"  - Dev Capability:\\n\");\n+\tfor (i = 0; i < RTE_DIM(caps_name); i++)\n+\t\tfprintf(file, \"\\t  -- support %s: %s\\n\", caps_name[i],\n+\t\t\thw->capability & BIT(i) ? \"yes\" : \"no\");\n+}\n+\n+static const char *\n+get_fdir_tuple_name(uint32_t index)\n+{\n+\tstatic const char *tuple_name[] = {\n+\t\t\"outer_dst_mac\",\n+\t\t\"outer_src_mac\",\n+\t\t\"outer_vlan_1st_tag\",\n+\t\t\"outer_vlan_2st_tag\",\n+\t\t\"outer_eth_type\",\n+\t\t\"outer_l2_rsv\",\n+\t\t\"outer_ip_tos\",\n+\t\t\"outer_ip_proto\",\n+\t\t\"outer_src_ip\",\n+\t\t\"outer_dst_ip\",\n+\t\t\"outer_l3_rsv\",\n+\t\t\"outer_src_port\",\n+\t\t\"outer_dst_port\",\n+\t\t\"outer_l4_rsv\",\n+\t\t\"outer_tun_vni\",\n+\t\t\"outer_tun_flow_id\",\n+\t\t\"inner_dst_mac\",\n+\t\t\"inner_src_mac\",\n+\t\t\"inner_vlan_tag1\",\n+\t\t\"inner_vlan_tag2\",\n+\t\t\"inner_eth_type\",\n+\t\t\"inner_l2_rsv\",\n+\t\t\"inner_ip_tos\",\n+\t\t\"inner_ip_proto\",\n+\t\t\"inner_src_ip\",\n+\t\t\"inner_dst_ip\",\n+\t\t\"inner_l3_rsv\",\n+\t\t\"inner_src_port\",\n+\t\t\"inner_dst_port\",\n+\t\t\"inner_sctp_tag\",\n+\t};\n+\tif (index < RTE_DIM(tuple_name))\n+\t\treturn tuple_name[index];\n+\telse\n+\t\treturn \"unknown\";\n+}\n+\n+static void\n+get_fdir_basic_info(FILE *file, struct hns3_pf *pf)\n+{\n+#define TMPBUF_SIZE\t\t2048\n+#define PERLINE_TUPLE_NAMES\t4\n+\tstruct hns3_fd_cfg *fdcfg = &pf->fdir.fd_cfg;\n+\tchar tmpbuf[TMPBUF_SIZE] = {0};\n+\tuint32_t i, count = 0;\n+\n+\tfprintf(file, \"  - Fdir Info:\\n\");\n+\tfprintf(file,\n+\t\t\"\\t  -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\\n\"\n+\t\t\"\\t  -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\\n\"\n+\t\t\"\\t  -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\\n\"\n+\t\t\"\\t  -- active_tuples:\\n\",\n+\t\tfdcfg->fd_mode, fdcfg->max_key_length,\n+\t\tfdcfg->rule_num[HNS3_FD_STAGE_1],\n+\t\tfdcfg->cnt_num[HNS3_FD_STAGE_1],\n+\t\tfdcfg->key_cfg[HNS3_FD_STAGE_1].key_sel,\n+\t\tfdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active,\n+\t\tfdcfg->key_cfg[HNS3_FD_STAGE_1].meta_data_active,\n+\t\tfdcfg->key_cfg[HNS3_FD_STAGE_1].inner_sipv6_word_en,\n+\t\tfdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en,\n+\t\tfdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en,\n+\t\tfdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en);\n+\n+\tfor (i = 0; i < MAX_TUPLE; i++) {\n+\t\tif (!(fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active & BIT(i)))\n+\t\t\tcontinue;\n+\t\tif (count % PERLINE_TUPLE_NAMES == 0)\n+\t\t\tfprintf(file, \"\\t      \");\n+\t\tfprintf(file, \" %s\", get_fdir_tuple_name(i));\n+\t\tcount++;\n+\t\tif (count % PERLINE_TUPLE_NAMES == 0)\n+\t\t\tfprintf(file, \"\\n\");\n+\t}\n+\tif (count % PERLINE_TUPLE_NAMES)\n+\t\tfprintf(file, \"\\n\");\n+\n+\tfprintf(file, \"%s\", tmpbuf);\n+}\n+\n+static void\n+get_device_basic_info(FILE *file, struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = &hns->hw;\n+\n+\tfprintf(file,\n+\t\t\"  - Device Base Info:\\n\"\n+\t\t\"\\t  -- name: %s\\n\"\n+\t\t\"\\t  -- adapter_state=%s\\n\"\n+\t\t\"\\t  -- nb_rx_queues=%u nb_tx_queues=%u\\n\"\n+\t\t\"\\t  -- total_tqps_num=%u tqps_num=%u intr_tqps_num=%u\\n\"\n+\t\t\"\\t  -- rss_size_max=%u alloc_rss_size=%u tx_qnum_per_tc=%u\\n\"\n+\t\t\"\\t  -- min_tx_pkt_len=%u intr_mapping_mode=%u vlan_mode=%u\\n\"\n+\t\t\"\\t  -- tso_mode=%u max_non_tso_bd_num=%u\\n\"\n+\t\t\"\\t  -- max_tm_rate=%u Mbps\\n\"\n+\t\t\"\\t  -- set link down: %s\\n\"\n+\t\t\"\\t  -- rx_func_hint=%s tx_func_hint=%s\\n\"\n+\t\t\"\\t  -- dev_flags: lsc=%d\\n\"\n+\t\t\"\\t  -- intr_conf: lsc=%u rxq=%u\\n\",\n+\t\tdev->data->name,\n+\t\tget_adapter_state_name(hw->adapter_state),\n+\t\tdev->data->nb_rx_queues, dev->data->nb_tx_queues,\n+\t\thw->total_tqps_num, hw->tqps_num, hw->intr_tqps_num,\n+\t\thw->rss_size_max, hw->alloc_rss_size, hw->tx_qnum_per_tc,\n+\t\thw->min_tx_pkt_len, hw->intr.mapping_mode, hw->vlan_mode,\n+\t\thw->tso_mode, hw->max_non_tso_bd_num,\n+\t\thw->max_tm_rate,\n+\t\thw->set_link_down ? \"Yes\" : \"No\",\n+\t\tget_io_func_hint_name(hns->rx_func_hint),\n+\t\tget_io_func_hint_name(hns->tx_func_hint),\n+\t\t!!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC),\n+\t\tdev->data->dev_conf.intr_conf.lsc,\n+\t\tdev->data->dev_conf.intr_conf.rxq);\n+}\n+\n+/*\n+ * Note: caller must make sure queue_id < nb_queues\n+ *       nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,\n+ *                           eth_dev->data->nb_tx_queues)\n+ */\n+static struct hns3_rx_queue *\n+get_rx_queue(struct rte_eth_dev *dev, unsigned int queue_id)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tunsigned int offset;\n+\tvoid **rx_queues;\n+\n+\tif (queue_id < dev->data->nb_rx_queues) {\n+\t\trx_queues = dev->data->rx_queues;\n+\t\toffset = queue_id;\n+\t} else {\n+\t\t/*\n+\t\t * For kunpeng930, fake queue is not exist. But since the queues\n+\t\t * are usually accessd in pairs, this branch may still exist.\n+\t\t */\n+\t\tif (hns3_dev_get_support(hw, INDEP_TXRX))\n+\t\t\treturn NULL;\n+\n+\t\trx_queues = hw->fkq_data.rx_queues;\n+\t\toffset = queue_id - dev->data->nb_rx_queues;\n+\t}\n+\n+\tif (rx_queues != NULL && rx_queues[offset] != NULL)\n+\t\treturn rx_queues[offset];\n+\n+\thns3_err(hw, \"Detect rx_queues is NULL!\\n\");\n+\treturn NULL;\n+}\n+\n+/*\n+ * Note: caller must make sure queue_id < nb_queues\n+ *       nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,\n+ *                           eth_dev->data->nb_tx_queues)\n+ */\n+static struct hns3_tx_queue *\n+get_tx_queue(struct rte_eth_dev *dev, unsigned int queue_id)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tunsigned int offset;\n+\tvoid **tx_queues;\n+\n+\tif (queue_id < dev->data->nb_tx_queues) {\n+\t\ttx_queues = dev->data->tx_queues;\n+\t\toffset = queue_id;\n+\t} else {\n+\t\t/*\n+\t\t * For kunpeng930, fake queue is not exist. But since the queues\n+\t\t * are usually accessd in pairs, this branch may still exist.\n+\t\t */\n+\t\tif (hns3_dev_get_support(hw, INDEP_TXRX))\n+\t\t\treturn NULL;\n+\t\ttx_queues = hw->fkq_data.tx_queues;\n+\t\toffset = queue_id - dev->data->nb_tx_queues;\n+\t}\n+\n+\tif (tx_queues != NULL && tx_queues[offset] != NULL)\n+\t\treturn tx_queues[offset];\n+\n+\thns3_err(hw, \"Detect tx_queues is NULL!\\n\");\n+\treturn NULL;\n+}\n+\n+static void\n+get_rxtx_fake_queue_info(FILE *file, struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns);\n+\tstruct hns3_rx_queue *rxq;\n+\tstruct hns3_tx_queue *txq;\n+\tunsigned int queue_id;\n+\n+\tif (dev->data->nb_rx_queues != dev->data->nb_tx_queues &&\n+\t    !hns3_dev_get_support(hw, INDEP_TXRX)) {\n+\t\tqueue_id = RTE_MIN(dev->data->nb_rx_queues,\n+\t\t\t\t   dev->data->nb_tx_queues);\n+\t\trxq = get_rx_queue(dev, queue_id);\n+\t\tif (rxq == NULL)\n+\t\t\treturn;\n+\t\ttxq = get_tx_queue(dev, queue_id);\n+\t\tif (txq == NULL)\n+\t\t\treturn;\n+\t\tfprintf(file,\n+\t\t\t\"\\t  -- first fake_queue rxtx info:\\n\"\n+\t\t\t\"\\t       rx: port=%u nb_desc=%u free_thresh=%u\\n\"\n+\t\t\t\"\\t       tx: port=%u nb_desc=%u\\n\",\n+\t\t\trxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,\n+\t\t\ttxq->port_id, txq->nb_tx_desc);\n+\t}\n+}\n+\n+static void\n+get_queue_enable_state(struct hns3_hw *hw, uint32_t *queue_state,\n+\t\t\tuint32_t nb_queues, bool is_rxq)\n+{\n+#define STATE_SIZE (sizeof(*queue_state) * CHAR_BIT)\n+\tuint32_t queue_en_reg;\n+\tuint32_t reg_offset;\n+\tuint32_t state;\n+\tuint32_t i;\n+\n+\tqueue_en_reg = is_rxq ? HNS3_RING_RX_EN_REG : HNS3_RING_TX_EN_REG;\n+\tfor (i = 0; i < nb_queues; i++) {\n+\t\treg_offset = hns3_get_tqp_reg_offset(i);\n+\t\tstate = hns3_read_dev(hw, reg_offset + HNS3_RING_EN_REG);\n+\t\tif (hns3_dev_get_support(hw, INDEP_TXRX))\n+\t\t\tstate = state && hns3_read_dev(hw, reg_offset +\n+\t\t\t\t\t\t       queue_en_reg);\n+\t\thns3_set_bit(queue_state[i / STATE_SIZE],\n+\t\t\t\ti % STATE_SIZE, state);\n+\t}\n+}\n+\n+static void\n+print_queue_state_perline(FILE *file, const uint32_t *queue_state,\n+\t\t\t  uint32_t nb_queues, uint32_t line_num)\n+{\n+#define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)\n+\tuint32_t qid = line_num * NUM_QUEUE_PER_LINE;\n+\tuint32_t j;\n+\n+\tfor (j = 0; j < NUM_QUEUE_PER_LINE; j++) {\n+\t\tfprintf(file, \"%1lx\", hns3_get_bit(queue_state[line_num], j));\n+\n+\t\tif (qid % CHAR_BIT == CHAR_BIT - 1) {\n+\t\t\tfprintf(file, \"%s\",\n+\t\t\t\tj == NUM_QUEUE_PER_LINE - 1 ? \"\\n\" : \":\");\n+\t\t}\n+\t\tqid++;\n+\t\tif (qid >= nb_queues) {\n+\t\t\tfprintf(file, \"\\n\");\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+}\t\t\t\n+\n+static void\n+display_queue_enable_state(FILE *file, const uint32_t *queue_state,\n+\t\t\t   uint32_t nb_queues, bool is_rxq)\n+{\n+#define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)\n+\tuint32_t i;\n+\n+\tif (nb_queues == 0) {\n+\t\tfprintf(file, \"\\t       %s queue number is 0\\n\",\n+\t\t\t\tis_rxq ? \"Rx\" : \"Tx\");\n+\t\treturn;\n+\t}\n+\n+\tfprintf(file, \"\\t       %s queue id | enable state bitMap\\n\",\n+\t\t\tis_rxq ? \"rx\" : \"tx\");\n+\n+\tfor (i = 0; i < (nb_queues - 1) / NUM_QUEUE_PER_LINE + 1; i++) {\n+\t\tuint32_t line_end = (i + 1) * NUM_QUEUE_PER_LINE - 1;\n+\t\tuint32_t line_start = i * NUM_QUEUE_PER_LINE;\n+\t\tfprintf(file, \"\\t       %04u - %04u | \", line_start,\n+\t\t\tnb_queues - 1 > line_end ? line_end : nb_queues - 1);\n+\n+\n+\t\tprint_queue_state_perline(file, queue_state, nb_queues, i);\n+\t}\n+}\n+\n+static void\n+get_rxtx_queue_enable_state(FILE *file, struct rte_eth_dev *dev)\n+{\n+#define MAX_TQP_NUM 1280\n+#define QUEUE_BITMAP_SIZE (MAX_TQP_NUM / 32)\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tuint32_t rx_queue_state[QUEUE_BITMAP_SIZE] = {0};\n+\tuint32_t tx_queue_state[QUEUE_BITMAP_SIZE] = {0};\n+\tuint32_t nb_rx_queues;\n+\tuint32_t nb_tx_queues;\n+\n+\tnb_rx_queues = dev->data->nb_rx_queues;\n+\tnb_tx_queues = dev->data->nb_tx_queues;\n+\n+\tfprintf(file, \"\\t  -- enable state:\\n\");\n+\tget_queue_enable_state(hw, rx_queue_state, nb_rx_queues, true);\n+\tdisplay_queue_enable_state(file, rx_queue_state, nb_rx_queues,\n+\t\t\t\t\t true);\n+\n+\tget_queue_enable_state(hw, tx_queue_state, nb_tx_queues, false);\n+\tdisplay_queue_enable_state(file, tx_queue_state, nb_tx_queues,\n+\t\t\t\t\t false);\n+}\n+\n+static void\n+get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_rx_queue *rxq;\n+\tstruct hns3_tx_queue *txq;\n+\tunsigned int queue_id = 0;\n+\n+\trxq = get_rx_queue(dev, queue_id);\n+\tif (rxq == NULL)\n+\t\treturn;\n+\ttxq = get_tx_queue(dev, queue_id);\n+\tif (txq == NULL)\n+\t\treturn;\n+\tfprintf(file,\"  - Rx/Tx Queue Info:\\n\");\n+\tfprintf(file,\n+\t\t\"\\t  -- nb_rx_queues=%u nb_tx_queues=%u, \"\n+\t\t\"first queue rxtx info:\\n\"\n+\t\t\"\\t       rx: port=%u nb_desc=%u free_thresh=%u\\n\"\n+\t\t\"\\t       tx: port=%u nb_desc=%u\\n\"\n+\t\t\"\\t  -- tx push: %s\\n\",\n+\t\tdev->data->nb_rx_queues,\n+\t\tdev->data->nb_tx_queues,\n+\t\trxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,\n+\t\ttxq->port_id, txq->nb_tx_desc,\n+\t\ttxq->tx_push_enable ? \"enabled\" : \"disabled\");\n+\n+\tget_rxtx_fake_queue_info(file, dev);\n+\tget_rxtx_queue_enable_state(file, dev);\n+}\n+\n+static int\n+get_vlan_filter_cfg(FILE *file, struct hns3_hw *hw)\n+{\n+#define HNS3_FILTER_TYPE_VF\t\t0\n+#define HNS3_FILTER_TYPE_PORT\t\t1\n+#define HNS3_FILTER_FE_NIC_INGRESS_B\tBIT(0)\n+#define HNS3_FILTER_FE_NIC_EGRESS_B\tBIT(1)\n+\tstruct hns3_vlan_filter_ctrl_cmd *req;\n+\tstruct hns3_cmd_desc desc;\n+\tuint8_t i;\n+\tint ret;\n+\n+\tstatic const uint32_t vlan_filter_type[] = {\n+\t\tHNS3_FILTER_TYPE_PORT,\n+\t\tHNS3_FILTER_TYPE_VF\n+\t};\n+\n+\tfor (i = 0; i < RTE_DIM(vlan_filter_type); i++) {\n+\t\thns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_FILTER_CTRL,\n+\t\t\t\t\t\ttrue);\n+\t\treq = (struct hns3_vlan_filter_ctrl_cmd *)desc.data;\n+\t\treq->vlan_type = vlan_filter_type[i];\n+\t\treq->vf_id = HNS3_PF_FUNC_ID;\n+\t\tret = hns3_cmd_send(hw, &desc, 1);\n+\t\tif (ret != 0) {\n+\t\t\thns3_err(hw,\n+\t\t\t\t\"NIC IMP exec ret=%d desc_num=%d optcode=0x%x!\",\n+\t\t\t\tret, 1, rte_le_to_cpu_16(desc.opcode));\n+\t\t\treturn ret;\n+\t\t}\n+\t\tfprintf(file,\n+\t\t\t\"\\t  -- %s VLAN filter configuration\\n\"\n+\t\t\t\"\\t       nic_ingress           :%s\\n\"\n+\t\t\t\"\\t       nic_egress            :%s\\n\",\n+\t\t\treq->vlan_type == HNS3_FILTER_TYPE_PORT ?\n+\t\t\t\"Port\" : \"VF\",\n+\t\t\treq->vlan_fe & HNS3_FILTER_FE_NIC_INGRESS_B ?\n+\t\t\t\"Enable\" : \"Disable\",\n+\t\t\treq->vlan_fe & HNS3_FILTER_FE_NIC_EGRESS_B ?\n+\t\t\t\"Enable\" : \"Disable\");\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+get_vlan_rx_offload_cfg(FILE *file, struct hns3_hw *hw)\n+{\n+\tstruct hns3_vport_vtag_rx_cfg_cmd *req;\n+\tstruct hns3_cmd_desc desc;\n+\tuint16_t vport_id;\n+\tuint8_t bitmap;\n+\tint ret;\n+\n+\thns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_RX_CFG, true);\n+\treq = (struct hns3_vport_vtag_rx_cfg_cmd *)desc.data;\n+\tvport_id = HNS3_PF_FUNC_ID;\n+\treq->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;\n+\tbitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);\n+\treq->vf_bitmap[req->vf_offset] = bitmap;\n+\n+\t/*\n+\t * current version VF is not supported when PF is driven by DPDK driver,\n+\t * just need to configure rx parameters for PF vport.\n+\t */\n+\tret = hns3_cmd_send(hw, &desc, 1);\n+\tif (ret != 0) {\n+\t\thns3_err(hw,\n+\t\t\t\"NIC IMP exec ret=%d desc_num=%d optcode=0x%x!\",\n+\t\t\tret, 1, rte_le_to_cpu_16(desc.opcode));\n+\t\treturn ret;\n+\t}\n+\n+\tfprintf(file,\n+\t\t\"\\t  -- RX VLAN configuration\\n\"\n+\t\t\"\\t       vlan1_strip_en        :%s\\n\"\n+\t\t\"\\t       vlan2_strip_en        :%s\\n\"\n+\t\t\"\\t       vlan1_vlan_prionly    :%s\\n\"\n+\t\t\"\\t       vlan2_vlan_prionly    :%s\\n\"\n+\t\t\"\\t       vlan1_strip_discard   :%s\\n\"\n+\t\t\"\\t       vlan2_strip_discard   :%s\\n\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_REM_TAG1_EN_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_REM_TAG2_EN_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_SHOW_TAG1_EN_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_SHOW_TAG2_EN_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_DISCARD_TAG1_EN_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_DISCARD_TAG2_EN_B) ? \"Enable\" : \"Disable\");\n+\n+\treturn 0;\n+}\n+\n+static void\n+parse_tx_vlan_cfg(FILE *file, struct hns3_vport_vtag_tx_cfg_cmd *req)\n+{\n+#define VLAN_VID_MASK 0x0fff\n+#define VLAN_PRIO_SHIFT 13\n+\n+\tfprintf(file,\n+\t\t\"\\t  -- TX VLAN configuration\\n\"\n+\t\t\"\\t       accept_tag1           :%s\\n\"\n+\t\t\"\\t       accept_untag1         :%s\\n\"\n+\t\t\"\\t       insert_tag1_en        :%s\\n\"\n+\t\t\"\\t       default_vlan_tag1 = %d, qos = %d\\n\"\n+\t\t\"\\t       accept_tag2           :%s\\n\"\n+\t\t\"\\t       accept_untag2         :%s\\n\"\n+\t\t\"\\t       insert_tag2_en        :%s\\n\"\n+\t\t\"\\t       default_vlan_tag2 = %d, qos = %d\\n\"\n+\t\t\"\\t       vlan_shift_mode       :%s\\n\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_ACCEPT_TAG1_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_ACCEPT_UNTAG1_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_PORT_INS_TAG1_EN_B) ? \"Enable\" : \"Disable\",\n+\t\treq->def_vlan_tag1 & VLAN_VID_MASK,\n+\t\treq->def_vlan_tag1 >> VLAN_PRIO_SHIFT,\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_ACCEPT_TAG2_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_ACCEPT_UNTAG2_B) ? \"Enable\" : \"Disable\",\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_PORT_INS_TAG2_EN_B) ? \"Enable\" : \"Disable\",\n+\t\treq->def_vlan_tag2 & VLAN_VID_MASK,\n+\t\treq->def_vlan_tag2 >> VLAN_PRIO_SHIFT,\n+\t\thns3_get_bit(req->vport_vlan_cfg,\n+\t\t\tHNS3_TAG_SHIFT_MODE_EN_B) ? \"Enable\" :\n+\t\t\t\"Disable\");\n+}\n+\n+static int\n+get_vlan_tx_offload_cfg(FILE *file, struct hns3_hw *hw)\n+{\n+\tstruct hns3_vport_vtag_tx_cfg_cmd *req;\n+\tstruct hns3_cmd_desc desc;\n+\tuint16_t vport_id;\n+\tuint8_t bitmap;\n+\tint ret;\n+\n+\thns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_TX_CFG, true);\n+\treq = (struct hns3_vport_vtag_tx_cfg_cmd *)desc.data;\n+\tvport_id = HNS3_PF_FUNC_ID;\n+\treq->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;\n+\tbitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);\n+\treq->vf_bitmap[req->vf_offset] = bitmap;\n+\t/*\n+\t * current version VF is not supported when PF is driven by DPDK driver,\n+\t * just need to configure tx parameters for PF vport.\n+\t */\n+\tret = hns3_cmd_send(hw, &desc, 1);\n+\tif (ret != 0) {\n+\t\thns3_err(hw,\n+\t\t\t\"NIC IMP exec ret=%d desc_num=%d optcode=0x%x!\",\n+\t\t\tret, 1, rte_le_to_cpu_16(desc.opcode));\n+\t\treturn ret;\n+\t}\n+\n+\tparse_tx_vlan_cfg(file, req);\n+\n+\treturn 0;\n+}\n+\n+static void\n+get_port_pvid_info(FILE *file, struct hns3_hw *hw)\n+{\n+\tfprintf(file, \"\\t  -- pvid status: %s\\n\",\n+\t\thw->port_base_vlan_cfg.state ? \"on\" : \"off\");\n+}\n+\n+static void\n+get_vlan_config_info(FILE *file, struct hns3_hw *hw)\n+{\n+\tint ret;\n+\n+\tfprintf(file,\"  - VLAN Config Info:\\n\");\n+\tret = get_vlan_filter_cfg(file, hw);\n+\tif (ret < 0)\n+\t\treturn;\n+\n+\tret = get_vlan_rx_offload_cfg(file, hw);\n+\tif (ret < 0)\n+\t\treturn;\n+\n+\tret = get_vlan_tx_offload_cfg(file, hw);\n+\tif (ret < 0)\n+\t\treturn;\n+\n+\tget_port_pvid_info(file, hw);\t\n+}\n+\n+static void\n+get_tm_conf_shaper_info(FILE *file, struct hns3_tm_conf *conf)\n+{\n+\tstruct hns3_shaper_profile_list *shaper_profile_list =\n+\t\t&conf->shaper_profile_list;\n+\tstruct hns3_tm_shaper_profile *shaper_profile;\n+\n+\tif (!conf->nb_shaper_profile)\n+\t\treturn;\n+\n+\tfprintf(file, \"  shaper_profile:\\n\");\n+\tTAILQ_FOREACH(shaper_profile, shaper_profile_list, node) {\n+\t\tfprintf(file,\n+\t\t\t\"    id=%u reference_count=%u peak_rate=%\"PRIu64\"Bps\\n\",\n+\t\t\tshaper_profile->shaper_profile_id,\n+\t\t\tshaper_profile->reference_count,\n+\t\t\tshaper_profile->profile.peak.rate);\n+\t}\n+}\n+\n+static void\n+get_tm_conf_port_node_info(FILE *file, struct hns3_tm_conf *conf)\n+{\n+\tif (!conf->root)\n+\t\treturn;\n+\n+\tfprintf(file,\n+\t\t\"  port_node: \\n\"\n+\t\t\"    node_id=%u reference_count=%u shaper_profile_id=%d\\n\",\n+\t\tconf->root->id, conf->root->reference_count,\n+\t\tconf->root->shaper_profile ?\n+\t\t(int)conf->root->shaper_profile->shaper_profile_id : -1);\n+}\n+\n+static void\n+get_tm_conf_tc_node_info(FILE *file, struct hns3_tm_conf *conf)\n+{\n+\tstruct hns3_tm_node_list *tc_list = &conf->tc_list;\n+\tstruct hns3_tm_node *tc_node[HNS3_MAX_TC_NUM];\n+\tstruct hns3_tm_node *tm_node;\n+\tuint32_t tidx;\n+\n+\tif (!conf->nb_tc_node)\n+\t\treturn;\n+\n+\tfprintf(file, \"  tc_node: \\n\");\n+\tmemset(tc_node, 0, sizeof(tc_node));\n+\tTAILQ_FOREACH(tm_node, tc_list, node) {\n+\t\ttidx = hns3_tm_calc_node_tc_no(conf, tm_node->id);\n+\t\tif (tidx < HNS3_MAX_TC_NUM)\n+\t\t\ttc_node[tidx] = tm_node;\n+\t}\n+\n+\tfor (tidx = 0; tidx < HNS3_MAX_TC_NUM; tidx++) {\n+\t\ttm_node = tc_node[tidx];\n+\t\tif (tm_node == NULL)\n+\t\t\tcontinue;\n+\t\tfprintf(file,\n+\t\t\t\"    id=%u TC%u reference_count=%u parent_id=%d \"\n+\t\t\t\"shaper_profile_id=%d\\n\",\n+\t\t\ttm_node->id, hns3_tm_calc_node_tc_no(conf, tm_node->id),\n+\t\t\ttm_node->reference_count,\n+\t\t\ttm_node->parent ? (int)tm_node->parent->id : -1,\n+\t\t\ttm_node->shaper_profile ?\n+\t\t\t(int)tm_node->shaper_profile->shaper_profile_id : -1);\n+\t}\n+}\n+\n+static void\n+get_tm_conf_queue_format_info(FILE *file, struct hns3_tm_node **queue_node,\n+\t\t\t      uint32_t *queue_node_tc,  uint32_t nb_tx_queues)\n+{\n+#define PERLINE_QUEUES\t32\n+#define PERLINE_STRIDE\t8\n+#define LINE_BUF_SIZE\t1024\n+\tuint32_t i, j, line_num, start_queue, end_queue;\n+\tchar tmpbuf[LINE_BUF_SIZE] = {0};\n+\n+\tline_num = (nb_tx_queues + PERLINE_QUEUES - 1) / PERLINE_QUEUES;\n+\tfor (i = 0; i < line_num; i++) {\n+\t\tstart_queue = i * PERLINE_QUEUES;\n+\t\tend_queue = (i + 1) * PERLINE_QUEUES - 1;\n+\t\tif (end_queue > nb_tx_queues - 1)\n+\t\t\tend_queue = nb_tx_queues - 1;\n+\t\tfprintf(file, \"    %04u - %04u | \", start_queue, end_queue);\n+\t\tfor (j = start_queue; j < nb_tx_queues; j++) {\n+\t\t\tif (j >= end_queue + 1)\n+\t\t\t\tbreak;\n+\t\t\tif (j > start_queue && j % PERLINE_STRIDE == 0)\n+\t\t\t\tfprintf(file, \":\");\n+\t\t\tfprintf(file, \"%u\",\n+\t\t\t\tqueue_node[j] ? queue_node_tc[j] :\n+\t\t\t\tHNS3_MAX_TC_NUM);\n+\t\t}\n+\t\tfprintf(file, \"%s\\n\", tmpbuf);\n+\t}\n+}\n+\n+static void\n+get_tm_conf_queue_node_info(FILE *file, struct hns3_tm_conf *conf,\n+\t\t\t    uint32_t nb_tx_queues)\n+{\n+\tstruct hns3_tm_node_list *queue_list = &conf->queue_list;\n+\tuint32_t nb_queue_node = conf->nb_leaf_nodes_max + 1;\n+\tstruct hns3_tm_node *queue_node[nb_queue_node];\n+\tuint32_t queue_node_tc[nb_queue_node];\n+\tstruct hns3_tm_node *tm_node;\n+\n+\tif (!conf->nb_queue_node)\n+\t\treturn;\n+\n+\tfprintf(file,\n+\t\t\"  queue_node: \\n\"\n+\t\t\"    tx queue id | mapped tc (8 mean node not exist)\\n\");\n+\n+\tmemset(queue_node, 0, sizeof(queue_node));\n+\tmemset(queue_node_tc, 0, sizeof(queue_node_tc));\n+\tnb_tx_queues = RTE_MIN(nb_tx_queues, nb_queue_node);\n+\tTAILQ_FOREACH(tm_node, queue_list, node) {\n+\t\tif (tm_node->id >= nb_queue_node)\n+\t\t\tcontinue;\n+\t\tqueue_node[tm_node->id] = tm_node;\n+\t\tqueue_node_tc[tm_node->id] = tm_node->parent ?\n+\t\t\thns3_tm_calc_node_tc_no(conf, tm_node->parent->id) : 0;\n+\t\tnb_tx_queues = RTE_MAX(nb_tx_queues, tm_node->id + 1);\n+\t}\n+\n+\tget_tm_conf_queue_format_info(file, queue_node, queue_node_tc,\n+\t\t\t\t      nb_tx_queues);\n+}\n+\n+static void\n+get_tm_conf_info(FILE *file, struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);\n+\tstruct hns3_tm_conf *conf = &pf->tm_conf;\n+\n+\tfprintf(file, \"  - TM config info:\\n\");\n+\tfprintf(file,\n+\t\t\"\\t  -- nb_leaf_nodes_max=%u nb_nodes_max=%u\\n\"\n+\t\t\"\\t  -- nb_shaper_profile=%u nb_tc_node=%u nb_queue_node=%u\\n\"\n+\t\t\"\\t  -- committed=%u\\n\",\n+\t\tconf->nb_leaf_nodes_max, conf->nb_nodes_max,\n+\t\tconf->nb_shaper_profile, conf->nb_tc_node, conf->nb_queue_node,\n+\t\tconf->committed);\n+\n+\tget_tm_conf_shaper_info(file, conf);\n+\tget_tm_conf_port_node_info(file, conf);\n+\tget_tm_conf_tc_node_info(file, conf);\n+\tget_tm_conf_queue_node_info(file, conf, dev->data->nb_tx_queues);\n+}\n+\n+static void\n+hns3_fc_mode_to_rxtx_pause(enum hns3_fc_mode fc_mode, bool *rx_pause,\n+\t\t\t   bool *tx_pause)\n+{\n+\tswitch (fc_mode) {\n+\tcase HNS3_FC_NONE:\n+\t\t*tx_pause = false;\n+\t\t*rx_pause = false;\n+\t\tbreak;\n+\tcase HNS3_FC_RX_PAUSE:\n+\t\t*rx_pause = true;\n+\t\t*tx_pause = false;\n+\t\tbreak;\n+\tcase HNS3_FC_TX_PAUSE:\n+\t\t*rx_pause = false;\n+\t\t*tx_pause = true;\n+\t\tbreak;\n+\tcase HNS3_FC_FULL:\n+\t\t*rx_pause = true;\n+\t\t*tx_pause = true;\n+\t\tbreak;\n+\tdefault:\n+\t\t*rx_pause = false;\n+\t\t*tx_pause = false;\n+\t\tbreak;\n+\t}\n+}\n+\n+static bool\n+is_link_fc_mode(struct hns3_adapter *hns)\n+{\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tstruct hns3_pf *pf = &hns->pf;\n+\n+\tif (hw->current_fc_status == HNS3_FC_STATUS_PFC)\n+\t\treturn false;\n+\n+\tif (hw->num_tc > 1 && !pf->support_multi_tc_pause)\n+\t\treturn false;\n+\n+\treturn true;\n+}\n+\n+static void\n+get_link_fc_info(FILE *file, struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tstruct rte_eth_fc_conf fc_conf;\n+\tbool rx_pause1;\n+\tbool tx_pause1;\n+\tbool rx_pause2;\n+\tbool tx_pause2;\n+\tint ret;\n+\n+\tif (!is_link_fc_mode(hns))\n+\t\treturn;\n+\n+\tret = hns3_flow_ctrl_get(dev, &fc_conf);\n+\tif (ret)  {\n+\t\tfprintf(file, \"get device flow control info fail!\\n\");\n+\t\treturn;\n+\t}\n+\n+\thns3_fc_mode_to_rxtx_pause(hw->requested_fc_mode,\n+\t\t\t\t   &rx_pause1, &tx_pause1);\n+\thns3_fc_mode_to_rxtx_pause((enum hns3_fc_mode)fc_conf.mode,\n+\t\t\t\t   &rx_pause2, &tx_pause2);\n+\n+\tfprintf(file,\n+\t\t\"\\t  -- link_fc_info:\\n\"\n+\t\t\"\\t       Requested fc:\\n\"\n+\t\t\"\\t         Rx:\t%s\\n\"\n+\t\t\"\\t         Tx:\t%s\\n\"\n+\t\t\"\\t       Current fc:\\n\"\n+\t\t\"\\t         Rx:\t%s\\n\"\n+\t\t\"\\t         Tx:\t%s\\n\"\n+\t\t\"\\t       Autonegotiate: %s\\n\"\n+\t\t\"\\t       Pause time:\t0x%x\\n\",\n+\t\trx_pause1 ? \"On\" : \"Off\", tx_pause1 ? \"On\" : \"Off\",\n+\t\trx_pause2 ? \"On\" : \"Off\", tx_pause2 ? \"On\" : \"Off\",\n+\t\tfc_conf.autoneg == ETH_LINK_AUTONEG ? \"On\" : \"Off\",\n+\t\tfc_conf.pause_time);\n+}\n+\n+static void\n+get_flow_ctrl_info(FILE *file, struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = &hns->hw;\n+\n+\tfprintf(file, \"  - Flow Ctrl Info:\\n\");\n+\tfprintf(file,\n+\t\t\"\\t  -- fc_common_info:\\n\"\n+\t\t\"\\t       current_fc_status=%u\\n\"\n+\t\t\"\\t       requested_fc_mode=%u\\n\",\n+\t\thw->current_fc_status,\n+\t\thw->requested_fc_mode);\n+\n+\tget_link_fc_info(file, dev);\n+}\n+\n+int\n+hns3_eth_dev_priv_dump(FILE *file, struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = &hns->hw;\n+\n+\tget_device_basic_info(file, dev);\n+\tget_dev_feature_capability(file, hw);\n+\n+\t/* VF is only support dumping basic info and feaure capability */\n+\tif (hns->is_vf)\n+\t\treturn 0;\t\n+\n+\tget_dev_mac_info(file, hns);\n+\tget_rxtx_queue_info(file, dev);\n+\tget_vlan_config_info(file, hw);\n+\tget_fdir_basic_info(file, &hns->pf);\t\n+\tget_tm_conf_info(file, dev);\n+\tget_flow_ctrl_info(file, dev);\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c\nindex f443d71039..7a822768c2 100644\n--- a/drivers/net/hns3/hns3_ethdev_vf.c\n+++ b/drivers/net/hns3/hns3_ethdev_vf.c\n@@ -2290,6 +2290,7 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = {\n \t.get_reg            = hns3_get_regs,\n \t.dev_supported_ptypes_get = hns3_dev_supported_ptypes_get,\n \t.tx_done_cleanup    = hns3_tx_done_cleanup,\n+\t.eth_dev_priv_dump  = hns3_eth_dev_priv_dump,\n };\n \n static const struct hns3_reset_ops hns3vf_reset_ops = {\ndiff --git a/drivers/net/hns3/meson.build b/drivers/net/hns3/meson.build\nindex 8a4c7cc100..665b2afedf 100644\n--- a/drivers/net/hns3/meson.build\n+++ b/drivers/net/hns3/meson.build\n@@ -30,6 +30,7 @@ sources = files(\n         'hns3_tm.c',\n         'hns3_ptp.c',\n         'hns3_common.c',\n+\t'hns3_ethdev_dump.c',\n )\n \n deps += ['hash']\ndiff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h\nindex d95605a355..e75ff3f15b 100644\n--- a/lib/ethdev/ethdev_driver.h\n+++ b/lib/ethdev/ethdev_driver.h\n@@ -990,6 +990,20 @@ typedef int (*eth_representor_info_get_t)(struct rte_eth_dev *dev,\n typedef int (*eth_rx_metadata_negotiate_t)(struct rte_eth_dev *dev,\n \t\t\t\t       uint64_t *features);\n \n+/**\n+ * @internal\n+ * Get ethdev private info.\n+ *\n+ * @param file\n+ *   A pointer to a file for output.\n+ * @param dev\n+ *   Port (ethdev) handle.\n+ *\n+ * @return\n+ *   Negative errno value on error, positive value on success.\n+ */\n+typedef int (*eth_dev_priv_dump_t)(FILE *file, struct rte_eth_dev *dev);\n+\n /**\n  * @internal A structure containing the functions exported by an Ethernet driver.\n  */\n@@ -1186,6 +1200,9 @@ struct eth_dev_ops {\n \t * kinds of metadata to the PMD\n \t */\n \teth_rx_metadata_negotiate_t rx_metadata_negotiate;\n+\n+\t/** Dump ethdev private info */\n+\teth_dev_priv_dump_t eth_dev_priv_dump;\n };\n \n /**\ndiff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c\nindex 29b5ee32b4..7d755c6b04 100644\n--- a/lib/ethdev/rte_ethdev.c\n+++ b/lib/ethdev/rte_ethdev.c\n@@ -6487,6 +6487,21 @@ rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features)\n \t\t       (*dev->dev_ops->rx_metadata_negotiate)(dev, features));\n }\n \n+int\n+rte_eth_dev_priv_dump(FILE *file, uint16_t port_id)\n+{\n+\tstruct rte_eth_dev *dev;\n+\tint ret;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);\n+\tdev = &rte_eth_devices[port_id];\n+\n+\tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->eth_dev_priv_dump, -ENOTSUP);\n+\tret = (*dev->dev_ops->eth_dev_priv_dump)(file, dev);\n+\n+\treturn ret;\n+}\n+\n RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);\n \n RTE_INIT(ethdev_init_telemetry)\ndiff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h\nindex 096b676fc1..62a3bb5d80 100644\n--- a/lib/ethdev/rte_ethdev.h\n+++ b/lib/ethdev/rte_ethdev.h\n@@ -5888,6 +5888,22 @@ rte_eth_tx_buffer(uint16_t port_id, uint16_t queue_id,\n \treturn rte_eth_tx_buffer_flush(port_id, queue_id, buffer);\n }\n \n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice\n+ *\n+ * Get ethdev private info.\n+ *\n+ * @param file\n+ *   A pointer to a file for output.\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @return\n+ *   Negative errno value on error, positive value on success.\n+ */\n+__rte_experimental\n+int rte_eth_dev_priv_dump(FILE *file, uint16_t port_id);\n+\n #ifdef __cplusplus\n }\n #endif\n",
    "prefixes": []
}