All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wei Dai <wei.dai@intel.com>
To: ferruh.yigit@intel.com, jingjing.wu@intel.com, wenzhuo.lu@intel.com
Cc: dev@dpdk.org, Wei Dai <wei.dai@intel.com>
Subject: [PATCH v8] app/testpmd: add commands to test new offload API
Date: Wed,  9 May 2018 20:13:50 +0800	[thread overview]
Message-ID: <1525868030-64160-1-git-send-email-wei.dai@intel.com> (raw)
In-Reply-To: <20180403085735.3090-1-wei.dai@intel.com>

Add following testpmd run-time commands to support test of
new Rx offload API:
show port <port_id> rx_offload capabilities
show port <port_id> rx_offload configuration
port config <port_id> rx_offload <offload> on|off
port <port_id> rxq <queue_id> rx_offload <offload> on|off
Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_strip", "ipv4_cksum", ...

Add following testpmd run-time commands to support test of
new Tx offload API:
show port <port_id> tx_offload capabilities
show port <port_id> tx_offload configuration
port config <port_id> tx_offload <offload> on|off
port <port_id> txq <queue_id> tx_offload <offload> on|off
Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_insert", "udp_cksum", ...

Signed-off-by: Wei Dai <wei.dai@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>

---
v8:
  Change the command formats according to feedback from community:
  1. Change "[rt]x_offload get capabilit <port_id>"
     to "show port <port_id> [rt]x_offload capabilitis"
  2. Change "[rt]x_offload get configuration <port_id>"
     to "show port <port_id> [rt]x_offload configuration"
  3. Change "[rt]x_offload enable|disable per_port <offload> <port_id>"
     to "port config <port_id> [rt]x_offload <offload> on|off"
  4. Change "[rt]x_offload enable|disable per_queue <offload> <port_id>
     <queue_id>" to "port <port_id> [rt]xq <queue_id> [rt]x_offload
     <offload> on|off"
---
 app/test-pmd/cmdline.c                      | 807 ++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c                      |  16 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  87 +++
 3 files changed, 904 insertions(+), 6 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9615670..2904d3d 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16448,6 +16448,805 @@ cmdline_parse_inst_t cmd_load_from_file = {
 	},
 };
 
+/* Get Rx offloads capabilities */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	portid_t port_id;
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t capabilities;
+};
+
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_show =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 show, "show");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_rx_offload_get_capa_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 port_id, UINT16);
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_rx_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 rx_offload, "rx_offload");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capabilities =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capabilities, "capabilities");
+
+static void
+print_rx_offloads(uint64_t offloads)
+{
+	uint64_t single_offload;
+	int begin;
+	int end;
+	int bit;
+
+	if (offloads == 0)
+		return;
+
+	begin = __builtin_ctzll(offloads);
+	end = sizeof(offloads) * CHAR_BIT - __builtin_clzll(offloads);
+
+	single_offload = 1 << begin;
+	for (bit = begin; bit < end; bit++) {
+		if (offloads & single_offload)
+			printf(" %s",
+			       rte_eth_dev_rx_offload_name(single_offload));
+		single_offload <<= 1;
+	}
+}
+
+static void
+cmd_rx_offload_get_capa_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_rx_offload_get_capa_result *res = parsed_result;
+	struct rte_eth_dev_info dev_info;
+	portid_t port_id = res->port_id;
+	uint64_t queue_offloads;
+	uint64_t port_offloads;
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	queue_offloads = dev_info.rx_queue_offload_capa;
+	port_offloads = dev_info.rx_offload_capa ^ queue_offloads;
+
+	printf("Rx Offloading Capabilities of port %d :\n", port_id);
+	printf("  Per Queue :");
+	print_rx_offloads(queue_offloads);
+
+	printf("\n");
+	printf("  Per Port  :");
+	print_rx_offloads(port_offloads);
+	printf("\n\n");
+}
+
+cmdline_parse_inst_t cmd_rx_offload_get_capa = {
+	.f = cmd_rx_offload_get_capa_parsed,
+	.data = NULL,
+	.help_str = "show port <port_id> rx_offload capabilities",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_show,
+		(void *)&cmd_rx_offload_get_capa_port,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_capabilities,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	portid_t port_id;
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t configuration;
+};
+
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_show =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 show, "show");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_rx_offload_get_configuration_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 port_id, UINT16);
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_rx_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 rx_offload, "rx_offload");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+
+static void
+cmd_rx_offload_get_configuration_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_rx_offload_get_configuration_result *res = parsed_result;
+	struct rte_eth_dev_info dev_info;
+	portid_t port_id = res->port_id;
+	struct rte_port *port = &ports[port_id];
+	uint64_t port_offloads;
+	uint64_t queue_offloads;
+	uint16_t nb_rx_queues;
+	int q;
+
+	printf("Rx Offloading Configuration of port %d :\n", port_id);
+
+	port_offloads = port->dev_conf.rxmode.offloads;
+	printf("  Port :");
+	print_rx_offloads(port_offloads);
+	printf("\n");
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_rx_queues = dev_info.nb_rx_queues;
+	for (q = 0; q < nb_rx_queues; q++) {
+		queue_offloads = port->rx_conf[q].offloads;
+		printf("  Queue[%2d] :", q);
+		print_rx_offloads(queue_offloads);
+		printf("\n");
+	}
+	printf("\n");
+}
+
+cmdline_parse_inst_t cmd_rx_offload_get_configuration = {
+	.f = cmd_rx_offload_get_configuration_parsed,
+	.data = NULL,
+	.help_str = "show port <port_id> rx_offload configuration",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_show,
+		(void *)&cmd_rx_offload_get_configuration_port,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	portid_t port_id;
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t offload;
+	cmdline_fixed_string_t on_off;
+};
+
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 port, "port");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_config =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 config, "config");
+cmdline_parse_token_num_t cmd_config_per_port_rx_offload_result_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 port_id, UINT16);
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_rx_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 rx_offload, "rx_offload");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 offload, "vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#"
+			   "qinq_strip#outer_ipv4_cksum#macsec_strip#"
+			   "header_split#vlan_filter#vlan_extend#jumbo_frame#"
+			   "crc_strip#scatter#timestamp#security");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 on_off, "on#off");
+
+static uint64_t
+search_rx_offload(const char *name)
+{
+	uint64_t single_offload;
+	const char *single_name;
+	int found = 0;
+	unsigned int bit;
+
+	single_offload = 1;
+	for (bit = 0; bit < sizeof(single_offload) * CHAR_BIT; bit++) {
+		single_name = rte_eth_dev_rx_offload_name(single_offload);
+		if (!strcasecmp(single_name, name)) {
+			found = 1;
+			break;
+		} else if (!strcasecmp(single_name, "UNKNOWN"))
+			break;
+		else if (single_name == NULL)
+			break;
+		single_offload <<= 1;
+	}
+
+	if (found)
+		return single_offload;
+
+	return 0;
+}
+
+static void
+cmd_config_per_port_rx_offload_parsed(void *parsed_result,
+				__attribute__((unused)) struct cmdline *cl,
+				__attribute__((unused)) void *data)
+{
+	struct cmd_config_per_port_rx_offload_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_eth_dev_info dev_info;
+	struct rte_port *port = &ports[port_id];
+	uint64_t single_offload;
+	uint16_t nb_rx_queues;
+	int q;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	single_offload = search_rx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s\n", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_rx_queues = dev_info.nb_rx_queues;
+	if (!strcmp(res->on_off, "on")) {
+		port->dev_conf.rxmode.offloads |= single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_conf[q].offloads |= single_offload;
+	} else {
+		port->dev_conf.rxmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_conf[q].offloads &= ~single_offload;
+	}
+
+	cmd_reconfig_device_queue(port_id, 1, 1);
+}
+
+cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
+	.f = cmd_config_per_port_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "port config <port_id> rx_offload vlan_strip|ipv4_cksum|"
+		    "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|"
+		    "macsec_strip|header_split|vlan_filter|vlan_extend|"
+		    "jumbo_frame|crc_strip|scatter|timestamp|security "
+		    "on|off",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_port,
+		(void *)&cmd_config_per_port_rx_offload_result_config,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_on_off,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t port;
+	portid_t port_id;
+	cmdline_fixed_string_t rxq;
+	uint16_t queue_id;
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t offload;
+	cmdline_fixed_string_t on_off;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_config_per_queue_rx_offload_result_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 port_id, UINT16);
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rxq =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 rxq, "rxq");
+cmdline_parse_token_num_t cmd_config_per_queue_rx_offload_result_queue_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 queue_id, UINT16);
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rxoffload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 rx_offload, "rx_offload");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 offload, "vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#"
+			   "qinq_strip#outer_ipv4_cksum#macsec_strip#"
+			   "header_split#vlan_filter#vlan_extend#jumbo_frame#"
+			   "crc_strip#scatter#timestamp#security");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 on_off, "on#off");
+
+static void
+cmd_config_per_queue_rx_offload_parsed(void *parsed_result,
+				__attribute__((unused)) struct cmdline *cl,
+				__attribute__((unused)) void *data)
+{
+	struct cmd_config_per_queue_rx_offload_result *res = parsed_result;
+	struct rte_eth_dev_info dev_info;
+	portid_t port_id = res->port_id;
+	uint16_t queue_id = res->queue_id;
+	struct rte_port *port = &ports[port_id];
+	uint64_t single_offload;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	if (queue_id >= dev_info.nb_rx_queues) {
+		printf("Error: input queue_id should be 0 ... "
+		       "%d\n", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	single_offload = search_rx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s\n", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->on_off, "on"))
+		port->rx_conf[queue_id].offloads |= single_offload;
+	else
+		port->rx_conf[queue_id].offloads &= ~single_offload;
+
+	cmd_reconfig_device_queue(port_id, 1, 1);
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
+	.f = cmd_config_per_queue_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "port <port_id> rxq <queue_id> rx_offload "
+		    "vlan_strip|ipv4_cksum|"
+		    "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|"
+		    "macsec_strip|header_split|vlan_filter|vlan_extend|"
+		    "jumbo_frame|crc_strip|scatter|timestamp|security "
+		    "on|off",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_port,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_rxq,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_rxoffload,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_on_off,
+		NULL,
+	}
+};
+
+/* Get Tx offloads capabilities */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	portid_t port_id;
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t capabilities;
+};
+
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_show =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 show, "show");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_tx_offload_get_capa_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 port_id, UINT16);
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_tx_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 tx_offload, "tx_offload");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capabilities =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capabilities, "capabilities");
+
+static void
+print_tx_offloads(uint64_t offloads)
+{
+	uint64_t single_offload;
+	int begin;
+	int end;
+	int bit;
+
+	if (offloads == 0)
+		return;
+
+	begin = __builtin_ctzll(offloads);
+	end = sizeof(offloads) * CHAR_BIT - __builtin_clzll(offloads);
+
+	single_offload = 1 << begin;
+	for (bit = begin; bit < end; bit++) {
+		if (offloads & single_offload)
+			printf(" %s",
+			       rte_eth_dev_tx_offload_name(single_offload));
+		single_offload <<= 1;
+	}
+}
+
+static void
+cmd_tx_offload_get_capa_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_offload_get_capa_result *res = parsed_result;
+	struct rte_eth_dev_info dev_info;
+	portid_t port_id = res->port_id;
+	uint64_t queue_offloads;
+	uint64_t port_offloads;
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	queue_offloads = dev_info.tx_queue_offload_capa;
+	port_offloads = dev_info.tx_offload_capa ^ queue_offloads;
+
+	printf("Tx Offloading Capabilities of port %d :\n", port_id);
+	printf("  Per Queue :");
+	print_tx_offloads(queue_offloads);
+
+	printf("\n");
+	printf("  Per Port  :");
+	print_tx_offloads(port_offloads);
+	printf("\n\n");
+}
+
+cmdline_parse_inst_t cmd_tx_offload_get_capa = {
+	.f = cmd_tx_offload_get_capa_parsed,
+	.data = NULL,
+	.help_str = "show port <port_id> tx_offload capabilities",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_show,
+		(void *)&cmd_tx_offload_get_capa_port,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_capabilities,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	portid_t port_id;
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t configuration;
+};
+
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_show =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 show, "show");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_tx_offload_get_configuration_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 port_id, UINT16);
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_tx_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 tx_offload, "tx_offload");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+
+static void
+cmd_tx_offload_get_configuration_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_offload_get_configuration_result *res = parsed_result;
+	struct rte_eth_dev_info dev_info;
+	portid_t port_id = res->port_id;
+	struct rte_port *port = &ports[port_id];
+	uint64_t port_offloads;
+	uint64_t queue_offloads;
+	uint16_t nb_tx_queues;
+	int q;
+
+	printf("Tx Offloading Configuration of port %d :\n", port_id);
+
+	port_offloads = port->dev_conf.txmode.offloads;
+	printf("  Port :");
+	print_tx_offloads(port_offloads);
+	printf("\n");
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_tx_queues = dev_info.nb_tx_queues;
+	for (q = 0; q < nb_tx_queues; q++) {
+		queue_offloads = port->tx_conf[q].offloads;
+		printf("  Queue[%2d] :", q);
+		print_tx_offloads(queue_offloads);
+		printf("\n");
+	}
+	printf("\n");
+}
+
+cmdline_parse_inst_t cmd_tx_offload_get_configuration = {
+	.f = cmd_tx_offload_get_configuration_parsed,
+	.data = NULL,
+	.help_str = "show port <port_id> tx_offload configuration",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_show,
+		(void *)&cmd_tx_offload_get_configuration_port,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	portid_t port_id;
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t offload;
+	cmdline_fixed_string_t on_off;
+};
+
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 port, "port");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_config =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 config, "config");
+cmdline_parse_token_num_t cmd_config_per_port_tx_offload_result_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 port_id, UINT16);
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_tx_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 tx_offload, "tx_offload");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 offload, "vlan_insert#ipv4_cksum#udp_cksum#udp_cksum#"
+			  "sctp_cksum#tcp_tso#udp_tso#outer_ipv4_cksum#"
+			  "qinq_insert#vxlan_tnl_tso#gre_tnl_tso#"
+			  "ipip_tnl_tso#geneve_tnl_tso#macsec_insert#"
+			  "mt_lockfree#multi_segs#fast_free#security");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 on_off, "on#off");
+
+static uint64_t
+search_tx_offload(const char *name)
+{
+	uint64_t single_offload;
+	const char *single_name;
+	int found = 0;
+	unsigned int bit;
+
+	single_offload = 1;
+	for (bit = 0; bit < sizeof(single_offload) * CHAR_BIT; bit++) {
+		single_name = rte_eth_dev_tx_offload_name(single_offload);
+		if (!strcasecmp(single_name, name)) {
+			found = 1;
+			break;
+		} else if (!strcasecmp(single_name, "UNKNOWN"))
+			break;
+		else if (single_name == NULL)
+			break;
+		single_offload <<= 1;
+	}
+
+	if (found)
+		return single_offload;
+
+	return 0;
+}
+
+static void
+cmd_config_per_port_tx_offload_parsed(void *parsed_result,
+				__attribute__((unused)) struct cmdline *cl,
+				__attribute__((unused)) void *data)
+{
+	struct cmd_config_per_port_tx_offload_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_eth_dev_info dev_info;
+	struct rte_port *port = &ports[port_id];
+	uint64_t single_offload;
+	uint16_t nb_tx_queues;
+	int q;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	single_offload = search_tx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s\n", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_tx_queues = dev_info.nb_tx_queues;
+	if (!strcmp(res->on_off, "on")) {
+		port->dev_conf.txmode.offloads |= single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_conf[q].offloads |= single_offload;
+	} else {
+		port->dev_conf.txmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_conf[q].offloads &= ~single_offload;
+	}
+
+	cmd_reconfig_device_queue(port_id, 1, 1);
+}
+
+cmdline_parse_inst_t cmd_config_per_port_tx_offload = {
+	.f = cmd_config_per_port_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "port config <port_id> tx_offload "
+		    "vlan_insert|ipv4_cksum|udp_cksum|udp_cksum|"
+		    "sctp_cksum|tcp_tso|udp_tso|outer_ipv4_cksum|"
+		    "qinq_insert|vxlan_tnl_tso|gre_tnl_tso|"
+		    "ipip_tnl_tso|geneve_tnl_tso|macsec_insert|"
+		    "mt_lockfree|multi_segs|fast_free|security "
+		    "on|off",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_port,
+		(void *)&cmd_config_per_port_tx_offload_result_config,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_on_off,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t port;
+	portid_t port_id;
+	cmdline_fixed_string_t txq;
+	uint16_t queue_id;
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t offload;
+	cmdline_fixed_string_t on_off;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_config_per_queue_tx_offload_result_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 port_id, UINT16);
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_txq =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 txq, "txq");
+cmdline_parse_token_num_t cmd_config_per_queue_tx_offload_result_queue_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 queue_id, UINT16);
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_txoffload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 tx_offload, "tx_offload");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_offload =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 offload, "vlan_insert#ipv4_cksum#udp_cksum#udp_cksum#"
+			  "sctp_cksum#tcp_tso#udp_tso#outer_ipv4_cksum#"
+			  "qinq_insert#vxlan_tnl_tso#gre_tnl_tso#"
+			  "ipip_tnl_tso#geneve_tnl_tso#macsec_insert#"
+			  "mt_lockfree#multi_segs#fast_free#security");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 on_off, "on#off");
+
+static void
+cmd_config_per_queue_tx_offload_parsed(void *parsed_result,
+				__attribute__((unused)) struct cmdline *cl,
+				__attribute__((unused)) void *data)
+{
+	struct cmd_config_per_queue_tx_offload_result *res = parsed_result;
+	struct rte_eth_dev_info dev_info;
+	portid_t port_id = res->port_id;
+	uint16_t queue_id = res->queue_id;
+	struct rte_port *port = &ports[port_id];
+	uint64_t single_offload;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	if (queue_id >= dev_info.nb_tx_queues) {
+		printf("Error: input queue_id should be 0 ... "
+		       "%d\n", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	single_offload = search_tx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s\n", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->on_off, "on"))
+		port->tx_conf[queue_id].offloads |= single_offload;
+	else
+		port->tx_conf[queue_id].offloads &= ~single_offload;
+
+	cmd_reconfig_device_queue(port_id, 1, 1);
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_tx_offload = {
+	.f = cmd_config_per_queue_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "port <port_id> txq <queue_id> tx_offload "
+		    "vlan_insert|ipv4_cksum|udp_cksum|udp_cksum|"
+		    "sctp_cksum|tcp_tso|udp_tso|outer_ipv4_cksum|"
+		    "qinq_insert|vxlan_tnl_tso|gre_tnl_tso|"
+		    "ipip_tnl_tso|geneve_tnl_tso|macsec_insert|"
+		    "mt_lockfree|multi_segs|fast_free|security "
+		    "on|off",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_port,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_txq,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_txoffload,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_on_off,
+		NULL,
+	}
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -16695,6 +17494,14 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
 	(cmdline_parse_inst_t *)&cmd_cfg_tunnel_udp_port,
+	(cmdline_parse_inst_t *)&cmd_rx_offload_get_capa,
+	(cmdline_parse_inst_t *)&cmd_rx_offload_get_configuration,
+	(cmdline_parse_inst_t *)&cmd_config_per_port_rx_offload,
+	(cmdline_parse_inst_t *)&cmd_config_per_queue_rx_offload,
+	(cmdline_parse_inst_t *)&cmd_tx_offload_get_capa,
+	(cmdline_parse_inst_t *)&cmd_tx_offload_get_configuration,
+	(cmdline_parse_inst_t *)&cmd_config_per_port_tx_offload,
+	(cmdline_parse_inst_t *)&cmd_config_per_queue_tx_offload,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index db23f23..d0247ea 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -667,6 +667,7 @@ init_config(void)
 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
 	struct rte_gro_param gro_param;
 	uint32_t gso_types;
+	int k;
 
 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
 
@@ -718,6 +719,15 @@ init_config(void)
 			}
 		}
 
+		/* Apply Rx offloads configuration */
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_conf[k].offloads =
+				port->dev_conf.rxmode.offloads;
+		/* Apply Tx offloads configuration */
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_conf[k].offloads =
+				port->dev_conf.txmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1598,9 +1608,6 @@ start_port(portid_t pid)
 			for (qi = 0; qi < nb_txq; qi++) {
 				port->tx_conf[qi].txq_flags =
 					ETH_TXQ_FLAGS_IGNORE;
-				/* Apply Tx offloads configuration */
-				port->tx_conf[qi].offloads =
-					port->dev_conf.txmode.offloads;
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1629,9 +1636,6 @@ start_port(portid_t pid)
 				return -1;
 			}
 			for (qi = 0; qi < nb_rxq; qi++) {
-				/* Apply Rx offloads configuration */
-				port->rx_conf[qi].offloads =
-					port->dev_conf.rxmode.offloads;
 				/* setup rx queues */
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 013a405..992282c 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -393,6 +393,34 @@ List all items from the pctype mapping table::
 
    testpmd> show port (port_id) pctype mapping
 
+show rx offloading capabilities
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List all per queue and per port Rx offloading capabilities of a port::
+
+   testpmd> show port (port_id) rx_offload capabilities
+
+show rx offloading configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List port level and all queue level Rx offloading configuration::
+
+   testpmd> show port (port_id) rx_offload configuration
+
+show tx offloading capabilities
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List all per queue and per port Tx offloading capabilities of a port::
+
+   testpmd> show port (port_id) tx_offload capabilities
+
+show tx offloading configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List port level and all queue level Tx offloading configuration::
+
+   testpmd> show port (port_id) tx_offload configuration
+
 
 Configuration Functions
 -----------------------
@@ -1444,6 +1472,65 @@ Reset ptype mapping table::
 
    testpmd> ptype mapping reset (port_id)
 
+config per port Rx offloading
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enable or disable a per port Rx offloading on all Rx queues of a port::
+   testpmd> port config (port_id) rx_offload (offloading) on|off
+
+Where:
+* ``offloading``: can be any of these offloading capability:
+                  vlan_strip, ipv4_cksum, udp_cksum, tcp_cksum, tcp_lro,
+                  qinq_strip, outer_ipv4_cksum, macsec_strip,
+                  header_split, vlan_filter, vlan_extend, jumbo_frame,
+                  crc_strip, scatter, timestamp, security
+This command should be run when the port is stopped, or else it will fail.
+
+config per queue Rx offloading
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enable or disable a per queue Rx offloading only on a specific Rx queue::
+   testpmd> port (port_id) rxq (queue_id) rx_offload (offloading) on|off
+
+Where:
+* ``offloading``: can be any of these offloading capability:
+                  vlan_strip, ipv4_cksum, udp_cksum, tcp_cksum, tcp_lro,
+                  qinq_strip, outer_ipv4_cksum, macsec_strip,
+                  header_split, vlan_filter, vlan_extend, jumbo_frame,
+                  crc_strip, scatter, timestamp, security
+This command should be run when the port is stopped, or else it will fail.
+
+config per port Tx offloading
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enable or disable a per port Tx offloading on all Tx queues of a port::
+   testpmd> port config (port_id) tx_offload (offloading) on|off
+
+Where:
+* ``offloading``: can be any of these offloading capability:
+                  vlan_insert, ipv4_cksum, udp_cksum, udp_cksum,
+                  sctp_cksum, tcp_tso, udp_tso, outer_ipv4_cksum,
+                  qinq_insert, vxlan_tnl_tso, gre_tnl_tso,
+                  ipip_tnl_tso, geneve_tnl_tso, macsec_insert,
+                  mt_lockfree, multi_segs, fast_free, security
+This command should be run when the port is stopped, or else it will fail.
+
+config per queue Tx offloading
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enable or disable a per queue Tx offloading only on a specific Tx queue::
+   testpmd> port (port_id) txq (queue_id) tx_offload (offloading) on|off
+
+Where:
+* ``offloading``: can be any of these offloading capability:
+                  vlan_insert, ipv4_cksum, udp_cksum, udp_cksum,
+                  sctp_cksum, tcp_tso, udp_tso, outer_ipv4_cksum,
+                  qinq_insert, vxlan_tnl_tso, gre_tnl_tso,
+                  ipip_tnl_tso, geneve_tnl_tso, macsec_insert,
+                  mt_lockfree, multi_segs, fast_free, security
+This command should be run when the port is stopped, or else it will fail.
+
+
 Port Functions
 --------------
 
-- 
2.7.5

  parent reply	other threads:[~2018-05-09 12:14 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-12  8:15 [PATCH 0/2] app/testpmd: add new commands to test new Tx/Rx offload API Wei Dai
2018-03-12  8:15 ` [PATCH 1/2] app/testpmd: add commands to test new Rx " Wei Dai
2018-03-12  8:42   ` Andrew Rybchenko
2018-03-13  1:06     ` Dai, Wei
2018-03-12  8:15 ` [PATCH 2/2] app/testpmd: add commands to test new Tx " Wei Dai
2018-03-13  6:42 ` [PATCH v2 0/2] app/testpmd: add new commands to test new Tx/Rx " Wei Dai
2018-03-13  6:42   ` [PATCH v2 1/2] app/testpmd: add commands to test new Rx " Wei Dai
2018-03-13  7:21     ` Andrew Rybchenko
2018-03-13  9:30       ` Ananyev, Konstantin
2018-03-17 13:45         ` Dai, Wei
2018-03-14 19:40     ` Wu, Jingjing
2018-03-17 13:49       ` Dai, Wei
2018-03-13  6:42   ` [PATCH v2 2/2] app/testpmd: add commands to test new Tx " Wei Dai
2018-03-17 13:31   ` [PATCH v3 0/3] app/testpmd: add new commands to test new Tx/Rx " Wei Dai
2018-03-17 13:31     ` [PATCH v3 1/3] ethdev: add enum type for loop on Rx/Tx offloads Wei Dai
2018-03-17 13:31     ` [PATCH v3 2/3] app/testpmd: add commands to test new Rx offload API Wei Dai
2018-03-17 13:31     ` [PATCH v3 3/3] app/testpmd: add commands to test new Tx " Wei Dai
2018-03-19 12:33     ` [PATCH v4 0/3] app/testpmd: add new commands to test new Tx/Rx offload Wei Dai
2018-03-19 12:33       ` [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx offloads Wei Dai
2018-03-19 12:33       ` [PATCH v4 2/3] app/testpmd: add commands to test new Rx offload API Wei Dai
2018-03-19 12:33       ` [PATCH v4 3/3] pp/testpmd: add commands to test new Tx " Wei Dai
2018-03-19 12:40     ` [PATCH v4 0/3] app/testpmd: add new commands to test new Tx/Rx offload Wei Dai
2018-03-19 12:40       ` [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx offloads Wei Dai
2018-03-19 14:05         ` Zhang, Qi Z
2018-03-20  1:52           ` Dai, Wei
2018-03-19 12:40       ` [PATCH v4 2/3] app/testpmd: add commands to test new Rx offload API Wei Dai
2018-03-19 12:40       ` [PATCH v4 3/3] app/testpmd: add commands to test new Tx " Wei Dai
2018-03-20  3:09       ` [PATCH v5 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Wei Dai
2018-03-20  3:09         ` [PATCH v5 1/2] app/testpmd: add commands to test new Rx offload API Wei Dai
2018-03-20  3:09         ` [PATCH v5 2/2] app/testpmd: add commands to test new Tx " Wei Dai
2018-03-22  8:00         ` [PATCH v6 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Wei Dai
2018-03-22  8:00           ` [PATCH v6 1/2] app/testpmd: add commands to test new Rx offload API Wei Dai
2018-03-30  8:40             ` Wu, Jingjing
2018-03-22  8:00           ` [PATCH v6 2/2] app/testpmd: add commands to test new Tx " Wei Dai
2018-03-30 23:05             ` Wu, Jingjing
2018-04-03  8:57           ` [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Wei Dai
2018-04-03  8:57             ` [PATCH v7 1/2] app/testpmd: add commands to test new Rx offload API Wei Dai
2018-04-03  8:57             ` [PATCH v7 2/2] app/testpmd: add commands to test new Tx " Wei Dai
2018-04-12 17:53             ` [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Ferruh Yigit
2018-05-08 13:30             ` Dai, Wei
2018-05-08 15:33               ` Ferruh Yigit
2018-05-09 12:13             ` Wei Dai [this message]
2018-05-11  0:00               ` [PATCH v8] app/testpmd: add commands to test new offload API Ferruh Yigit
2018-05-11  0:10                 ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1525868030-64160-1-git-send-email-wei.dai@intel.com \
    --to=wei.dai@intel.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=jingjing.wu@intel.com \
    --cc=wenzhuo.lu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.