* [PATCH] app/testpmd: add help messages for multi-process
2022-03-04 1:22 ` [PATCH] 1 version Min Hu (Connor)
@ 2022-03-04 1:22 ` Min Hu (Connor)
2022-03-04 1:25 ` Min Hu (Connor)
2022-03-04 1:22 ` [PATCH] dpdk: show dev basic info Min Hu (Connor)
` (3 subsequent siblings)
4 siblings, 1 reply; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:22 UTC (permalink / raw)
To: dev
Cc: Huisong Li, stable, Xiaoyun Li, Aman Singh, Yuying Zhang,
Lijun Ou, Min Hu (Connor),
Ajit Khaparde
From: Huisong Li <lihuisong@huawei.com>
This patch adds help messages for multi-process.
Fixes: a550baf24af9 ("app/testpmd: support multi-process")
Cc: stable@dpdk.org
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
app/test-pmd/parameters.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 5251722d0f..6cc7afe15a 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -211,6 +211,8 @@ usage(char* progname)
printf(" --hairpin-mode=0xXX: bitmask set the hairpin port mode.\n"
" 0x10 - explicit Tx rule, 0x02 - hairpin ports paired\n"
" 0x01 - hairpin ports loop, 0x00 - hairpin port self\n");
+ printf(" --num-procs: the number of processes which will be used\n");
+ printf(" --proc-id : the id of the current process (id < num-procs)\n");
}
#ifdef RTE_LIB_CMDLINE
--
2.33.0
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] app/testpmd: add help messages for multi-process
2022-03-04 1:22 ` [PATCH] app/testpmd: add help messages for multi-process Min Hu (Connor)
@ 2022-03-04 1:25 ` Min Hu (Connor)
0 siblings, 0 replies; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:25 UTC (permalink / raw)
To: dev
Cc: Huisong Li, stable, Xiaoyun Li, Aman Singh, Yuying Zhang,
Lijun Ou, Ajit Khaparde
Sorry, this patch should be abandoned.
在 2022/3/4 9:22, Min Hu (Connor) 写道:
> From: Huisong Li <lihuisong@huawei.com>
>
> This patch adds help messages for multi-process.
>
> Fixes: a550baf24af9 ("app/testpmd: support multi-process")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> ---
> app/test-pmd/parameters.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
> index 5251722d0f..6cc7afe15a 100644
> --- a/app/test-pmd/parameters.c
> +++ b/app/test-pmd/parameters.c
> @@ -211,6 +211,8 @@ usage(char* progname)
> printf(" --hairpin-mode=0xXX: bitmask set the hairpin port mode.\n"
> " 0x10 - explicit Tx rule, 0x02 - hairpin ports paired\n"
> " 0x01 - hairpin ports loop, 0x00 - hairpin port self\n");
> + printf(" --num-procs: the number of processes which will be used\n");
> + printf(" --proc-id : the id of the current process (id < num-procs)\n");
> }
>
> #ifdef RTE_LIB_CMDLINE
>
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH] dpdk: show dev basic info
2022-03-04 1:22 ` [PATCH] 1 version Min Hu (Connor)
2022-03-04 1:22 ` [PATCH] app/testpmd: add help messages for multi-process Min Hu (Connor)
@ 2022-03-04 1:22 ` Min Hu (Connor)
2022-03-04 1:25 ` Min Hu (Connor)
2022-03-04 1:22 ` [PATCH v4] ethdev: introduce dump API Min Hu (Connor)
` (2 subsequent siblings)
4 siblings, 1 reply; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:22 UTC (permalink / raw)
To: dev
Cc: Min Hu (Connor),
Maryam Tahhan, Reshma Pattan, Yisen Zhuang, Lijun Ou,
Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
version 1
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
app/proc-info/main.c | 254 ++++++++
drivers/net/hns3/hns3_ethdev.c | 3 +-
drivers/net/hns3/hns3_ethdev.h | 3 +
drivers/net/hns3/hns3_ethdev_dump.c | 917 ++++++++++++++++++++++++++++
drivers/net/hns3/hns3_ethdev_vf.c | 1 +
drivers/net/hns3/meson.build | 1 +
lib/ethdev/ethdev_driver.h | 17 +
lib/ethdev/rte_ethdev.c | 15 +
lib/ethdev/rte_ethdev.h | 16 +
9 files changed, 1226 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/hns3/hns3_ethdev_dump.c
diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index a4271047e6..8644edfa7d 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -47,6 +47,12 @@
#define STATS_BDR_STR(w, s) printf("%.*s%s%.*s\n", w, \
STATS_BDR_FMT, s, w, STATS_BDR_FMT)
+/** Information for a given RSS type. */
+struct rss_type_info {
+ const char *str; /**< Type name. */
+ uint64_t rss_type; /**< Type value. */
+};
+
/**< mask of enabled ports */
static unsigned long enabled_port_mask;
/**< Enable stats. */
@@ -81,6 +87,8 @@ static char bdr_str[MAX_STRING_LEN];
/**< Enable show port. */
static uint32_t enable_shw_port;
+/**< Enable show port. */
+static uint32_t enable_shw_port_priv;
/**< Enable show tm. */
static uint32_t enable_shw_tm;
/**< Enable show crypto. */
@@ -98,6 +106,84 @@ static char *mempool_iter_name;
static uint32_t enable_dump_regs;
static char *dump_regs_file_prefix;
+static const struct rss_type_info rss_type_table[] = {
+ { "all", RTE_ETH_RSS_ETH | RTE_ETH_RSS_VLAN | RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP |
+ RTE_ETH_RSS_UDP | RTE_ETH_RSS_SCTP | RTE_ETH_RSS_L2_PAYLOAD |
+ RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_ESP | RTE_ETH_RSS_AH | RTE_ETH_RSS_PFCP |
+ RTE_ETH_RSS_GTPU | RTE_ETH_RSS_ECPRI | RTE_ETH_RSS_MPLS},
+ { "none", 0 },
+ { "eth", RTE_ETH_RSS_ETH },
+ { "l2-src-only", RTE_ETH_RSS_L2_SRC_ONLY },
+ { "l2-dst-only", RTE_ETH_RSS_L2_DST_ONLY },
+ { "vlan", RTE_ETH_RSS_VLAN },
+ { "s-vlan", RTE_ETH_RSS_S_VLAN },
+ { "c-vlan", RTE_ETH_RSS_C_VLAN },
+ { "ipv4", RTE_ETH_RSS_IPV4 },
+ { "ipv4-frag", RTE_ETH_RSS_FRAG_IPV4 },
+ { "ipv4-tcp", RTE_ETH_RSS_NONFRAG_IPV4_TCP },
+ { "ipv4-udp", RTE_ETH_RSS_NONFRAG_IPV4_UDP },
+ { "ipv4-sctp", RTE_ETH_RSS_NONFRAG_IPV4_SCTP },
+ { "ipv4-other", RTE_ETH_RSS_NONFRAG_IPV4_OTHER },
+ { "ipv6", RTE_ETH_RSS_IPV6 },
+ { "ipv6-frag", RTE_ETH_RSS_FRAG_IPV6 },
+ { "ipv6-tcp", RTE_ETH_RSS_NONFRAG_IPV6_TCP },
+ { "ipv6-udp", RTE_ETH_RSS_NONFRAG_IPV6_UDP },
+ { "ipv6-sctp", RTE_ETH_RSS_NONFRAG_IPV6_SCTP },
+ { "ipv6-other", RTE_ETH_RSS_NONFRAG_IPV6_OTHER },
+ { "l2-payload", RTE_ETH_RSS_L2_PAYLOAD },
+ { "ipv6-ex", RTE_ETH_RSS_IPV6_EX },
+ { "ipv6-tcp-ex", RTE_ETH_RSS_IPV6_TCP_EX },
+ { "ipv6-udp-ex", RTE_ETH_RSS_IPV6_UDP_EX },
+ { "port", RTE_ETH_RSS_PORT },
+ { "vxlan", RTE_ETH_RSS_VXLAN },
+ { "geneve", RTE_ETH_RSS_GENEVE },
+ { "nvgre", RTE_ETH_RSS_NVGRE },
+ { "ip", RTE_ETH_RSS_IP },
+ { "udp", RTE_ETH_RSS_UDP },
+ { "tcp", RTE_ETH_RSS_TCP },
+ { "sctp", RTE_ETH_RSS_SCTP },
+ { "tunnel", RTE_ETH_RSS_TUNNEL },
+ { "l3-pre32", RTE_ETH_RSS_L3_PRE32 },
+ { "l3-pre40", RTE_ETH_RSS_L3_PRE40 },
+ { "l3-pre48", RTE_ETH_RSS_L3_PRE48 },
+ { "l3-pre56", RTE_ETH_RSS_L3_PRE56 },
+ { "l3-pre64", RTE_ETH_RSS_L3_PRE64 },
+ { "l3-pre96", RTE_ETH_RSS_L3_PRE96 },
+ { "l3-src-only", RTE_ETH_RSS_L3_SRC_ONLY },
+ { "l3-dst-only", RTE_ETH_RSS_L3_DST_ONLY },
+ { "l4-src-only", RTE_ETH_RSS_L4_SRC_ONLY },
+ { "l4-dst-only", RTE_ETH_RSS_L4_DST_ONLY },
+ { "esp", RTE_ETH_RSS_ESP },
+ { "ah", RTE_ETH_RSS_AH },
+ { "l2tpv3", RTE_ETH_RSS_L2TPV3 },
+ { "pfcp", RTE_ETH_RSS_PFCP },
+ { "pppoe", RTE_ETH_RSS_PPPOE },
+ { "gtpu", RTE_ETH_RSS_GTPU },
+ { "ecpri", RTE_ETH_RSS_ECPRI },
+ { "mpls", RTE_ETH_RSS_MPLS },
+ { "ipv4-chksum", RTE_ETH_RSS_IPV4_CHKSUM },
+ { "l4-chksum", RTE_ETH_RSS_L4_CHKSUM },
+ { NULL, 0 },
+};
+
+/** Information for a ethernet speed info. */
+static const struct {
+ uint32_t speed;
+ const char *str;
+}eth_speed_table[] = {
+ { ETH_LINK_SPEED_10M_HD, "10Mbps-HD" },
+ { ETH_LINK_SPEED_10M, "10Mbps" },
+ { ETH_LINK_SPEED_100M_HD, "100Mbps-HD" },
+ { ETH_LINK_SPEED_100M, "100Mbps" },
+ { ETH_LINK_SPEED_1G, "1Gbps" },
+ { ETH_LINK_SPEED_10G, "10Gbps" },
+ { ETH_LINK_SPEED_25G, "25Gbps" },
+ { ETH_LINK_SPEED_40G, "40Gbps" },
+ { ETH_LINK_SPEED_50G, "50Gbps" },
+ { ETH_LINK_SPEED_100G, "100Gbps" },
+ { ETH_LINK_SPEED_200G, "200Gbps" },
+};
+
/**< display usage */
static void
proc_info_usage(const char *prgname)
@@ -118,6 +204,7 @@ proc_info_usage(const char *prgname)
" --collectd-format: to print statistics to STDOUT in expected by collectd format\n"
" --host-id STRING: host id used to identify the system process is running on\n"
" --show-port: to display ports information\n"
+ " --show-port-private: to display ports private information\n"
" --show-tm: to display traffic manager information for ports\n"
" --show-crypto: to display crypto information\n"
" --show-ring[=name]: to display ring information\n"
@@ -225,6 +312,7 @@ proc_info_parse_args(int argc, char **argv)
{"xstats-ids", 1, NULL, 1},
{"host-id", 0, NULL, 0},
{"show-port", 0, NULL, 0},
+ {"show-port-private", 0, NULL, 0},
{"show-tm", 0, NULL, 0},
{"show-crypto", 0, NULL, 0},
{"show-ring", optional_argument, NULL, 0},
@@ -275,6 +363,9 @@ proc_info_parse_args(int argc, char **argv)
else if (!strncmp(long_option[option_index].name,
"show-port", MAX_LONG_OPT_SZ))
enable_shw_port = 1;
+ else if (!strncmp(long_option[option_index].name,
+ "show-port-private", MAX_LONG_OPT_SZ))
+ enable_shw_port_priv = 1;
else if (!strncmp(long_option[option_index].name,
"show-tm", MAX_LONG_OPT_SZ))
enable_shw_tm = 1;
@@ -697,6 +788,119 @@ show_offloads(uint64_t offloads,
}
}
+static void
+show_dev_info(struct rte_eth_dev_info *dev_info)
+{
+ printf(" - device info\n");
+ printf( "\t -- maximum number of MAC addresses: %u\n"
+ "\t -- maximum number of MAC addresses of hash filtering: %u\n"
+ "\t -- hash key size in bytes: %u\n"
+ "\t -- redirection table size: %u\n"
+ "\t -- RSS offload flow type: 0x%"PRIx64"\n"
+ "\t -- minimum size of RX buffer: %u\n"
+ "\t -- maximum configurable length of RX packet: %u\n"
+ "\t -- maximum number of VFs: %u\n"
+ "\t -- maximum number of VMDq pools: %u\n"
+ "\t -- current number of RX queues: %u\n"
+ "\t -- max possible RX queues: %u\n"
+ "\t -- current number of TX queues: %u\n"
+ "\t -- max possible TX queues: %u\n"
+ "\t -- max segment number per packet of TX: %u\n"
+ "\t -- max segment number per MTU/TSO of TX: %u\n",
+ dev_info->max_mac_addrs, dev_info->max_hash_mac_addrs,
+ dev_info->hash_key_size, dev_info->reta_size,
+ dev_info->flow_type_rss_offloads,
+ dev_info->min_rx_bufsize, dev_info->max_rx_pktlen,
+ dev_info->max_vfs, dev_info->max_vmdq_pools,
+ dev_info->nb_rx_queues, dev_info->max_rx_queues,
+ dev_info->nb_tx_queues, dev_info->max_tx_queues,
+ dev_info->tx_desc_lim.nb_seg_max,
+ dev_info->tx_desc_lim.nb_mtu_seg_max);
+}
+
+static void
+show_port_rss_info(uint16_t port_id, struct rte_eth_dev_info *dev_info)
+{
+#define RSS_HASH_KEY_LENGTH 64
+ struct rte_eth_rss_conf rss_conf = {0};
+ uint8_t rss_key[RSS_HASH_KEY_LENGTH];
+ uint8_t hash_key_size;
+ uint64_t rss_hf;
+ uint8_t i;
+ int ret;
+
+ if (dev_info->hash_key_size > 0 &&
+ dev_info->hash_key_size <= sizeof(rss_key))
+ hash_key_size = dev_info->hash_key_size;
+ else
+ return;
+
+ rss_conf.rss_key = rss_key;
+ rss_conf.rss_key_len = hash_key_size;
+ ret = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
+ if (ret != 0)
+ return;
+
+ printf(" - RSS info\n");
+ rss_hf = rss_conf.rss_hf;
+ if (rss_hf == 0) {
+ printf( "\t -- RSS disabled");
+ return;
+ }
+ ret = printf("\t -- RSS functions: ");
+
+ for (i = 0; rss_type_table[i].str; i++)
+ if (rss_hf & rss_type_table[i].rss_type)
+ printf("%s ", rss_type_table[i].str);
+ printf("\n");
+ printf("\t -- RSS key: ");
+
+ for (i = 0; i < rss_conf.rss_key_len; i++)
+ printf("%02X", rss_conf.rss_key[i]);
+ printf("\n");
+}
+
+static void
+show_dev_speed_capability(uint32_t speed_capa)
+{
+ int size = sizeof(eth_speed_table) / sizeof(eth_speed_table[0]);
+ int i;
+
+ printf(" - Device Speed Capability: ");
+ for (i = 0; i < size; i++)
+ if (speed_capa & eth_speed_table[i].speed)
+ printf("%s ", eth_speed_table[i].str);
+
+ if (!(speed_capa & ETH_LINK_SPEED_FIXED)) {
+ printf("auto");
+ }
+
+ printf("\n");
+}
+
+static void
+show_dev_rxtx_burst_mode(uint16_t port_id)
+{
+ struct rte_eth_burst_mode rx_mode;
+ struct rte_eth_burst_mode tx_mode;
+
+ memset(&rx_mode, 0, sizeof(rx_mode));
+ memset(&tx_mode, 0, sizeof(tx_mode));
+
+ if (rte_eth_rx_burst_mode_get(port_id, 0, &rx_mode) == 0 &&
+ rte_eth_tx_burst_mode_get(port_id, 0, &tx_mode) == 0) {
+ printf(" - Burst mode:\n");
+ printf( "\t -- Rx burst mode: %s%s\n"
+ "\t -- Tx burst mode: %s%s\n",
+ rx_mode.info,
+ rx_mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
+ " (per queue)" : "",
+ tx_mode.info,
+ tx_mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
+ " (per queue)" : "");
+ }
+}
+
static void
show_port(void)
{
@@ -714,6 +918,7 @@ show_port(void)
struct rte_eth_fc_conf fc_conf;
struct rte_ether_addr mac;
struct rte_eth_dev_owner owner;
+ int vlan_offload;
/* Skip if port is not in mask */
if ((enabled_port_mask & (1ul << i)) == 0)
@@ -792,6 +997,25 @@ show_port(void)
if (ret == 0)
printf("\t -- mtu (%d)\n", mtu);
+ if (dev_info.rx_offload_capa != 0) {
+ printf(" - device capability Rx");
+ show_offloads(dev_info.rx_offload_capa,
+ rte_eth_dev_rx_offload_name);
+ printf("\n");
+ }
+
+ if (dev_info.tx_offload_capa != 0) {
+ printf(" - device capability Tx");
+ show_offloads(dev_info.tx_offload_capa,
+ rte_eth_dev_tx_offload_name);
+ printf("\n");
+ }
+
+ show_dev_speed_capability(dev_info.speed_capa);
+ show_dev_info(&dev_info);
+ show_port_rss_info(i, &dev_info);
+ show_dev_rxtx_burst_mode(i);
+
for (j = 0; j < dev_info.nb_rx_queues; j++) {
struct rte_eth_rxq_info queue_info;
int count;
@@ -870,12 +1094,38 @@ show_port(void)
}
}
+ vlan_offload = rte_eth_dev_get_vlan_offload(i);
+ printf(" - VLAN offload: 0x%x\n", vlan_offload);
+
#ifdef RTE_LIB_SECURITY
show_security_context(i, true);
#endif
}
}
+static void
+show_port_private_info(void)
+{
+ int i;
+
+ snprintf(bdr_str, MAX_STRING_LEN, " show - Port PMD Private ");
+ STATS_BDR_STR(10, bdr_str);
+
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+ /* Skip if port is not in mask */
+ if ((enabled_port_mask & (1ul << i)) == 0)
+ continue;
+
+ /* Skip if port is unused */
+ if (!rte_eth_dev_is_valid_port(i))
+ continue;
+
+ snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i);
+ STATS_BDR_STR(5, bdr_str);
+ rte_eth_dev_priv_dump(stdout, i);
+ }
+}
+
static void
display_nodecap_info(int is_leaf, struct rte_tm_node_capabilities *cap)
{
@@ -1534,6 +1784,8 @@ main(int argc, char **argv)
/* show information for PMD */
if (enable_shw_port)
show_port();
+ if (enable_shw_port_priv)
+ show_port_private_info();
if (enable_shw_tm)
show_tm();
if (enable_shw_crypto)
@@ -1546,6 +1798,8 @@ main(int argc, char **argv)
iter_mempool(mempool_iter_name);
if (enable_dump_regs)
dump_regs(dump_regs_file_prefix);
+ if (enable_dump_regs)
+ dump_regs(dump_regs_file_prefix);
RTE_ETH_FOREACH_DEV(i)
rte_eth_dev_close(i);
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 0f5e9efb3c..a6d617a400 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -5514,7 +5514,7 @@ hns3_get_current_fc_mode(struct rte_eth_dev *dev)
return hns3_get_autoneg_fc_mode(hw);
}
-static int
+int
hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
{
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -6732,6 +6732,7 @@ static const struct eth_dev_ops hns3_eth_dev_ops = {
.timesync_adjust_time = hns3_timesync_adjust_time,
.timesync_read_time = hns3_timesync_read_time,
.timesync_write_time = hns3_timesync_write_time,
+ .eth_dev_priv_dump = hns3_eth_dev_priv_dump,
};
static const struct hns3_reset_ops hns3_reset_ops = {
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 678ee6cf97..24b39f1f1f 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -1068,6 +1068,8 @@ hns3_test_and_clear_bit(unsigned int nr, volatile uint64_t *addr)
return __atomic_fetch_and(addr, ~mask, __ATOMIC_RELAXED) & mask;
}
+int
+hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf);
uint32_t hns3_get_speed_capa(struct hns3_hw *hw);
int hns3_buffer_alloc(struct hns3_hw *hw);
@@ -1093,6 +1095,7 @@ int hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts);
int hns3_timesync_write_time(struct rte_eth_dev *dev,
const struct timespec *ts);
int hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);
+int hns3_eth_dev_priv_dump(FILE *file, struct rte_eth_dev *dev);
static inline bool
is_reset_pending(struct hns3_adapter *hns)
diff --git a/drivers/net/hns3/hns3_ethdev_dump.c b/drivers/net/hns3/hns3_ethdev_dump.c
new file mode 100644
index 0000000000..0d2b96f900
--- /dev/null
+++ b/drivers/net/hns3/hns3_ethdev_dump.c
@@ -0,0 +1,917 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 HiSilicon Limited
+ */
+
+#include <rte_kvargs.h>
+#include <rte_bus_pci.h>
+#include <ethdev_pci.h>
+#include <rte_pci.h>
+
+#include "hns3_common.h"
+#include "hns3_logs.h"
+#include "hns3_regs.h"
+#include "hns3_rxtx.h"
+
+static const char *
+get_adapter_state_name(uint32_t state)
+{
+ static const char *state_name[] = {
+ "UNINITIALIZED",
+ "INITIALIZED",
+ "CONFIGURING",
+ "CONFIGURED",
+ "STARTING",
+ "STARTED",
+ "STOPPING",
+ "CLOSING",
+ "CLOSED",
+ "REMOVED",
+ "NSTATES"
+ };
+
+ if (state < RTE_DIM(state_name))
+ return state_name[state];
+ else
+ return "unknown";
+}
+
+static const char *
+get_io_func_hint_name(uint32_t hint)
+{
+ switch (hint) {
+ case HNS3_IO_FUNC_HINT_NONE:
+ return "none";
+ case HNS3_IO_FUNC_HINT_VEC:
+ return "vec";
+ case HNS3_IO_FUNC_HINT_SVE:
+ return "sve";
+ case HNS3_IO_FUNC_HINT_SIMPLE:
+ return "simple";
+ case HNS3_IO_FUNC_HINT_COMMON:
+ return "common";
+ default:
+ return "unknown";
+ }
+}
+
+static void
+get_dev_mac_info(FILE *file, struct hns3_adapter *hns)
+{
+ struct hns3_hw *hw = &hns->hw;
+ struct hns3_pf *pf = &hns->pf;
+
+ fprintf(file, " - MAC Info:\n");
+ fprintf(file,
+ "\t -- query_type=%u\n"
+ "\t -- supported_speed=0x%x\n"
+ "\t -- advertising=0x%x\n"
+ "\t -- lp_advertising=0x%x\n"
+ "\t -- support_autoneg=%s\n"
+ "\t -- support_fc_autoneg=%s\n",
+ hw->mac.query_type,
+ hw->mac.supported_speed,
+ hw->mac.advertising,
+ hw->mac.lp_advertising,
+ hw->mac.support_autoneg != 0 ? "Yes" : "No",
+ pf->support_fc_autoneg ? "Yes" : "No");
+}
+
+static void
+get_dev_feature_capability(FILE *file, struct hns3_hw *hw)
+{
+ const char * const caps_name[] = {
+ "DCB",
+ "COPPER",
+ "FD QUEUE REGION",
+ "PTP",
+ "TX PUSH",
+ "INDEP TXRX",
+ "STASH",
+ "SIMPLE BD",
+ "RXD Advanced Layout",
+ "OUTER UDP CKSUM",
+ "RAS IMP",
+ "TM",
+ "VF VLAN FILTER MOD",
+ };
+ uint32_t i;
+
+ fprintf(file, " - Dev Capability:\n");
+ for (i = 0; i < RTE_DIM(caps_name); i++)
+ fprintf(file, "\t -- support %s: %s\n", caps_name[i],
+ hw->capability & BIT(i) ? "yes" : "no");
+}
+
+static const char *
+get_fdir_tuple_name(uint32_t index)
+{
+ static const char *tuple_name[] = {
+ "outer_dst_mac",
+ "outer_src_mac",
+ "outer_vlan_1st_tag",
+ "outer_vlan_2st_tag",
+ "outer_eth_type",
+ "outer_l2_rsv",
+ "outer_ip_tos",
+ "outer_ip_proto",
+ "outer_src_ip",
+ "outer_dst_ip",
+ "outer_l3_rsv",
+ "outer_src_port",
+ "outer_dst_port",
+ "outer_l4_rsv",
+ "outer_tun_vni",
+ "outer_tun_flow_id",
+ "inner_dst_mac",
+ "inner_src_mac",
+ "inner_vlan_tag1",
+ "inner_vlan_tag2",
+ "inner_eth_type",
+ "inner_l2_rsv",
+ "inner_ip_tos",
+ "inner_ip_proto",
+ "inner_src_ip",
+ "inner_dst_ip",
+ "inner_l3_rsv",
+ "inner_src_port",
+ "inner_dst_port",
+ "inner_sctp_tag",
+ };
+ if (index < RTE_DIM(tuple_name))
+ return tuple_name[index];
+ else
+ return "unknown";
+}
+
+static void
+get_fdir_basic_info(FILE *file, struct hns3_pf *pf)
+{
+#define TMPBUF_SIZE 2048
+#define PERLINE_TUPLE_NAMES 4
+ struct hns3_fd_cfg *fdcfg = &pf->fdir.fd_cfg;
+ char tmpbuf[TMPBUF_SIZE] = {0};
+ uint32_t i, count = 0;
+
+ fprintf(file, " - Fdir Info:\n");
+ fprintf(file,
+ "\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n"
+ "\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n"
+ "\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n"
+ "\t -- active_tuples:\n",
+ fdcfg->fd_mode, fdcfg->max_key_length,
+ fdcfg->rule_num[HNS3_FD_STAGE_1],
+ fdcfg->cnt_num[HNS3_FD_STAGE_1],
+ fdcfg->key_cfg[HNS3_FD_STAGE_1].key_sel,
+ fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active,
+ fdcfg->key_cfg[HNS3_FD_STAGE_1].meta_data_active,
+ fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_sipv6_word_en,
+ fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en,
+ fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en,
+ fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en);
+
+ for (i = 0; i < MAX_TUPLE; i++) {
+ if (!(fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active & BIT(i)))
+ continue;
+ if (count % PERLINE_TUPLE_NAMES == 0)
+ fprintf(file, "\t ");
+ fprintf(file, " %s", get_fdir_tuple_name(i));
+ count++;
+ if (count % PERLINE_TUPLE_NAMES == 0)
+ fprintf(file, "\n");
+ }
+ if (count % PERLINE_TUPLE_NAMES)
+ fprintf(file, "\n");
+
+ fprintf(file, "%s", tmpbuf);
+}
+
+static void
+get_device_basic_info(FILE *file, struct rte_eth_dev *dev)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = &hns->hw;
+
+ fprintf(file,
+ " - Device Base Info:\n"
+ "\t -- name: %s\n"
+ "\t -- adapter_state=%s\n"
+ "\t -- nb_rx_queues=%u nb_tx_queues=%u\n"
+ "\t -- total_tqps_num=%u tqps_num=%u intr_tqps_num=%u\n"
+ "\t -- rss_size_max=%u alloc_rss_size=%u tx_qnum_per_tc=%u\n"
+ "\t -- min_tx_pkt_len=%u intr_mapping_mode=%u vlan_mode=%u\n"
+ "\t -- tso_mode=%u max_non_tso_bd_num=%u\n"
+ "\t -- max_tm_rate=%u Mbps\n"
+ "\t -- set link down: %s\n"
+ "\t -- rx_func_hint=%s tx_func_hint=%s\n"
+ "\t -- dev_flags: lsc=%d\n"
+ "\t -- intr_conf: lsc=%u rxq=%u\n",
+ dev->data->name,
+ get_adapter_state_name(hw->adapter_state),
+ dev->data->nb_rx_queues, dev->data->nb_tx_queues,
+ hw->total_tqps_num, hw->tqps_num, hw->intr_tqps_num,
+ hw->rss_size_max, hw->alloc_rss_size, hw->tx_qnum_per_tc,
+ hw->min_tx_pkt_len, hw->intr.mapping_mode, hw->vlan_mode,
+ hw->tso_mode, hw->max_non_tso_bd_num,
+ hw->max_tm_rate,
+ hw->set_link_down ? "Yes" : "No",
+ get_io_func_hint_name(hns->rx_func_hint),
+ get_io_func_hint_name(hns->tx_func_hint),
+ !!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC),
+ dev->data->dev_conf.intr_conf.lsc,
+ dev->data->dev_conf.intr_conf.rxq);
+}
+
+/*
+ * Note: caller must make sure queue_id < nb_queues
+ * nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
+ * eth_dev->data->nb_tx_queues)
+ */
+static struct hns3_rx_queue *
+get_rx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = &hns->hw;
+ unsigned int offset;
+ void **rx_queues;
+
+ if (queue_id < dev->data->nb_rx_queues) {
+ rx_queues = dev->data->rx_queues;
+ offset = queue_id;
+ } else {
+ /*
+ * For kunpeng930, fake queue is not exist. But since the queues
+ * are usually accessd in pairs, this branch may still exist.
+ */
+ if (hns3_dev_get_support(hw, INDEP_TXRX))
+ return NULL;
+
+ rx_queues = hw->fkq_data.rx_queues;
+ offset = queue_id - dev->data->nb_rx_queues;
+ }
+
+ if (rx_queues != NULL && rx_queues[offset] != NULL)
+ return rx_queues[offset];
+
+ hns3_err(hw, "Detect rx_queues is NULL!\n");
+ return NULL;
+}
+
+/*
+ * Note: caller must make sure queue_id < nb_queues
+ * nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
+ * eth_dev->data->nb_tx_queues)
+ */
+static struct hns3_tx_queue *
+get_tx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = &hns->hw;
+ unsigned int offset;
+ void **tx_queues;
+
+ if (queue_id < dev->data->nb_tx_queues) {
+ tx_queues = dev->data->tx_queues;
+ offset = queue_id;
+ } else {
+ /*
+ * For kunpeng930, fake queue is not exist. But since the queues
+ * are usually accessd in pairs, this branch may still exist.
+ */
+ if (hns3_dev_get_support(hw, INDEP_TXRX))
+ return NULL;
+ tx_queues = hw->fkq_data.tx_queues;
+ offset = queue_id - dev->data->nb_tx_queues;
+ }
+
+ if (tx_queues != NULL && tx_queues[offset] != NULL)
+ return tx_queues[offset];
+
+ hns3_err(hw, "Detect tx_queues is NULL!\n");
+ return NULL;
+}
+
+static void
+get_rxtx_fake_queue_info(FILE *file, struct rte_eth_dev *dev)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns);
+ struct hns3_rx_queue *rxq;
+ struct hns3_tx_queue *txq;
+ unsigned int queue_id;
+
+ if (dev->data->nb_rx_queues != dev->data->nb_tx_queues &&
+ !hns3_dev_get_support(hw, INDEP_TXRX)) {
+ queue_id = RTE_MIN(dev->data->nb_rx_queues,
+ dev->data->nb_tx_queues);
+ rxq = get_rx_queue(dev, queue_id);
+ if (rxq == NULL)
+ return;
+ txq = get_tx_queue(dev, queue_id);
+ if (txq == NULL)
+ return;
+ fprintf(file,
+ "\t -- first fake_queue rxtx info:\n"
+ "\t rx: port=%u nb_desc=%u free_thresh=%u\n"
+ "\t tx: port=%u nb_desc=%u\n",
+ rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
+ txq->port_id, txq->nb_tx_desc);
+ }
+}
+
+static void
+get_queue_enable_state(struct hns3_hw *hw, uint32_t *queue_state,
+ uint32_t nb_queues, bool is_rxq)
+{
+#define STATE_SIZE (sizeof(*queue_state) * CHAR_BIT)
+ uint32_t queue_en_reg;
+ uint32_t reg_offset;
+ uint32_t state;
+ uint32_t i;
+
+ queue_en_reg = is_rxq ? HNS3_RING_RX_EN_REG : HNS3_RING_TX_EN_REG;
+ for (i = 0; i < nb_queues; i++) {
+ reg_offset = hns3_get_tqp_reg_offset(i);
+ state = hns3_read_dev(hw, reg_offset + HNS3_RING_EN_REG);
+ if (hns3_dev_get_support(hw, INDEP_TXRX))
+ state = state && hns3_read_dev(hw, reg_offset +
+ queue_en_reg);
+ hns3_set_bit(queue_state[i / STATE_SIZE],
+ i % STATE_SIZE, state);
+ }
+}
+
+static void
+print_queue_state_perline(FILE *file, const uint32_t *queue_state,
+ uint32_t nb_queues, uint32_t line_num)
+{
+#define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
+ uint32_t qid = line_num * NUM_QUEUE_PER_LINE;
+ uint32_t j;
+
+ for (j = 0; j < NUM_QUEUE_PER_LINE; j++) {
+ fprintf(file, "%1lx", hns3_get_bit(queue_state[line_num], j));
+
+ if (qid % CHAR_BIT == CHAR_BIT - 1) {
+ fprintf(file, "%s",
+ j == NUM_QUEUE_PER_LINE - 1 ? "\n" : ":");
+ }
+ qid++;
+ if (qid >= nb_queues) {
+ fprintf(file, "\n");
+ break;
+ }
+ }
+}
+
+static void
+display_queue_enable_state(FILE *file, const uint32_t *queue_state,
+ uint32_t nb_queues, bool is_rxq)
+{
+#define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
+ uint32_t i;
+
+ if (nb_queues == 0) {
+ fprintf(file, "\t %s queue number is 0\n",
+ is_rxq ? "Rx" : "Tx");
+ return;
+ }
+
+ fprintf(file, "\t %s queue id | enable state bitMap\n",
+ is_rxq ? "rx" : "tx");
+
+ for (i = 0; i < (nb_queues - 1) / NUM_QUEUE_PER_LINE + 1; i++) {
+ uint32_t line_end = (i + 1) * NUM_QUEUE_PER_LINE - 1;
+ uint32_t line_start = i * NUM_QUEUE_PER_LINE;
+ fprintf(file, "\t %04u - %04u | ", line_start,
+ nb_queues - 1 > line_end ? line_end : nb_queues - 1);
+
+
+ print_queue_state_perline(file, queue_state, nb_queues, i);
+ }
+}
+
+static void
+get_rxtx_queue_enable_state(FILE *file, struct rte_eth_dev *dev)
+{
+#define MAX_TQP_NUM 1280
+#define QUEUE_BITMAP_SIZE (MAX_TQP_NUM / 32)
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t rx_queue_state[QUEUE_BITMAP_SIZE] = {0};
+ uint32_t tx_queue_state[QUEUE_BITMAP_SIZE] = {0};
+ uint32_t nb_rx_queues;
+ uint32_t nb_tx_queues;
+
+ nb_rx_queues = dev->data->nb_rx_queues;
+ nb_tx_queues = dev->data->nb_tx_queues;
+
+ fprintf(file, "\t -- enable state:\n");
+ get_queue_enable_state(hw, rx_queue_state, nb_rx_queues, true);
+ display_queue_enable_state(file, rx_queue_state, nb_rx_queues,
+ true);
+
+ get_queue_enable_state(hw, tx_queue_state, nb_tx_queues, false);
+ display_queue_enable_state(file, tx_queue_state, nb_tx_queues,
+ false);
+}
+
+static void
+get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev)
+{
+ struct hns3_rx_queue *rxq;
+ struct hns3_tx_queue *txq;
+ unsigned int queue_id = 0;
+
+ rxq = get_rx_queue(dev, queue_id);
+ if (rxq == NULL)
+ return;
+ txq = get_tx_queue(dev, queue_id);
+ if (txq == NULL)
+ return;
+ fprintf(file," - Rx/Tx Queue Info:\n");
+ fprintf(file,
+ "\t -- nb_rx_queues=%u nb_tx_queues=%u, "
+ "first queue rxtx info:\n"
+ "\t rx: port=%u nb_desc=%u free_thresh=%u\n"
+ "\t tx: port=%u nb_desc=%u\n"
+ "\t -- tx push: %s\n",
+ dev->data->nb_rx_queues,
+ dev->data->nb_tx_queues,
+ rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
+ txq->port_id, txq->nb_tx_desc,
+ txq->tx_push_enable ? "enabled" : "disabled");
+
+ get_rxtx_fake_queue_info(file, dev);
+ get_rxtx_queue_enable_state(file, dev);
+}
+
+static int
+get_vlan_filter_cfg(FILE *file, struct hns3_hw *hw)
+{
+#define HNS3_FILTER_TYPE_VF 0
+#define HNS3_FILTER_TYPE_PORT 1
+#define HNS3_FILTER_FE_NIC_INGRESS_B BIT(0)
+#define HNS3_FILTER_FE_NIC_EGRESS_B BIT(1)
+ struct hns3_vlan_filter_ctrl_cmd *req;
+ struct hns3_cmd_desc desc;
+ uint8_t i;
+ int ret;
+
+ static const uint32_t vlan_filter_type[] = {
+ HNS3_FILTER_TYPE_PORT,
+ HNS3_FILTER_TYPE_VF
+ };
+
+ for (i = 0; i < RTE_DIM(vlan_filter_type); i++) {
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_FILTER_CTRL,
+ true);
+ req = (struct hns3_vlan_filter_ctrl_cmd *)desc.data;
+ req->vlan_type = vlan_filter_type[i];
+ req->vf_id = HNS3_PF_FUNC_ID;
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret != 0) {
+ hns3_err(hw,
+ "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
+ ret, 1, rte_le_to_cpu_16(desc.opcode));
+ return ret;
+ }
+ fprintf(file,
+ "\t -- %s VLAN filter configuration\n"
+ "\t nic_ingress :%s\n"
+ "\t nic_egress :%s\n",
+ req->vlan_type == HNS3_FILTER_TYPE_PORT ?
+ "Port" : "VF",
+ req->vlan_fe & HNS3_FILTER_FE_NIC_INGRESS_B ?
+ "Enable" : "Disable",
+ req->vlan_fe & HNS3_FILTER_FE_NIC_EGRESS_B ?
+ "Enable" : "Disable");
+ }
+
+ return 0;
+}
+
+static int
+get_vlan_rx_offload_cfg(FILE *file, struct hns3_hw *hw)
+{
+ struct hns3_vport_vtag_rx_cfg_cmd *req;
+ struct hns3_cmd_desc desc;
+ uint16_t vport_id;
+ uint8_t bitmap;
+ int ret;
+
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_RX_CFG, true);
+ req = (struct hns3_vport_vtag_rx_cfg_cmd *)desc.data;
+ vport_id = HNS3_PF_FUNC_ID;
+ req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;
+ bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);
+ req->vf_bitmap[req->vf_offset] = bitmap;
+
+ /*
+ * current version VF is not supported when PF is driven by DPDK driver,
+ * just need to configure rx parameters for PF vport.
+ */
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret != 0) {
+ hns3_err(hw,
+ "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
+ ret, 1, rte_le_to_cpu_16(desc.opcode));
+ return ret;
+ }
+
+ fprintf(file,
+ "\t -- RX VLAN configuration\n"
+ "\t vlan1_strip_en :%s\n"
+ "\t vlan2_strip_en :%s\n"
+ "\t vlan1_vlan_prionly :%s\n"
+ "\t vlan2_vlan_prionly :%s\n"
+ "\t vlan1_strip_discard :%s\n"
+ "\t vlan2_strip_discard :%s\n",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_REM_TAG1_EN_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_REM_TAG2_EN_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_SHOW_TAG1_EN_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_SHOW_TAG2_EN_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_DISCARD_TAG1_EN_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_DISCARD_TAG2_EN_B) ? "Enable" : "Disable");
+
+ return 0;
+}
+
+static void
+parse_tx_vlan_cfg(FILE *file, struct hns3_vport_vtag_tx_cfg_cmd *req)
+{
+#define VLAN_VID_MASK 0x0fff
+#define VLAN_PRIO_SHIFT 13
+
+ fprintf(file,
+ "\t -- TX VLAN configuration\n"
+ "\t accept_tag1 :%s\n"
+ "\t accept_untag1 :%s\n"
+ "\t insert_tag1_en :%s\n"
+ "\t default_vlan_tag1 = %d, qos = %d\n"
+ "\t accept_tag2 :%s\n"
+ "\t accept_untag2 :%s\n"
+ "\t insert_tag2_en :%s\n"
+ "\t default_vlan_tag2 = %d, qos = %d\n"
+ "\t vlan_shift_mode :%s\n",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_ACCEPT_TAG1_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_ACCEPT_UNTAG1_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_PORT_INS_TAG1_EN_B) ? "Enable" : "Disable",
+ req->def_vlan_tag1 & VLAN_VID_MASK,
+ req->def_vlan_tag1 >> VLAN_PRIO_SHIFT,
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_ACCEPT_TAG2_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_ACCEPT_UNTAG2_B) ? "Enable" : "Disable",
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_PORT_INS_TAG2_EN_B) ? "Enable" : "Disable",
+ req->def_vlan_tag2 & VLAN_VID_MASK,
+ req->def_vlan_tag2 >> VLAN_PRIO_SHIFT,
+ hns3_get_bit(req->vport_vlan_cfg,
+ HNS3_TAG_SHIFT_MODE_EN_B) ? "Enable" :
+ "Disable");
+}
+
+static int
+get_vlan_tx_offload_cfg(FILE *file, struct hns3_hw *hw)
+{
+ struct hns3_vport_vtag_tx_cfg_cmd *req;
+ struct hns3_cmd_desc desc;
+ uint16_t vport_id;
+ uint8_t bitmap;
+ int ret;
+
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_TX_CFG, true);
+ req = (struct hns3_vport_vtag_tx_cfg_cmd *)desc.data;
+ vport_id = HNS3_PF_FUNC_ID;
+ req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;
+ bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);
+ req->vf_bitmap[req->vf_offset] = bitmap;
+ /*
+ * current version VF is not supported when PF is driven by DPDK driver,
+ * just need to configure tx parameters for PF vport.
+ */
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret != 0) {
+ hns3_err(hw,
+ "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
+ ret, 1, rte_le_to_cpu_16(desc.opcode));
+ return ret;
+ }
+
+ parse_tx_vlan_cfg(file, req);
+
+ return 0;
+}
+
+static void
+get_port_pvid_info(FILE *file, struct hns3_hw *hw)
+{
+ fprintf(file, "\t -- pvid status: %s\n",
+ hw->port_base_vlan_cfg.state ? "on" : "off");
+}
+
+static void
+get_vlan_config_info(FILE *file, struct hns3_hw *hw)
+{
+ int ret;
+
+ fprintf(file," - VLAN Config Info:\n");
+ ret = get_vlan_filter_cfg(file, hw);
+ if (ret < 0)
+ return;
+
+ ret = get_vlan_rx_offload_cfg(file, hw);
+ if (ret < 0)
+ return;
+
+ ret = get_vlan_tx_offload_cfg(file, hw);
+ if (ret < 0)
+ return;
+
+ get_port_pvid_info(file, hw);
+}
+
+static void
+get_tm_conf_shaper_info(FILE *file, struct hns3_tm_conf *conf)
+{
+ struct hns3_shaper_profile_list *shaper_profile_list =
+ &conf->shaper_profile_list;
+ struct hns3_tm_shaper_profile *shaper_profile;
+
+ if (!conf->nb_shaper_profile)
+ return;
+
+ fprintf(file, " shaper_profile:\n");
+ TAILQ_FOREACH(shaper_profile, shaper_profile_list, node) {
+ fprintf(file,
+ " id=%u reference_count=%u peak_rate=%"PRIu64"Bps\n",
+ shaper_profile->shaper_profile_id,
+ shaper_profile->reference_count,
+ shaper_profile->profile.peak.rate);
+ }
+}
+
+static void
+get_tm_conf_port_node_info(FILE *file, struct hns3_tm_conf *conf)
+{
+ if (!conf->root)
+ return;
+
+ fprintf(file,
+ " port_node: \n"
+ " node_id=%u reference_count=%u shaper_profile_id=%d\n",
+ conf->root->id, conf->root->reference_count,
+ conf->root->shaper_profile ?
+ (int)conf->root->shaper_profile->shaper_profile_id : -1);
+}
+
+static void
+get_tm_conf_tc_node_info(FILE *file, struct hns3_tm_conf *conf)
+{
+ struct hns3_tm_node_list *tc_list = &conf->tc_list;
+ struct hns3_tm_node *tc_node[HNS3_MAX_TC_NUM];
+ struct hns3_tm_node *tm_node;
+ uint32_t tidx;
+
+ if (!conf->nb_tc_node)
+ return;
+
+ fprintf(file, " tc_node: \n");
+ memset(tc_node, 0, sizeof(tc_node));
+ TAILQ_FOREACH(tm_node, tc_list, node) {
+ tidx = hns3_tm_calc_node_tc_no(conf, tm_node->id);
+ if (tidx < HNS3_MAX_TC_NUM)
+ tc_node[tidx] = tm_node;
+ }
+
+ for (tidx = 0; tidx < HNS3_MAX_TC_NUM; tidx++) {
+ tm_node = tc_node[tidx];
+ if (tm_node == NULL)
+ continue;
+ fprintf(file,
+ " id=%u TC%u reference_count=%u parent_id=%d "
+ "shaper_profile_id=%d\n",
+ tm_node->id, hns3_tm_calc_node_tc_no(conf, tm_node->id),
+ tm_node->reference_count,
+ tm_node->parent ? (int)tm_node->parent->id : -1,
+ tm_node->shaper_profile ?
+ (int)tm_node->shaper_profile->shaper_profile_id : -1);
+ }
+}
+
+static void
+get_tm_conf_queue_format_info(FILE *file, struct hns3_tm_node **queue_node,
+ uint32_t *queue_node_tc, uint32_t nb_tx_queues)
+{
+#define PERLINE_QUEUES 32
+#define PERLINE_STRIDE 8
+#define LINE_BUF_SIZE 1024
+ uint32_t i, j, line_num, start_queue, end_queue;
+ char tmpbuf[LINE_BUF_SIZE] = {0};
+
+ line_num = (nb_tx_queues + PERLINE_QUEUES - 1) / PERLINE_QUEUES;
+ for (i = 0; i < line_num; i++) {
+ start_queue = i * PERLINE_QUEUES;
+ end_queue = (i + 1) * PERLINE_QUEUES - 1;
+ if (end_queue > nb_tx_queues - 1)
+ end_queue = nb_tx_queues - 1;
+ fprintf(file, " %04u - %04u | ", start_queue, end_queue);
+ for (j = start_queue; j < nb_tx_queues; j++) {
+ if (j >= end_queue + 1)
+ break;
+ if (j > start_queue && j % PERLINE_STRIDE == 0)
+ fprintf(file, ":");
+ fprintf(file, "%u",
+ queue_node[j] ? queue_node_tc[j] :
+ HNS3_MAX_TC_NUM);
+ }
+ fprintf(file, "%s\n", tmpbuf);
+ }
+}
+
+static void
+get_tm_conf_queue_node_info(FILE *file, struct hns3_tm_conf *conf,
+ uint32_t nb_tx_queues)
+{
+ struct hns3_tm_node_list *queue_list = &conf->queue_list;
+ uint32_t nb_queue_node = conf->nb_leaf_nodes_max + 1;
+ struct hns3_tm_node *queue_node[nb_queue_node];
+ uint32_t queue_node_tc[nb_queue_node];
+ struct hns3_tm_node *tm_node;
+
+ if (!conf->nb_queue_node)
+ return;
+
+ fprintf(file,
+ " queue_node: \n"
+ " tx queue id | mapped tc (8 mean node not exist)\n");
+
+ memset(queue_node, 0, sizeof(queue_node));
+ memset(queue_node_tc, 0, sizeof(queue_node_tc));
+ nb_tx_queues = RTE_MIN(nb_tx_queues, nb_queue_node);
+ TAILQ_FOREACH(tm_node, queue_list, node) {
+ if (tm_node->id >= nb_queue_node)
+ continue;
+ queue_node[tm_node->id] = tm_node;
+ queue_node_tc[tm_node->id] = tm_node->parent ?
+ hns3_tm_calc_node_tc_no(conf, tm_node->parent->id) : 0;
+ nb_tx_queues = RTE_MAX(nb_tx_queues, tm_node->id + 1);
+ }
+
+ get_tm_conf_queue_format_info(file, queue_node, queue_node_tc,
+ nb_tx_queues);
+}
+
+static void
+get_tm_conf_info(FILE *file, struct rte_eth_dev *dev)
+{
+ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct hns3_tm_conf *conf = &pf->tm_conf;
+
+ fprintf(file, " - TM config info:\n");
+ fprintf(file,
+ "\t -- nb_leaf_nodes_max=%u nb_nodes_max=%u\n"
+ "\t -- nb_shaper_profile=%u nb_tc_node=%u nb_queue_node=%u\n"
+ "\t -- committed=%u\n",
+ conf->nb_leaf_nodes_max, conf->nb_nodes_max,
+ conf->nb_shaper_profile, conf->nb_tc_node, conf->nb_queue_node,
+ conf->committed);
+
+ get_tm_conf_shaper_info(file, conf);
+ get_tm_conf_port_node_info(file, conf);
+ get_tm_conf_tc_node_info(file, conf);
+ get_tm_conf_queue_node_info(file, conf, dev->data->nb_tx_queues);
+}
+
+static void
+hns3_fc_mode_to_rxtx_pause(enum hns3_fc_mode fc_mode, bool *rx_pause,
+ bool *tx_pause)
+{
+ switch (fc_mode) {
+ case HNS3_FC_NONE:
+ *tx_pause = false;
+ *rx_pause = false;
+ break;
+ case HNS3_FC_RX_PAUSE:
+ *rx_pause = true;
+ *tx_pause = false;
+ break;
+ case HNS3_FC_TX_PAUSE:
+ *rx_pause = false;
+ *tx_pause = true;
+ break;
+ case HNS3_FC_FULL:
+ *rx_pause = true;
+ *tx_pause = true;
+ break;
+ default:
+ *rx_pause = false;
+ *tx_pause = false;
+ break;
+ }
+}
+
+static bool
+is_link_fc_mode(struct hns3_adapter *hns)
+{
+ struct hns3_hw *hw = &hns->hw;
+ struct hns3_pf *pf = &hns->pf;
+
+ if (hw->current_fc_status == HNS3_FC_STATUS_PFC)
+ return false;
+
+ if (hw->num_tc > 1 && !pf->support_multi_tc_pause)
+ return false;
+
+ return true;
+}
+
+static void
+get_link_fc_info(FILE *file, struct rte_eth_dev *dev)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = &hns->hw;
+ struct rte_eth_fc_conf fc_conf;
+ bool rx_pause1;
+ bool tx_pause1;
+ bool rx_pause2;
+ bool tx_pause2;
+ int ret;
+
+ if (!is_link_fc_mode(hns))
+ return;
+
+ ret = hns3_flow_ctrl_get(dev, &fc_conf);
+ if (ret) {
+ fprintf(file, "get device flow control info fail!\n");
+ return;
+ }
+
+ hns3_fc_mode_to_rxtx_pause(hw->requested_fc_mode,
+ &rx_pause1, &tx_pause1);
+ hns3_fc_mode_to_rxtx_pause((enum hns3_fc_mode)fc_conf.mode,
+ &rx_pause2, &tx_pause2);
+
+ fprintf(file,
+ "\t -- link_fc_info:\n"
+ "\t Requested fc:\n"
+ "\t Rx: %s\n"
+ "\t Tx: %s\n"
+ "\t Current fc:\n"
+ "\t Rx: %s\n"
+ "\t Tx: %s\n"
+ "\t Autonegotiate: %s\n"
+ "\t Pause time: 0x%x\n",
+ rx_pause1 ? "On" : "Off", tx_pause1 ? "On" : "Off",
+ rx_pause2 ? "On" : "Off", tx_pause2 ? "On" : "Off",
+ fc_conf.autoneg == ETH_LINK_AUTONEG ? "On" : "Off",
+ fc_conf.pause_time);
+}
+
+static void
+get_flow_ctrl_info(FILE *file, struct rte_eth_dev *dev)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = &hns->hw;
+
+ fprintf(file, " - Flow Ctrl Info:\n");
+ fprintf(file,
+ "\t -- fc_common_info:\n"
+ "\t current_fc_status=%u\n"
+ "\t requested_fc_mode=%u\n",
+ hw->current_fc_status,
+ hw->requested_fc_mode);
+
+ get_link_fc_info(file, dev);
+}
+
+int
+hns3_eth_dev_priv_dump(FILE *file, struct rte_eth_dev *dev)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = &hns->hw;
+
+ get_device_basic_info(file, dev);
+ get_dev_feature_capability(file, hw);
+
+ /* VF is only support dumping basic info and feaure capability */
+ if (hns->is_vf)
+ return 0;
+
+ get_dev_mac_info(file, hns);
+ get_rxtx_queue_info(file, dev);
+ get_vlan_config_info(file, hw);
+ get_fdir_basic_info(file, &hns->pf);
+ get_tm_conf_info(file, dev);
+ get_flow_ctrl_info(file, dev);
+
+ return 0;
+}
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index f443d71039..7a822768c2 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -2290,6 +2290,7 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = {
.get_reg = hns3_get_regs,
.dev_supported_ptypes_get = hns3_dev_supported_ptypes_get,
.tx_done_cleanup = hns3_tx_done_cleanup,
+ .eth_dev_priv_dump = hns3_eth_dev_priv_dump,
};
static const struct hns3_reset_ops hns3vf_reset_ops = {
diff --git a/drivers/net/hns3/meson.build b/drivers/net/hns3/meson.build
index 8a4c7cc100..665b2afedf 100644
--- a/drivers/net/hns3/meson.build
+++ b/drivers/net/hns3/meson.build
@@ -30,6 +30,7 @@ sources = files(
'hns3_tm.c',
'hns3_ptp.c',
'hns3_common.c',
+ 'hns3_ethdev_dump.c',
)
deps += ['hash']
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index d95605a355..e75ff3f15b 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -990,6 +990,20 @@ typedef int (*eth_representor_info_get_t)(struct rte_eth_dev *dev,
typedef int (*eth_rx_metadata_negotiate_t)(struct rte_eth_dev *dev,
uint64_t *features);
+/**
+ * @internal
+ * Get ethdev private info.
+ *
+ * @param file
+ * A pointer to a file for output.
+ * @param dev
+ * Port (ethdev) handle.
+ *
+ * @return
+ * Negative errno value on error, positive value on success.
+ */
+typedef int (*eth_dev_priv_dump_t)(FILE *file, struct rte_eth_dev *dev);
+
/**
* @internal A structure containing the functions exported by an Ethernet driver.
*/
@@ -1186,6 +1200,9 @@ struct eth_dev_ops {
* kinds of metadata to the PMD
*/
eth_rx_metadata_negotiate_t rx_metadata_negotiate;
+
+ /** Dump ethdev private info */
+ eth_dev_priv_dump_t eth_dev_priv_dump;
};
/**
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 29b5ee32b4..7d755c6b04 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6487,6 +6487,21 @@ rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features)
(*dev->dev_ops->rx_metadata_negotiate)(dev, features));
}
+int
+rte_eth_dev_priv_dump(FILE *file, uint16_t port_id)
+{
+ struct rte_eth_dev *dev;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ dev = &rte_eth_devices[port_id];
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->eth_dev_priv_dump, -ENOTSUP);
+ ret = (*dev->dev_ops->eth_dev_priv_dump)(file, dev);
+
+ return ret;
+}
+
RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
RTE_INIT(ethdev_init_telemetry)
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 096b676fc1..62a3bb5d80 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5888,6 +5888,22 @@ rte_eth_tx_buffer(uint16_t port_id, uint16_t queue_id,
return rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
}
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get ethdev private info.
+ *
+ * @param file
+ * A pointer to a file for output.
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @return
+ * Negative errno value on error, positive value on success.
+ */
+__rte_experimental
+int rte_eth_dev_priv_dump(FILE *file, uint16_t port_id);
+
#ifdef __cplusplus
}
#endif
--
2.33.0
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] dpdk: show dev basic info
2022-03-04 1:22 ` [PATCH] dpdk: show dev basic info Min Hu (Connor)
@ 2022-03-04 1:25 ` Min Hu (Connor)
0 siblings, 0 replies; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:25 UTC (permalink / raw)
To: dev
Cc: Maryam Tahhan, Reshma Pattan, Yisen Zhuang, Lijun Ou,
Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
Sorry, this patch should be abandoned.
在 2022/3/4 9:22, Min Hu (Connor) 写道:
> version 1
>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
> app/proc-info/main.c | 254 ++++++++
> drivers/net/hns3/hns3_ethdev.c | 3 +-
> drivers/net/hns3/hns3_ethdev.h | 3 +
> drivers/net/hns3/hns3_ethdev_dump.c | 917 ++++++++++++++++++++++++++++
> drivers/net/hns3/hns3_ethdev_vf.c | 1 +
> drivers/net/hns3/meson.build | 1 +
> lib/ethdev/ethdev_driver.h | 17 +
> lib/ethdev/rte_ethdev.c | 15 +
> lib/ethdev/rte_ethdev.h | 16 +
> 9 files changed, 1226 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/hns3/hns3_ethdev_dump.c
>
> diff --git a/app/proc-info/main.c b/app/proc-info/main.c
> index a4271047e6..8644edfa7d 100644
> --- a/app/proc-info/main.c
> +++ b/app/proc-info/main.c
> @@ -47,6 +47,12 @@
> #define STATS_BDR_STR(w, s) printf("%.*s%s%.*s\n", w, \
> STATS_BDR_FMT, s, w, STATS_BDR_FMT)
>
> +/** Information for a given RSS type. */
> +struct rss_type_info {
> + const char *str; /**< Type name. */
> + uint64_t rss_type; /**< Type value. */
> +};
> +
> /**< mask of enabled ports */
> static unsigned long enabled_port_mask;
> /**< Enable stats. */
> @@ -81,6 +87,8 @@ static char bdr_str[MAX_STRING_LEN];
>
> /**< Enable show port. */
> static uint32_t enable_shw_port;
> +/**< Enable show port. */
> +static uint32_t enable_shw_port_priv;
> /**< Enable show tm. */
> static uint32_t enable_shw_tm;
> /**< Enable show crypto. */
> @@ -98,6 +106,84 @@ static char *mempool_iter_name;
> static uint32_t enable_dump_regs;
> static char *dump_regs_file_prefix;
>
> +static const struct rss_type_info rss_type_table[] = {
> + { "all", RTE_ETH_RSS_ETH | RTE_ETH_RSS_VLAN | RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP |
> + RTE_ETH_RSS_UDP | RTE_ETH_RSS_SCTP | RTE_ETH_RSS_L2_PAYLOAD |
> + RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_ESP | RTE_ETH_RSS_AH | RTE_ETH_RSS_PFCP |
> + RTE_ETH_RSS_GTPU | RTE_ETH_RSS_ECPRI | RTE_ETH_RSS_MPLS},
> + { "none", 0 },
> + { "eth", RTE_ETH_RSS_ETH },
> + { "l2-src-only", RTE_ETH_RSS_L2_SRC_ONLY },
> + { "l2-dst-only", RTE_ETH_RSS_L2_DST_ONLY },
> + { "vlan", RTE_ETH_RSS_VLAN },
> + { "s-vlan", RTE_ETH_RSS_S_VLAN },
> + { "c-vlan", RTE_ETH_RSS_C_VLAN },
> + { "ipv4", RTE_ETH_RSS_IPV4 },
> + { "ipv4-frag", RTE_ETH_RSS_FRAG_IPV4 },
> + { "ipv4-tcp", RTE_ETH_RSS_NONFRAG_IPV4_TCP },
> + { "ipv4-udp", RTE_ETH_RSS_NONFRAG_IPV4_UDP },
> + { "ipv4-sctp", RTE_ETH_RSS_NONFRAG_IPV4_SCTP },
> + { "ipv4-other", RTE_ETH_RSS_NONFRAG_IPV4_OTHER },
> + { "ipv6", RTE_ETH_RSS_IPV6 },
> + { "ipv6-frag", RTE_ETH_RSS_FRAG_IPV6 },
> + { "ipv6-tcp", RTE_ETH_RSS_NONFRAG_IPV6_TCP },
> + { "ipv6-udp", RTE_ETH_RSS_NONFRAG_IPV6_UDP },
> + { "ipv6-sctp", RTE_ETH_RSS_NONFRAG_IPV6_SCTP },
> + { "ipv6-other", RTE_ETH_RSS_NONFRAG_IPV6_OTHER },
> + { "l2-payload", RTE_ETH_RSS_L2_PAYLOAD },
> + { "ipv6-ex", RTE_ETH_RSS_IPV6_EX },
> + { "ipv6-tcp-ex", RTE_ETH_RSS_IPV6_TCP_EX },
> + { "ipv6-udp-ex", RTE_ETH_RSS_IPV6_UDP_EX },
> + { "port", RTE_ETH_RSS_PORT },
> + { "vxlan", RTE_ETH_RSS_VXLAN },
> + { "geneve", RTE_ETH_RSS_GENEVE },
> + { "nvgre", RTE_ETH_RSS_NVGRE },
> + { "ip", RTE_ETH_RSS_IP },
> + { "udp", RTE_ETH_RSS_UDP },
> + { "tcp", RTE_ETH_RSS_TCP },
> + { "sctp", RTE_ETH_RSS_SCTP },
> + { "tunnel", RTE_ETH_RSS_TUNNEL },
> + { "l3-pre32", RTE_ETH_RSS_L3_PRE32 },
> + { "l3-pre40", RTE_ETH_RSS_L3_PRE40 },
> + { "l3-pre48", RTE_ETH_RSS_L3_PRE48 },
> + { "l3-pre56", RTE_ETH_RSS_L3_PRE56 },
> + { "l3-pre64", RTE_ETH_RSS_L3_PRE64 },
> + { "l3-pre96", RTE_ETH_RSS_L3_PRE96 },
> + { "l3-src-only", RTE_ETH_RSS_L3_SRC_ONLY },
> + { "l3-dst-only", RTE_ETH_RSS_L3_DST_ONLY },
> + { "l4-src-only", RTE_ETH_RSS_L4_SRC_ONLY },
> + { "l4-dst-only", RTE_ETH_RSS_L4_DST_ONLY },
> + { "esp", RTE_ETH_RSS_ESP },
> + { "ah", RTE_ETH_RSS_AH },
> + { "l2tpv3", RTE_ETH_RSS_L2TPV3 },
> + { "pfcp", RTE_ETH_RSS_PFCP },
> + { "pppoe", RTE_ETH_RSS_PPPOE },
> + { "gtpu", RTE_ETH_RSS_GTPU },
> + { "ecpri", RTE_ETH_RSS_ECPRI },
> + { "mpls", RTE_ETH_RSS_MPLS },
> + { "ipv4-chksum", RTE_ETH_RSS_IPV4_CHKSUM },
> + { "l4-chksum", RTE_ETH_RSS_L4_CHKSUM },
> + { NULL, 0 },
> +};
> +
> +/** Information for a ethernet speed info. */
> +static const struct {
> + uint32_t speed;
> + const char *str;
> +}eth_speed_table[] = {
> + { ETH_LINK_SPEED_10M_HD, "10Mbps-HD" },
> + { ETH_LINK_SPEED_10M, "10Mbps" },
> + { ETH_LINK_SPEED_100M_HD, "100Mbps-HD" },
> + { ETH_LINK_SPEED_100M, "100Mbps" },
> + { ETH_LINK_SPEED_1G, "1Gbps" },
> + { ETH_LINK_SPEED_10G, "10Gbps" },
> + { ETH_LINK_SPEED_25G, "25Gbps" },
> + { ETH_LINK_SPEED_40G, "40Gbps" },
> + { ETH_LINK_SPEED_50G, "50Gbps" },
> + { ETH_LINK_SPEED_100G, "100Gbps" },
> + { ETH_LINK_SPEED_200G, "200Gbps" },
> +};
> +
> /**< display usage */
> static void
> proc_info_usage(const char *prgname)
> @@ -118,6 +204,7 @@ proc_info_usage(const char *prgname)
> " --collectd-format: to print statistics to STDOUT in expected by collectd format\n"
> " --host-id STRING: host id used to identify the system process is running on\n"
> " --show-port: to display ports information\n"
> + " --show-port-private: to display ports private information\n"
> " --show-tm: to display traffic manager information for ports\n"
> " --show-crypto: to display crypto information\n"
> " --show-ring[=name]: to display ring information\n"
> @@ -225,6 +312,7 @@ proc_info_parse_args(int argc, char **argv)
> {"xstats-ids", 1, NULL, 1},
> {"host-id", 0, NULL, 0},
> {"show-port", 0, NULL, 0},
> + {"show-port-private", 0, NULL, 0},
> {"show-tm", 0, NULL, 0},
> {"show-crypto", 0, NULL, 0},
> {"show-ring", optional_argument, NULL, 0},
> @@ -275,6 +363,9 @@ proc_info_parse_args(int argc, char **argv)
> else if (!strncmp(long_option[option_index].name,
> "show-port", MAX_LONG_OPT_SZ))
> enable_shw_port = 1;
> + else if (!strncmp(long_option[option_index].name,
> + "show-port-private", MAX_LONG_OPT_SZ))
> + enable_shw_port_priv = 1;
> else if (!strncmp(long_option[option_index].name,
> "show-tm", MAX_LONG_OPT_SZ))
> enable_shw_tm = 1;
> @@ -697,6 +788,119 @@ show_offloads(uint64_t offloads,
> }
> }
>
> +static void
> +show_dev_info(struct rte_eth_dev_info *dev_info)
> +{
> + printf(" - device info\n");
> + printf( "\t -- maximum number of MAC addresses: %u\n"
> + "\t -- maximum number of MAC addresses of hash filtering: %u\n"
> + "\t -- hash key size in bytes: %u\n"
> + "\t -- redirection table size: %u\n"
> + "\t -- RSS offload flow type: 0x%"PRIx64"\n"
> + "\t -- minimum size of RX buffer: %u\n"
> + "\t -- maximum configurable length of RX packet: %u\n"
> + "\t -- maximum number of VFs: %u\n"
> + "\t -- maximum number of VMDq pools: %u\n"
> + "\t -- current number of RX queues: %u\n"
> + "\t -- max possible RX queues: %u\n"
> + "\t -- current number of TX queues: %u\n"
> + "\t -- max possible TX queues: %u\n"
> + "\t -- max segment number per packet of TX: %u\n"
> + "\t -- max segment number per MTU/TSO of TX: %u\n",
> + dev_info->max_mac_addrs, dev_info->max_hash_mac_addrs,
> + dev_info->hash_key_size, dev_info->reta_size,
> + dev_info->flow_type_rss_offloads,
> + dev_info->min_rx_bufsize, dev_info->max_rx_pktlen,
> + dev_info->max_vfs, dev_info->max_vmdq_pools,
> + dev_info->nb_rx_queues, dev_info->max_rx_queues,
> + dev_info->nb_tx_queues, dev_info->max_tx_queues,
> + dev_info->tx_desc_lim.nb_seg_max,
> + dev_info->tx_desc_lim.nb_mtu_seg_max);
> +}
> +
> +static void
> +show_port_rss_info(uint16_t port_id, struct rte_eth_dev_info *dev_info)
> +{
> +#define RSS_HASH_KEY_LENGTH 64
> + struct rte_eth_rss_conf rss_conf = {0};
> + uint8_t rss_key[RSS_HASH_KEY_LENGTH];
> + uint8_t hash_key_size;
> + uint64_t rss_hf;
> + uint8_t i;
> + int ret;
> +
> + if (dev_info->hash_key_size > 0 &&
> + dev_info->hash_key_size <= sizeof(rss_key))
> + hash_key_size = dev_info->hash_key_size;
> + else
> + return;
> +
> + rss_conf.rss_key = rss_key;
> + rss_conf.rss_key_len = hash_key_size;
> + ret = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
> + if (ret != 0)
> + return;
> +
> + printf(" - RSS info\n");
> + rss_hf = rss_conf.rss_hf;
> + if (rss_hf == 0) {
> + printf( "\t -- RSS disabled");
> + return;
> + }
> + ret = printf("\t -- RSS functions: ");
> +
> + for (i = 0; rss_type_table[i].str; i++)
> + if (rss_hf & rss_type_table[i].rss_type)
> + printf("%s ", rss_type_table[i].str);
> + printf("\n");
> + printf("\t -- RSS key: ");
> +
> + for (i = 0; i < rss_conf.rss_key_len; i++)
> + printf("%02X", rss_conf.rss_key[i]);
> + printf("\n");
> +}
> +
> +static void
> +show_dev_speed_capability(uint32_t speed_capa)
> +{
> + int size = sizeof(eth_speed_table) / sizeof(eth_speed_table[0]);
> + int i;
> +
> + printf(" - Device Speed Capability: ");
> + for (i = 0; i < size; i++)
> + if (speed_capa & eth_speed_table[i].speed)
> + printf("%s ", eth_speed_table[i].str);
> +
> + if (!(speed_capa & ETH_LINK_SPEED_FIXED)) {
> + printf("auto");
> + }
> +
> + printf("\n");
> +}
> +
> +static void
> +show_dev_rxtx_burst_mode(uint16_t port_id)
> +{
> + struct rte_eth_burst_mode rx_mode;
> + struct rte_eth_burst_mode tx_mode;
> +
> + memset(&rx_mode, 0, sizeof(rx_mode));
> + memset(&tx_mode, 0, sizeof(tx_mode));
> +
> + if (rte_eth_rx_burst_mode_get(port_id, 0, &rx_mode) == 0 &&
> + rte_eth_tx_burst_mode_get(port_id, 0, &tx_mode) == 0) {
> + printf(" - Burst mode:\n");
> + printf( "\t -- Rx burst mode: %s%s\n"
> + "\t -- Tx burst mode: %s%s\n",
> + rx_mode.info,
> + rx_mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
> + " (per queue)" : "",
> + tx_mode.info,
> + tx_mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
> + " (per queue)" : "");
> + }
> +}
> +
> static void
> show_port(void)
> {
> @@ -714,6 +918,7 @@ show_port(void)
> struct rte_eth_fc_conf fc_conf;
> struct rte_ether_addr mac;
> struct rte_eth_dev_owner owner;
> + int vlan_offload;
>
> /* Skip if port is not in mask */
> if ((enabled_port_mask & (1ul << i)) == 0)
> @@ -792,6 +997,25 @@ show_port(void)
> if (ret == 0)
> printf("\t -- mtu (%d)\n", mtu);
>
> + if (dev_info.rx_offload_capa != 0) {
> + printf(" - device capability Rx");
> + show_offloads(dev_info.rx_offload_capa,
> + rte_eth_dev_rx_offload_name);
> + printf("\n");
> + }
> +
> + if (dev_info.tx_offload_capa != 0) {
> + printf(" - device capability Tx");
> + show_offloads(dev_info.tx_offload_capa,
> + rte_eth_dev_tx_offload_name);
> + printf("\n");
> + }
> +
> + show_dev_speed_capability(dev_info.speed_capa);
> + show_dev_info(&dev_info);
> + show_port_rss_info(i, &dev_info);
> + show_dev_rxtx_burst_mode(i);
> +
> for (j = 0; j < dev_info.nb_rx_queues; j++) {
> struct rte_eth_rxq_info queue_info;
> int count;
> @@ -870,12 +1094,38 @@ show_port(void)
> }
> }
>
> + vlan_offload = rte_eth_dev_get_vlan_offload(i);
> + printf(" - VLAN offload: 0x%x\n", vlan_offload);
> +
> #ifdef RTE_LIB_SECURITY
> show_security_context(i, true);
> #endif
> }
> }
>
> +static void
> +show_port_private_info(void)
> +{
> + int i;
> +
> + snprintf(bdr_str, MAX_STRING_LEN, " show - Port PMD Private ");
> + STATS_BDR_STR(10, bdr_str);
> +
> + for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
> + /* Skip if port is not in mask */
> + if ((enabled_port_mask & (1ul << i)) == 0)
> + continue;
> +
> + /* Skip if port is unused */
> + if (!rte_eth_dev_is_valid_port(i))
> + continue;
> +
> + snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i);
> + STATS_BDR_STR(5, bdr_str);
> + rte_eth_dev_priv_dump(stdout, i);
> + }
> +}
> +
> static void
> display_nodecap_info(int is_leaf, struct rte_tm_node_capabilities *cap)
> {
> @@ -1534,6 +1784,8 @@ main(int argc, char **argv)
> /* show information for PMD */
> if (enable_shw_port)
> show_port();
> + if (enable_shw_port_priv)
> + show_port_private_info();
> if (enable_shw_tm)
> show_tm();
> if (enable_shw_crypto)
> @@ -1546,6 +1798,8 @@ main(int argc, char **argv)
> iter_mempool(mempool_iter_name);
> if (enable_dump_regs)
> dump_regs(dump_regs_file_prefix);
> + if (enable_dump_regs)
> + dump_regs(dump_regs_file_prefix);
>
> RTE_ETH_FOREACH_DEV(i)
> rte_eth_dev_close(i);
> diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
> index 0f5e9efb3c..a6d617a400 100644
> --- a/drivers/net/hns3/hns3_ethdev.c
> +++ b/drivers/net/hns3/hns3_ethdev.c
> @@ -5514,7 +5514,7 @@ hns3_get_current_fc_mode(struct rte_eth_dev *dev)
> return hns3_get_autoneg_fc_mode(hw);
> }
>
> -static int
> +int
> hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
> {
> struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> @@ -6732,6 +6732,7 @@ static const struct eth_dev_ops hns3_eth_dev_ops = {
> .timesync_adjust_time = hns3_timesync_adjust_time,
> .timesync_read_time = hns3_timesync_read_time,
> .timesync_write_time = hns3_timesync_write_time,
> + .eth_dev_priv_dump = hns3_eth_dev_priv_dump,
> };
>
> static const struct hns3_reset_ops hns3_reset_ops = {
> diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
> index 678ee6cf97..24b39f1f1f 100644
> --- a/drivers/net/hns3/hns3_ethdev.h
> +++ b/drivers/net/hns3/hns3_ethdev.h
> @@ -1068,6 +1068,8 @@ hns3_test_and_clear_bit(unsigned int nr, volatile uint64_t *addr)
> return __atomic_fetch_and(addr, ~mask, __ATOMIC_RELAXED) & mask;
> }
>
> +int
> +hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf);
> uint32_t hns3_get_speed_capa(struct hns3_hw *hw);
>
> int hns3_buffer_alloc(struct hns3_hw *hw);
> @@ -1093,6 +1095,7 @@ int hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts);
> int hns3_timesync_write_time(struct rte_eth_dev *dev,
> const struct timespec *ts);
> int hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);
> +int hns3_eth_dev_priv_dump(FILE *file, struct rte_eth_dev *dev);
>
> static inline bool
> is_reset_pending(struct hns3_adapter *hns)
> diff --git a/drivers/net/hns3/hns3_ethdev_dump.c b/drivers/net/hns3/hns3_ethdev_dump.c
> new file mode 100644
> index 0000000000..0d2b96f900
> --- /dev/null
> +++ b/drivers/net/hns3/hns3_ethdev_dump.c
> @@ -0,0 +1,917 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2021 HiSilicon Limited
> + */
> +
> +#include <rte_kvargs.h>
> +#include <rte_bus_pci.h>
> +#include <ethdev_pci.h>
> +#include <rte_pci.h>
> +
> +#include "hns3_common.h"
> +#include "hns3_logs.h"
> +#include "hns3_regs.h"
> +#include "hns3_rxtx.h"
> +
> +static const char *
> +get_adapter_state_name(uint32_t state)
> +{
> + static const char *state_name[] = {
> + "UNINITIALIZED",
> + "INITIALIZED",
> + "CONFIGURING",
> + "CONFIGURED",
> + "STARTING",
> + "STARTED",
> + "STOPPING",
> + "CLOSING",
> + "CLOSED",
> + "REMOVED",
> + "NSTATES"
> + };
> +
> + if (state < RTE_DIM(state_name))
> + return state_name[state];
> + else
> + return "unknown";
> +}
> +
> +static const char *
> +get_io_func_hint_name(uint32_t hint)
> +{
> + switch (hint) {
> + case HNS3_IO_FUNC_HINT_NONE:
> + return "none";
> + case HNS3_IO_FUNC_HINT_VEC:
> + return "vec";
> + case HNS3_IO_FUNC_HINT_SVE:
> + return "sve";
> + case HNS3_IO_FUNC_HINT_SIMPLE:
> + return "simple";
> + case HNS3_IO_FUNC_HINT_COMMON:
> + return "common";
> + default:
> + return "unknown";
> + }
> +}
> +
> +static void
> +get_dev_mac_info(FILE *file, struct hns3_adapter *hns)
> +{
> + struct hns3_hw *hw = &hns->hw;
> + struct hns3_pf *pf = &hns->pf;
> +
> + fprintf(file, " - MAC Info:\n");
> + fprintf(file,
> + "\t -- query_type=%u\n"
> + "\t -- supported_speed=0x%x\n"
> + "\t -- advertising=0x%x\n"
> + "\t -- lp_advertising=0x%x\n"
> + "\t -- support_autoneg=%s\n"
> + "\t -- support_fc_autoneg=%s\n",
> + hw->mac.query_type,
> + hw->mac.supported_speed,
> + hw->mac.advertising,
> + hw->mac.lp_advertising,
> + hw->mac.support_autoneg != 0 ? "Yes" : "No",
> + pf->support_fc_autoneg ? "Yes" : "No");
> +}
> +
> +static void
> +get_dev_feature_capability(FILE *file, struct hns3_hw *hw)
> +{
> + const char * const caps_name[] = {
> + "DCB",
> + "COPPER",
> + "FD QUEUE REGION",
> + "PTP",
> + "TX PUSH",
> + "INDEP TXRX",
> + "STASH",
> + "SIMPLE BD",
> + "RXD Advanced Layout",
> + "OUTER UDP CKSUM",
> + "RAS IMP",
> + "TM",
> + "VF VLAN FILTER MOD",
> + };
> + uint32_t i;
> +
> + fprintf(file, " - Dev Capability:\n");
> + for (i = 0; i < RTE_DIM(caps_name); i++)
> + fprintf(file, "\t -- support %s: %s\n", caps_name[i],
> + hw->capability & BIT(i) ? "yes" : "no");
> +}
> +
> +static const char *
> +get_fdir_tuple_name(uint32_t index)
> +{
> + static const char *tuple_name[] = {
> + "outer_dst_mac",
> + "outer_src_mac",
> + "outer_vlan_1st_tag",
> + "outer_vlan_2st_tag",
> + "outer_eth_type",
> + "outer_l2_rsv",
> + "outer_ip_tos",
> + "outer_ip_proto",
> + "outer_src_ip",
> + "outer_dst_ip",
> + "outer_l3_rsv",
> + "outer_src_port",
> + "outer_dst_port",
> + "outer_l4_rsv",
> + "outer_tun_vni",
> + "outer_tun_flow_id",
> + "inner_dst_mac",
> + "inner_src_mac",
> + "inner_vlan_tag1",
> + "inner_vlan_tag2",
> + "inner_eth_type",
> + "inner_l2_rsv",
> + "inner_ip_tos",
> + "inner_ip_proto",
> + "inner_src_ip",
> + "inner_dst_ip",
> + "inner_l3_rsv",
> + "inner_src_port",
> + "inner_dst_port",
> + "inner_sctp_tag",
> + };
> + if (index < RTE_DIM(tuple_name))
> + return tuple_name[index];
> + else
> + return "unknown";
> +}
> +
> +static void
> +get_fdir_basic_info(FILE *file, struct hns3_pf *pf)
> +{
> +#define TMPBUF_SIZE 2048
> +#define PERLINE_TUPLE_NAMES 4
> + struct hns3_fd_cfg *fdcfg = &pf->fdir.fd_cfg;
> + char tmpbuf[TMPBUF_SIZE] = {0};
> + uint32_t i, count = 0;
> +
> + fprintf(file, " - Fdir Info:\n");
> + fprintf(file,
> + "\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n"
> + "\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n"
> + "\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n"
> + "\t -- active_tuples:\n",
> + fdcfg->fd_mode, fdcfg->max_key_length,
> + fdcfg->rule_num[HNS3_FD_STAGE_1],
> + fdcfg->cnt_num[HNS3_FD_STAGE_1],
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].key_sel,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].meta_data_active,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_sipv6_word_en,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en);
> +
> + for (i = 0; i < MAX_TUPLE; i++) {
> + if (!(fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active & BIT(i)))
> + continue;
> + if (count % PERLINE_TUPLE_NAMES == 0)
> + fprintf(file, "\t ");
> + fprintf(file, " %s", get_fdir_tuple_name(i));
> + count++;
> + if (count % PERLINE_TUPLE_NAMES == 0)
> + fprintf(file, "\n");
> + }
> + if (count % PERLINE_TUPLE_NAMES)
> + fprintf(file, "\n");
> +
> + fprintf(file, "%s", tmpbuf);
> +}
> +
> +static void
> +get_device_basic_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> +
> + fprintf(file,
> + " - Device Base Info:\n"
> + "\t -- name: %s\n"
> + "\t -- adapter_state=%s\n"
> + "\t -- nb_rx_queues=%u nb_tx_queues=%u\n"
> + "\t -- total_tqps_num=%u tqps_num=%u intr_tqps_num=%u\n"
> + "\t -- rss_size_max=%u alloc_rss_size=%u tx_qnum_per_tc=%u\n"
> + "\t -- min_tx_pkt_len=%u intr_mapping_mode=%u vlan_mode=%u\n"
> + "\t -- tso_mode=%u max_non_tso_bd_num=%u\n"
> + "\t -- max_tm_rate=%u Mbps\n"
> + "\t -- set link down: %s\n"
> + "\t -- rx_func_hint=%s tx_func_hint=%s\n"
> + "\t -- dev_flags: lsc=%d\n"
> + "\t -- intr_conf: lsc=%u rxq=%u\n",
> + dev->data->name,
> + get_adapter_state_name(hw->adapter_state),
> + dev->data->nb_rx_queues, dev->data->nb_tx_queues,
> + hw->total_tqps_num, hw->tqps_num, hw->intr_tqps_num,
> + hw->rss_size_max, hw->alloc_rss_size, hw->tx_qnum_per_tc,
> + hw->min_tx_pkt_len, hw->intr.mapping_mode, hw->vlan_mode,
> + hw->tso_mode, hw->max_non_tso_bd_num,
> + hw->max_tm_rate,
> + hw->set_link_down ? "Yes" : "No",
> + get_io_func_hint_name(hns->rx_func_hint),
> + get_io_func_hint_name(hns->tx_func_hint),
> + !!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC),
> + dev->data->dev_conf.intr_conf.lsc,
> + dev->data->dev_conf.intr_conf.rxq);
> +}
> +
> +/*
> + * Note: caller must make sure queue_id < nb_queues
> + * nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
> + * eth_dev->data->nb_tx_queues)
> + */
> +static struct hns3_rx_queue *
> +get_rx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> + unsigned int offset;
> + void **rx_queues;
> +
> + if (queue_id < dev->data->nb_rx_queues) {
> + rx_queues = dev->data->rx_queues;
> + offset = queue_id;
> + } else {
> + /*
> + * For kunpeng930, fake queue is not exist. But since the queues
> + * are usually accessd in pairs, this branch may still exist.
> + */
> + if (hns3_dev_get_support(hw, INDEP_TXRX))
> + return NULL;
> +
> + rx_queues = hw->fkq_data.rx_queues;
> + offset = queue_id - dev->data->nb_rx_queues;
> + }
> +
> + if (rx_queues != NULL && rx_queues[offset] != NULL)
> + return rx_queues[offset];
> +
> + hns3_err(hw, "Detect rx_queues is NULL!\n");
> + return NULL;
> +}
> +
> +/*
> + * Note: caller must make sure queue_id < nb_queues
> + * nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
> + * eth_dev->data->nb_tx_queues)
> + */
> +static struct hns3_tx_queue *
> +get_tx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> + unsigned int offset;
> + void **tx_queues;
> +
> + if (queue_id < dev->data->nb_tx_queues) {
> + tx_queues = dev->data->tx_queues;
> + offset = queue_id;
> + } else {
> + /*
> + * For kunpeng930, fake queue is not exist. But since the queues
> + * are usually accessd in pairs, this branch may still exist.
> + */
> + if (hns3_dev_get_support(hw, INDEP_TXRX))
> + return NULL;
> + tx_queues = hw->fkq_data.tx_queues;
> + offset = queue_id - dev->data->nb_tx_queues;
> + }
> +
> + if (tx_queues != NULL && tx_queues[offset] != NULL)
> + return tx_queues[offset];
> +
> + hns3_err(hw, "Detect tx_queues is NULL!\n");
> + return NULL;
> +}
> +
> +static void
> +get_rxtx_fake_queue_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns);
> + struct hns3_rx_queue *rxq;
> + struct hns3_tx_queue *txq;
> + unsigned int queue_id;
> +
> + if (dev->data->nb_rx_queues != dev->data->nb_tx_queues &&
> + !hns3_dev_get_support(hw, INDEP_TXRX)) {
> + queue_id = RTE_MIN(dev->data->nb_rx_queues,
> + dev->data->nb_tx_queues);
> + rxq = get_rx_queue(dev, queue_id);
> + if (rxq == NULL)
> + return;
> + txq = get_tx_queue(dev, queue_id);
> + if (txq == NULL)
> + return;
> + fprintf(file,
> + "\t -- first fake_queue rxtx info:\n"
> + "\t rx: port=%u nb_desc=%u free_thresh=%u\n"
> + "\t tx: port=%u nb_desc=%u\n",
> + rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
> + txq->port_id, txq->nb_tx_desc);
> + }
> +}
> +
> +static void
> +get_queue_enable_state(struct hns3_hw *hw, uint32_t *queue_state,
> + uint32_t nb_queues, bool is_rxq)
> +{
> +#define STATE_SIZE (sizeof(*queue_state) * CHAR_BIT)
> + uint32_t queue_en_reg;
> + uint32_t reg_offset;
> + uint32_t state;
> + uint32_t i;
> +
> + queue_en_reg = is_rxq ? HNS3_RING_RX_EN_REG : HNS3_RING_TX_EN_REG;
> + for (i = 0; i < nb_queues; i++) {
> + reg_offset = hns3_get_tqp_reg_offset(i);
> + state = hns3_read_dev(hw, reg_offset + HNS3_RING_EN_REG);
> + if (hns3_dev_get_support(hw, INDEP_TXRX))
> + state = state && hns3_read_dev(hw, reg_offset +
> + queue_en_reg);
> + hns3_set_bit(queue_state[i / STATE_SIZE],
> + i % STATE_SIZE, state);
> + }
> +}
> +
> +static void
> +print_queue_state_perline(FILE *file, const uint32_t *queue_state,
> + uint32_t nb_queues, uint32_t line_num)
> +{
> +#define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
> + uint32_t qid = line_num * NUM_QUEUE_PER_LINE;
> + uint32_t j;
> +
> + for (j = 0; j < NUM_QUEUE_PER_LINE; j++) {
> + fprintf(file, "%1lx", hns3_get_bit(queue_state[line_num], j));
> +
> + if (qid % CHAR_BIT == CHAR_BIT - 1) {
> + fprintf(file, "%s",
> + j == NUM_QUEUE_PER_LINE - 1 ? "\n" : ":");
> + }
> + qid++;
> + if (qid >= nb_queues) {
> + fprintf(file, "\n");
> + break;
> + }
> + }
> +}
> +
> +static void
> +display_queue_enable_state(FILE *file, const uint32_t *queue_state,
> + uint32_t nb_queues, bool is_rxq)
> +{
> +#define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
> + uint32_t i;
> +
> + if (nb_queues == 0) {
> + fprintf(file, "\t %s queue number is 0\n",
> + is_rxq ? "Rx" : "Tx");
> + return;
> + }
> +
> + fprintf(file, "\t %s queue id | enable state bitMap\n",
> + is_rxq ? "rx" : "tx");
> +
> + for (i = 0; i < (nb_queues - 1) / NUM_QUEUE_PER_LINE + 1; i++) {
> + uint32_t line_end = (i + 1) * NUM_QUEUE_PER_LINE - 1;
> + uint32_t line_start = i * NUM_QUEUE_PER_LINE;
> + fprintf(file, "\t %04u - %04u | ", line_start,
> + nb_queues - 1 > line_end ? line_end : nb_queues - 1);
> +
> +
> + print_queue_state_perline(file, queue_state, nb_queues, i);
> + }
> +}
> +
> +static void
> +get_rxtx_queue_enable_state(FILE *file, struct rte_eth_dev *dev)
> +{
> +#define MAX_TQP_NUM 1280
> +#define QUEUE_BITMAP_SIZE (MAX_TQP_NUM / 32)
> + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> + uint32_t rx_queue_state[QUEUE_BITMAP_SIZE] = {0};
> + uint32_t tx_queue_state[QUEUE_BITMAP_SIZE] = {0};
> + uint32_t nb_rx_queues;
> + uint32_t nb_tx_queues;
> +
> + nb_rx_queues = dev->data->nb_rx_queues;
> + nb_tx_queues = dev->data->nb_tx_queues;
> +
> + fprintf(file, "\t -- enable state:\n");
> + get_queue_enable_state(hw, rx_queue_state, nb_rx_queues, true);
> + display_queue_enable_state(file, rx_queue_state, nb_rx_queues,
> + true);
> +
> + get_queue_enable_state(hw, tx_queue_state, nb_tx_queues, false);
> + display_queue_enable_state(file, tx_queue_state, nb_tx_queues,
> + false);
> +}
> +
> +static void
> +get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_rx_queue *rxq;
> + struct hns3_tx_queue *txq;
> + unsigned int queue_id = 0;
> +
> + rxq = get_rx_queue(dev, queue_id);
> + if (rxq == NULL)
> + return;
> + txq = get_tx_queue(dev, queue_id);
> + if (txq == NULL)
> + return;
> + fprintf(file," - Rx/Tx Queue Info:\n");
> + fprintf(file,
> + "\t -- nb_rx_queues=%u nb_tx_queues=%u, "
> + "first queue rxtx info:\n"
> + "\t rx: port=%u nb_desc=%u free_thresh=%u\n"
> + "\t tx: port=%u nb_desc=%u\n"
> + "\t -- tx push: %s\n",
> + dev->data->nb_rx_queues,
> + dev->data->nb_tx_queues,
> + rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
> + txq->port_id, txq->nb_tx_desc,
> + txq->tx_push_enable ? "enabled" : "disabled");
> +
> + get_rxtx_fake_queue_info(file, dev);
> + get_rxtx_queue_enable_state(file, dev);
> +}
> +
> +static int
> +get_vlan_filter_cfg(FILE *file, struct hns3_hw *hw)
> +{
> +#define HNS3_FILTER_TYPE_VF 0
> +#define HNS3_FILTER_TYPE_PORT 1
> +#define HNS3_FILTER_FE_NIC_INGRESS_B BIT(0)
> +#define HNS3_FILTER_FE_NIC_EGRESS_B BIT(1)
> + struct hns3_vlan_filter_ctrl_cmd *req;
> + struct hns3_cmd_desc desc;
> + uint8_t i;
> + int ret;
> +
> + static const uint32_t vlan_filter_type[] = {
> + HNS3_FILTER_TYPE_PORT,
> + HNS3_FILTER_TYPE_VF
> + };
> +
> + for (i = 0; i < RTE_DIM(vlan_filter_type); i++) {
> + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_FILTER_CTRL,
> + true);
> + req = (struct hns3_vlan_filter_ctrl_cmd *)desc.data;
> + req->vlan_type = vlan_filter_type[i];
> + req->vf_id = HNS3_PF_FUNC_ID;
> + ret = hns3_cmd_send(hw, &desc, 1);
> + if (ret != 0) {
> + hns3_err(hw,
> + "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
> + ret, 1, rte_le_to_cpu_16(desc.opcode));
> + return ret;
> + }
> + fprintf(file,
> + "\t -- %s VLAN filter configuration\n"
> + "\t nic_ingress :%s\n"
> + "\t nic_egress :%s\n",
> + req->vlan_type == HNS3_FILTER_TYPE_PORT ?
> + "Port" : "VF",
> + req->vlan_fe & HNS3_FILTER_FE_NIC_INGRESS_B ?
> + "Enable" : "Disable",
> + req->vlan_fe & HNS3_FILTER_FE_NIC_EGRESS_B ?
> + "Enable" : "Disable");
> + }
> +
> + return 0;
> +}
> +
> +static int
> +get_vlan_rx_offload_cfg(FILE *file, struct hns3_hw *hw)
> +{
> + struct hns3_vport_vtag_rx_cfg_cmd *req;
> + struct hns3_cmd_desc desc;
> + uint16_t vport_id;
> + uint8_t bitmap;
> + int ret;
> +
> + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_RX_CFG, true);
> + req = (struct hns3_vport_vtag_rx_cfg_cmd *)desc.data;
> + vport_id = HNS3_PF_FUNC_ID;
> + req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;
> + bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);
> + req->vf_bitmap[req->vf_offset] = bitmap;
> +
> + /*
> + * current version VF is not supported when PF is driven by DPDK driver,
> + * just need to configure rx parameters for PF vport.
> + */
> + ret = hns3_cmd_send(hw, &desc, 1);
> + if (ret != 0) {
> + hns3_err(hw,
> + "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
> + ret, 1, rte_le_to_cpu_16(desc.opcode));
> + return ret;
> + }
> +
> + fprintf(file,
> + "\t -- RX VLAN configuration\n"
> + "\t vlan1_strip_en :%s\n"
> + "\t vlan2_strip_en :%s\n"
> + "\t vlan1_vlan_prionly :%s\n"
> + "\t vlan2_vlan_prionly :%s\n"
> + "\t vlan1_strip_discard :%s\n"
> + "\t vlan2_strip_discard :%s\n",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_REM_TAG1_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_REM_TAG2_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_SHOW_TAG1_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_SHOW_TAG2_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_DISCARD_TAG1_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_DISCARD_TAG2_EN_B) ? "Enable" : "Disable");
> +
> + return 0;
> +}
> +
> +static void
> +parse_tx_vlan_cfg(FILE *file, struct hns3_vport_vtag_tx_cfg_cmd *req)
> +{
> +#define VLAN_VID_MASK 0x0fff
> +#define VLAN_PRIO_SHIFT 13
> +
> + fprintf(file,
> + "\t -- TX VLAN configuration\n"
> + "\t accept_tag1 :%s\n"
> + "\t accept_untag1 :%s\n"
> + "\t insert_tag1_en :%s\n"
> + "\t default_vlan_tag1 = %d, qos = %d\n"
> + "\t accept_tag2 :%s\n"
> + "\t accept_untag2 :%s\n"
> + "\t insert_tag2_en :%s\n"
> + "\t default_vlan_tag2 = %d, qos = %d\n"
> + "\t vlan_shift_mode :%s\n",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_ACCEPT_TAG1_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_ACCEPT_UNTAG1_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_PORT_INS_TAG1_EN_B) ? "Enable" : "Disable",
> + req->def_vlan_tag1 & VLAN_VID_MASK,
> + req->def_vlan_tag1 >> VLAN_PRIO_SHIFT,
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_ACCEPT_TAG2_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_ACCEPT_UNTAG2_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_PORT_INS_TAG2_EN_B) ? "Enable" : "Disable",
> + req->def_vlan_tag2 & VLAN_VID_MASK,
> + req->def_vlan_tag2 >> VLAN_PRIO_SHIFT,
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_TAG_SHIFT_MODE_EN_B) ? "Enable" :
> + "Disable");
> +}
> +
> +static int
> +get_vlan_tx_offload_cfg(FILE *file, struct hns3_hw *hw)
> +{
> + struct hns3_vport_vtag_tx_cfg_cmd *req;
> + struct hns3_cmd_desc desc;
> + uint16_t vport_id;
> + uint8_t bitmap;
> + int ret;
> +
> + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_TX_CFG, true);
> + req = (struct hns3_vport_vtag_tx_cfg_cmd *)desc.data;
> + vport_id = HNS3_PF_FUNC_ID;
> + req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;
> + bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);
> + req->vf_bitmap[req->vf_offset] = bitmap;
> + /*
> + * current version VF is not supported when PF is driven by DPDK driver,
> + * just need to configure tx parameters for PF vport.
> + */
> + ret = hns3_cmd_send(hw, &desc, 1);
> + if (ret != 0) {
> + hns3_err(hw,
> + "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
> + ret, 1, rte_le_to_cpu_16(desc.opcode));
> + return ret;
> + }
> +
> + parse_tx_vlan_cfg(file, req);
> +
> + return 0;
> +}
> +
> +static void
> +get_port_pvid_info(FILE *file, struct hns3_hw *hw)
> +{
> + fprintf(file, "\t -- pvid status: %s\n",
> + hw->port_base_vlan_cfg.state ? "on" : "off");
> +}
> +
> +static void
> +get_vlan_config_info(FILE *file, struct hns3_hw *hw)
> +{
> + int ret;
> +
> + fprintf(file," - VLAN Config Info:\n");
> + ret = get_vlan_filter_cfg(file, hw);
> + if (ret < 0)
> + return;
> +
> + ret = get_vlan_rx_offload_cfg(file, hw);
> + if (ret < 0)
> + return;
> +
> + ret = get_vlan_tx_offload_cfg(file, hw);
> + if (ret < 0)
> + return;
> +
> + get_port_pvid_info(file, hw);
> +}
> +
> +static void
> +get_tm_conf_shaper_info(FILE *file, struct hns3_tm_conf *conf)
> +{
> + struct hns3_shaper_profile_list *shaper_profile_list =
> + &conf->shaper_profile_list;
> + struct hns3_tm_shaper_profile *shaper_profile;
> +
> + if (!conf->nb_shaper_profile)
> + return;
> +
> + fprintf(file, " shaper_profile:\n");
> + TAILQ_FOREACH(shaper_profile, shaper_profile_list, node) {
> + fprintf(file,
> + " id=%u reference_count=%u peak_rate=%"PRIu64"Bps\n",
> + shaper_profile->shaper_profile_id,
> + shaper_profile->reference_count,
> + shaper_profile->profile.peak.rate);
> + }
> +}
> +
> +static void
> +get_tm_conf_port_node_info(FILE *file, struct hns3_tm_conf *conf)
> +{
> + if (!conf->root)
> + return;
> +
> + fprintf(file,
> + " port_node: \n"
> + " node_id=%u reference_count=%u shaper_profile_id=%d\n",
> + conf->root->id, conf->root->reference_count,
> + conf->root->shaper_profile ?
> + (int)conf->root->shaper_profile->shaper_profile_id : -1);
> +}
> +
> +static void
> +get_tm_conf_tc_node_info(FILE *file, struct hns3_tm_conf *conf)
> +{
> + struct hns3_tm_node_list *tc_list = &conf->tc_list;
> + struct hns3_tm_node *tc_node[HNS3_MAX_TC_NUM];
> + struct hns3_tm_node *tm_node;
> + uint32_t tidx;
> +
> + if (!conf->nb_tc_node)
> + return;
> +
> + fprintf(file, " tc_node: \n");
> + memset(tc_node, 0, sizeof(tc_node));
> + TAILQ_FOREACH(tm_node, tc_list, node) {
> + tidx = hns3_tm_calc_node_tc_no(conf, tm_node->id);
> + if (tidx < HNS3_MAX_TC_NUM)
> + tc_node[tidx] = tm_node;
> + }
> +
> + for (tidx = 0; tidx < HNS3_MAX_TC_NUM; tidx++) {
> + tm_node = tc_node[tidx];
> + if (tm_node == NULL)
> + continue;
> + fprintf(file,
> + " id=%u TC%u reference_count=%u parent_id=%d "
> + "shaper_profile_id=%d\n",
> + tm_node->id, hns3_tm_calc_node_tc_no(conf, tm_node->id),
> + tm_node->reference_count,
> + tm_node->parent ? (int)tm_node->parent->id : -1,
> + tm_node->shaper_profile ?
> + (int)tm_node->shaper_profile->shaper_profile_id : -1);
> + }
> +}
> +
> +static void
> +get_tm_conf_queue_format_info(FILE *file, struct hns3_tm_node **queue_node,
> + uint32_t *queue_node_tc, uint32_t nb_tx_queues)
> +{
> +#define PERLINE_QUEUES 32
> +#define PERLINE_STRIDE 8
> +#define LINE_BUF_SIZE 1024
> + uint32_t i, j, line_num, start_queue, end_queue;
> + char tmpbuf[LINE_BUF_SIZE] = {0};
> +
> + line_num = (nb_tx_queues + PERLINE_QUEUES - 1) / PERLINE_QUEUES;
> + for (i = 0; i < line_num; i++) {
> + start_queue = i * PERLINE_QUEUES;
> + end_queue = (i + 1) * PERLINE_QUEUES - 1;
> + if (end_queue > nb_tx_queues - 1)
> + end_queue = nb_tx_queues - 1;
> + fprintf(file, " %04u - %04u | ", start_queue, end_queue);
> + for (j = start_queue; j < nb_tx_queues; j++) {
> + if (j >= end_queue + 1)
> + break;
> + if (j > start_queue && j % PERLINE_STRIDE == 0)
> + fprintf(file, ":");
> + fprintf(file, "%u",
> + queue_node[j] ? queue_node_tc[j] :
> + HNS3_MAX_TC_NUM);
> + }
> + fprintf(file, "%s\n", tmpbuf);
> + }
> +}
> +
> +static void
> +get_tm_conf_queue_node_info(FILE *file, struct hns3_tm_conf *conf,
> + uint32_t nb_tx_queues)
> +{
> + struct hns3_tm_node_list *queue_list = &conf->queue_list;
> + uint32_t nb_queue_node = conf->nb_leaf_nodes_max + 1;
> + struct hns3_tm_node *queue_node[nb_queue_node];
> + uint32_t queue_node_tc[nb_queue_node];
> + struct hns3_tm_node *tm_node;
> +
> + if (!conf->nb_queue_node)
> + return;
> +
> + fprintf(file,
> + " queue_node: \n"
> + " tx queue id | mapped tc (8 mean node not exist)\n");
> +
> + memset(queue_node, 0, sizeof(queue_node));
> + memset(queue_node_tc, 0, sizeof(queue_node_tc));
> + nb_tx_queues = RTE_MIN(nb_tx_queues, nb_queue_node);
> + TAILQ_FOREACH(tm_node, queue_list, node) {
> + if (tm_node->id >= nb_queue_node)
> + continue;
> + queue_node[tm_node->id] = tm_node;
> + queue_node_tc[tm_node->id] = tm_node->parent ?
> + hns3_tm_calc_node_tc_no(conf, tm_node->parent->id) : 0;
> + nb_tx_queues = RTE_MAX(nb_tx_queues, tm_node->id + 1);
> + }
> +
> + get_tm_conf_queue_format_info(file, queue_node, queue_node_tc,
> + nb_tx_queues);
> +}
> +
> +static void
> +get_tm_conf_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> + struct hns3_tm_conf *conf = &pf->tm_conf;
> +
> + fprintf(file, " - TM config info:\n");
> + fprintf(file,
> + "\t -- nb_leaf_nodes_max=%u nb_nodes_max=%u\n"
> + "\t -- nb_shaper_profile=%u nb_tc_node=%u nb_queue_node=%u\n"
> + "\t -- committed=%u\n",
> + conf->nb_leaf_nodes_max, conf->nb_nodes_max,
> + conf->nb_shaper_profile, conf->nb_tc_node, conf->nb_queue_node,
> + conf->committed);
> +
> + get_tm_conf_shaper_info(file, conf);
> + get_tm_conf_port_node_info(file, conf);
> + get_tm_conf_tc_node_info(file, conf);
> + get_tm_conf_queue_node_info(file, conf, dev->data->nb_tx_queues);
> +}
> +
> +static void
> +hns3_fc_mode_to_rxtx_pause(enum hns3_fc_mode fc_mode, bool *rx_pause,
> + bool *tx_pause)
> +{
> + switch (fc_mode) {
> + case HNS3_FC_NONE:
> + *tx_pause = false;
> + *rx_pause = false;
> + break;
> + case HNS3_FC_RX_PAUSE:
> + *rx_pause = true;
> + *tx_pause = false;
> + break;
> + case HNS3_FC_TX_PAUSE:
> + *rx_pause = false;
> + *tx_pause = true;
> + break;
> + case HNS3_FC_FULL:
> + *rx_pause = true;
> + *tx_pause = true;
> + break;
> + default:
> + *rx_pause = false;
> + *tx_pause = false;
> + break;
> + }
> +}
> +
> +static bool
> +is_link_fc_mode(struct hns3_adapter *hns)
> +{
> + struct hns3_hw *hw = &hns->hw;
> + struct hns3_pf *pf = &hns->pf;
> +
> + if (hw->current_fc_status == HNS3_FC_STATUS_PFC)
> + return false;
> +
> + if (hw->num_tc > 1 && !pf->support_multi_tc_pause)
> + return false;
> +
> + return true;
> +}
> +
> +static void
> +get_link_fc_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> + struct rte_eth_fc_conf fc_conf;
> + bool rx_pause1;
> + bool tx_pause1;
> + bool rx_pause2;
> + bool tx_pause2;
> + int ret;
> +
> + if (!is_link_fc_mode(hns))
> + return;
> +
> + ret = hns3_flow_ctrl_get(dev, &fc_conf);
> + if (ret) {
> + fprintf(file, "get device flow control info fail!\n");
> + return;
> + }
> +
> + hns3_fc_mode_to_rxtx_pause(hw->requested_fc_mode,
> + &rx_pause1, &tx_pause1);
> + hns3_fc_mode_to_rxtx_pause((enum hns3_fc_mode)fc_conf.mode,
> + &rx_pause2, &tx_pause2);
> +
> + fprintf(file,
> + "\t -- link_fc_info:\n"
> + "\t Requested fc:\n"
> + "\t Rx: %s\n"
> + "\t Tx: %s\n"
> + "\t Current fc:\n"
> + "\t Rx: %s\n"
> + "\t Tx: %s\n"
> + "\t Autonegotiate: %s\n"
> + "\t Pause time: 0x%x\n",
> + rx_pause1 ? "On" : "Off", tx_pause1 ? "On" : "Off",
> + rx_pause2 ? "On" : "Off", tx_pause2 ? "On" : "Off",
> + fc_conf.autoneg == ETH_LINK_AUTONEG ? "On" : "Off",
> + fc_conf.pause_time);
> +}
> +
> +static void
> +get_flow_ctrl_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> +
> + fprintf(file, " - Flow Ctrl Info:\n");
> + fprintf(file,
> + "\t -- fc_common_info:\n"
> + "\t current_fc_status=%u\n"
> + "\t requested_fc_mode=%u\n",
> + hw->current_fc_status,
> + hw->requested_fc_mode);
> +
> + get_link_fc_info(file, dev);
> +}
> +
> +int
> +hns3_eth_dev_priv_dump(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> +
> + get_device_basic_info(file, dev);
> + get_dev_feature_capability(file, hw);
> +
> + /* VF is only support dumping basic info and feaure capability */
> + if (hns->is_vf)
> + return 0;
> +
> + get_dev_mac_info(file, hns);
> + get_rxtx_queue_info(file, dev);
> + get_vlan_config_info(file, hw);
> + get_fdir_basic_info(file, &hns->pf);
> + get_tm_conf_info(file, dev);
> + get_flow_ctrl_info(file, dev);
> +
> + return 0;
> +}
> diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
> index f443d71039..7a822768c2 100644
> --- a/drivers/net/hns3/hns3_ethdev_vf.c
> +++ b/drivers/net/hns3/hns3_ethdev_vf.c
> @@ -2290,6 +2290,7 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = {
> .get_reg = hns3_get_regs,
> .dev_supported_ptypes_get = hns3_dev_supported_ptypes_get,
> .tx_done_cleanup = hns3_tx_done_cleanup,
> + .eth_dev_priv_dump = hns3_eth_dev_priv_dump,
> };
>
> static const struct hns3_reset_ops hns3vf_reset_ops = {
> diff --git a/drivers/net/hns3/meson.build b/drivers/net/hns3/meson.build
> index 8a4c7cc100..665b2afedf 100644
> --- a/drivers/net/hns3/meson.build
> +++ b/drivers/net/hns3/meson.build
> @@ -30,6 +30,7 @@ sources = files(
> 'hns3_tm.c',
> 'hns3_ptp.c',
> 'hns3_common.c',
> + 'hns3_ethdev_dump.c',
> )
>
> deps += ['hash']
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index d95605a355..e75ff3f15b 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -990,6 +990,20 @@ typedef int (*eth_representor_info_get_t)(struct rte_eth_dev *dev,
> typedef int (*eth_rx_metadata_negotiate_t)(struct rte_eth_dev *dev,
> uint64_t *features);
>
> +/**
> + * @internal
> + * Get ethdev private info.
> + *
> + * @param file
> + * A pointer to a file for output.
> + * @param dev
> + * Port (ethdev) handle.
> + *
> + * @return
> + * Negative errno value on error, positive value on success.
> + */
> +typedef int (*eth_dev_priv_dump_t)(FILE *file, struct rte_eth_dev *dev);
> +
> /**
> * @internal A structure containing the functions exported by an Ethernet driver.
> */
> @@ -1186,6 +1200,9 @@ struct eth_dev_ops {
> * kinds of metadata to the PMD
> */
> eth_rx_metadata_negotiate_t rx_metadata_negotiate;
> +
> + /** Dump ethdev private info */
> + eth_dev_priv_dump_t eth_dev_priv_dump;
> };
>
> /**
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index 29b5ee32b4..7d755c6b04 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -6487,6 +6487,21 @@ rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features)
> (*dev->dev_ops->rx_metadata_negotiate)(dev, features));
> }
>
> +int
> +rte_eth_dev_priv_dump(FILE *file, uint16_t port_id)
> +{
> + struct rte_eth_dev *dev;
> + int ret;
> +
> + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> + dev = &rte_eth_devices[port_id];
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->eth_dev_priv_dump, -ENOTSUP);
> + ret = (*dev->dev_ops->eth_dev_priv_dump)(file, dev);
> +
> + return ret;
> +}
> +
> RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
>
> RTE_INIT(ethdev_init_telemetry)
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index 096b676fc1..62a3bb5d80 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -5888,6 +5888,22 @@ rte_eth_tx_buffer(uint16_t port_id, uint16_t queue_id,
> return rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
> }
>
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
> + *
> + * Get ethdev private info.
> + *
> + * @param file
> + * A pointer to a file for output.
> + * @param port_id
> + * The port identifier of the Ethernet device.
> + * @return
> + * Negative errno value on error, positive value on success.
> + */
> +__rte_experimental
> +int rte_eth_dev_priv_dump(FILE *file, uint16_t port_id);
> +
> #ifdef __cplusplus
> }
> #endif
>
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4] ethdev: introduce dump API
2022-03-04 1:22 ` [PATCH] 1 version Min Hu (Connor)
2022-03-04 1:22 ` [PATCH] app/testpmd: add help messages for multi-process Min Hu (Connor)
2022-03-04 1:22 ` [PATCH] dpdk: show dev basic info Min Hu (Connor)
@ 2022-03-04 1:22 ` Min Hu (Connor)
2022-03-04 1:26 ` Min Hu (Connor)
2022-03-04 1:22 ` [PATCH] net/bonding: fix slaves initializing on mtu setting Min Hu (Connor)
2022-03-04 1:25 ` [PATCH] 1 version Min Hu (Connor)
4 siblings, 1 reply; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:22 UTC (permalink / raw)
To: dev
Cc: Min Hu (Connor),
Morten Brørup, Ray Kinsella, Ajit Khaparde, Ferruh Yigit,
Thomas Monjalon, Andrew Rybchenko
Added the ethdev dump API which provides querying private info from device.
There exists many private properties in different PMD drivers, such as
adapter state, Rx/Tx func algorithm in hns3 PMD. The information of these
properties is important for debug. As the information is private, the new
API is introduced.
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
Acked-by: Ray Kinsella <mdr@ashroe.eu>
Acked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
v4:
* fix comments for API.
v3:
* change 'ethdev' to 'device'.
v2:
* fixed comments from Ferruh.
---
doc/guides/rel_notes/release_22_03.rst | 7 +++++++
lib/ethdev/ethdev_driver.h | 22 ++++++++++++++++++++++
lib/ethdev/rte_ethdev.c | 17 +++++++++++++++++
lib/ethdev/rte_ethdev.h | 20 ++++++++++++++++++++
lib/ethdev/version.map | 1 +
5 files changed, 67 insertions(+)
diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
index 0f1d3adaf2..10ac807e1c 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -80,6 +80,13 @@ New Features
New APIs, ``rte_eth_dev_priority_flow_ctrl_queue_info_get()`` and
``rte_eth_dev_priority_flow_ctrl_queue_configure()``, was added.
+* **Added the private dump API, for query private info from device.**
+
+ Added the private dump API which provides querying private info from device.
+ There exists many private properties in different PMD drivers. The
+ information of these properties is important for debug. As the information
+ is private, the new API is introduced.
+
* **Updated AF_XDP PMD**
* Added support for libxdp >=v1.2.2.
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 76a3975c1b..617b450d57 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -1045,6 +1045,25 @@ typedef int (*eth_ip_reassembly_conf_get_t)(struct rte_eth_dev *dev,
typedef int (*eth_ip_reassembly_conf_set_t)(struct rte_eth_dev *dev,
const struct rte_eth_ip_reassembly_params *conf);
+/**
+ * @internal
+ * Dump private info from device to a file.
+ *
+ * @param dev
+ * Port (ethdev) handle.
+ * @param file
+ * A pointer to a file for output.
+ *
+ * @return
+ * Negative value on error, 0 on success.
+ *
+ * @retval 0
+ * Success
+ * @retval -EINVAL
+ * Invalid file
+ */
+typedef int (*eth_dev_priv_dump_t)(struct rte_eth_dev *dev, FILE *file);
+
/**
* @internal A structure containing the functions exported by an Ethernet driver.
*/
@@ -1252,6 +1271,9 @@ struct eth_dev_ops {
eth_ip_reassembly_conf_get_t ip_reassembly_conf_get;
/** Set IP reassembly configuration */
eth_ip_reassembly_conf_set_t ip_reassembly_conf_set;
+
+ /** Dump private info from device */
+ eth_dev_priv_dump_t eth_dev_priv_dump;
};
/**
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index c95b3cd3db..2a479bea21 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6750,6 +6750,23 @@ rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag_offset)
return 0;
}
+int
+rte_eth_dev_priv_dump(uint16_t port_id, FILE *file)
+{
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ dev = &rte_eth_devices[port_id];
+
+ if (file == NULL) {
+ RTE_ETHDEV_LOG(ERR, "Invalid file (NULL)\n");
+ return -EINVAL;
+ }
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->eth_dev_priv_dump, -ENOTSUP);
+ return eth_err(port_id, (*dev->dev_ops->eth_dev_priv_dump)(dev, file));
+}
+
RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
RTE_INIT(ethdev_init_telemetry)
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index f554e716bc..3439b04119 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5432,6 +5432,26 @@ typedef struct {
uint16_t nb_frags;
} rte_eth_ip_reassembly_dynfield_t;
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Dump private info from device to a file. Provided data and the order depends
+ * on the PMD.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param file
+ * A pointer to a file for output.
+ * @return
+ * - (0) on success.
+ * - (-ENODEV) if *port_id* is invalid.
+ * - (-EINVAL) if null file.
+ * - (-ENOTSUP) if the device does not support this function.
+ * - (-EIO) if device is removed.
+ */
+__rte_experimental
+int rte_eth_dev_priv_dump(uint16_t port_id, FILE *file);
#include <rte_ethdev_core.h>
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 1ca7ec33ee..fb82c8bf53 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -263,6 +263,7 @@ EXPERIMENTAL {
rte_eth_ip_reassembly_capability_get;
rte_eth_ip_reassembly_conf_get;
rte_eth_ip_reassembly_conf_set;
+ rte_eth_dev_priv_dump;
};
INTERNAL {
--
2.33.0
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4] ethdev: introduce dump API
2022-03-04 1:22 ` [PATCH v4] ethdev: introduce dump API Min Hu (Connor)
@ 2022-03-04 1:26 ` Min Hu (Connor)
0 siblings, 0 replies; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:26 UTC (permalink / raw)
To: dev
Cc: Morten Brørup, Ray Kinsella, Ajit Khaparde, Ferruh Yigit,
Thomas Monjalon, Andrew Rybchenko
Sorry, this patch should be skipped.
在 2022/3/4 9:22, Min Hu (Connor) 写道:
> Added the ethdev dump API which provides querying private info from device.
> There exists many private properties in different PMD drivers, such as
> adapter state, Rx/Tx func algorithm in hns3 PMD. The information of these
> properties is important for debug. As the information is private, the new
> API is introduced.
>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> Acked-by: Morten Brørup <mb@smartsharesystems.com>
> Acked-by: Ray Kinsella <mdr@ashroe.eu>
> Acked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
> v4:
> * fix comments for API.
> v3:
> * change 'ethdev' to 'device'.
> v2:
> * fixed comments from Ferruh.
> ---
> doc/guides/rel_notes/release_22_03.rst | 7 +++++++
> lib/ethdev/ethdev_driver.h | 22 ++++++++++++++++++++++
> lib/ethdev/rte_ethdev.c | 17 +++++++++++++++++
> lib/ethdev/rte_ethdev.h | 20 ++++++++++++++++++++
> lib/ethdev/version.map | 1 +
> 5 files changed, 67 insertions(+)
>
> diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
> index 0f1d3adaf2..10ac807e1c 100644
> --- a/doc/guides/rel_notes/release_22_03.rst
> +++ b/doc/guides/rel_notes/release_22_03.rst
> @@ -80,6 +80,13 @@ New Features
> New APIs, ``rte_eth_dev_priority_flow_ctrl_queue_info_get()`` and
> ``rte_eth_dev_priority_flow_ctrl_queue_configure()``, was added.
>
> +* **Added the private dump API, for query private info from device.**
> +
> + Added the private dump API which provides querying private info from device.
> + There exists many private properties in different PMD drivers. The
> + information of these properties is important for debug. As the information
> + is private, the new API is introduced.
> +
> * **Updated AF_XDP PMD**
>
> * Added support for libxdp >=v1.2.2.
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index 76a3975c1b..617b450d57 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -1045,6 +1045,25 @@ typedef int (*eth_ip_reassembly_conf_get_t)(struct rte_eth_dev *dev,
> typedef int (*eth_ip_reassembly_conf_set_t)(struct rte_eth_dev *dev,
> const struct rte_eth_ip_reassembly_params *conf);
>
> +/**
> + * @internal
> + * Dump private info from device to a file.
> + *
> + * @param dev
> + * Port (ethdev) handle.
> + * @param file
> + * A pointer to a file for output.
> + *
> + * @return
> + * Negative value on error, 0 on success.
> + *
> + * @retval 0
> + * Success
> + * @retval -EINVAL
> + * Invalid file
> + */
> +typedef int (*eth_dev_priv_dump_t)(struct rte_eth_dev *dev, FILE *file);
> +
> /**
> * @internal A structure containing the functions exported by an Ethernet driver.
> */
> @@ -1252,6 +1271,9 @@ struct eth_dev_ops {
> eth_ip_reassembly_conf_get_t ip_reassembly_conf_get;
> /** Set IP reassembly configuration */
> eth_ip_reassembly_conf_set_t ip_reassembly_conf_set;
> +
> + /** Dump private info from device */
> + eth_dev_priv_dump_t eth_dev_priv_dump;
> };
>
> /**
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index c95b3cd3db..2a479bea21 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -6750,6 +6750,23 @@ rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag_offset)
> return 0;
> }
>
> +int
> +rte_eth_dev_priv_dump(uint16_t port_id, FILE *file)
> +{
> + struct rte_eth_dev *dev;
> +
> + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> + dev = &rte_eth_devices[port_id];
> +
> + if (file == NULL) {
> + RTE_ETHDEV_LOG(ERR, "Invalid file (NULL)\n");
> + return -EINVAL;
> + }
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->eth_dev_priv_dump, -ENOTSUP);
> + return eth_err(port_id, (*dev->dev_ops->eth_dev_priv_dump)(dev, file));
> +}
> +
> RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
>
> RTE_INIT(ethdev_init_telemetry)
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index f554e716bc..3439b04119 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -5432,6 +5432,26 @@ typedef struct {
> uint16_t nb_frags;
> } rte_eth_ip_reassembly_dynfield_t;
>
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
> + *
> + * Dump private info from device to a file. Provided data and the order depends
> + * on the PMD.
> + *
> + * @param port_id
> + * The port identifier of the Ethernet device.
> + * @param file
> + * A pointer to a file for output.
> + * @return
> + * - (0) on success.
> + * - (-ENODEV) if *port_id* is invalid.
> + * - (-EINVAL) if null file.
> + * - (-ENOTSUP) if the device does not support this function.
> + * - (-EIO) if device is removed.
> + */
> +__rte_experimental
> +int rte_eth_dev_priv_dump(uint16_t port_id, FILE *file);
>
> #include <rte_ethdev_core.h>
>
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
> index 1ca7ec33ee..fb82c8bf53 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -263,6 +263,7 @@ EXPERIMENTAL {
> rte_eth_ip_reassembly_capability_get;
> rte_eth_ip_reassembly_conf_get;
> rte_eth_ip_reassembly_conf_set;
> + rte_eth_dev_priv_dump;
> };
>
> INTERNAL {
>
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH] net/bonding: fix slaves initializing on mtu setting
2022-03-04 1:22 ` [PATCH] 1 version Min Hu (Connor)
` (2 preceding siblings ...)
2022-03-04 1:22 ` [PATCH v4] ethdev: introduce dump API Min Hu (Connor)
@ 2022-03-04 1:22 ` Min Hu (Connor)
2022-03-04 1:27 ` Min Hu (Connor)
2022-03-04 1:25 ` [PATCH] 1 version Min Hu (Connor)
4 siblings, 1 reply; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:22 UTC (permalink / raw)
To: dev
Cc: Wan Junjie, Chas Williams, Min Hu (Connor),
Ferruh Yigit, Andrew Rybchenko, Ivan Ilchenko
From: Wan Junjie <wanjunjie@bytedance.com>
If a initial process for the bonding device is like:
rte_eth_dev_configure
rte_eth_dev_set_mtu
queue setup and start, etc.
Pass the vdev args to application, and init bonding device only.
-a 0000:af:00.0 --vdev="net_bonding0,mode=2,slave=0000:af:00.0"
It will fail and compain for the slave device
"Port 0 must be configured before MTU set"
Test can be reproduced with ovs.
Fixes: b26bee1 ("ethdev: forbid MTU set before device configure")
Signed-off-by: Wan Junjie <wanjunjie@bytedance.com>
---
app/test/test_link_bonding.c | 4 +++
| 4 +++
drivers/net/bonding/eth_bond_private.h | 4 +++
drivers/net/bonding/rte_eth_bond_api.c | 6 ++++
drivers/net/bonding/rte_eth_bond_pmd.c | 43 ++++++++++++++++++++++----
5 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
index dc6fc46b9c..12c50ef393 100644
--- a/app/test/test_link_bonding.c
+++ b/app/test/test_link_bonding.c
@@ -181,6 +181,10 @@ configure_ethdev(uint16_t port_id, uint8_t start, uint8_t en_isr)
test_params->nb_tx_q, &default_pmd_conf),
"rte_eth_dev_configure for port %d failed", port_id);
+ int ret = rte_eth_dev_set_mtu(port_id, 1550);
+ RTE_TEST_ASSERT(ret == 0 || ret == -ENOTSUP,
+ "rte_eth_dev_set_mtu for port %d failed", port_id);
+
for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
rte_eth_dev_socket_id(port_id), &rx_conf_default,
--git a/app/test/test_link_bonding_rssconf.c b/app/test/test_link_bonding_rssconf.c
index f9eae93973..7228965ced 100644
--- a/app/test/test_link_bonding_rssconf.c
+++ b/app/test/test_link_bonding_rssconf.c
@@ -128,6 +128,10 @@ configure_ethdev(uint16_t port_id, struct rte_eth_conf *eth_conf,
RXTX_QUEUE_COUNT, eth_conf) == 0, "Failed to configure device %u",
port_id);
+ int ret = rte_eth_dev_set_mtu(port_id, 1550);
+ RTE_TEST_ASSERT(ret == 0 || ret == -ENOTSUP,
+ "rte_eth_dev_set_mtu for port %d failed", port_id);
+
for (rxq = 0; rxq < RXTX_QUEUE_COUNT; rxq++) {
TEST_ASSERT(rte_eth_rx_queue_setup(port_id, rxq, RXTX_RING_SIZE,
rte_eth_dev_socket_id(port_id), NULL,
diff --git a/drivers/net/bonding/eth_bond_private.h b/drivers/net/bonding/eth_bond_private.h
index 156335c425..8222e3cd38 100644
--- a/drivers/net/bonding/eth_bond_private.h
+++ b/drivers/net/bonding/eth_bond_private.h
@@ -246,6 +246,10 @@ int
slave_configure(struct rte_eth_dev *bonded_eth_dev,
struct rte_eth_dev *slave_eth_dev);
+int
+slave_start(struct rte_eth_dev *bonded_eth_dev,
+ struct rte_eth_dev *slave_eth_dev);
+
void
slave_remove(struct bond_dev_private *internals,
struct rte_eth_dev *slave_eth_dev);
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index b78867b125..4ac191c468 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -566,6 +566,12 @@ __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id)
slave_port_id);
return -1;
}
+ if (slave_start(bonded_eth_dev, slave_eth_dev) != 0) {
+ internals->slave_count--;
+ RTE_BOND_LOG(ERR, "rte_bond_slaves_start: port=%d",
+ slave_port_id);
+ return -1;
+ }
}
/* Update all slave devices MACs */
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index bfa931098e..58dad0a0e3 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1678,14 +1678,10 @@ int
slave_configure(struct rte_eth_dev *bonded_eth_dev,
struct rte_eth_dev *slave_eth_dev)
{
- struct bond_rx_queue *bd_rx_q;
- struct bond_tx_queue *bd_tx_q;
uint16_t nb_rx_queues;
uint16_t nb_tx_queues;
int errval;
- uint16_t q_id;
- struct rte_flow_error flow_error;
struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
@@ -1758,6 +1754,19 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
slave_eth_dev->data->port_id, errval);
return errval;
}
+ return 0;
+}
+
+int
+slave_start(struct rte_eth_dev *bonded_eth_dev,
+ struct rte_eth_dev *slave_eth_dev)
+{
+ int errval = 0;
+ struct bond_rx_queue *bd_rx_q;
+ struct bond_tx_queue *bd_tx_q;
+ uint16_t q_id;
+ struct rte_flow_error flow_error;
+ struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
/* Setup Rx Queues */
for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
@@ -1806,10 +1815,13 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
return errval;
}
- if (internals->mode4.dedicated_queues.flow[slave_eth_dev->data->port_id] != NULL)
- rte_flow_destroy(slave_eth_dev->data->port_id,
+ if (internals->mode4.dedicated_queues.flow[slave_eth_dev->data->port_id] != NULL) {
+ errval = rte_flow_destroy(slave_eth_dev->data->port_id,
internals->mode4.dedicated_queues.flow[slave_eth_dev->data->port_id],
&flow_error);
+ RTE_BOND_LOG(ERR, "bond_ethdev_8023ad_flow_destroy: port=%d, err (%d)",
+ slave_eth_dev->data->port_id, errval);
+ }
errval = bond_ethdev_8023ad_flow_set(bonded_eth_dev,
slave_eth_dev->data->port_id);
@@ -2001,6 +2013,13 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
internals->slaves[i].port_id);
goto out_err;
}
+ if (slave_start(eth_dev, slave_ethdev) != 0) {
+ RTE_BOND_LOG(ERR,
+ "bonded port (%d) failed to start slave device (%d)",
+ eth_dev->data->port_id,
+ internals->slaves[i].port_id);
+ goto out_err;
+ }
/* We will need to poll for link status if any slave doesn't
* support interrupts
*/
@@ -3847,6 +3866,18 @@ bond_ethdev_configure(struct rte_eth_dev *dev)
return -1;
}
+ /* configure slaves so we can pass mtu setting */
+ for (i = 0; i < internals->slave_count; i++) {
+ struct rte_eth_dev *slave_ethdev =
+ &(rte_eth_devices[internals->slaves[i].port_id]);
+ if (slave_configure(dev, slave_ethdev) != 0) {
+ RTE_BOND_LOG(ERR,
+ "bonded port (%d) failed to configure slave device (%d)",
+ dev->data->port_id,
+ internals->slaves[i].port_id);
+ return -1;
+ }
+ }
return 0;
}
--
2.33.0
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] net/bonding: fix slaves initializing on mtu setting
2022-03-04 1:22 ` [PATCH] net/bonding: fix slaves initializing on mtu setting Min Hu (Connor)
@ 2022-03-04 1:27 ` Min Hu (Connor)
0 siblings, 0 replies; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:27 UTC (permalink / raw)
To: dev
Cc: Wan Junjie, Chas Williams, Ferruh Yigit, Andrew Rybchenko, Ivan Ilchenko
Sorry, this patch should be skipped.
在 2022/3/4 9:22, Min Hu (Connor) 写道:
> From: Wan Junjie <wanjunjie@bytedance.com>
>
> If a initial process for the bonding device is like:
> rte_eth_dev_configure
> rte_eth_dev_set_mtu
> queue setup and start, etc.
>
> Pass the vdev args to application, and init bonding device only.
> -a 0000:af:00.0 --vdev="net_bonding0,mode=2,slave=0000:af:00.0"
>
> It will fail and compain for the slave device
> "Port 0 must be configured before MTU set"
>
> Test can be reproduced with ovs.
>
> Fixes: b26bee1 ("ethdev: forbid MTU set before device configure")
>
> Signed-off-by: Wan Junjie <wanjunjie@bytedance.com>
> ---
> app/test/test_link_bonding.c | 4 +++
> app/test/test_link_bonding_rssconf.c | 4 +++
> drivers/net/bonding/eth_bond_private.h | 4 +++
> drivers/net/bonding/rte_eth_bond_api.c | 6 ++++
> drivers/net/bonding/rte_eth_bond_pmd.c | 43 ++++++++++++++++++++++----
> 5 files changed, 55 insertions(+), 6 deletions(-)
>
> diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
> index dc6fc46b9c..12c50ef393 100644
> --- a/app/test/test_link_bonding.c
> +++ b/app/test/test_link_bonding.c
> @@ -181,6 +181,10 @@ configure_ethdev(uint16_t port_id, uint8_t start, uint8_t en_isr)
> test_params->nb_tx_q, &default_pmd_conf),
> "rte_eth_dev_configure for port %d failed", port_id);
>
> + int ret = rte_eth_dev_set_mtu(port_id, 1550);
> + RTE_TEST_ASSERT(ret == 0 || ret == -ENOTSUP,
> + "rte_eth_dev_set_mtu for port %d failed", port_id);
> +
> for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
> TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
> rte_eth_dev_socket_id(port_id), &rx_conf_default,
> diff --git a/app/test/test_link_bonding_rssconf.c b/app/test/test_link_bonding_rssconf.c
> index f9eae93973..7228965ced 100644
> --- a/app/test/test_link_bonding_rssconf.c
> +++ b/app/test/test_link_bonding_rssconf.c
> @@ -128,6 +128,10 @@ configure_ethdev(uint16_t port_id, struct rte_eth_conf *eth_conf,
> RXTX_QUEUE_COUNT, eth_conf) == 0, "Failed to configure device %u",
> port_id);
>
> + int ret = rte_eth_dev_set_mtu(port_id, 1550);
> + RTE_TEST_ASSERT(ret == 0 || ret == -ENOTSUP,
> + "rte_eth_dev_set_mtu for port %d failed", port_id);
> +
> for (rxq = 0; rxq < RXTX_QUEUE_COUNT; rxq++) {
> TEST_ASSERT(rte_eth_rx_queue_setup(port_id, rxq, RXTX_RING_SIZE,
> rte_eth_dev_socket_id(port_id), NULL,
> diff --git a/drivers/net/bonding/eth_bond_private.h b/drivers/net/bonding/eth_bond_private.h
> index 156335c425..8222e3cd38 100644
> --- a/drivers/net/bonding/eth_bond_private.h
> +++ b/drivers/net/bonding/eth_bond_private.h
> @@ -246,6 +246,10 @@ int
> slave_configure(struct rte_eth_dev *bonded_eth_dev,
> struct rte_eth_dev *slave_eth_dev);
>
> +int
> +slave_start(struct rte_eth_dev *bonded_eth_dev,
> + struct rte_eth_dev *slave_eth_dev);
> +
> void
> slave_remove(struct bond_dev_private *internals,
> struct rte_eth_dev *slave_eth_dev);
> diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
> index b78867b125..4ac191c468 100644
> --- a/drivers/net/bonding/rte_eth_bond_api.c
> +++ b/drivers/net/bonding/rte_eth_bond_api.c
> @@ -566,6 +566,12 @@ __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id)
> slave_port_id);
> return -1;
> }
> + if (slave_start(bonded_eth_dev, slave_eth_dev) != 0) {
> + internals->slave_count--;
> + RTE_BOND_LOG(ERR, "rte_bond_slaves_start: port=%d",
> + slave_port_id);
> + return -1;
> + }
> }
>
> /* Update all slave devices MACs */
> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
> index bfa931098e..58dad0a0e3 100644
> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> @@ -1678,14 +1678,10 @@ int
> slave_configure(struct rte_eth_dev *bonded_eth_dev,
> struct rte_eth_dev *slave_eth_dev)
> {
> - struct bond_rx_queue *bd_rx_q;
> - struct bond_tx_queue *bd_tx_q;
> uint16_t nb_rx_queues;
> uint16_t nb_tx_queues;
>
> int errval;
> - uint16_t q_id;
> - struct rte_flow_error flow_error;
>
> struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
>
> @@ -1758,6 +1754,19 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
> slave_eth_dev->data->port_id, errval);
> return errval;
> }
> + return 0;
> +}
> +
> +int
> +slave_start(struct rte_eth_dev *bonded_eth_dev,
> + struct rte_eth_dev *slave_eth_dev)
> +{
> + int errval = 0;
> + struct bond_rx_queue *bd_rx_q;
> + struct bond_tx_queue *bd_tx_q;
> + uint16_t q_id;
> + struct rte_flow_error flow_error;
> + struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
>
> /* Setup Rx Queues */
> for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
> @@ -1806,10 +1815,13 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
> return errval;
> }
>
> - if (internals->mode4.dedicated_queues.flow[slave_eth_dev->data->port_id] != NULL)
> - rte_flow_destroy(slave_eth_dev->data->port_id,
> + if (internals->mode4.dedicated_queues.flow[slave_eth_dev->data->port_id] != NULL) {
> + errval = rte_flow_destroy(slave_eth_dev->data->port_id,
> internals->mode4.dedicated_queues.flow[slave_eth_dev->data->port_id],
> &flow_error);
> + RTE_BOND_LOG(ERR, "bond_ethdev_8023ad_flow_destroy: port=%d, err (%d)",
> + slave_eth_dev->data->port_id, errval);
> + }
>
> errval = bond_ethdev_8023ad_flow_set(bonded_eth_dev,
> slave_eth_dev->data->port_id);
> @@ -2001,6 +2013,13 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
> internals->slaves[i].port_id);
> goto out_err;
> }
> + if (slave_start(eth_dev, slave_ethdev) != 0) {
> + RTE_BOND_LOG(ERR,
> + "bonded port (%d) failed to start slave device (%d)",
> + eth_dev->data->port_id,
> + internals->slaves[i].port_id);
> + goto out_err;
> + }
> /* We will need to poll for link status if any slave doesn't
> * support interrupts
> */
> @@ -3847,6 +3866,18 @@ bond_ethdev_configure(struct rte_eth_dev *dev)
> return -1;
> }
>
> + /* configure slaves so we can pass mtu setting */
> + for (i = 0; i < internals->slave_count; i++) {
> + struct rte_eth_dev *slave_ethdev =
> + &(rte_eth_devices[internals->slaves[i].port_id]);
> + if (slave_configure(dev, slave_ethdev) != 0) {
> + RTE_BOND_LOG(ERR,
> + "bonded port (%d) failed to configure slave device (%d)",
> + dev->data->port_id,
> + internals->slaves[i].port_id);
> + return -1;
> + }
> + }
> return 0;
> }
>
>
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] 1 version
2022-03-04 1:22 ` [PATCH] 1 version Min Hu (Connor)
` (3 preceding siblings ...)
2022-03-04 1:22 ` [PATCH] net/bonding: fix slaves initializing on mtu setting Min Hu (Connor)
@ 2022-03-04 1:25 ` Min Hu (Connor)
4 siblings, 0 replies; 39+ messages in thread
From: Min Hu (Connor) @ 2022-03-04 1:25 UTC (permalink / raw)
To: dev; +Cc: Maryam Tahhan, Reshma Pattan, Yisen Zhuang, Lijun Ou
Sorry, this patch should be abandoned.
在 2022/3/4 9:22, Min Hu (Connor) 写道:
> ---
> app/proc-info/main.c | 253 ++++++++
> drivers/net/hns3/hns3_ethdev.c | 3 +-
> drivers/net/hns3/hns3_ethdev.h | 3 +
> drivers/net/hns3/hns3_ethdev_dump.c | 917 ++++++++++++++++++++++++++++
> drivers/net/hns3/hns3_ethdev_vf.c | 1 +
> drivers/net/hns3/meson.build | 1 +
> 6 files changed, 1177 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/hns3/hns3_ethdev_dump.c
>
> diff --git a/app/proc-info/main.c b/app/proc-info/main.c
> index 56070a3317..1d4f058d7b 100644
> --- a/app/proc-info/main.c
> +++ b/app/proc-info/main.c
> @@ -48,6 +48,12 @@
> #define STATS_BDR_STR(w, s) printf("%.*s%s%.*s\n", w, \
> STATS_BDR_FMT, s, w, STATS_BDR_FMT)
>
> +/** Information for a given RSS type. */
> +struct rss_type_info {
> + const char *str; /**< Type name. */
> + uint64_t rss_type; /**< Type value. */
> +};
> +
> /**< mask of enabled ports */
> static unsigned long enabled_port_mask;
> /**< Enable stats. */
> @@ -84,6 +90,8 @@ static char bdr_str[MAX_STRING_LEN];
>
> /**< Enable show port. */
> static uint32_t enable_shw_port;
> +/**< Enable show port. */
> +static uint32_t enable_shw_port_priv;
> /**< Enable show tm. */
> static uint32_t enable_shw_tm;
> /**< Enable show crypto. */
> @@ -101,6 +109,84 @@ static char *mempool_iter_name;
> static uint32_t enable_dump_regs;
> static char *dump_regs_file_prefix;
>
> +static const struct rss_type_info rss_type_table[] = {
> + { "all", RTE_ETH_RSS_ETH | RTE_ETH_RSS_VLAN | RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP |
> + RTE_ETH_RSS_UDP | RTE_ETH_RSS_SCTP | RTE_ETH_RSS_L2_PAYLOAD |
> + RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_ESP | RTE_ETH_RSS_AH | RTE_ETH_RSS_PFCP |
> + RTE_ETH_RSS_GTPU | RTE_ETH_RSS_ECPRI | RTE_ETH_RSS_MPLS},
> + { "none", 0 },
> + { "eth", RTE_ETH_RSS_ETH },
> + { "l2-src-only", RTE_ETH_RSS_L2_SRC_ONLY },
> + { "l2-dst-only", RTE_ETH_RSS_L2_DST_ONLY },
> + { "vlan", RTE_ETH_RSS_VLAN },
> + { "s-vlan", RTE_ETH_RSS_S_VLAN },
> + { "c-vlan", RTE_ETH_RSS_C_VLAN },
> + { "ipv4", RTE_ETH_RSS_IPV4 },
> + { "ipv4-frag", RTE_ETH_RSS_FRAG_IPV4 },
> + { "ipv4-tcp", RTE_ETH_RSS_NONFRAG_IPV4_TCP },
> + { "ipv4-udp", RTE_ETH_RSS_NONFRAG_IPV4_UDP },
> + { "ipv4-sctp", RTE_ETH_RSS_NONFRAG_IPV4_SCTP },
> + { "ipv4-other", RTE_ETH_RSS_NONFRAG_IPV4_OTHER },
> + { "ipv6", RTE_ETH_RSS_IPV6 },
> + { "ipv6-frag", RTE_ETH_RSS_FRAG_IPV6 },
> + { "ipv6-tcp", RTE_ETH_RSS_NONFRAG_IPV6_TCP },
> + { "ipv6-udp", RTE_ETH_RSS_NONFRAG_IPV6_UDP },
> + { "ipv6-sctp", RTE_ETH_RSS_NONFRAG_IPV6_SCTP },
> + { "ipv6-other", RTE_ETH_RSS_NONFRAG_IPV6_OTHER },
> + { "l2-payload", RTE_ETH_RSS_L2_PAYLOAD },
> + { "ipv6-ex", RTE_ETH_RSS_IPV6_EX },
> + { "ipv6-tcp-ex", RTE_ETH_RSS_IPV6_TCP_EX },
> + { "ipv6-udp-ex", RTE_ETH_RSS_IPV6_UDP_EX },
> + { "port", RTE_ETH_RSS_PORT },
> + { "vxlan", RTE_ETH_RSS_VXLAN },
> + { "geneve", RTE_ETH_RSS_GENEVE },
> + { "nvgre", RTE_ETH_RSS_NVGRE },
> + { "ip", RTE_ETH_RSS_IP },
> + { "udp", RTE_ETH_RSS_UDP },
> + { "tcp", RTE_ETH_RSS_TCP },
> + { "sctp", RTE_ETH_RSS_SCTP },
> + { "tunnel", RTE_ETH_RSS_TUNNEL },
> + { "l3-pre32", RTE_ETH_RSS_L3_PRE32 },
> + { "l3-pre40", RTE_ETH_RSS_L3_PRE40 },
> + { "l3-pre48", RTE_ETH_RSS_L3_PRE48 },
> + { "l3-pre56", RTE_ETH_RSS_L3_PRE56 },
> + { "l3-pre64", RTE_ETH_RSS_L3_PRE64 },
> + { "l3-pre96", RTE_ETH_RSS_L3_PRE96 },
> + { "l3-src-only", RTE_ETH_RSS_L3_SRC_ONLY },
> + { "l3-dst-only", RTE_ETH_RSS_L3_DST_ONLY },
> + { "l4-src-only", RTE_ETH_RSS_L4_SRC_ONLY },
> + { "l4-dst-only", RTE_ETH_RSS_L4_DST_ONLY },
> + { "esp", RTE_ETH_RSS_ESP },
> + { "ah", RTE_ETH_RSS_AH },
> + { "l2tpv3", RTE_ETH_RSS_L2TPV3 },
> + { "pfcp", RTE_ETH_RSS_PFCP },
> + { "pppoe", RTE_ETH_RSS_PPPOE },
> + { "gtpu", RTE_ETH_RSS_GTPU },
> + { "ecpri", RTE_ETH_RSS_ECPRI },
> + { "mpls", RTE_ETH_RSS_MPLS },
> + { "ipv4-chksum", RTE_ETH_RSS_IPV4_CHKSUM },
> + { "l4-chksum", RTE_ETH_RSS_L4_CHKSUM },
> + { NULL, 0 },
> +};
> +
> +/** Information for a ethernet speed info. */
> +static const struct {
> + uint32_t speed;
> + const char *str;
> +} eth_speed_table[] = {
> + { RTE_ETH_LINK_SPEED_10M_HD, "10Mbps-HD" },
> + { RTE_ETH_LINK_SPEED_10M, "10Mbps" },
> + { RTE_ETH_LINK_SPEED_100M_HD, "100Mbps-HD" },
> + { RTE_ETH_LINK_SPEED_100M, "100Mbps" },
> + { RTE_ETH_LINK_SPEED_1G, "1Gbps" },
> + { RTE_ETH_LINK_SPEED_10G, "10Gbps" },
> + { RTE_ETH_LINK_SPEED_25G, "25Gbps" },
> + { RTE_ETH_LINK_SPEED_40G, "40Gbps" },
> + { RTE_ETH_LINK_SPEED_50G, "50Gbps" },
> + { RTE_ETH_LINK_SPEED_100G, "100Gbps" },
> + { RTE_ETH_LINK_SPEED_200G, "200Gbps" },
> +};
> +
> /**< display usage */
> static void
> proc_info_usage(const char *prgname)
> @@ -123,6 +209,7 @@ proc_info_usage(const char *prgname)
> " --collectd-format: to print statistics to STDOUT in expected by collectd format\n"
> " --host-id STRING: host id used to identify the system process is running on\n"
> " --show-port: to display ports information\n"
> + " --show-port-private: to display ports private information\n"
> " --show-tm: to display traffic manager information for ports\n"
> " --show-crypto: to display crypto information\n"
> " --show-ring[=name]: to display ring information\n"
> @@ -232,6 +319,7 @@ proc_info_parse_args(int argc, char **argv)
> {"xstats-ids", 1, NULL, 1},
> {"host-id", 0, NULL, 0},
> {"show-port", 0, NULL, 0},
> + {"show-port-private", 0, NULL, 0},
> {"show-tm", 0, NULL, 0},
> {"show-crypto", 0, NULL, 0},
> {"show-ring", optional_argument, NULL, 0},
> @@ -284,6 +372,9 @@ proc_info_parse_args(int argc, char **argv)
> else if (!strncmp(long_option[option_index].name,
> "show-port", MAX_LONG_OPT_SZ))
> enable_shw_port = 1;
> + else if (!strncmp(long_option[option_index].name,
> + "show-port-private", MAX_LONG_OPT_SZ))
> + enable_shw_port_priv = 1;
> else if (!strncmp(long_option[option_index].name,
> "show-tm", MAX_LONG_OPT_SZ))
> enable_shw_tm = 1;
> @@ -708,6 +799,118 @@ show_offloads(uint64_t offloads,
> }
> }
>
> +static void
> +show_dev_info(struct rte_eth_dev_info *dev_info)
> +{
> + printf(" - device info\n");
> + printf("\t -- maximum number of MAC addresses: %u\n"
> + "\t -- maximum number of MAC addresses of hash filtering: %u\n"
> + "\t -- hash key size in bytes: %u\n"
> + "\t -- redirection table size: %u\n"
> + "\t -- RSS offload flow type: 0x%"PRIx64"\n"
> + "\t -- minimum size of RX buffer: %u\n"
> + "\t -- maximum configurable length of RX packet: %u\n"
> + "\t -- maximum number of VFs: %u\n"
> + "\t -- maximum number of VMDq pools: %u\n"
> + "\t -- current number of RX queues: %u\n"
> + "\t -- max possible RX queues: %u\n"
> + "\t -- current number of TX queues: %u\n"
> + "\t -- max possible TX queues: %u\n"
> + "\t -- max segment number per packet of TX: %u\n"
> + "\t -- max segment number per MTU/TSO of TX: %u\n",
> + dev_info->max_mac_addrs, dev_info->max_hash_mac_addrs,
> + dev_info->hash_key_size, dev_info->reta_size,
> + dev_info->flow_type_rss_offloads,
> + dev_info->min_rx_bufsize, dev_info->max_rx_pktlen,
> + dev_info->max_vfs, dev_info->max_vmdq_pools,
> + dev_info->nb_rx_queues, dev_info->max_rx_queues,
> + dev_info->nb_tx_queues, dev_info->max_tx_queues,
> + dev_info->tx_desc_lim.nb_seg_max,
> + dev_info->tx_desc_lim.nb_mtu_seg_max);
> +}
> +
> +static void
> +show_port_rss_info(uint16_t port_id, struct rte_eth_dev_info *dev_info)
> +{
> +#define RSS_HASH_KEY_LENGTH 64
> + struct rte_eth_rss_conf rss_conf = {0};
> + uint8_t rss_key[RSS_HASH_KEY_LENGTH];
> + uint8_t hash_key_size;
> + uint64_t rss_hf;
> + uint8_t i;
> + int ret;
> +
> + if (dev_info->hash_key_size > 0 &&
> + dev_info->hash_key_size <= sizeof(rss_key))
> + hash_key_size = dev_info->hash_key_size;
> + else
> + return;
> +
> + rss_conf.rss_key = rss_key;
> + rss_conf.rss_key_len = hash_key_size;
> + ret = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
> + if (ret != 0)
> + return;
> +
> + printf(" - RSS info\n");
> + rss_hf = rss_conf.rss_hf;
> + if (rss_hf == 0) {
> + printf("\t -- RSS disabled");
> + return;
> + }
> + ret = printf("\t -- RSS functions: ");
> +
> + for (i = 0; rss_type_table[i].str; i++)
> + if (rss_hf & rss_type_table[i].rss_type)
> + printf("%s ", rss_type_table[i].str);
> + printf("\n");
> + printf("\t -- RSS key: ");
> +
> + for (i = 0; i < rss_conf.rss_key_len; i++)
> + printf("%02X", rss_conf.rss_key[i]);
> + printf("\n");
> +}
> +
> +static void
> +show_dev_speed_capability(uint32_t speed_capa)
> +{
> + int size = RTE_DIM(eth_speed_table);
> + int i;
> +
> + printf(" - Device Speed Capability: ");
> + for (i = 0; i < size; i++)
> + if (speed_capa & eth_speed_table[i].speed)
> + printf("%s ", eth_speed_table[i].str);
> +
> + if (!(speed_capa & RTE_ETH_LINK_SPEED_FIXED))
> + printf("auto");
> +
> + printf("\n");
> +}
> +
> +static void
> +show_dev_rxtx_burst_mode(uint16_t port_id)
> +{
> + struct rte_eth_burst_mode rx_mode;
> + struct rte_eth_burst_mode tx_mode;
> +
> + memset(&rx_mode, 0, sizeof(rx_mode));
> + memset(&tx_mode, 0, sizeof(tx_mode));
> +
> + if (rte_eth_rx_burst_mode_get(port_id, 0, &rx_mode) == 0 &&
> + rte_eth_tx_burst_mode_get(port_id, 0, &tx_mode) == 0) {
> + printf(" - Burst mode:\n");
> + printf("\t -- Rx burst mode: %s%s\n"
> + "\t -- Tx burst mode: %s%s\n",
> + rx_mode.info,
> + rx_mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
> + " (per queue)" : "",
> + tx_mode.info,
> + tx_mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
> + " (per queue)" : "");
> + }
> +}
> +
> static void
> show_port(void)
> {
> @@ -725,6 +928,7 @@ show_port(void)
> struct rte_eth_fc_conf fc_conf;
> struct rte_ether_addr mac;
> struct rte_eth_dev_owner owner;
> + int vlan_offload;
>
> /* Skip if port is not in mask */
> if ((enabled_port_mask & (1ul << i)) == 0)
> @@ -803,6 +1007,25 @@ show_port(void)
> if (ret == 0)
> printf("\t -- mtu (%d)\n", mtu);
>
> + if (dev_info.rx_offload_capa != 0) {
> + printf(" - device capability Rx");
> + show_offloads(dev_info.rx_offload_capa,
> + rte_eth_dev_rx_offload_name);
> + printf("\n");
> + }
> +
> + if (dev_info.tx_offload_capa != 0) {
> + printf(" - device capability Tx");
> + show_offloads(dev_info.tx_offload_capa,
> + rte_eth_dev_tx_offload_name);
> + printf("\n");
> + }
> +
> + show_dev_speed_capability(dev_info.speed_capa);
> + show_dev_info(&dev_info);
> + show_port_rss_info(i, &dev_info);
> + show_dev_rxtx_burst_mode(i);
> +
> for (j = 0; j < dev_info.nb_rx_queues; j++) {
> struct rte_eth_rxq_info queue_info;
> int count;
> @@ -881,12 +1104,38 @@ show_port(void)
> }
> }
>
> + vlan_offload = rte_eth_dev_get_vlan_offload(i);
> + printf(" - VLAN offload: 0x%x\n", vlan_offload);
> +
> #ifdef RTE_LIB_SECURITY
> show_security_context(i, true);
> #endif
> }
> }
>
> +static void
> +show_port_private_info(void)
> +{
> + int i;
> +
> + snprintf(bdr_str, MAX_STRING_LEN, " show - Port PMD Private ");
> + STATS_BDR_STR(10, bdr_str);
> +
> + for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
> + /* Skip if port is not in mask */
> + if ((enabled_port_mask & (1ul << i)) == 0)
> + continue;
> +
> + /* Skip if port is unused */
> + if (!rte_eth_dev_is_valid_port(i))
> + continue;
> +
> + snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i);
> + STATS_BDR_STR(5, bdr_str);
> + rte_eth_dev_priv_dump(i, stdout);
> + }
> +}
> +
> static void
> display_nodecap_info(int is_leaf, struct rte_tm_node_capabilities *cap)
> {
> @@ -1549,6 +1798,8 @@ main(int argc, char **argv)
> /* show information for PMD */
> if (enable_shw_port)
> show_port();
> + if (enable_shw_port_priv)
> + show_port_private_info();
> if (enable_shw_tm)
> show_tm();
> if (enable_shw_crypto)
> @@ -1561,6 +1812,8 @@ main(int argc, char **argv)
> iter_mempool(mempool_iter_name);
> if (enable_dump_regs)
> dump_regs(dump_regs_file_prefix);
> + if (enable_dump_regs)
> + dump_regs(dump_regs_file_prefix);
>
> RTE_ETH_FOREACH_DEV(i)
> rte_eth_dev_close(i);
> diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
> index 2641b6f79b..4e089e682f 100644
> --- a/drivers/net/hns3/hns3_ethdev.c
> +++ b/drivers/net/hns3/hns3_ethdev.c
> @@ -5350,7 +5350,7 @@ hns3_get_current_fc_mode(struct rte_eth_dev *dev)
> return hns3_get_autoneg_fc_mode(hw);
> }
>
> -static int
> +int
> hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
> {
> struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> @@ -6568,6 +6568,7 @@ static const struct eth_dev_ops hns3_eth_dev_ops = {
> .timesync_adjust_time = hns3_timesync_adjust_time,
> .timesync_read_time = hns3_timesync_read_time,
> .timesync_write_time = hns3_timesync_write_time,
> + .eth_dev_priv_dump = hns3_eth_dev_priv_dump,
> };
>
> static const struct hns3_reset_ops hns3_reset_ops = {
> diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
> index ef028a7b2c..9a0fa09b57 100644
> --- a/drivers/net/hns3/hns3_ethdev.h
> +++ b/drivers/net/hns3/hns3_ethdev.h
> @@ -1030,6 +1030,8 @@ hns3_test_and_clear_bit(unsigned int nr, volatile uint64_t *addr)
> return __atomic_fetch_and(addr, ~mask, __ATOMIC_RELAXED) & mask;
> }
>
> +int
> +hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf);
> uint32_t hns3_get_speed_capa(struct hns3_hw *hw);
>
> int hns3_buffer_alloc(struct hns3_hw *hw);
> @@ -1055,6 +1057,7 @@ int hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts);
> int hns3_timesync_write_time(struct rte_eth_dev *dev,
> const struct timespec *ts);
> int hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);
> +int hns3_eth_dev_priv_dump(struct rte_eth_dev *dev, FILE *file);
>
> static inline bool
> is_reset_pending(struct hns3_adapter *hns)
> diff --git a/drivers/net/hns3/hns3_ethdev_dump.c b/drivers/net/hns3/hns3_ethdev_dump.c
> new file mode 100644
> index 0000000000..1ceb42d57e
> --- /dev/null
> +++ b/drivers/net/hns3/hns3_ethdev_dump.c
> @@ -0,0 +1,917 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2021 HiSilicon Limited
> + */
> +
> +#include <rte_kvargs.h>
> +#include <rte_bus_pci.h>
> +#include <ethdev_pci.h>
> +#include <rte_pci.h>
> +
> +#include "hns3_common.h"
> +#include "hns3_logs.h"
> +#include "hns3_regs.h"
> +#include "hns3_rxtx.h"
> +
> +static const char *
> +get_adapter_state_name(uint32_t state)
> +{
> + static const char * const state_name[] = {
> + "UNINITIALIZED",
> + "INITIALIZED",
> + "CONFIGURING",
> + "CONFIGURED",
> + "STARTING",
> + "STARTED",
> + "STOPPING",
> + "CLOSING",
> + "CLOSED",
> + "REMOVED",
> + "NSTATES"
> + };
> +
> + if (state < RTE_DIM(state_name))
> + return state_name[state];
> + else
> + return "unknown";
> +}
> +
> +static const char *
> +get_io_func_hint_name(uint32_t hint)
> +{
> + switch (hint) {
> + case HNS3_IO_FUNC_HINT_NONE:
> + return "none";
> + case HNS3_IO_FUNC_HINT_VEC:
> + return "vec";
> + case HNS3_IO_FUNC_HINT_SVE:
> + return "sve";
> + case HNS3_IO_FUNC_HINT_SIMPLE:
> + return "simple";
> + case HNS3_IO_FUNC_HINT_COMMON:
> + return "common";
> + default:
> + return "unknown";
> + }
> +}
> +
> +static void
> +get_dev_mac_info(FILE *file, struct hns3_adapter *hns)
> +{
> + struct hns3_hw *hw = &hns->hw;
> + struct hns3_pf *pf = &hns->pf;
> +
> + fprintf(file, " - MAC Info:\n");
> + fprintf(file,
> + "\t -- query_type=%u\n"
> + "\t -- supported_speed=0x%x\n"
> + "\t -- advertising=0x%x\n"
> + "\t -- lp_advertising=0x%x\n"
> + "\t -- support_autoneg=%s\n"
> + "\t -- support_fc_autoneg=%s\n",
> + hw->mac.query_type,
> + hw->mac.supported_speed,
> + hw->mac.advertising,
> + hw->mac.lp_advertising,
> + hw->mac.support_autoneg != 0 ? "Yes" : "No",
> + pf->support_fc_autoneg ? "Yes" : "No");
> +}
> +
> +static void
> +get_dev_feature_capability(FILE *file, struct hns3_hw *hw)
> +{
> + const char * const caps_name[] = {
> + "DCB",
> + "COPPER",
> + "FD QUEUE REGION",
> + "PTP",
> + "TX PUSH",
> + "INDEP TXRX",
> + "STASH",
> + "SIMPLE BD",
> + "RXD Advanced Layout",
> + "OUTER UDP CKSUM",
> + "RAS IMP",
> + "TM",
> + "VF VLAN FILTER MOD",
> + };
> + uint32_t i;
> +
> + fprintf(file, " - Dev Capability:\n");
> + for (i = 0; i < RTE_DIM(caps_name); i++)
> + fprintf(file, "\t -- support %s: %s\n", caps_name[i],
> + hw->capability & BIT(i) ? "yes" : "no");
> +}
> +
> +static const char *
> +get_fdir_tuple_name(uint32_t index)
> +{
> + static const char * const tuple_name[] = {
> + "outer_dst_mac",
> + "outer_src_mac",
> + "outer_vlan_1st_tag",
> + "outer_vlan_2nd_tag",
> + "outer_eth_type",
> + "outer_l2_rsv",
> + "outer_ip_tos",
> + "outer_ip_proto",
> + "outer_src_ip",
> + "outer_dst_ip",
> + "outer_l3_rsv",
> + "outer_src_port",
> + "outer_dst_port",
> + "outer_l4_rsv",
> + "outer_tun_vni",
> + "outer_tun_flow_id",
> + "inner_dst_mac",
> + "inner_src_mac",
> + "inner_vlan_tag1",
> + "inner_vlan_tag2",
> + "inner_eth_type",
> + "inner_l2_rsv",
> + "inner_ip_tos",
> + "inner_ip_proto",
> + "inner_src_ip",
> + "inner_dst_ip",
> + "inner_l3_rsv",
> + "inner_src_port",
> + "inner_dst_port",
> + "inner_sctp_tag",
> + };
> + if (index < RTE_DIM(tuple_name))
> + return tuple_name[index];
> + else
> + return "unknown";
> +}
> +
> +static void
> +get_fdir_basic_info(FILE *file, struct hns3_pf *pf)
> +{
> +#define TMPBUF_SIZE 2048
> +#define PERLINE_TUPLE_NAMES 4
> + struct hns3_fd_cfg *fdcfg = &pf->fdir.fd_cfg;
> + char tmpbuf[TMPBUF_SIZE] = {0};
> + uint32_t i, count = 0;
> +
> + fprintf(file, " - Fdir Info:\n");
> + fprintf(file,
> + "\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n"
> + "\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n"
> + "\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n"
> + "\t -- active_tuples:\n",
> + fdcfg->fd_mode, fdcfg->max_key_length,
> + fdcfg->rule_num[HNS3_FD_STAGE_1],
> + fdcfg->cnt_num[HNS3_FD_STAGE_1],
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].key_sel,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].meta_data_active,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_sipv6_word_en,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en,
> + fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en);
> +
> + for (i = 0; i < MAX_TUPLE; i++) {
> + if (!(fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active & BIT(i)))
> + continue;
> + if (count % PERLINE_TUPLE_NAMES == 0)
> + fprintf(file, "\t ");
> + fprintf(file, " %s", get_fdir_tuple_name(i));
> + count++;
> + if (count % PERLINE_TUPLE_NAMES == 0)
> + fprintf(file, "\n");
> + }
> + if (count % PERLINE_TUPLE_NAMES)
> + fprintf(file, "\n");
> +
> + fprintf(file, "%s", tmpbuf);
> +}
> +
> +static void
> +get_device_basic_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> +
> + fprintf(file,
> + " - Device Base Info:\n"
> + "\t -- name: %s\n"
> + "\t -- adapter_state=%s\n"
> + "\t -- nb_rx_queues=%u nb_tx_queues=%u\n"
> + "\t -- total_tqps_num=%u tqps_num=%u intr_tqps_num=%u\n"
> + "\t -- rss_size_max=%u alloc_rss_size=%u tx_qnum_per_tc=%u\n"
> + "\t -- min_tx_pkt_len=%u intr_mapping_mode=%u vlan_mode=%u\n"
> + "\t -- tso_mode=%u max_non_tso_bd_num=%u\n"
> + "\t -- max_tm_rate=%u Mbps\n"
> + "\t -- set link down: %s\n"
> + "\t -- rx_func_hint=%s tx_func_hint=%s\n"
> + "\t -- dev_flags: lsc=%d\n"
> + "\t -- intr_conf: lsc=%u rxq=%u\n",
> + dev->data->name,
> + get_adapter_state_name(hw->adapter_state),
> + dev->data->nb_rx_queues, dev->data->nb_tx_queues,
> + hw->total_tqps_num, hw->tqps_num, hw->intr_tqps_num,
> + hw->rss_size_max, hw->alloc_rss_size, hw->tx_qnum_per_tc,
> + hw->min_tx_pkt_len, hw->intr.mapping_mode, hw->vlan_mode,
> + hw->tso_mode, hw->max_non_tso_bd_num,
> + hw->max_tm_rate,
> + hw->set_link_down ? "Yes" : "No",
> + get_io_func_hint_name(hns->rx_func_hint),
> + get_io_func_hint_name(hns->tx_func_hint),
> + !!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC),
> + dev->data->dev_conf.intr_conf.lsc,
> + dev->data->dev_conf.intr_conf.rxq);
> +}
> +
> +/*
> + * Note: caller must make sure queue_id < nb_queues
> + * nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
> + * eth_dev->data->nb_tx_queues)
> + */
> +static struct hns3_rx_queue *
> +get_rx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> + unsigned int offset;
> + void **rx_queues;
> +
> + if (queue_id < dev->data->nb_rx_queues) {
> + rx_queues = dev->data->rx_queues;
> + offset = queue_id;
> + } else {
> + /*
> + * For kunpeng930, fake queue is not exist. But since the queues
> + * are usually accessd in pairs, this branch may still exist.
> + */
> + if (hns3_dev_get_support(hw, INDEP_TXRX))
> + return NULL;
> +
> + rx_queues = hw->fkq_data.rx_queues;
> + offset = queue_id - dev->data->nb_rx_queues;
> + }
> +
> + if (rx_queues != NULL && rx_queues[offset] != NULL)
> + return rx_queues[offset];
> +
> + hns3_err(hw, "Detect rx_queues is NULL!\n");
> + return NULL;
> +}
> +
> +/*
> + * Note: caller must make sure queue_id < nb_queues
> + * nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
> + * eth_dev->data->nb_tx_queues)
> + */
> +static struct hns3_tx_queue *
> +get_tx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> + unsigned int offset;
> + void **tx_queues;
> +
> + if (queue_id < dev->data->nb_tx_queues) {
> + tx_queues = dev->data->tx_queues;
> + offset = queue_id;
> + } else {
> + /*
> + * For kunpeng930, fake queue is not exist. But since the queues
> + * are usually accessd in pairs, this branch may still exist.
> + */
> + if (hns3_dev_get_support(hw, INDEP_TXRX))
> + return NULL;
> + tx_queues = hw->fkq_data.tx_queues;
> + offset = queue_id - dev->data->nb_tx_queues;
> + }
> +
> + if (tx_queues != NULL && tx_queues[offset] != NULL)
> + return tx_queues[offset];
> +
> + hns3_err(hw, "Detect tx_queues is NULL!\n");
> + return NULL;
> +}
> +
> +static void
> +get_rxtx_fake_queue_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns);
> + struct hns3_rx_queue *rxq;
> + struct hns3_tx_queue *txq;
> + unsigned int queue_id;
> +
> + if (dev->data->nb_rx_queues != dev->data->nb_tx_queues &&
> + !hns3_dev_get_support(hw, INDEP_TXRX)) {
> + queue_id = RTE_MIN(dev->data->nb_rx_queues,
> + dev->data->nb_tx_queues);
> + rxq = get_rx_queue(dev, queue_id);
> + if (rxq == NULL)
> + return;
> + txq = get_tx_queue(dev, queue_id);
> + if (txq == NULL)
> + return;
> + fprintf(file,
> + "\t -- first fake_queue rxtx info:\n"
> + "\t rx: port=%u nb_desc=%u free_thresh=%u\n"
> + "\t tx: port=%u nb_desc=%u\n",
> + rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
> + txq->port_id, txq->nb_tx_desc);
> + }
> +}
> +
> +static void
> +get_queue_enable_state(struct hns3_hw *hw, uint32_t *queue_state,
> + uint32_t nb_queues, bool is_rxq)
> +{
> +#define STATE_SIZE (sizeof(*queue_state) * CHAR_BIT)
> + uint32_t queue_en_reg;
> + uint32_t reg_offset;
> + uint32_t state;
> + uint32_t i;
> +
> + queue_en_reg = is_rxq ? HNS3_RING_RX_EN_REG : HNS3_RING_TX_EN_REG;
> + for (i = 0; i < nb_queues; i++) {
> + reg_offset = hns3_get_tqp_reg_offset(i);
> + state = hns3_read_dev(hw, reg_offset + HNS3_RING_EN_REG);
> + if (hns3_dev_get_support(hw, INDEP_TXRX))
> + state = state && hns3_read_dev(hw, reg_offset +
> + queue_en_reg);
> + hns3_set_bit(queue_state[i / STATE_SIZE],
> + i % STATE_SIZE, state);
> + }
> +}
> +
> +static void
> +print_queue_state_perline(FILE *file, const uint32_t *queue_state,
> + uint32_t nb_queues, uint32_t line_num)
> +{
> +#define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
> + uint32_t qid = line_num * NUM_QUEUE_PER_LINE;
> + uint32_t j;
> +
> + for (j = 0; j < NUM_QUEUE_PER_LINE; j++) {
> + fprintf(file, "%1lx", hns3_get_bit(queue_state[line_num], j));
> +
> + if (qid % CHAR_BIT == CHAR_BIT - 1) {
> + fprintf(file, "%s",
> + j == NUM_QUEUE_PER_LINE - 1 ? "\n" : ":");
> + }
> + qid++;
> + if (qid >= nb_queues) {
> + fprintf(file, "\n");
> + break;
> + }
> + }
> +}
> +
> +static void
> +display_queue_enable_state(FILE *file, const uint32_t *queue_state,
> + uint32_t nb_queues, bool is_rxq)
> +{
> +#define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
> + uint32_t i;
> +
> + if (nb_queues == 0) {
> + fprintf(file, "\t %s queue number is 0\n",
> + is_rxq ? "Rx" : "Tx");
> + return;
> + }
> +
> + fprintf(file, "\t %s queue id | enable state bitMap\n",
> + is_rxq ? "rx" : "tx");
> +
> + for (i = 0; i < (nb_queues - 1) / NUM_QUEUE_PER_LINE + 1; i++) {
> + uint32_t line_end = (i + 1) * NUM_QUEUE_PER_LINE - 1;
> + uint32_t line_start = i * NUM_QUEUE_PER_LINE;
> + fprintf(file, "\t %04u - %04u | ", line_start,
> + nb_queues - 1 > line_end ? line_end : nb_queues - 1);
> +
> +
> + print_queue_state_perline(file, queue_state, nb_queues, i);
> + }
> +}
> +
> +static void
> +get_rxtx_queue_enable_state(FILE *file, struct rte_eth_dev *dev)
> +{
> +#define MAX_TQP_NUM 1280
> +#define QUEUE_BITMAP_SIZE (MAX_TQP_NUM / 32)
> + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> + uint32_t rx_queue_state[QUEUE_BITMAP_SIZE] = {0};
> + uint32_t tx_queue_state[QUEUE_BITMAP_SIZE] = {0};
> + uint32_t nb_rx_queues;
> + uint32_t nb_tx_queues;
> +
> + nb_rx_queues = dev->data->nb_rx_queues;
> + nb_tx_queues = dev->data->nb_tx_queues;
> +
> + fprintf(file, "\t -- enable state:\n");
> + get_queue_enable_state(hw, rx_queue_state, nb_rx_queues, true);
> + display_queue_enable_state(file, rx_queue_state, nb_rx_queues,
> + true);
> +
> + get_queue_enable_state(hw, tx_queue_state, nb_tx_queues, false);
> + display_queue_enable_state(file, tx_queue_state, nb_tx_queues,
> + false);
> +}
> +
> +static void
> +get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_rx_queue *rxq;
> + struct hns3_tx_queue *txq;
> + unsigned int queue_id = 0;
> +
> + rxq = get_rx_queue(dev, queue_id);
> + if (rxq == NULL)
> + return;
> + txq = get_tx_queue(dev, queue_id);
> + if (txq == NULL)
> + return;
> + fprintf(file, " - Rx/Tx Queue Info:\n");
> + fprintf(file,
> + "\t -- nb_rx_queues=%u nb_tx_queues=%u, "
> + "first queue rxtx info:\n"
> + "\t rx: port=%u nb_desc=%u free_thresh=%u\n"
> + "\t tx: port=%u nb_desc=%u\n"
> + "\t -- tx push: %s\n",
> + dev->data->nb_rx_queues,
> + dev->data->nb_tx_queues,
> + rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
> + txq->port_id, txq->nb_tx_desc,
> + txq->tx_push_enable ? "enabled" : "disabled");
> +
> + get_rxtx_fake_queue_info(file, dev);
> + get_rxtx_queue_enable_state(file, dev);
> +}
> +
> +static int
> +get_vlan_filter_cfg(FILE *file, struct hns3_hw *hw)
> +{
> +#define HNS3_FILTER_TYPE_VF 0
> +#define HNS3_FILTER_TYPE_PORT 1
> +#define HNS3_FILTER_FE_NIC_INGRESS_B BIT(0)
> +#define HNS3_FILTER_FE_NIC_EGRESS_B BIT(1)
> + struct hns3_vlan_filter_ctrl_cmd *req;
> + struct hns3_cmd_desc desc;
> + uint8_t i;
> + int ret;
> +
> + static const uint32_t vlan_filter_type[] = {
> + HNS3_FILTER_TYPE_PORT,
> + HNS3_FILTER_TYPE_VF
> + };
> +
> + for (i = 0; i < RTE_DIM(vlan_filter_type); i++) {
> + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_FILTER_CTRL,
> + true);
> + req = (struct hns3_vlan_filter_ctrl_cmd *)desc.data;
> + req->vlan_type = vlan_filter_type[i];
> + req->vf_id = HNS3_PF_FUNC_ID;
> + ret = hns3_cmd_send(hw, &desc, 1);
> + if (ret != 0) {
> + hns3_err(hw,
> + "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
> + ret, 1, rte_le_to_cpu_16(desc.opcode));
> + return ret;
> + }
> + fprintf(file,
> + "\t -- %s VLAN filter configuration\n"
> + "\t nic_ingress :%s\n"
> + "\t nic_egress :%s\n",
> + req->vlan_type == HNS3_FILTER_TYPE_PORT ?
> + "Port" : "VF",
> + req->vlan_fe & HNS3_FILTER_FE_NIC_INGRESS_B ?
> + "Enable" : "Disable",
> + req->vlan_fe & HNS3_FILTER_FE_NIC_EGRESS_B ?
> + "Enable" : "Disable");
> + }
> +
> + return 0;
> +}
> +
> +static int
> +get_vlan_rx_offload_cfg(FILE *file, struct hns3_hw *hw)
> +{
> + struct hns3_vport_vtag_rx_cfg_cmd *req;
> + struct hns3_cmd_desc desc;
> + uint16_t vport_id;
> + uint8_t bitmap;
> + int ret;
> +
> + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_RX_CFG, true);
> + req = (struct hns3_vport_vtag_rx_cfg_cmd *)desc.data;
> + vport_id = HNS3_PF_FUNC_ID;
> + req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;
> + bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);
> + req->vf_bitmap[req->vf_offset] = bitmap;
> +
> + /*
> + * current version VF is not supported when PF is driven by DPDK driver,
> + * just need to configure rx parameters for PF vport.
> + */
> + ret = hns3_cmd_send(hw, &desc, 1);
> + if (ret != 0) {
> + hns3_err(hw,
> + "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
> + ret, 1, rte_le_to_cpu_16(desc.opcode));
> + return ret;
> + }
> +
> + fprintf(file,
> + "\t -- RX VLAN configuration\n"
> + "\t vlan1_strip_en :%s\n"
> + "\t vlan2_strip_en :%s\n"
> + "\t vlan1_vlan_prionly :%s\n"
> + "\t vlan2_vlan_prionly :%s\n"
> + "\t vlan1_strip_discard :%s\n"
> + "\t vlan2_strip_discard :%s\n",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_REM_TAG1_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_REM_TAG2_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_SHOW_TAG1_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_SHOW_TAG2_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_DISCARD_TAG1_EN_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_DISCARD_TAG2_EN_B) ? "Enable" : "Disable");
> +
> + return 0;
> +}
> +
> +static void
> +parse_tx_vlan_cfg(FILE *file, struct hns3_vport_vtag_tx_cfg_cmd *req)
> +{
> +#define VLAN_VID_MASK 0x0fff
> +#define VLAN_PRIO_SHIFT 13
> +
> + fprintf(file,
> + "\t -- TX VLAN configuration\n"
> + "\t accept_tag1 :%s\n"
> + "\t accept_untag1 :%s\n"
> + "\t insert_tag1_en :%s\n"
> + "\t default_vlan_tag1 = %d, qos = %d\n"
> + "\t accept_tag2 :%s\n"
> + "\t accept_untag2 :%s\n"
> + "\t insert_tag2_en :%s\n"
> + "\t default_vlan_tag2 = %d, qos = %d\n"
> + "\t vlan_shift_mode :%s\n",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_ACCEPT_TAG1_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_ACCEPT_UNTAG1_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_PORT_INS_TAG1_EN_B) ? "Enable" : "Disable",
> + req->def_vlan_tag1 & VLAN_VID_MASK,
> + req->def_vlan_tag1 >> VLAN_PRIO_SHIFT,
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_ACCEPT_TAG2_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_ACCEPT_UNTAG2_B) ? "Enable" : "Disable",
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_PORT_INS_TAG2_EN_B) ? "Enable" : "Disable",
> + req->def_vlan_tag2 & VLAN_VID_MASK,
> + req->def_vlan_tag2 >> VLAN_PRIO_SHIFT,
> + hns3_get_bit(req->vport_vlan_cfg,
> + HNS3_TAG_SHIFT_MODE_EN_B) ? "Enable" :
> + "Disable");
> +}
> +
> +static int
> +get_vlan_tx_offload_cfg(FILE *file, struct hns3_hw *hw)
> +{
> + struct hns3_vport_vtag_tx_cfg_cmd *req;
> + struct hns3_cmd_desc desc;
> + uint16_t vport_id;
> + uint8_t bitmap;
> + int ret;
> +
> + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_TX_CFG, true);
> + req = (struct hns3_vport_vtag_tx_cfg_cmd *)desc.data;
> + vport_id = HNS3_PF_FUNC_ID;
> + req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;
> + bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);
> + req->vf_bitmap[req->vf_offset] = bitmap;
> + /*
> + * current version VF is not supported when PF is driven by DPDK driver,
> + * just need to configure tx parameters for PF vport.
> + */
> + ret = hns3_cmd_send(hw, &desc, 1);
> + if (ret != 0) {
> + hns3_err(hw,
> + "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
> + ret, 1, rte_le_to_cpu_16(desc.opcode));
> + return ret;
> + }
> +
> + parse_tx_vlan_cfg(file, req);
> +
> + return 0;
> +}
> +
> +static void
> +get_port_pvid_info(FILE *file, struct hns3_hw *hw)
> +{
> + fprintf(file, "\t -- pvid status: %s\n",
> + hw->port_base_vlan_cfg.state ? "on" : "off");
> +}
> +
> +static void
> +get_vlan_config_info(FILE *file, struct hns3_hw *hw)
> +{
> + int ret;
> +
> + fprintf(file, " - VLAN Config Info:\n");
> + ret = get_vlan_filter_cfg(file, hw);
> + if (ret < 0)
> + return;
> +
> + ret = get_vlan_rx_offload_cfg(file, hw);
> + if (ret < 0)
> + return;
> +
> + ret = get_vlan_tx_offload_cfg(file, hw);
> + if (ret < 0)
> + return;
> +
> + get_port_pvid_info(file, hw);
> +}
> +
> +static void
> +get_tm_conf_shaper_info(FILE *file, struct hns3_tm_conf *conf)
> +{
> + struct hns3_shaper_profile_list *shaper_profile_list =
> + &conf->shaper_profile_list;
> + struct hns3_tm_shaper_profile *shaper_profile;
> +
> + if (!conf->nb_shaper_profile)
> + return;
> +
> + fprintf(file, " shaper_profile:\n");
> + TAILQ_FOREACH(shaper_profile, shaper_profile_list, node) {
> + fprintf(file,
> + " id=%u reference_count=%u peak_rate=%" PRIu64 "Bps\n",
> + shaper_profile->shaper_profile_id,
> + shaper_profile->reference_count,
> + shaper_profile->profile.peak.rate);
> + }
> +}
> +
> +static void
> +get_tm_conf_port_node_info(FILE *file, struct hns3_tm_conf *conf)
> +{
> + if (!conf->root)
> + return;
> +
> + fprintf(file,
> + " port_node: \n"
> + " node_id=%u reference_count=%u shaper_profile_id=%d\n",
> + conf->root->id, conf->root->reference_count,
> + conf->root->shaper_profile ?
> + (int)conf->root->shaper_profile->shaper_profile_id : -1);
> +}
> +
> +static void
> +get_tm_conf_tc_node_info(FILE *file, struct hns3_tm_conf *conf)
> +{
> + struct hns3_tm_node_list *tc_list = &conf->tc_list;
> + struct hns3_tm_node *tc_node[HNS3_MAX_TC_NUM];
> + struct hns3_tm_node *tm_node;
> + uint32_t tidx;
> +
> + if (!conf->nb_tc_node)
> + return;
> +
> + fprintf(file, " tc_node: \n");
> + memset(tc_node, 0, sizeof(tc_node));
> + TAILQ_FOREACH(tm_node, tc_list, node) {
> + tidx = hns3_tm_calc_node_tc_no(conf, tm_node->id);
> + if (tidx < HNS3_MAX_TC_NUM)
> + tc_node[tidx] = tm_node;
> + }
> +
> + for (tidx = 0; tidx < HNS3_MAX_TC_NUM; tidx++) {
> + tm_node = tc_node[tidx];
> + if (tm_node == NULL)
> + continue;
> + fprintf(file,
> + " id=%u TC%u reference_count=%u parent_id=%d "
> + "shaper_profile_id=%d\n",
> + tm_node->id, hns3_tm_calc_node_tc_no(conf, tm_node->id),
> + tm_node->reference_count,
> + tm_node->parent ? (int)tm_node->parent->id : -1,
> + tm_node->shaper_profile ?
> + (int)tm_node->shaper_profile->shaper_profile_id : -1);
> + }
> +}
> +
> +static void
> +get_tm_conf_queue_format_info(FILE *file, struct hns3_tm_node **queue_node,
> + uint32_t *queue_node_tc, uint32_t nb_tx_queues)
> +{
> +#define PERLINE_QUEUES 32
> +#define PERLINE_STRIDE 8
> +#define LINE_BUF_SIZE 1024
> + uint32_t i, j, line_num, start_queue, end_queue;
> + char tmpbuf[LINE_BUF_SIZE] = {0};
> +
> + line_num = (nb_tx_queues + PERLINE_QUEUES - 1) / PERLINE_QUEUES;
> + for (i = 0; i < line_num; i++) {
> + start_queue = i * PERLINE_QUEUES;
> + end_queue = (i + 1) * PERLINE_QUEUES - 1;
> + if (end_queue > nb_tx_queues - 1)
> + end_queue = nb_tx_queues - 1;
> + fprintf(file, " %04u - %04u | ", start_queue, end_queue);
> + for (j = start_queue; j < nb_tx_queues; j++) {
> + if (j >= end_queue + 1)
> + break;
> + if (j > start_queue && j % PERLINE_STRIDE == 0)
> + fprintf(file, ":");
> + fprintf(file, "%u",
> + queue_node[j] ? queue_node_tc[j] :
> + HNS3_MAX_TC_NUM);
> + }
> + fprintf(file, "%s\n", tmpbuf);
> + }
> +}
> +
> +static void
> +get_tm_conf_queue_node_info(FILE *file, struct hns3_tm_conf *conf,
> + uint32_t nb_tx_queues)
> +{
> + struct hns3_tm_node_list *queue_list = &conf->queue_list;
> + uint32_t nb_queue_node = conf->nb_leaf_nodes_max + 1;
> + struct hns3_tm_node *queue_node[nb_queue_node];
> + uint32_t queue_node_tc[nb_queue_node];
> + struct hns3_tm_node *tm_node;
> +
> + if (!conf->nb_queue_node)
> + return;
> +
> + fprintf(file,
> + " queue_node: \n"
> + " tx queue id | mapped tc (8 mean node not exist)\n");
> +
> + memset(queue_node, 0, sizeof(queue_node));
> + memset(queue_node_tc, 0, sizeof(queue_node_tc));
> + nb_tx_queues = RTE_MIN(nb_tx_queues, nb_queue_node);
> + TAILQ_FOREACH(tm_node, queue_list, node) {
> + if (tm_node->id >= nb_queue_node)
> + continue;
> + queue_node[tm_node->id] = tm_node;
> + queue_node_tc[tm_node->id] = tm_node->parent ?
> + hns3_tm_calc_node_tc_no(conf, tm_node->parent->id) : 0;
> + nb_tx_queues = RTE_MAX(nb_tx_queues, tm_node->id + 1);
> + }
> +
> + get_tm_conf_queue_format_info(file, queue_node, queue_node_tc,
> + nb_tx_queues);
> +}
> +
> +static void
> +get_tm_conf_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> + struct hns3_tm_conf *conf = &pf->tm_conf;
> +
> + fprintf(file, " - TM config info:\n");
> + fprintf(file,
> + "\t -- nb_leaf_nodes_max=%u nb_nodes_max=%u\n"
> + "\t -- nb_shaper_profile=%u nb_tc_node=%u nb_queue_node=%u\n"
> + "\t -- committed=%u\n",
> + conf->nb_leaf_nodes_max, conf->nb_nodes_max,
> + conf->nb_shaper_profile, conf->nb_tc_node, conf->nb_queue_node,
> + conf->committed);
> +
> + get_tm_conf_shaper_info(file, conf);
> + get_tm_conf_port_node_info(file, conf);
> + get_tm_conf_tc_node_info(file, conf);
> + get_tm_conf_queue_node_info(file, conf, dev->data->nb_tx_queues);
> +}
> +
> +static void
> +hns3_fc_mode_to_rxtx_pause(enum hns3_fc_mode fc_mode, bool *rx_pause,
> + bool *tx_pause)
> +{
> + switch (fc_mode) {
> + case HNS3_FC_NONE:
> + *tx_pause = false;
> + *rx_pause = false;
> + break;
> + case HNS3_FC_RX_PAUSE:
> + *rx_pause = true;
> + *tx_pause = false;
> + break;
> + case HNS3_FC_TX_PAUSE:
> + *rx_pause = false;
> + *tx_pause = true;
> + break;
> + case HNS3_FC_FULL:
> + *rx_pause = true;
> + *tx_pause = true;
> + break;
> + default:
> + *rx_pause = false;
> + *tx_pause = false;
> + break;
> + }
> +}
> +
> +static bool
> +is_link_fc_mode(struct hns3_adapter *hns)
> +{
> + struct hns3_hw *hw = &hns->hw;
> + struct hns3_pf *pf = &hns->pf;
> +
> + if (hw->current_fc_status == HNS3_FC_STATUS_PFC)
> + return false;
> +
> + if (hw->num_tc > 1 && !pf->support_multi_tc_pause)
> + return false;
> +
> + return true;
> +}
> +
> +static void
> +get_link_fc_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> + struct rte_eth_fc_conf fc_conf;
> + bool rx_pause1;
> + bool tx_pause1;
> + bool rx_pause2;
> + bool tx_pause2;
> + int ret;
> +
> + if (!is_link_fc_mode(hns))
> + return;
> +
> + ret = hns3_flow_ctrl_get(dev, &fc_conf);
> + if (ret) {
> + fprintf(file, "get device flow control info fail!\n");
> + return;
> + }
> +
> + hns3_fc_mode_to_rxtx_pause(hw->requested_fc_mode,
> + &rx_pause1, &tx_pause1);
> + hns3_fc_mode_to_rxtx_pause((enum hns3_fc_mode)fc_conf.mode,
> + &rx_pause2, &tx_pause2);
> +
> + fprintf(file,
> + "\t -- link_fc_info:\n"
> + "\t Requested fc:\n"
> + "\t Rx: %s\n"
> + "\t Tx: %s\n"
> + "\t Current fc:\n"
> + "\t Rx: %s\n"
> + "\t Tx: %s\n"
> + "\t Autonegotiate: %s\n"
> + "\t Pause time: 0x%x\n",
> + rx_pause1 ? "On" : "Off", tx_pause1 ? "On" : "Off",
> + rx_pause2 ? "On" : "Off", tx_pause2 ? "On" : "Off",
> + fc_conf.autoneg == RTE_ETH_LINK_AUTONEG ? "On" : "Off",
> + fc_conf.pause_time);
> +}
> +
> +static void
> +get_flow_ctrl_info(FILE *file, struct rte_eth_dev *dev)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> +
> + fprintf(file, " - Flow Ctrl Info:\n");
> + fprintf(file,
> + "\t -- fc_common_info:\n"
> + "\t current_fc_status=%u\n"
> + "\t requested_fc_mode=%u\n",
> + hw->current_fc_status,
> + hw->requested_fc_mode);
> +
> + get_link_fc_info(file, dev);
> +}
> +
> +int
> +hns3_eth_dev_priv_dump(struct rte_eth_dev *dev, FILE *file)
> +{
> + struct hns3_adapter *hns = dev->data->dev_private;
> + struct hns3_hw *hw = &hns->hw;
> +
> + get_device_basic_info(file, dev);
> + get_dev_feature_capability(file, hw);
> +
> + /* VF is only support dumping basic info and feaure capability */
> + if (hns->is_vf)
> + return 0;
> +
> + get_dev_mac_info(file, hns);
> + get_rxtx_queue_info(file, dev);
> + get_vlan_config_info(file, hw);
> + get_fdir_basic_info(file, &hns->pf);
> + get_tm_conf_info(file, dev);
> + get_flow_ctrl_info(file, dev);
> +
> + return 0;
> +}
> diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
> index dab1130dad..06ddf64184 100644
> --- a/drivers/net/hns3/hns3_ethdev_vf.c
> +++ b/drivers/net/hns3/hns3_ethdev_vf.c
> @@ -2290,6 +2290,7 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = {
> .get_reg = hns3_get_regs,
> .dev_supported_ptypes_get = hns3_dev_supported_ptypes_get,
> .tx_done_cleanup = hns3_tx_done_cleanup,
> + .eth_dev_priv_dump = hns3_eth_dev_priv_dump,
> };
>
> static const struct hns3_reset_ops hns3vf_reset_ops = {
> diff --git a/drivers/net/hns3/meson.build b/drivers/net/hns3/meson.build
> index 8a4c7cc100..665b2afedf 100644
> --- a/drivers/net/hns3/meson.build
> +++ b/drivers/net/hns3/meson.build
> @@ -30,6 +30,7 @@ sources = files(
> 'hns3_tm.c',
> 'hns3_ptp.c',
> 'hns3_common.c',
> + 'hns3_ethdev_dump.c',
> )
>
> deps += ['hash']
>
^ permalink raw reply [flat|nested] 39+ messages in thread