All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] app/testpmd: add new commands to test new Tx/Rx offload API
@ 2018-03-12  8:15 Wei Dai
  2018-03-12  8:15 ` [PATCH 1/2] app/testpmd: add commands to test new Rx " Wei Dai
                   ` (2 more replies)
  0 siblings, 3 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-12  8:15 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Existed testpmd commands can't support per queue offload configuration.
And there are different commands to enable or disable different offloading.
This patch set add following commands to support new Tx/Rx offloading API test.

To get Rx offload capability of a port, please run:
testpmd > rx_offload get capability <port_id>

To get current Rx offload per queue and per port configuration of a port, run:
tesstpmd > rx_offload get configuration <port_id>

To enable or disable a Rx per port offloading, please run:
testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>

To enable or disable a Tx per port offloading, please run:
testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>

Same commands like "tx_offload ..." are also added to support new Tx offload API test.

Wei Dai (2):
  app/testpmd: add commands to test new Rx offload API
  app/testpmd: add commands to test new Tx offload API

 app/test-pmd/cmdline.c | 930 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  28 +-
 app/test-pmd/testpmd.h |   2 +
 3 files changed, 956 insertions(+), 4 deletions(-)

-- 
2.7.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 1/2] app/testpmd: add commands to test new Rx offload API
  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 ` Wei Dai
  2018-03-12  8:42   ` Andrew Rybchenko
  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
  2 siblings, 1 reply; 44+ messages in thread
From: Wei Dai @ 2018-03-12  8:15 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Rx offload API:
rx_offload get capability <port_id>
rx_offload get configuration <port_id>
rx_offload enable|disable per_port vlan_strip|ipv4_cksum... <port_id>
rx_offload enable|disable per_queue vlan_strip|iipv4_cksum... <port_id>
<queue_id>

Above last 2 commands should be run when the port is stopped.

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 app/test-pmd/cmdline.c | 456 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  15 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 470 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index d1dc1de..1a08b3d 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -15996,6 +15996,458 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
 	},
 };
 
+static const char * const rx_offload_names[] = {
+	"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"
+};
+
+#define MAX_NUM_OF_RX_OFFLOADS	\
+	((int)(sizeof(rx_offload_names)/sizeof(rx_offload_names[0])))
+
+/* Get Rx offloads capability */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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;
+	uint64_t mask;
+	int k;
+
+	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 :");
+	mask = 1;
+	for (k = 0; k < MAX_NUM_OF_RX_OFFLOADS; k++) {
+		if (queue_offloads & mask)
+			printf(" %s", rx_offload_names[k]);
+		mask <<= 1;
+	}
+	printf("\n");
+	printf("  Per Port  :");
+	mask = 1;
+	for (k = 0; k < MAX_NUM_OF_RX_OFFLOADS; k++) {
+		if (port_offloads & mask)
+			printf(" %s", rx_offload_names[k]);
+		mask <<= 1;
+	}
+	printf("\n\n");
+}
+
+cmdline_parse_inst_t cmd_rx_offload_get_capa = {
+	.f = cmd_rx_offload_get_capa_parsed,
+	.data = NULL,
+	.help_str = "rx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_get,
+		(void *)&cmd_rx_offload_get_capa_capability,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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;
+	uint64_t mask;
+	uint16_t nb_rx_queues;
+	int q;
+	int k;
+
+	printf("Rx Offloading Configuration of port %d :\n", port_id);
+
+	port_offloads = port->dev_conf.rxmode.offloads;
+	printf("  Port :");
+	mask = 1;
+	for (k = 0; k < MAX_NUM_OF_RX_OFFLOADS; k++) {
+		if (port_offloads & mask)
+			printf(" %s", rx_offload_names[k]);
+		mask <<= 1;
+	}
+	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_offloads[q];
+		printf("  Queue[%2d] :", q);
+		mask = 1;
+		for (k = 0; k < MAX_NUM_OF_RX_OFFLOADS; k++) {
+			if (queue_offloads & mask)
+				printf(" %s", rx_offload_names[k]);
+			mask <<= 1;
+		}
+		printf("\n");
+	}
+	printf("\n");
+}
+
+cmdline_parse_inst_t cmd_rx_offload_get_configuration = {
+	.f = cmd_rx_offload_get_configuration_parsed,
+	.data = NULL,
+	.help_str = "rx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_get,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static int
+config_rx_offload(const char *name, uint64_t *offload, int on)
+{
+	uint64_t local = *offload;
+
+	if (!strcmp(name, "vlan_strip")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_VLAN_STRIP;
+		else
+			local &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
+	} else if (!strcmp(name, "ipv4_cksum")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_IPV4_CKSUM;
+		else
+			local &= ~DEV_RX_OFFLOAD_IPV4_CKSUM;
+	} else if (!strcmp(name, "udp_cksum")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_UDP_CKSUM;
+		else
+			local &= ~DEV_RX_OFFLOAD_UDP_CKSUM;
+	} else if (!strcmp(name, "tcp_cksum")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_TCP_CKSUM;
+		else
+			local &= ~DEV_RX_OFFLOAD_TCP_CKSUM;
+	} else if (!strcmp(name, "tcp_lro")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_TCP_LRO;
+		else
+			local &= ~DEV_RX_OFFLOAD_TCP_LRO;
+	} else if (!strcmp(name, "qinq_strip")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_QINQ_STRIP;
+		else
+			local &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
+	} else if (!strcmp(name, "outer_ipv4_cksum")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
+		else
+			local &= ~DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
+	} else if (!strcmp(name, "macsec_strip")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_MACSEC_STRIP;
+		else
+			local &= ~DEV_RX_OFFLOAD_MACSEC_STRIP;
+	} else if (!strcmp(name, "header_split")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_HEADER_SPLIT;
+		else
+			local &= ~DEV_RX_OFFLOAD_HEADER_SPLIT;
+	} else if (!strcmp(name, "vlan_filter")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_VLAN_FILTER;
+		else
+			local &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
+	} else if (!strcmp(name, "vlan_extend")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_VLAN_EXTEND;
+		else
+			local &= ~DEV_RX_OFFLOAD_VLAN_EXTEND;
+	} else if (!strcmp(name, "jumbo_frame")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_JUMBO_FRAME;
+		else
+			local &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
+	} else if (!strcmp(name, "crc_strip")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_CRC_STRIP;
+		else
+			local &= ~DEV_RX_OFFLOAD_CRC_STRIP;
+	} else if (!strcmp(name, "scatter")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_SCATTER;
+		else
+			local &= ~DEV_RX_OFFLOAD_SCATTER;
+	} else if (!strcmp(name, "timestamp")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_TIMESTAMP;
+		else
+			local &= ~DEV_RX_OFFLOAD_TIMESTAMP;
+	} else if (!strcmp(name, "security")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_SECURITY;
+		else
+			local &= ~DEV_RX_OFFLOAD_SECURITY;
+	} else
+		return -1;
+
+	*offload = local;
+	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_port *port = &ports[port_id];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else if (!strcmp(res->en_dis, "disable"))
+		on = 0;
+	else {
+		printf("Unknown parameter: %s\n", res->en_dis);
+		return;
+	}
+
+	if (config_rx_offload(res->offload,
+			      &port->dev_conf.rxmode.offloads, on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
+	.f = cmd_config_per_port_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_port 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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_rx_offload_result_per_port,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else if (!strcmp(res->en_dis, "disable"))
+		on = 0;
+	else {
+		printf("Unknown parameter: %s\n", res->en_dis);
+		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", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	if (config_rx_offload(res->offload,
+			      &port->rx_offloads[queue_id], on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
+	.f = cmd_config_per_queue_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_queue 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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_rx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16272,6 +16724,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+	(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,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e258..9786bfe 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -656,6 +656,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);
 
@@ -707,6 +708,17 @@ init_config(void)
 			}
 		}
 
+		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
+						sizeof(port->rx_offloads[0]) *
+						port->dev_info.max_rx_queues,
+						sizeof(port->rx_offloads[0]));
+		if (port->rx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->rx_offload[0]) "
+				 "failed\n", port->dev_info.max_rx_queues);
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1615,10 +1627,9 @@ start_port(portid_t pid)
 				port->need_reconfig_queues = 1;
 				return -1;
 			}
-			/* Apply Rx offloads configuration */
-			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
 			/* setup rx queues */
 			for (qi = 0; qi < nb_rxq; qi++) {
+				port->rx_conf.offloads = port->rx_offloads[qi];
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
 					struct rte_mempool * mp =
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea..dcad260 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -183,6 +183,7 @@ struct rte_port {
 	uint8_t                 dcb_flag;   /**< enable dcb */
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
+	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 2/2] app/testpmd: add commands to test new Tx offload API
  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:15 ` Wei Dai
  2018-03-13  6:42 ` [PATCH v2 0/2] app/testpmd: add new commands to test new Tx/Rx " Wei Dai
  2 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-12  8:15 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Tx offload API:
tx_offload get capability <port_id>
tx_offload get configuration <port_id>
tx_offload enable|disable per_port vlan_insert|udp_cksum... <port_id>
tx_offload enable|disable per_queue vlan_insert|udp_cksum... <port_id>
<queue_id>

Above last 2 commands should be run when the port is stopped.

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 app/test-pmd/cmdline.c | 474 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  13 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 486 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 1a08b3d..dcc7638 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16448,6 +16448,476 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
 	}
 };
 
+static const char * const tx_offload_names[] = {
+	"VLAN_INSERT",
+	"IPV4_CKSUM",
+	"UDP_CKSUM",
+	"TCP_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",
+	"MBUF_FAST_FREE",
+	"SECURITY"
+};
+
+#define MAX_NUM_OF_TX_OFFLOADS	\
+	((int)(sizeof(tx_offload_names)/sizeof(tx_offload_names[0])))
+
+/* Get Tx offloads capability */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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;
+	uint64_t mask;
+	int k;
+
+	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 :");
+	mask = 1;
+	for (k = 0; k < MAX_NUM_OF_TX_OFFLOADS; k++) {
+		if (queue_offloads & mask)
+			printf(" %s", tx_offload_names[k]);
+		mask <<= 1;
+	}
+	printf("\n");
+	printf("  Per Port  :");
+	mask = 1;
+	for (k = 0; k < MAX_NUM_OF_TX_OFFLOADS; k++) {
+		if (port_offloads & mask)
+			printf(" %s", tx_offload_names[k]);
+		mask <<= 1;
+	}
+	printf("\n\n");
+}
+
+cmdline_parse_inst_t cmd_tx_offload_get_capa = {
+	.f = cmd_tx_offload_get_capa_parsed,
+	.data = NULL,
+	.help_str = "tx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_get,
+		(void *)&cmd_tx_offload_get_capa_capability,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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;
+	uint64_t mask;
+	uint16_t nb_tx_queues;
+	int q;
+	int k;
+
+	printf("Tx Offloading Configuration of port %d :\n", port_id);
+
+	port_offloads = port->dev_conf.txmode.offloads;
+	printf("  Port :");
+	mask = 1;
+	for (k = 0; k < MAX_NUM_OF_TX_OFFLOADS; k++) {
+		if (port_offloads & mask)
+			printf(" %s", tx_offload_names[k]);
+		mask <<= 1;
+	}
+	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_offloads[q];
+		printf("  Queue[%2d] :", q);
+		mask = 1;
+		for (k = 0; k < MAX_NUM_OF_TX_OFFLOADS; k++) {
+			if (queue_offloads & mask)
+				printf(" %s", tx_offload_names[k]);
+			mask <<= 1;
+		}
+		printf("\n");
+	}
+	printf("\n");
+}
+
+cmdline_parse_inst_t cmd_tx_offload_get_configuration = {
+	.f = cmd_tx_offload_get_configuration_parsed,
+	.data = NULL,
+	.help_str = "tx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_get,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static int
+config_tx_offload(const char *name, uint64_t *offload, int on)
+{
+	uint64_t local = *offload;
+
+	if (!strcmp(name, "vlan_insert")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_VLAN_INSERT;
+		else
+			local &= ~DEV_TX_OFFLOAD_VLAN_INSERT;
+	} else if (!strcmp(name, "ipv4_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_IPV4_CKSUM;
+	} else if (!strcmp(name, "udp_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_UDP_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_UDP_CKSUM;
+	} else if (!strcmp(name, "tcp_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_TCP_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_TCP_CKSUM;
+	} else if (!strcmp(name, "sccp_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_SCTP_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_SCTP_CKSUM;
+	} else if (!strcmp(name, "tcp_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_TCP_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_TCP_TSO;
+	} else if (!strcmp(name, "udp_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_UDP_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_UDP_TSO;
+	} else if (!strcmp(name, "outer_ipv4_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+	} else if (!strcmp(name, "qinq_insert")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_QINQ_INSERT;
+		else
+			local &= ~DEV_TX_OFFLOAD_QINQ_INSERT;
+	} else if (!strcmp(name, "vxlan_tnl_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_VXLAN_TNL_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_VXLAN_TNL_TSO;
+	} else if (!strcmp(name, "gre_tnl_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_GRE_TNL_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_GRE_TNL_TSO;
+	} else if (!strcmp(name, "ipip_tnl_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_IPIP_TNL_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_IPIP_TNL_TSO;
+	} else if (!strcmp(name, "geneve_tnl_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
+	} else if (!strcmp(name, "macsec_insert")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_MACSEC_INSERT;
+		else
+			local &= ~DEV_TX_OFFLOAD_MACSEC_INSERT;
+	} else if (!strcmp(name, "mt_lockfree")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_MT_LOCKFREE;
+		else
+			local &= ~DEV_TX_OFFLOAD_MT_LOCKFREE;
+	} else if (!strcmp(name, "multi_segs")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_MULTI_SEGS;
+		else
+			local &= ~DEV_TX_OFFLOAD_MULTI_SEGS;
+	} else if (!strcmp(name, "mbuf_fast_free")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+		else
+			local &= ~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+	} else if (!strcmp(name, "security")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_SECURITY;
+		else
+			local &= ~DEV_TX_OFFLOAD_SECURITY;
+	} else
+		return -1;
+
+	*offload = local;
+	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_port *port = &ports[port_id];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else if (!strcmp(res->en_dis, "disable"))
+		on = 0;
+	else {
+		printf("Unknown parameter: %s\n", res->en_dis);
+		return;
+	}
+
+	if (config_tx_offload(res->offload,
+			      &port->dev_conf.txmode.offloads, on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_tx_offload = {
+	.f = cmd_config_per_port_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_port "
+		    "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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_tx_offload_result_per_port,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else if (!strcmp(res->en_dis, "disable"))
+		on = 0;
+	else {
+		printf("Unknown parameter: %s\n", res->en_dis);
+		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", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	if (config_tx_offload(res->offload,
+			      &port->tx_offloads[queue_id], on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_tx_offload = {
+	.f = cmd_config_per_queue_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_queue "
+		    "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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_tx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16728,6 +17198,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(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 9786bfe..690074e 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -718,6 +718,16 @@ init_config(void)
 				 "failed\n", port->dev_info.max_rx_queues);
 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
 			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+		port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads",
+						sizeof(port->tx_offloads[0]) *
+						port->dev_info.max_tx_queues,
+						sizeof(port->tx_offloads[0]));
+		if (port->tx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->tx_offload[0]) "
+				 "failed\n", port->dev_info.max_tx_queues);
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_offloads[k] = port->dev_conf.txmode.offloads;
 
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
@@ -1599,10 +1609,9 @@ start_port(portid_t pid)
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
-			/* Apply Tx offloads configuration */
-			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+				port->tx_conf.offloads = port->tx_offloads[qi];
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index dcad260..b0bd14e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -184,6 +184,7 @@ struct rte_port {
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
+	uint64_t		*tx_offloads; /**< offloads of each Tx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH 1/2] app/testpmd: add commands to test new Rx offload API
  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
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Rybchenko @ 2018-03-12  8:42 UTC (permalink / raw)
  To: Wei Dai, wenzhuo.lu, jingjing.wu; +Cc: dev

On 03/12/2018 11:15 AM, Wei Dai wrote:
> Add following testpmd run-time commands to support test of
> new Rx offload API:
> rx_offload get capability <port_id>
> rx_offload get configuration <port_id>
> rx_offload enable|disable per_port vlan_strip|ipv4_cksum... <port_id>
> rx_offload enable|disable per_queue vlan_strip|iipv4_cksum... <port_id>
> <queue_id>
>
> Above last 2 commands should be run when the port is stopped.
>
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> ---
>   app/test-pmd/cmdline.c | 456 +++++++++++++++++++++++++++++++++++++++++++++++++
>   app/test-pmd/testpmd.c |  15 +-
>   app/test-pmd/testpmd.h |   1 +
>   3 files changed, 470 insertions(+), 2 deletions(-)
>
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index d1dc1de..1a08b3d 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -15996,6 +15996,458 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
>   	},
>   };
>   
> +static const char * const rx_offload_names[] = {
> +	"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"
> +};

There are already rte_rx_offload_names in librte_ethdev/rte_ethdev.c and
rte_eth_dev_rx_offload_name() function in API.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 1/2] app/testpmd: add commands to test new Rx offload API
  2018-03-12  8:42   ` Andrew Rybchenko
@ 2018-03-13  1:06     ` Dai, Wei
  0 siblings, 0 replies; 44+ messages in thread
From: Dai, Wei @ 2018-03-13  1:06 UTC (permalink / raw)
  To: Andrew Rybchenko, Lu, Wenzhuo, Wu, Jingjing; +Cc: dev

> -----Original Message-----
> From: Andrew Rybchenko [mailto:arybchenko@solarflare.com]
> Sent: Monday, March 12, 2018 4:43 PM
> To: Dai, Wei <wei.dai@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> Wu, Jingjing <jingjing.wu@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 1/2] app/testpmd: add commands to test
> new Rx offload API
> 
> On 03/12/2018 11:15 AM, Wei Dai wrote:
> > Add following testpmd run-time commands to support test of new Rx
> > offload API:
> > rx_offload get capability <port_id>
> > rx_offload get configuration <port_id> rx_offload enable|disable
> > per_port vlan_strip|ipv4_cksum... <port_id> rx_offload enable|disable
> > per_queue vlan_strip|iipv4_cksum... <port_id> <queue_id>
> >
> > Above last 2 commands should be run when the port is stopped.
> >
> > Signed-off-by: Wei Dai <wei.dai@intel.com>
> > ---
> >   app/test-pmd/cmdline.c | 456
> +++++++++++++++++++++++++++++++++++++++++++++++++
> >   app/test-pmd/testpmd.c |  15 +-
> >   app/test-pmd/testpmd.h |   1 +
> >   3 files changed, 470 insertions(+), 2 deletions(-)
> >
> > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> > d1dc1de..1a08b3d 100644
> > --- a/app/test-pmd/cmdline.c
> > +++ b/app/test-pmd/cmdline.c
> > @@ -15996,6 +15996,458 @@ cmdline_parse_inst_t
> cmd_ptype_mapping_update = {
> >   	},
> >   };
> >
> > +static const char * const rx_offload_names[] = {
> > +	"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"
> > +};
> 
> There are already rte_rx_offload_names in librte_ethdev/rte_ethdev.c and
> rte_eth_dev_rx_offload_name() function in API.
Andrew, thanks for your feedback.
I will use rte_eth_dev_rx_offload_name( ) in my v2 patch set.


^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v2 0/2] app/testpmd: add new commands to test new Tx/Rx offload API
  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:15 ` [PATCH 2/2] app/testpmd: add commands to test new Tx " Wei Dai
@ 2018-03-13  6:42 ` Wei Dai
  2018-03-13  6:42   ` [PATCH v2 1/2] app/testpmd: add commands to test new Rx " Wei Dai
                     ` (2 more replies)
  2 siblings, 3 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-13  6:42 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Existed testpmd commands can't support per queue offload configuration.
And there are different commands to enable or disable different offloading.
This patch set add following commands to support new Tx/Rx offloading API test.

To get Rx offload capability of a port, please run:
testpmd > rx_offload get capability <port_id>

To get current Rx offload per queue and per port configuration of a port, run:
tesstpmd > rx_offload get configuration <port_id>

To enable or disable a Rx per port offloading, please run:
testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>

To enable or disable a Tx per port offloading, please run:
testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>

Same commands like "tx_offload ..." are also added to support new Tx offload API test.

---
v2: 
   use rte_eth_dev_rx_offload_name() and rte_eth_dev_tx_offload_name().
   remove static const strings of Rx/Tx offload names.

Wei Dai (2):
  app/testpmd: add commands to test new Rx offload API
  app/testpmd: add commands to test new Tx offload API

 app/test-pmd/cmdline.c | 863 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  28 +-
 app/test-pmd/testpmd.h |   2 +
 3 files changed, 889 insertions(+), 4 deletions(-)

-- 
2.7.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v2 1/2] app/testpmd: add commands to test new Rx offload API
  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   ` Wei Dai
  2018-03-13  7:21     ` Andrew Rybchenko
  2018-03-14 19:40     ` Wu, Jingjing
  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
  2 siblings, 2 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-13  6:42 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Rx offload API:
rx_offload get capability <port_id>
rx_offload get configuration <port_id>
rx_offload enable|disable per_port <offload> <port_id>
rx_offload enable|disable per_queue <offload> <port_id> <queue_id>

Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_strip", "ipv4_cksum", ...

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 app/test-pmd/cmdline.c | 424 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  15 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 438 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index d1dc1de..dfd0ca6 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -15996,6 +15996,426 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
 	},
 };
 
+/* Get Rx offloads capability */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+static void
+print_rx_offloads(uint64_t offloads)
+{
+	uint64_t single_offload;
+
+	for (single_offload = DEV_RX_OFFLOAD_VLAN_STRIP;
+	     single_offload <= DEV_RX_OFFLOAD_SECURITY;
+	     single_offload <<= 1)
+		if (offloads & single_offload)
+			printf(" %s",
+			       rte_eth_dev_rx_offload_name(single_offload));
+}
+
+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 = "rx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_get,
+		(void *)&cmd_rx_offload_get_capa_capability,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "rx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_get,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static int
+config_rx_offload(const char *name, uint64_t *offload, int on)
+{
+	uint64_t local = *offload;
+
+	if (!strcmp(name, "vlan_strip")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_VLAN_STRIP;
+		else
+			local &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
+	} else if (!strcmp(name, "ipv4_cksum")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_IPV4_CKSUM;
+		else
+			local &= ~DEV_RX_OFFLOAD_IPV4_CKSUM;
+	} else if (!strcmp(name, "udp_cksum")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_UDP_CKSUM;
+		else
+			local &= ~DEV_RX_OFFLOAD_UDP_CKSUM;
+	} else if (!strcmp(name, "tcp_cksum")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_TCP_CKSUM;
+		else
+			local &= ~DEV_RX_OFFLOAD_TCP_CKSUM;
+	} else if (!strcmp(name, "tcp_lro")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_TCP_LRO;
+		else
+			local &= ~DEV_RX_OFFLOAD_TCP_LRO;
+	} else if (!strcmp(name, "qinq_strip")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_QINQ_STRIP;
+		else
+			local &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
+	} else if (!strcmp(name, "outer_ipv4_cksum")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
+		else
+			local &= ~DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
+	} else if (!strcmp(name, "macsec_strip")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_MACSEC_STRIP;
+		else
+			local &= ~DEV_RX_OFFLOAD_MACSEC_STRIP;
+	} else if (!strcmp(name, "header_split")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_HEADER_SPLIT;
+		else
+			local &= ~DEV_RX_OFFLOAD_HEADER_SPLIT;
+	} else if (!strcmp(name, "vlan_filter")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_VLAN_FILTER;
+		else
+			local &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
+	} else if (!strcmp(name, "vlan_extend")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_VLAN_EXTEND;
+		else
+			local &= ~DEV_RX_OFFLOAD_VLAN_EXTEND;
+	} else if (!strcmp(name, "jumbo_frame")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_JUMBO_FRAME;
+		else
+			local &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
+	} else if (!strcmp(name, "crc_strip")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_CRC_STRIP;
+		else
+			local &= ~DEV_RX_OFFLOAD_CRC_STRIP;
+	} else if (!strcmp(name, "scatter")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_SCATTER;
+		else
+			local &= ~DEV_RX_OFFLOAD_SCATTER;
+	} else if (!strcmp(name, "timestamp")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_TIMESTAMP;
+		else
+			local &= ~DEV_RX_OFFLOAD_TIMESTAMP;
+	} else if (!strcmp(name, "security")) {
+		if (on)
+			local |= DEV_RX_OFFLOAD_SECURITY;
+		else
+			local &= ~DEV_RX_OFFLOAD_SECURITY;
+	} else
+		return -1;
+
+	*offload = local;
+	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_port *port = &ports[port_id];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else if (!strcmp(res->en_dis, "disable"))
+		on = 0;
+	else {
+		printf("Unknown parameter: %s\n", res->en_dis);
+		return;
+	}
+
+	if (config_rx_offload(res->offload,
+			      &port->dev_conf.rxmode.offloads, on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
+	.f = cmd_config_per_port_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_port 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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_rx_offload_result_per_port,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else if (!strcmp(res->en_dis, "disable"))
+		on = 0;
+	else {
+		printf("Unknown parameter: %s\n", res->en_dis);
+		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", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	if (config_rx_offload(res->offload,
+			      &port->rx_offloads[queue_id], on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
+	.f = cmd_config_per_queue_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_queue 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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_rx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16272,6 +16692,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+	(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,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e258..9786bfe 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -656,6 +656,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);
 
@@ -707,6 +708,17 @@ init_config(void)
 			}
 		}
 
+		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
+						sizeof(port->rx_offloads[0]) *
+						port->dev_info.max_rx_queues,
+						sizeof(port->rx_offloads[0]));
+		if (port->rx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->rx_offload[0]) "
+				 "failed\n", port->dev_info.max_rx_queues);
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1615,10 +1627,9 @@ start_port(portid_t pid)
 				port->need_reconfig_queues = 1;
 				return -1;
 			}
-			/* Apply Rx offloads configuration */
-			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
 			/* setup rx queues */
 			for (qi = 0; qi < nb_rxq; qi++) {
+				port->rx_conf.offloads = port->rx_offloads[qi];
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
 					struct rte_mempool * mp =
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea..dcad260 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -183,6 +183,7 @@ struct rte_port {
 	uint8_t                 dcb_flag;   /**< enable dcb */
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
+	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 2/2] app/testpmd: add commands to test new Tx offload API
  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  6:42   ` Wei Dai
  2018-03-17 13:31   ` [PATCH v3 0/3] app/testpmd: add new commands to test new Tx/Rx " Wei Dai
  2 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-13  6:42 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Tx offload API:
tx_offload get capability <port_id>
tx_offload get configuration <port_id>
tx_offload enable|disable per_port <offload> <port_id>
tx_offload enable|disable per_queue <offload> <port_id> <queue_id>

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>
---
 app/test-pmd/cmdline.c | 439 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  13 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 451 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index dfd0ca6..5c4fcf4 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16416,6 +16416,441 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
 	}
 };
 
+/* Get Tx offloads capability */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+static void
+print_tx_offloads(uint64_t offloads)
+{
+	uint64_t single_offload;
+
+	for (single_offload = DEV_TX_OFFLOAD_VLAN_INSERT;
+	     single_offload <= DEV_TX_OFFLOAD_SECURITY;
+	     single_offload <<= 1)
+		if (offloads & single_offload)
+			printf(" %s",
+			       rte_eth_dev_tx_offload_name(single_offload));
+}
+
+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 = "tx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_get,
+		(void *)&cmd_tx_offload_get_capa_capability,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "tx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_get,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static int
+config_tx_offload(const char *name, uint64_t *offload, int on)
+{
+	uint64_t local = *offload;
+
+	if (!strcmp(name, "vlan_insert")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_VLAN_INSERT;
+		else
+			local &= ~DEV_TX_OFFLOAD_VLAN_INSERT;
+	} else if (!strcmp(name, "ipv4_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_IPV4_CKSUM;
+	} else if (!strcmp(name, "udp_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_UDP_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_UDP_CKSUM;
+	} else if (!strcmp(name, "tcp_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_TCP_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_TCP_CKSUM;
+	} else if (!strcmp(name, "sccp_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_SCTP_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_SCTP_CKSUM;
+	} else if (!strcmp(name, "tcp_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_TCP_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_TCP_TSO;
+	} else if (!strcmp(name, "udp_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_UDP_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_UDP_TSO;
+	} else if (!strcmp(name, "outer_ipv4_cksum")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+		else
+			local &= ~DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+	} else if (!strcmp(name, "qinq_insert")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_QINQ_INSERT;
+		else
+			local &= ~DEV_TX_OFFLOAD_QINQ_INSERT;
+	} else if (!strcmp(name, "vxlan_tnl_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_VXLAN_TNL_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_VXLAN_TNL_TSO;
+	} else if (!strcmp(name, "gre_tnl_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_GRE_TNL_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_GRE_TNL_TSO;
+	} else if (!strcmp(name, "ipip_tnl_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_IPIP_TNL_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_IPIP_TNL_TSO;
+	} else if (!strcmp(name, "geneve_tnl_tso")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
+		else
+			local &= ~DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
+	} else if (!strcmp(name, "macsec_insert")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_MACSEC_INSERT;
+		else
+			local &= ~DEV_TX_OFFLOAD_MACSEC_INSERT;
+	} else if (!strcmp(name, "mt_lockfree")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_MT_LOCKFREE;
+		else
+			local &= ~DEV_TX_OFFLOAD_MT_LOCKFREE;
+	} else if (!strcmp(name, "multi_segs")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_MULTI_SEGS;
+		else
+			local &= ~DEV_TX_OFFLOAD_MULTI_SEGS;
+	} else if (!strcmp(name, "mbuf_fast_free")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+		else
+			local &= ~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+	} else if (!strcmp(name, "security")) {
+		if (on)
+			local |= DEV_TX_OFFLOAD_SECURITY;
+		else
+			local &= ~DEV_TX_OFFLOAD_SECURITY;
+	} else
+		return -1;
+
+	*offload = local;
+	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_port *port = &ports[port_id];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else if (!strcmp(res->en_dis, "disable"))
+		on = 0;
+	else {
+		printf("Unknown parameter: %s\n", res->en_dis);
+		return;
+	}
+
+	if (config_tx_offload(res->offload,
+			      &port->dev_conf.txmode.offloads, on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_tx_offload = {
+	.f = cmd_config_per_port_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_port "
+		    "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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_tx_offload_result_per_port,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else if (!strcmp(res->en_dis, "disable"))
+		on = 0;
+	else {
+		printf("Unknown parameter: %s\n", res->en_dis);
+		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", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	if (config_tx_offload(res->offload,
+			      &port->tx_offloads[queue_id], on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_tx_offload = {
+	.f = cmd_config_per_queue_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_queue "
+		    "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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_tx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16696,6 +17131,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(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 9786bfe..690074e 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -718,6 +718,16 @@ init_config(void)
 				 "failed\n", port->dev_info.max_rx_queues);
 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
 			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+		port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads",
+						sizeof(port->tx_offloads[0]) *
+						port->dev_info.max_tx_queues,
+						sizeof(port->tx_offloads[0]));
+		if (port->tx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->tx_offload[0]) "
+				 "failed\n", port->dev_info.max_tx_queues);
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_offloads[k] = port->dev_conf.txmode.offloads;
 
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
@@ -1599,10 +1609,9 @@ start_port(portid_t pid)
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
-			/* Apply Tx offloads configuration */
-			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+				port->tx_conf.offloads = port->tx_offloads[qi];
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index dcad260..b0bd14e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -184,6 +184,7 @@ struct rte_port {
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
+	uint64_t		*tx_offloads; /**< offloads of each Tx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 1/2] app/testpmd: add commands to test new Rx offload API
  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-14 19:40     ` Wu, Jingjing
  1 sibling, 1 reply; 44+ messages in thread
From: Andrew Rybchenko @ 2018-03-13  7:21 UTC (permalink / raw)
  To: Wei Dai, wenzhuo.lu, jingjing.wu; +Cc: dev

On 03/13/2018 09:42 AM, Wei Dai wrote:
> Add following testpmd run-time commands to support test of
> new Rx offload API:
> rx_offload get capability <port_id>
> rx_offload get configuration <port_id>
> rx_offload enable|disable per_port <offload> <port_id>
> rx_offload enable|disable per_queue <offload> <port_id> <queue_id>
>
> Above last 2 commands should be run when the port is stopped.
> And <offload> can be one of "vlan_strip", "ipv4_cksum", ...
>
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> ---
>   app/test-pmd/cmdline.c | 424 +++++++++++++++++++++++++++++++++++++++++++++++++
>   app/test-pmd/testpmd.c |  15 +-
>   app/test-pmd/testpmd.h |   1 +
>   3 files changed, 438 insertions(+), 2 deletions(-)
>
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index d1dc1de..dfd0ca6 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -15996,6 +15996,426 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
>   	},
>   };
>   
> +/* Get Rx offloads capability */
> +struct cmd_rx_offload_get_capa_result {
> +	cmdline_fixed_string_t rx_offload;
> +	cmdline_fixed_string_t get;
> +	cmdline_fixed_string_t capability;
> +	portid_t port_id;
> +};
> +
> +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_get =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_rx_offload_get_capa_result,
> +		 get, "get");
> +cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_rx_offload_get_capa_result,
> +		 capability, "capability");
> +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);
> +
> +static void
> +print_rx_offloads(uint64_t offloads)
> +{
> +	uint64_t single_offload;
> +
> +	for (single_offload = DEV_RX_OFFLOAD_VLAN_STRIP;
> +	     single_offload <= DEV_RX_OFFLOAD_SECURITY;

It requires attention when a new offload is added.
Please, consider to use something like __builtin_ffsll(), print name of
the found bit, clear it and retry. It allows to avoid boundaries 
specification.

<snip>


> +static int
> +config_rx_offload(const char *name, uint64_t *offload, int on)
> +{
> +	uint64_t local = *offload;
> +
> +	if (!strcmp(name, "vlan_strip")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_VLAN_STRIP;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
> +	} else if (!strcmp(name, "ipv4_cksum")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_IPV4_CKSUM;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_IPV4_CKSUM;
> +	} else if (!strcmp(name, "udp_cksum")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_UDP_CKSUM;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_UDP_CKSUM;
> +	} else if (!strcmp(name, "tcp_cksum")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_TCP_CKSUM;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_TCP_CKSUM;
> +	} else if (!strcmp(name, "tcp_lro")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_TCP_LRO;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_TCP_LRO;
> +	} else if (!strcmp(name, "qinq_strip")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_QINQ_STRIP;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
> +	} else if (!strcmp(name, "outer_ipv4_cksum")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
> +	} else if (!strcmp(name, "macsec_strip")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_MACSEC_STRIP;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_MACSEC_STRIP;
> +	} else if (!strcmp(name, "header_split")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_HEADER_SPLIT;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_HEADER_SPLIT;
> +	} else if (!strcmp(name, "vlan_filter")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_VLAN_FILTER;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
> +	} else if (!strcmp(name, "vlan_extend")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_VLAN_EXTEND;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_VLAN_EXTEND;
> +	} else if (!strcmp(name, "jumbo_frame")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_JUMBO_FRAME;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
> +	} else if (!strcmp(name, "crc_strip")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_CRC_STRIP;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_CRC_STRIP;
> +	} else if (!strcmp(name, "scatter")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_SCATTER;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_SCATTER;
> +	} else if (!strcmp(name, "timestamp")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_TIMESTAMP;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_TIMESTAMP;
> +	} else if (!strcmp(name, "security")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_SECURITY;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_SECURITY;
> +	} else
> +		return -1;

I was going to suggest rte_eth_dev_rx_offload_name(), strcasecmp() and loop.
It is possible to iterate on all U64 bits or add a way to get all 
offload bits from rte_ethdev.
However it still requires list of offloads in the help below. So, it is 
not easy to get rig of
offloads list completely. Just an idea. Up to you.

<snip>

> +cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
> +	.f = cmd_config_per_port_rx_offload_parsed,
> +	.data = NULL,
> +	.help_str = "rx_offload enable|disable per_port 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 "
> +		    "<port_id>",
>

<snip>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 1/2] app/testpmd: add commands to test new Rx offload API
  2018-03-13  7:21     ` Andrew Rybchenko
@ 2018-03-13  9:30       ` Ananyev, Konstantin
  2018-03-17 13:45         ` Dai, Wei
  0 siblings, 1 reply; 44+ messages in thread
From: Ananyev, Konstantin @ 2018-03-13  9:30 UTC (permalink / raw)
  To: Andrew Rybchenko, Dai, Wei, Lu, Wenzhuo, Wu, Jingjing; +Cc: dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Andrew Rybchenko
> Sent: Tuesday, March 13, 2018 7:21 AM
> To: Dai, Wei <wei.dai@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 1/2] app/testpmd: add commands to test new Rx offload API
> 
> On 03/13/2018 09:42 AM, Wei Dai wrote:
> > Add following testpmd run-time commands to support test of
> > new Rx offload API:
> > rx_offload get capability <port_id>
> > rx_offload get configuration <port_id>
> > rx_offload enable|disable per_port <offload> <port_id>
> > rx_offload enable|disable per_queue <offload> <port_id> <queue_id>
> >
> > Above last 2 commands should be run when the port is stopped.
> > And <offload> can be one of "vlan_strip", "ipv4_cksum", ...
> >
> > Signed-off-by: Wei Dai <wei.dai@intel.com>
> > ---
> >   app/test-pmd/cmdline.c | 424 +++++++++++++++++++++++++++++++++++++++++++++++++
> >   app/test-pmd/testpmd.c |  15 +-
> >   app/test-pmd/testpmd.h |   1 +
> >   3 files changed, 438 insertions(+), 2 deletions(-)
> >
> > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> > index d1dc1de..dfd0ca6 100644
> > --- a/app/test-pmd/cmdline.c
> > +++ b/app/test-pmd/cmdline.c
> > @@ -15996,6 +15996,426 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
> >   	},
> >   };
> >
> > +/* Get Rx offloads capability */
> > +struct cmd_rx_offload_get_capa_result {
> > +	cmdline_fixed_string_t rx_offload;
> > +	cmdline_fixed_string_t get;
> > +	cmdline_fixed_string_t capability;
> > +	portid_t port_id;
> > +};
> > +
> > +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_get =
> > +	TOKEN_STRING_INITIALIZER
> > +		(struct cmd_rx_offload_get_capa_result,
> > +		 get, "get");
> > +cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
> > +	TOKEN_STRING_INITIALIZER
> > +		(struct cmd_rx_offload_get_capa_result,
> > +		 capability, "capability");
> > +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);
> > +
> > +static void
> > +print_rx_offloads(uint64_t offloads)
> > +{
> > +	uint64_t single_offload;
> > +
> > +	for (single_offload = DEV_RX_OFFLOAD_VLAN_STRIP;
> > +	     single_offload <= DEV_RX_OFFLOAD_SECURITY;
> 
> It requires attention when a new offload is added.
> Please, consider to use something like __builtin_ffsll(), print name of
> the found bit, clear it and retry. It allows to avoid boundaries
> specification.
> 
> <snip>
> 
> 
> > +static int
> > +config_rx_offload(const char *name, uint64_t *offload, int on)
> > +{
> > +	uint64_t local = *offload;
> > +
> > +	if (!strcmp(name, "vlan_strip")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_VLAN_STRIP;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
> > +	} else if (!strcmp(name, "ipv4_cksum")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_IPV4_CKSUM;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_IPV4_CKSUM;
> > +	} else if (!strcmp(name, "udp_cksum")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_UDP_CKSUM;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_UDP_CKSUM;
> > +	} else if (!strcmp(name, "tcp_cksum")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_TCP_CKSUM;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_TCP_CKSUM;
> > +	} else if (!strcmp(name, "tcp_lro")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_TCP_LRO;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_TCP_LRO;
> > +	} else if (!strcmp(name, "qinq_strip")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_QINQ_STRIP;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
> > +	} else if (!strcmp(name, "outer_ipv4_cksum")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
> > +	} else if (!strcmp(name, "macsec_strip")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_MACSEC_STRIP;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_MACSEC_STRIP;
> > +	} else if (!strcmp(name, "header_split")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_HEADER_SPLIT;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_HEADER_SPLIT;
> > +	} else if (!strcmp(name, "vlan_filter")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_VLAN_FILTER;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
> > +	} else if (!strcmp(name, "vlan_extend")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_VLAN_EXTEND;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_VLAN_EXTEND;
> > +	} else if (!strcmp(name, "jumbo_frame")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_JUMBO_FRAME;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
> > +	} else if (!strcmp(name, "crc_strip")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_CRC_STRIP;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_CRC_STRIP;
> > +	} else if (!strcmp(name, "scatter")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_SCATTER;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_SCATTER;
> > +	} else if (!strcmp(name, "timestamp")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_TIMESTAMP;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_TIMESTAMP;
> > +	} else if (!strcmp(name, "security")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_SECURITY;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_SECURITY;
> > +	} else
> > +		return -1;
> 
> I was going to suggest rte_eth_dev_rx_offload_name(), strcasecmp() and loop.

+1

> It is possible to iterate on all U64 bits or add a way to get all
> offload bits from rte_ethdev.
> However it still requires list of offloads in the help below. So, it is
> not easy to get rig of
> offloads list completely. Just an idea. Up to you.
> 
> <snip>
> 
> > +cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
> > +	.f = cmd_config_per_port_rx_offload_parsed,
> > +	.data = NULL,
> > +	.help_str = "rx_offload enable|disable per_port 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 "
> > +		    "<port_id>",
> >
> 
> <snip>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 1/2] app/testpmd: add commands to test new Rx offload API
  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-14 19:40     ` Wu, Jingjing
  2018-03-17 13:49       ` Dai, Wei
  1 sibling, 1 reply; 44+ messages in thread
From: Wu, Jingjing @ 2018-03-14 19:40 UTC (permalink / raw)
  To: Dai, Wei, Lu, Wenzhuo; +Cc: dev

<...>

> +static int
> +config_rx_offload(const char *name, uint64_t *offload, int on)
> +{
> +	uint64_t local = *offload;
> +
> +	if (!strcmp(name, "vlan_strip")) {
> +		if (on)
> +			local |= DEV_RX_OFFLOAD_VLAN_STRIP;
> +		else
> +			local &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
Would it decrease the lines if move the "on" checking to the end of this function, just set the
BIT which you want to set or mask here?
<...>

> +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_port *port = &ports[port_id];
> +	int on;
> +
> +	if (port->port_status != RTE_PORT_STOPPED) {
> +		printf("Error: Can't config offload when Port %d "
> +		       "is not stopped\n", port_id);
> +		return;
> +	}
> +
> +	if (!strcmp(res->en_dis, "enable"))
> +		on = 1;
> +	else if (!strcmp(res->en_dis, "disable"))
> +		on = 0;
> +	else {
> +		printf("Unknown parameter: %s\n", res->en_dis);
> +		return;
The en_dis is already defined as "enable#disable", so the else is useless here.

<...>

> +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];
> +	int on;
> +
> +	if (port->port_status != RTE_PORT_STOPPED) {
> +		printf("Error: Can't config offload when Port %d "
> +		       "is not stopped\n", port_id);
> +		return;
> +	}
> +
> +	if (!strcmp(res->en_dis, "enable"))
> +		on = 1;
> +	else if (!strcmp(res->en_dis, "disable"))
> +		on = 0;
> +	else {
> +		printf("Unknown parameter: %s\n", res->en_dis);
> +		return;
Same comments as above.
<...>

> @@ -707,6 +708,17 @@ init_config(void)
>  			}
>  		}
> 
> +		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
> +						sizeof(port->rx_offloads[0]) *
> +						port->dev_info.max_rx_queues,
> +						sizeof(port->rx_offloads[0]));

When will you free it?

> +		if (port->rx_offloads == NULL)
> +			rte_exit(EXIT_FAILURE,
> +				 "rte_zmalloc(%d port->rx_offload[0]) "
> +				 "failed\n", port->dev_info.max_rx_queues);
> +		for (k = 0; k < port->dev_info.max_rx_queues; k++)
> +			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
> +
In the get configure command, the port->rx_offloads is printed.
Here you init it to be port configuration, when will you update it?

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v3 0/3] app/testpmd: add new commands to test new Tx/Rx offload API
  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  6:42   ` [PATCH v2 2/2] app/testpmd: add commands to test new Tx " Wei Dai
@ 2018-03-17 13:31   ` Wei Dai
  2018-03-17 13:31     ` [PATCH v3 1/3] ethdev: add enum type for loop on Rx/Tx offloads Wei Dai
                       ` (4 more replies)
  2 siblings, 5 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-17 13:31 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Existed testpmd commands can't support per queue offload configuration.
And there are different commands to enable or disable different offloading.
This patch set add following commands to support new Tx/Rx offloading API test.

To get Rx offload capability of a port, please run:
testpmd > rx_offload get capability <port_id>

To get current Rx offload per queue and per port configuration of a port, run:
tesstpmd > rx_offload get configuration <port_id>

To enable or disable a Rx per port offloading, please run:
testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>

To enable or disable a Tx per port offloading, please run:
testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>

Same commands like "tx_offload ..." are also added to support new Tx offload API test.

---
v3:
   add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
   free memory of port->rx_offloads and port->tx_offloads when testpmd is existed
v2: 
   use rte_eth_dev_rx_offload_name() and rte_eth_dev_tx_offload_name().
   remove static const strings of Rx/Tx offload names.

Wei Dai (3):
  ethdev: add enum type for loop on Rx/Tx offloads
  app/testpmd: add commands to test new Rx offload API
  app/testpmd: add commands to test new Tx offload API

 app/test-pmd/cmdline.c        | 739 ++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c        |  34 +-
 app/test-pmd/testpmd.h        |   2 +
 lib/librte_ether/rte_ethdev.h |  44 +++
 4 files changed, 815 insertions(+), 4 deletions(-)

-- 
2.7.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v3 1/3] ethdev: add enum type for loop on Rx/Tx offloads
  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     ` Wei Dai
  2018-03-17 13:31     ` [PATCH v3 2/3] app/testpmd: add commands to test new Rx offload API Wei Dai
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-17 13:31 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

This patch adds enum rte_eth_rx_offload_type and
enum rte_eth_tx_offload_type. For a loop on all
Rx offloads, it is convenient to begin with the
first enum member ETH_RX_OFFLOAD_FIRST_FEATURE
and to end at ETH_RX_OFFLOAD_TOTAL_NUM.
A loop on all Tx offloads can begin with
ETH_TX_OFFLOAD_FIRST_FEATURE and end at
ETH_TX_OFFLOAD_TOTAL_NUM.

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 lib/librte_ether/rte_ethdev.h | 44 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0361533..0089ea3 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -946,6 +946,27 @@ struct rte_eth_conf {
 			     DEV_RX_OFFLOAD_VLAN_FILTER | \
 			     DEV_RX_OFFLOAD_VLAN_EXTEND)
 
+enum rte_eth_rx_offload_type {
+	ETH_RX_OFFLOAD_FIRST_FEATURE = 0,
+	ETH_RX_OFFLOAD_VLAN_STRIP = ETH_RX_OFFLOAD_FIRST_FEATURE,
+	ETH_RX_OFFLOAD_IPV4_CKSUM,
+	ETH_RX_OFFLOAD_UDP_CKSUM,
+	ETH_RX_OFFLOAD_TCP_CKSUM,
+	ETH_RX_OFFLOAD_TCP_LRO,
+	ETH_RX_OFFLOAD_QINQ_STRIP,
+	ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM,
+	ETH_RX_OFFLOAD_MACSEC_STRIP,
+	ETH_RX_OFFLOAD_HEADER_SPLIT,
+	ETH_RX_OFFLOAD_VLAN_FILTER,
+	ETH_RX_OFFLOAD_VLAN_EXTEND,
+	ETH_RX_OFFLOAD_JUMBO_FRAME,
+	ETH_RX_OFFLOAD_CRC_STRIP,
+	ETH_RX_OFFLOAD_SCATTER,
+	ETH_RX_OFFLOAD_TIMESTAMP,
+	ETH_RX_OFFLOAD_SECURITY,
+	ETH_RX_OFFLOAD_TOTAL_NUM
+};
+
 /*
  * If new Rx offload capabilities are defined, they also must be
  * mentioned in rte_rx_offload_names in rte_ethdev.c file.
@@ -981,6 +1002,29 @@ struct rte_eth_conf {
  */
 #define DEV_TX_OFFLOAD_SECURITY         0x00020000
 
+enum rte_eth_tx_offload_type {
+	ETH_TX_OFFLOAD_FIRST_FEATURE = 0,
+	ETH_TX_OFFLOAD_VLAN_INSERT = ETH_TX_OFFLOAD_FIRST_FEATURE,
+	ETH_TX_OFFLOAD_IPV4_CKSUM,
+	ETH_TX_OFFLOAD_UDP_CKSUM,
+	ETH_TX_OFFLOAD_TCP_CKSUM,
+	ETH_TX_OFFLOAD_SCTP_CKSUM,
+	ETH_TX_OFFLOAD_TCP_TSO,
+	ETH_TX_OFFLOAD_UDP_TSO,
+	ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM,
+	ETH_TX_OFFLOAD_QINQ_INSERT,
+	ETH_TX_OFFLOAD_VXLAN_TNL_TSO,
+	ETH_TX_OFFLOAD_GRE_TNL_TSO,
+	ETH_TX_OFFLOAD_IPIP_TNL_TSO,
+	ETH_TX_OFFLOAD_GENEVE_TNL_TSO,
+	ETH_TX_OFFLOAD_MACSEC_INSERT,
+	ETH_TX_OFFLOAD_MT_LOCKFREE,
+	ETH_TX_OFFLOAD_MULTI_SEGS,
+	ETH_TX_OFFLOAD_MBUF_FAST_FREE,
+	ETH_TX_OFFLOAD_SECURITY,
+	ETH_TX_OFFLOAD_TOTAL_NUM
+};
+
 /*
  * If new Tx offload capabilities are defined, they also must be
  * mentioned in rte_tx_offload_names in rte_ethdev.c file.
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 2/3] app/testpmd: add commands to test new Rx offload API
  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     ` Wei Dai
  2018-03-17 13:31     ` [PATCH v3 3/3] app/testpmd: add commands to test new Tx " Wei Dai
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-17 13:31 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Rx offload API:
rx_offload get capability <port_id>
rx_offload get configuration <port_id>
rx_offload enable|disable per_port <offload> <port_id>
rx_offload enable|disable per_queue <offload> <port_id> <queue_id>

Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_strip", "ipv4_cksum", ...

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 app/test-pmd/cmdline.c | 367 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  19 ++-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 385 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 40b31ad..0475064 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -15996,6 +15996,369 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
 	},
 };
 
+/* Get Rx offloads capability */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "rx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_get,
+		(void *)&cmd_rx_offload_get_capa_capability,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "rx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_get,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static int
+config_rx_offload(const char *name, uint64_t *offload, int on)
+{
+	uint64_t single_offload;
+	const char *single_name;
+	int found = 0;
+	enum rte_eth_rx_offload_type type;
+
+	single_offload = 1;
+	for (type = ETH_RX_OFFLOAD_FIRST_FEATURE;
+	     type < ETH_RX_OFFLOAD_TOTAL_NUM; type++) {
+		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) {
+		if (on)
+			*offload |= single_offload;
+		else
+			*offload &= ~single_offload;
+		return 0;
+	}
+
+	return -1;
+}
+
+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_port *port = &ports[port_id];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else
+		on = 0;
+
+	if (config_rx_offload(res->offload,
+			      &port->dev_conf.rxmode.offloads, on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
+	.f = cmd_config_per_port_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_port 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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_rx_offload_result_per_port,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else
+		on = 0;
+
+	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", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	if (config_rx_offload(res->offload,
+			      &port->rx_offloads[queue_id], on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
+	.f = cmd_config_per_queue_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_queue 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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_rx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16272,6 +16635,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+	(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,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e258..e5de40a 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -656,6 +656,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);
 
@@ -707,6 +708,17 @@ init_config(void)
 			}
 		}
 
+		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
+						sizeof(port->rx_offloads[0]) *
+						port->dev_info.max_rx_queues,
+						sizeof(port->rx_offloads[0]));
+		if (port->rx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->rx_offload[0]) "
+				 "failed\n", port->dev_info.max_rx_queues);
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1615,10 +1627,9 @@ start_port(portid_t pid)
 				port->need_reconfig_queues = 1;
 				return -1;
 			}
-			/* Apply Rx offloads configuration */
-			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
 			/* setup rx queues */
 			for (qi = 0; qi < nb_rxq; qi++) {
+				port->rx_conf.offloads = port->rx_offloads[qi];
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
 					struct rte_mempool * mp =
@@ -1915,6 +1926,7 @@ detach_port(portid_t port_id)
 void
 pmd_test_exit(void)
 {
+	struct rte_port *port;
 	portid_t pt_id;
 
 	if (test_done == 0)
@@ -1927,6 +1939,9 @@ pmd_test_exit(void)
 			fflush(stdout);
 			stop_port(pt_id);
 			close_port(pt_id);
+			port = &ports[pt_id];
+			rte_free(port->rx_offloads);
+			port->rx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea..dcad260 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -183,6 +183,7 @@ struct rte_port {
 	uint8_t                 dcb_flag;   /**< enable dcb */
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
+	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 3/3] app/testpmd: add commands to test new Tx offload API
  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     ` 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:40     ` [PATCH v4 0/3] app/testpmd: add new commands to test new Tx/Rx offload Wei Dai
  4 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-17 13:31 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Tx offload API:
tx_offload get capability <port_id>
tx_offload get configuration <port_id>
tx_offload enable|disable per_port <offload> <port_id>
tx_offload enable|disable per_queue <offload> <port_id> <queue_id>

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>
---
 app/test-pmd/cmdline.c | 372 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  15 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 386 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0475064..a142517 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16359,6 +16359,374 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
 	}
 };
 
+/* Get Tx offloads capability */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "tx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_get,
+		(void *)&cmd_tx_offload_get_capa_capability,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "tx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_get,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static int
+config_tx_offload(const char *name, uint64_t *offload, int on)
+{
+	uint64_t single_offload;
+	const char *single_name;
+	int found = 0;
+	enum rte_eth_tx_offload_type type;
+
+	single_offload = 1;
+	for (type = ETH_TX_OFFLOAD_FIRST_FEATURE;
+	     type < ETH_TX_OFFLOAD_TOTAL_NUM; type++) {
+		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) {
+		if (on)
+			*offload |= single_offload;
+		else
+			*offload &= ~single_offload;
+		return 0;
+	}
+
+	return -1;
+}
+
+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_port *port = &ports[port_id];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else
+		on = 0;
+
+	if (config_tx_offload(res->offload,
+			      &port->dev_conf.txmode.offloads, on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_tx_offload = {
+	.f = cmd_config_per_port_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_port "
+		    "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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_tx_offload_result_per_port,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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];
+	int on;
+
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Error: Can't config offload when Port %d "
+		       "is not stopped\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		on = 1;
+	else
+		on = 0;
+
+	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", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	if (config_tx_offload(res->offload,
+			      &port->tx_offloads[queue_id], on)) {
+		printf("Unknown offload name: %s", res->offload);
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_tx_offload = {
+	.f = cmd_config_per_queue_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_queue "
+		    "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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_tx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16639,6 +17007,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(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 e5de40a..d7d5d4c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -718,6 +718,16 @@ init_config(void)
 				 "failed\n", port->dev_info.max_rx_queues);
 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
 			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+		port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads",
+						sizeof(port->tx_offloads[0]) *
+						port->dev_info.max_tx_queues,
+						sizeof(port->tx_offloads[0]));
+		if (port->tx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->tx_offload[0]) "
+				 "failed\n", port->dev_info.max_tx_queues);
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_offloads[k] = port->dev_conf.txmode.offloads;
 
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
@@ -1599,10 +1609,9 @@ start_port(portid_t pid)
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
-			/* Apply Tx offloads configuration */
-			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+				port->tx_conf.offloads = port->tx_offloads[qi];
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1942,6 +1951,8 @@ pmd_test_exit(void)
 			port = &ports[pt_id];
 			rte_free(port->rx_offloads);
 			port->rx_offloads = NULL;
+			rte_free(port->tx_offloads);
+			port->tx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index dcad260..b0bd14e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -184,6 +184,7 @@ struct rte_port {
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
+	uint64_t		*tx_offloads; /**< offloads of each Tx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 1/2] app/testpmd: add commands to test new Rx offload API
  2018-03-13  9:30       ` Ananyev, Konstantin
@ 2018-03-17 13:45         ` Dai, Wei
  0 siblings, 0 replies; 44+ messages in thread
From: Dai, Wei @ 2018-03-17 13:45 UTC (permalink / raw)
  To: Ananyev, Konstantin, Andrew Rybchenko, Lu, Wenzhuo, Wu, Jingjing; +Cc: dev

Thanks to Konstantin and Andrew for your feedback.
I will use __builtin_ctzll() and __builtin_clzll() in my v3 patch set.
I also will use strcasecmp and loop to do config_rx_offload() and
config_tx_offload() following your guidance.

> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Tuesday, March 13, 2018 5:31 PM
> To: Andrew Rybchenko <arybchenko@solarflare.com>; Dai, Wei
> <wei.dai@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH v2 1/2] app/testpmd: add commands to test
> new Rx offload API
> 
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Andrew
> Rybchenko
> > Sent: Tuesday, March 13, 2018 7:21 AM
> > To: Dai, Wei <wei.dai@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>;
> > Wu, Jingjing <jingjing.wu@intel.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v2 1/2] app/testpmd: add commands to
> > test new Rx offload API
> >
> > On 03/13/2018 09:42 AM, Wei Dai wrote:
> > > Add following testpmd run-time commands to support test of new Rx
> > > offload API:
> > > rx_offload get capability <port_id>
> > > rx_offload get configuration <port_id> rx_offload enable|disable
> > > per_port <offload> <port_id> rx_offload enable|disable per_queue
> > > <offload> <port_id> <queue_id>
> > >
> > > Above last 2 commands should be run when the port is stopped.
> > > And <offload> can be one of "vlan_strip", "ipv4_cksum", ...
> > >
> > > Signed-off-by: Wei Dai <wei.dai@intel.com>
> > > ---
> > > +	for (single_offload = DEV_RX_OFFLOAD_VLAN_STRIP;
> > > +	     single_offload <= DEV_RX_OFFLOAD_SECURITY;
> >
> > It requires attention when a new offload is added.
> > Please, consider to use something like __builtin_ffsll(), print name
> > of the found bit, clear it and retry. It allows to avoid boundaries
> > specification.
> >
> > <snip>
> >
> >
> > I was going to suggest rte_eth_dev_rx_offload_name(), strcasecmp() and
> loop.
> 
> +1
> 
> > It is possible to iterate on all U64 bits or add a way to get all
> > offload bits from rte_ethdev.
> > However it still requires list of offloads in the help below. So, it
> > is not easy to get rig of offloads list completely. Just an idea. Up
> > to you.
> >
> > <snip>
> >

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 1/2] app/testpmd: add commands to test new Rx offload API
  2018-03-14 19:40     ` Wu, Jingjing
@ 2018-03-17 13:49       ` Dai, Wei
  0 siblings, 0 replies; 44+ messages in thread
From: Dai, Wei @ 2018-03-17 13:49 UTC (permalink / raw)
  To: Wu, Jingjing, Lu, Wenzhuo; +Cc: dev

> -----Original Message-----
> From: Wu, Jingjing
> Sent: Thursday, March 15, 2018 3:41 AM
> To: Dai, Wei <wei.dai@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH v2 1/2] app/testpmd: add commands to test new Rx
> offload API
> 
> <...>
> 
> > +static int
> > +config_rx_offload(const char *name, uint64_t *offload, int on) {
> > +	uint64_t local = *offload;
> > +
> > +	if (!strcmp(name, "vlan_strip")) {
> > +		if (on)
> > +			local |= DEV_RX_OFFLOAD_VLAN_STRIP;
> > +		else
> > +			local &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
> Would it decrease the lines if move the "on" checking to the end of this
> function, just set the BIT which you want to set or mask here?

Thanks, will follow your suggestion in v3 patch set.

> <...>
> 
> > +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_port *port = &ports[port_id];
> > +	int on;
> > +
> > +	if (port->port_status != RTE_PORT_STOPPED) {
> > +		printf("Error: Can't config offload when Port %d "
> > +		       "is not stopped\n", port_id);
> > +		return;
> > +	}
> > +
> > +	if (!strcmp(res->en_dis, "enable"))
> > +		on = 1;
> > +	else if (!strcmp(res->en_dis, "disable"))
> > +		on = 0;
> > +	else {
> > +		printf("Unknown parameter: %s\n", res->en_dis);
> > +		return;
> The en_dis is already defined as "enable#disable", so the else is useless here.
Thanks, the second if and second else can be removed and will change in v3 patch set.

> 
> <...>
> 
> > +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];
> > +	int on;
> > +
> > +	if (port->port_status != RTE_PORT_STOPPED) {
> > +		printf("Error: Can't config offload when Port %d "
> > +		       "is not stopped\n", port_id);
> > +		return;
> > +	}
> > +
> > +	if (!strcmp(res->en_dis, "enable"))
> > +		on = 1;
> > +	else if (!strcmp(res->en_dis, "disable"))
> > +		on = 0;
> > +	else {
> > +		printf("Unknown parameter: %s\n", res->en_dis);
> > +		return;
> Same comments as above.
> <...>
> 
> > @@ -707,6 +708,17 @@ init_config(void)
> >  			}
> >  		}
> >
> > +		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
> > +						sizeof(port->rx_offloads[0]) *
> > +						port->dev_info.max_rx_queues,
> > +						sizeof(port->rx_offloads[0]));
> 
> When will you free it?
I will free port->rx_offloads and port->tx_offloads when testpmd is existed.
> 
> > +		if (port->rx_offloads == NULL)
> > +			rte_exit(EXIT_FAILURE,
> > +				 "rte_zmalloc(%d port->rx_offload[0]) "
> > +				 "failed\n", port->dev_info.max_rx_queues);
> > +		for (k = 0; k < port->dev_info.max_rx_queues; k++)
> > +			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
> > +
> In the get configure command, the port->rx_offloads is printed.
> Here you init it to be port configuration, when will you update it?
This init_config() is only run once in the initialization stage in the main().
Port->rx_offloads[] can be changed using new testpmd command in this patch set.
Testpmd> rx_offload enable/disable per_queue <offload> <port_id> <queue_id>
And will be applied when the command port start <port_id> is run.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v4 0/3] app/testpmd: add new commands to test new Tx/Rx offload
  2018-03-17 13:31   ` [PATCH v3 0/3] app/testpmd: add new commands to test new Tx/Rx " Wei Dai
                       ` (2 preceding siblings ...)
  2018-03-17 13:31     ` [PATCH v3 3/3] app/testpmd: add commands to test new Tx " Wei Dai
@ 2018-03-19 12:33     ` Wei Dai
  2018-03-19 12:33       ` [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx offloads Wei Dai
                         ` (2 more replies)
  2018-03-19 12:40     ` [PATCH v4 0/3] app/testpmd: add new commands to test new Tx/Rx offload Wei Dai
  4 siblings, 3 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-19 12:33 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Existed testpmd commands can't support per queue offload configuration.
And there are different commands to enable or disable different offloading.
This patch set add following commands to support new Tx/Rx offloading API test.

To get Rx offload capability of a port, please run:
testpmd > rx_offload get capability <port_id>

To get current Rx offload per queue and per port configuration of a port, run:
tesstpmd > rx_offload get configuration <port_id>

To enable or disable a Rx per port offloading, please run:
testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>
This command will set|clear the associated bit in dev->dev_conf.rxmode.offloads
for rte_eth_dev_configure and tx_conf->offloads of all Rx queues for 
rte_eth_rx_queue_setup( ).

To enable or disable a Tx per port offloading, please run:
testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>

Same commands like "tx_offload ..." are also added to support new Tx offload API test.

---
v4:
   improve testpmd command per port offload to set or clear the port configuration
   and the queue configuration of all queues.
v3:
   add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
   free memory of port->rx_offloads and port->tx_offloads when testpmd is existed
v2: 
   use rte_eth_dev_rx_offload_name() and rte_eth_dev_tx_offload_name().
   remove static const strings of Rx/Tx offload names.

Wei Dai (3):
  ethdev: add enum type for loop on Rx/Tx offloads
  app/testpmd: add commands to test new Rx offload API
  pp/testpmd: add commands to test new Tx offload API

 app/test-pmd/cmdline.c        | 753 ++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c        |  34 +-
 app/test-pmd/testpmd.h        |   2 +
 lib/librte_ether/rte_ethdev.h |  44 +++
 4 files changed, 829 insertions(+), 4 deletions(-)

-- 
2.7.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx offloads
  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       ` 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
  2 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-19 12:33 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

This patch adds enum rte_eth_rx_offload_type and
enum rte_eth_tx_offload_type. For a loop on all
Rx offloads, it is convenient to begin with the
first enum member ETH_RX_OFFLOAD_FIRST_FEATURE
and to end at ETH_RX_OFFLOAD_TOTAL_NUM.
A loop on all Tx offloads can begin with
ETH_TX_OFFLOAD_FIRST_FEATURE and end at
ETH_TX_OFFLOAD_TOTAL_NUM.

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 lib/librte_ether/rte_ethdev.h | 44 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0361533..0089ea3 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -946,6 +946,27 @@ struct rte_eth_conf {
 			     DEV_RX_OFFLOAD_VLAN_FILTER | \
 			     DEV_RX_OFFLOAD_VLAN_EXTEND)
 
+enum rte_eth_rx_offload_type {
+	ETH_RX_OFFLOAD_FIRST_FEATURE = 0,
+	ETH_RX_OFFLOAD_VLAN_STRIP = ETH_RX_OFFLOAD_FIRST_FEATURE,
+	ETH_RX_OFFLOAD_IPV4_CKSUM,
+	ETH_RX_OFFLOAD_UDP_CKSUM,
+	ETH_RX_OFFLOAD_TCP_CKSUM,
+	ETH_RX_OFFLOAD_TCP_LRO,
+	ETH_RX_OFFLOAD_QINQ_STRIP,
+	ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM,
+	ETH_RX_OFFLOAD_MACSEC_STRIP,
+	ETH_RX_OFFLOAD_HEADER_SPLIT,
+	ETH_RX_OFFLOAD_VLAN_FILTER,
+	ETH_RX_OFFLOAD_VLAN_EXTEND,
+	ETH_RX_OFFLOAD_JUMBO_FRAME,
+	ETH_RX_OFFLOAD_CRC_STRIP,
+	ETH_RX_OFFLOAD_SCATTER,
+	ETH_RX_OFFLOAD_TIMESTAMP,
+	ETH_RX_OFFLOAD_SECURITY,
+	ETH_RX_OFFLOAD_TOTAL_NUM
+};
+
 /*
  * If new Rx offload capabilities are defined, they also must be
  * mentioned in rte_rx_offload_names in rte_ethdev.c file.
@@ -981,6 +1002,29 @@ struct rte_eth_conf {
  */
 #define DEV_TX_OFFLOAD_SECURITY         0x00020000
 
+enum rte_eth_tx_offload_type {
+	ETH_TX_OFFLOAD_FIRST_FEATURE = 0,
+	ETH_TX_OFFLOAD_VLAN_INSERT = ETH_TX_OFFLOAD_FIRST_FEATURE,
+	ETH_TX_OFFLOAD_IPV4_CKSUM,
+	ETH_TX_OFFLOAD_UDP_CKSUM,
+	ETH_TX_OFFLOAD_TCP_CKSUM,
+	ETH_TX_OFFLOAD_SCTP_CKSUM,
+	ETH_TX_OFFLOAD_TCP_TSO,
+	ETH_TX_OFFLOAD_UDP_TSO,
+	ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM,
+	ETH_TX_OFFLOAD_QINQ_INSERT,
+	ETH_TX_OFFLOAD_VXLAN_TNL_TSO,
+	ETH_TX_OFFLOAD_GRE_TNL_TSO,
+	ETH_TX_OFFLOAD_IPIP_TNL_TSO,
+	ETH_TX_OFFLOAD_GENEVE_TNL_TSO,
+	ETH_TX_OFFLOAD_MACSEC_INSERT,
+	ETH_TX_OFFLOAD_MT_LOCKFREE,
+	ETH_TX_OFFLOAD_MULTI_SEGS,
+	ETH_TX_OFFLOAD_MBUF_FAST_FREE,
+	ETH_TX_OFFLOAD_SECURITY,
+	ETH_TX_OFFLOAD_TOTAL_NUM
+};
+
 /*
  * If new Tx offload capabilities are defined, they also must be
  * mentioned in rte_tx_offload_names in rte_ethdev.c file.
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v4 2/3] app/testpmd: add commands to test new Rx offload API
  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       ` Wei Dai
  2018-03-19 12:33       ` [PATCH v4 3/3] pp/testpmd: add commands to test new Tx " Wei Dai
  2 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-19 12:33 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Rx offload API:
rx_offload get capability <port_id>
rx_offload get configuration <port_id>
rx_offload enable|disable per_port <offload> <port_id>
rx_offload enable|disable per_queue <offload> <port_id> <queue_id>

Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_strip", "ipv4_cksum", ...

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 app/test-pmd/cmdline.c | 374 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  19 ++-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 392 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 40b31ad..ae735d0 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -15996,6 +15996,376 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
 	},
 };
 
+/* Get Rx offloads capability */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "rx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_get,
+		(void *)&cmd_rx_offload_get_capa_capability,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "rx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_get,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static uint64_t
+search_rx_offload(const char *name)
+{
+	uint64_t single_offload;
+	const char *single_name;
+	int found = 0;
+	enum rte_eth_rx_offload_type type;
+
+	single_offload = 1;
+	for (type = ETH_RX_OFFLOAD_FIRST_FEATURE;
+	     type < ETH_RX_OFFLOAD_TOTAL_NUM; type++) {
+		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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_rx_queues = dev_info.nb_rx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.rxmode.offloads |= single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.rxmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] &= ~single_offload;
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
+	.f = cmd_config_per_port_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_port 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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_rx_offload_result_per_port,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	single_offload = search_rx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->rx_offloads[queue_id] |= single_offload;
+	else
+		port->rx_offloads[queue_id] &= ~single_offload;
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
+	.f = cmd_config_per_queue_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_queue 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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_rx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16272,6 +16642,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+	(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,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e258..e5de40a 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -656,6 +656,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);
 
@@ -707,6 +708,17 @@ init_config(void)
 			}
 		}
 
+		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
+						sizeof(port->rx_offloads[0]) *
+						port->dev_info.max_rx_queues,
+						sizeof(port->rx_offloads[0]));
+		if (port->rx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->rx_offload[0]) "
+				 "failed\n", port->dev_info.max_rx_queues);
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1615,10 +1627,9 @@ start_port(portid_t pid)
 				port->need_reconfig_queues = 1;
 				return -1;
 			}
-			/* Apply Rx offloads configuration */
-			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
 			/* setup rx queues */
 			for (qi = 0; qi < nb_rxq; qi++) {
+				port->rx_conf.offloads = port->rx_offloads[qi];
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
 					struct rte_mempool * mp =
@@ -1915,6 +1926,7 @@ detach_port(portid_t port_id)
 void
 pmd_test_exit(void)
 {
+	struct rte_port *port;
 	portid_t pt_id;
 
 	if (test_done == 0)
@@ -1927,6 +1939,9 @@ pmd_test_exit(void)
 			fflush(stdout);
 			stop_port(pt_id);
 			close_port(pt_id);
+			port = &ports[pt_id];
+			rte_free(port->rx_offloads);
+			port->rx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea..dcad260 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -183,6 +183,7 @@ struct rte_port {
 	uint8_t                 dcb_flag;   /**< enable dcb */
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
+	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v4 3/3] pp/testpmd: add commands to test new Tx offload API
  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       ` Wei Dai
  2 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-19 12:33 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Tx offload API:
tx_offload get capability <port_id>
tx_offload get configuration <port_id>
tx_offload enable|disable per_port <offload> <port_id>
tx_offload enable|disable per_queue <offload> <port_id> <queue_id>

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>
---
 app/test-pmd/cmdline.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  15 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 393 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ae735d0..e977910 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16366,6 +16366,381 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
 	}
 };
 
+/* Get Tx offloads capability */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "tx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_get,
+		(void *)&cmd_tx_offload_get_capa_capability,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "tx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_get,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static uint64_t
+search_tx_offload(const char *name)
+{
+	uint64_t single_offload;
+	const char *single_name;
+	int found = 0;
+	enum rte_eth_tx_offload_type type;
+
+	single_offload = 1;
+	for (type = ETH_TX_OFFLOAD_FIRST_FEATURE;
+	     type < ETH_TX_OFFLOAD_TOTAL_NUM; type++) {
+		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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_tx_queues = dev_info.nb_tx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.txmode.offloads |= single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.txmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] &= ~single_offload;
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_tx_offload = {
+	.f = cmd_config_per_port_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_port "
+		    "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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_tx_offload_result_per_port,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	single_offload = search_tx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->tx_offloads[queue_id] |= single_offload;
+	else
+		port->tx_offloads[queue_id] &= ~single_offload;
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_tx_offload = {
+	.f = cmd_config_per_queue_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_queue "
+		    "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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_tx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16646,6 +17021,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(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 e5de40a..d7d5d4c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -718,6 +718,16 @@ init_config(void)
 				 "failed\n", port->dev_info.max_rx_queues);
 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
 			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+		port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads",
+						sizeof(port->tx_offloads[0]) *
+						port->dev_info.max_tx_queues,
+						sizeof(port->tx_offloads[0]));
+		if (port->tx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->tx_offload[0]) "
+				 "failed\n", port->dev_info.max_tx_queues);
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_offloads[k] = port->dev_conf.txmode.offloads;
 
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
@@ -1599,10 +1609,9 @@ start_port(portid_t pid)
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
-			/* Apply Tx offloads configuration */
-			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+				port->tx_conf.offloads = port->tx_offloads[qi];
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1942,6 +1951,8 @@ pmd_test_exit(void)
 			port = &ports[pt_id];
 			rte_free(port->rx_offloads);
 			port->rx_offloads = NULL;
+			rte_free(port->tx_offloads);
+			port->tx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index dcad260..b0bd14e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -184,6 +184,7 @@ struct rte_port {
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
+	uint64_t		*tx_offloads; /**< offloads of each Tx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v4 0/3] app/testpmd: add new commands to test new Tx/Rx offload
  2018-03-17 13:31   ` [PATCH v3 0/3] app/testpmd: add new commands to test new Tx/Rx " Wei Dai
                       ` (3 preceding siblings ...)
  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:40     ` Wei Dai
  2018-03-19 12:40       ` [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx offloads Wei Dai
                         ` (3 more replies)
  4 siblings, 4 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-19 12:40 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Existed testpmd commands can't support per queue offload configuration.
And there are different commands to enable or disable different offloading.
This patch set add following commands to support new Tx/Rx offloading API test.

To get Rx offload capability of a port, please run:
testpmd > rx_offload get capability <port_id>

To get current Rx offload per queue and per port configuration of a port, run:
tesstpmd > rx_offload get configuration <port_id>

To enable or disable a Rx per port offloading, please run:
testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>
This command will set|clear the associated bit in dev->dev_conf.rxmode.offloads
for rte_eth_dev_configure and tx_conf->offloads of all Rx queues for 
rte_eth_rx_queue_setup( ).

To enable or disable a Tx per port offloading, please run:
testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>

Same commands like "tx_offload ..." are also added to support new Tx offload API test.

---
v4:
   improve testpmd command per port offload to set or clear the port configuration
   and the queue configuration of all queues.
v3:
   add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
   free memory of port->rx_offloads and port->tx_offloads when testpmd is existed
v2: 
   use rte_eth_dev_rx_offload_name() and rte_eth_dev_tx_offload_name().
   remove static const strings of Rx/Tx offload names.

Wei Dai (3):
  ethdev: add enum type for loop on Rx/Tx offloads
  app/testpmd: add commands to test new Rx offload API
  pp/testpmd: add commands to test new Tx offload API

 app/test-pmd/cmdline.c        | 753 ++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c        |  34 +-
 app/test-pmd/testpmd.h        |   2 +
 lib/librte_ether/rte_ethdev.h |  44 +++
 4 files changed, 829 insertions(+), 4 deletions(-)

-- 
2.7.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx offloads
  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       ` Wei Dai
  2018-03-19 14:05         ` Zhang, Qi Z
  2018-03-19 12:40       ` [PATCH v4 2/3] app/testpmd: add commands to test new Rx offload API Wei Dai
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 44+ messages in thread
From: Wei Dai @ 2018-03-19 12:40 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

This patch adds enum rte_eth_rx_offload_type and
enum rte_eth_tx_offload_type. For a loop on all
Rx offloads, it is convenient to begin with the
first enum member ETH_RX_OFFLOAD_FIRST_FEATURE
and to end at ETH_RX_OFFLOAD_TOTAL_NUM.
A loop on all Tx offloads can begin with
ETH_TX_OFFLOAD_FIRST_FEATURE and end at
ETH_TX_OFFLOAD_TOTAL_NUM.

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 lib/librte_ether/rte_ethdev.h | 44 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0361533..0089ea3 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -946,6 +946,27 @@ struct rte_eth_conf {
 			     DEV_RX_OFFLOAD_VLAN_FILTER | \
 			     DEV_RX_OFFLOAD_VLAN_EXTEND)
 
+enum rte_eth_rx_offload_type {
+	ETH_RX_OFFLOAD_FIRST_FEATURE = 0,
+	ETH_RX_OFFLOAD_VLAN_STRIP = ETH_RX_OFFLOAD_FIRST_FEATURE,
+	ETH_RX_OFFLOAD_IPV4_CKSUM,
+	ETH_RX_OFFLOAD_UDP_CKSUM,
+	ETH_RX_OFFLOAD_TCP_CKSUM,
+	ETH_RX_OFFLOAD_TCP_LRO,
+	ETH_RX_OFFLOAD_QINQ_STRIP,
+	ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM,
+	ETH_RX_OFFLOAD_MACSEC_STRIP,
+	ETH_RX_OFFLOAD_HEADER_SPLIT,
+	ETH_RX_OFFLOAD_VLAN_FILTER,
+	ETH_RX_OFFLOAD_VLAN_EXTEND,
+	ETH_RX_OFFLOAD_JUMBO_FRAME,
+	ETH_RX_OFFLOAD_CRC_STRIP,
+	ETH_RX_OFFLOAD_SCATTER,
+	ETH_RX_OFFLOAD_TIMESTAMP,
+	ETH_RX_OFFLOAD_SECURITY,
+	ETH_RX_OFFLOAD_TOTAL_NUM
+};
+
 /*
  * If new Rx offload capabilities are defined, they also must be
  * mentioned in rte_rx_offload_names in rte_ethdev.c file.
@@ -981,6 +1002,29 @@ struct rte_eth_conf {
  */
 #define DEV_TX_OFFLOAD_SECURITY         0x00020000
 
+enum rte_eth_tx_offload_type {
+	ETH_TX_OFFLOAD_FIRST_FEATURE = 0,
+	ETH_TX_OFFLOAD_VLAN_INSERT = ETH_TX_OFFLOAD_FIRST_FEATURE,
+	ETH_TX_OFFLOAD_IPV4_CKSUM,
+	ETH_TX_OFFLOAD_UDP_CKSUM,
+	ETH_TX_OFFLOAD_TCP_CKSUM,
+	ETH_TX_OFFLOAD_SCTP_CKSUM,
+	ETH_TX_OFFLOAD_TCP_TSO,
+	ETH_TX_OFFLOAD_UDP_TSO,
+	ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM,
+	ETH_TX_OFFLOAD_QINQ_INSERT,
+	ETH_TX_OFFLOAD_VXLAN_TNL_TSO,
+	ETH_TX_OFFLOAD_GRE_TNL_TSO,
+	ETH_TX_OFFLOAD_IPIP_TNL_TSO,
+	ETH_TX_OFFLOAD_GENEVE_TNL_TSO,
+	ETH_TX_OFFLOAD_MACSEC_INSERT,
+	ETH_TX_OFFLOAD_MT_LOCKFREE,
+	ETH_TX_OFFLOAD_MULTI_SEGS,
+	ETH_TX_OFFLOAD_MBUF_FAST_FREE,
+	ETH_TX_OFFLOAD_SECURITY,
+	ETH_TX_OFFLOAD_TOTAL_NUM
+};
+
 /*
  * If new Tx offload capabilities are defined, they also must be
  * mentioned in rte_tx_offload_names in rte_ethdev.c file.
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v4 2/3] app/testpmd: add commands to test new Rx offload API
  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 12:40       ` 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
  3 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-19 12:40 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Rx offload API:
rx_offload get capability <port_id>
rx_offload get configuration <port_id>
rx_offload enable|disable per_port <offload> <port_id>
rx_offload enable|disable per_queue <offload> <port_id> <queue_id>

Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_strip", "ipv4_cksum", ...

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 app/test-pmd/cmdline.c | 374 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  19 ++-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 392 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 40b31ad..ae735d0 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -15996,6 +15996,376 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
 	},
 };
 
+/* Get Rx offloads capability */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "rx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_get,
+		(void *)&cmd_rx_offload_get_capa_capability,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "rx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_get,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static uint64_t
+search_rx_offload(const char *name)
+{
+	uint64_t single_offload;
+	const char *single_name;
+	int found = 0;
+	enum rte_eth_rx_offload_type type;
+
+	single_offload = 1;
+	for (type = ETH_RX_OFFLOAD_FIRST_FEATURE;
+	     type < ETH_RX_OFFLOAD_TOTAL_NUM; type++) {
+		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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_rx_queues = dev_info.nb_rx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.rxmode.offloads |= single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.rxmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] &= ~single_offload;
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
+	.f = cmd_config_per_port_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_port 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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_rx_offload_result_per_port,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	single_offload = search_rx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->rx_offloads[queue_id] |= single_offload;
+	else
+		port->rx_offloads[queue_id] &= ~single_offload;
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
+	.f = cmd_config_per_queue_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_queue 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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_rx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16272,6 +16642,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+	(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,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e258..e5de40a 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -656,6 +656,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);
 
@@ -707,6 +708,17 @@ init_config(void)
 			}
 		}
 
+		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
+						sizeof(port->rx_offloads[0]) *
+						port->dev_info.max_rx_queues,
+						sizeof(port->rx_offloads[0]));
+		if (port->rx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->rx_offload[0]) "
+				 "failed\n", port->dev_info.max_rx_queues);
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1615,10 +1627,9 @@ start_port(portid_t pid)
 				port->need_reconfig_queues = 1;
 				return -1;
 			}
-			/* Apply Rx offloads configuration */
-			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
 			/* setup rx queues */
 			for (qi = 0; qi < nb_rxq; qi++) {
+				port->rx_conf.offloads = port->rx_offloads[qi];
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
 					struct rte_mempool * mp =
@@ -1915,6 +1926,7 @@ detach_port(portid_t port_id)
 void
 pmd_test_exit(void)
 {
+	struct rte_port *port;
 	portid_t pt_id;
 
 	if (test_done == 0)
@@ -1927,6 +1939,9 @@ pmd_test_exit(void)
 			fflush(stdout);
 			stop_port(pt_id);
 			close_port(pt_id);
+			port = &ports[pt_id];
+			rte_free(port->rx_offloads);
+			port->rx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea..dcad260 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -183,6 +183,7 @@ struct rte_port {
 	uint8_t                 dcb_flag;   /**< enable dcb */
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
+	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v4 3/3] app/testpmd: add commands to test new Tx offload API
  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 12:40       ` [PATCH v4 2/3] app/testpmd: add commands to test new Rx offload API Wei Dai
@ 2018-03-19 12:40       ` Wei Dai
  2018-03-20  3:09       ` [PATCH v5 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Wei Dai
  3 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-19 12:40 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Tx offload API:
tx_offload get capability <port_id>
tx_offload get configuration <port_id>
tx_offload enable|disable per_port <offload> <port_id>
tx_offload enable|disable per_queue <offload> <port_id> <queue_id>

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>
---
 app/test-pmd/cmdline.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  15 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 393 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ae735d0..e977910 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16366,6 +16366,381 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
 	}
 };
 
+/* Get Tx offloads capability */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "tx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_get,
+		(void *)&cmd_tx_offload_get_capa_capability,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "tx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_get,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+static uint64_t
+search_tx_offload(const char *name)
+{
+	uint64_t single_offload;
+	const char *single_name;
+	int found = 0;
+	enum rte_eth_tx_offload_type type;
+
+	single_offload = 1;
+	for (type = ETH_TX_OFFLOAD_FIRST_FEATURE;
+	     type < ETH_TX_OFFLOAD_TOTAL_NUM; type++) {
+		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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_tx_queues = dev_info.nb_tx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.txmode.offloads |= single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.txmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] &= ~single_offload;
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_tx_offload = {
+	.f = cmd_config_per_port_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_port "
+		    "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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_tx_offload_result_per_port,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	single_offload = search_tx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->tx_offloads[queue_id] |= single_offload;
+	else
+		port->tx_offloads[queue_id] &= ~single_offload;
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_tx_offload = {
+	.f = cmd_config_per_queue_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_queue "
+		    "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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_tx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16646,6 +17021,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(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 e5de40a..d7d5d4c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -718,6 +718,16 @@ init_config(void)
 				 "failed\n", port->dev_info.max_rx_queues);
 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
 			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+		port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads",
+						sizeof(port->tx_offloads[0]) *
+						port->dev_info.max_tx_queues,
+						sizeof(port->tx_offloads[0]));
+		if (port->tx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->tx_offload[0]) "
+				 "failed\n", port->dev_info.max_tx_queues);
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_offloads[k] = port->dev_conf.txmode.offloads;
 
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
@@ -1599,10 +1609,9 @@ start_port(portid_t pid)
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
-			/* Apply Tx offloads configuration */
-			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+				port->tx_conf.offloads = port->tx_offloads[qi];
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1942,6 +1951,8 @@ pmd_test_exit(void)
 			port = &ports[pt_id];
 			rte_free(port->rx_offloads);
 			port->rx_offloads = NULL;
+			rte_free(port->tx_offloads);
+			port->tx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index dcad260..b0bd14e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -184,6 +184,7 @@ struct rte_port {
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
+	uint64_t		*tx_offloads; /**< offloads of each Tx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx offloads
  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
  0 siblings, 1 reply; 44+ messages in thread
From: Zhang, Qi Z @ 2018-03-19 14:05 UTC (permalink / raw)
  To: Dai, Wei, Lu, Wenzhuo, Wu, Jingjing; +Cc: dev, Dai, Wei

Hi Daiwei:

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wei Dai
> Sent: Monday, March 19, 2018 8:41 PM
> To: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>
> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> Subject: [dpdk-dev] [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx
> offloads
> 
> This patch adds enum rte_eth_rx_offload_type and enum
> rte_eth_tx_offload_type. For a loop on all Rx offloads, it is convenient to
> begin with the first enum member ETH_RX_OFFLOAD_FIRST_FEATURE and to
> end at ETH_RX_OFFLOAD_TOTAL_NUM.
> A loop on all Tx offloads can begin with ETH_TX_OFFLOAD_FIRST_FEATURE
> and end at ETH_TX_OFFLOAD_TOTAL_NUM.
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.h | 44
> +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 0361533..0089ea3 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -946,6 +946,27 @@ struct rte_eth_conf {
>  			     DEV_RX_OFFLOAD_VLAN_FILTER | \
>  			     DEV_RX_OFFLOAD_VLAN_EXTEND)
> 
> +enum rte_eth_rx_offload_type {
> +	ETH_RX_OFFLOAD_FIRST_FEATURE = 0,
> +	ETH_RX_OFFLOAD_VLAN_STRIP = ETH_RX_OFFLOAD_FIRST_FEATURE,
> +	ETH_RX_OFFLOAD_IPV4_CKSUM,
> +	ETH_RX_OFFLOAD_UDP_CKSUM,
> +	ETH_RX_OFFLOAD_TCP_CKSUM,
> +	ETH_RX_OFFLOAD_TCP_LRO,
> +	ETH_RX_OFFLOAD_QINQ_STRIP,
> +	ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM,
> +	ETH_RX_OFFLOAD_MACSEC_STRIP,
> +	ETH_RX_OFFLOAD_HEADER_SPLIT,
> +	ETH_RX_OFFLOAD_VLAN_FILTER,
> +	ETH_RX_OFFLOAD_VLAN_EXTEND,
> +	ETH_RX_OFFLOAD_JUMBO_FRAME,
> +	ETH_RX_OFFLOAD_CRC_STRIP,
> +	ETH_RX_OFFLOAD_SCATTER,
> +	ETH_RX_OFFLOAD_TIMESTAMP,
> +	ETH_RX_OFFLOAD_SECURITY,
> +	ETH_RX_OFFLOAD_TOTAL_NUM
> +};

This looks a little duplicate with rte_rx_offload_names in rte_ethdev.c

In patch 2/3 and 3/3, I think if you simply loop from offload bit 0 to bit 63 to check the name, that should still work right?
then this patch could be unnecessary.
	
Regards
Qi
> +
>  /*
>   * If new Rx offload capabilities are defined, they also must be
>   * mentioned in rte_rx_offload_names in rte_ethdev.c file.
> @@ -981,6 +1002,29 @@ struct rte_eth_conf {
>   */
>  #define DEV_TX_OFFLOAD_SECURITY         0x00020000
> 
> +enum rte_eth_tx_offload_type {
> +	ETH_TX_OFFLOAD_FIRST_FEATURE = 0,
> +	ETH_TX_OFFLOAD_VLAN_INSERT = ETH_TX_OFFLOAD_FIRST_FEATURE,
> +	ETH_TX_OFFLOAD_IPV4_CKSUM,
> +	ETH_TX_OFFLOAD_UDP_CKSUM,
> +	ETH_TX_OFFLOAD_TCP_CKSUM,
> +	ETH_TX_OFFLOAD_SCTP_CKSUM,
> +	ETH_TX_OFFLOAD_TCP_TSO,
> +	ETH_TX_OFFLOAD_UDP_TSO,
> +	ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM,
> +	ETH_TX_OFFLOAD_QINQ_INSERT,
> +	ETH_TX_OFFLOAD_VXLAN_TNL_TSO,
> +	ETH_TX_OFFLOAD_GRE_TNL_TSO,
> +	ETH_TX_OFFLOAD_IPIP_TNL_TSO,
> +	ETH_TX_OFFLOAD_GENEVE_TNL_TSO,
> +	ETH_TX_OFFLOAD_MACSEC_INSERT,
> +	ETH_TX_OFFLOAD_MT_LOCKFREE,
> +	ETH_TX_OFFLOAD_MULTI_SEGS,
> +	ETH_TX_OFFLOAD_MBUF_FAST_FREE,
> +	ETH_TX_OFFLOAD_SECURITY,
> +	ETH_TX_OFFLOAD_TOTAL_NUM
> +};
> +
>  /*
>   * If new Tx offload capabilities are defined, they also must be
>   * mentioned in rte_tx_offload_names in rte_ethdev.c file.
> --
> 2.7.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v4 1/3] ethdev: add enum type for loop on Rx/Tx offloads
  2018-03-19 14:05         ` Zhang, Qi Z
@ 2018-03-20  1:52           ` Dai, Wei
  0 siblings, 0 replies; 44+ messages in thread
From: Dai, Wei @ 2018-03-20  1:52 UTC (permalink / raw)
  To: Zhang, Qi Z, Lu, Wenzhuo, Wu, Jingjing; +Cc: dev

Hi Zhang Qi
Thanks for your feedback.

> -----Original Message-----
> From: Zhang, Qi Z
> Sent: Monday, March 19, 2018 10:06 PM
> To: Dai, Wei <wei.dai@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> Wu, Jingjing <jingjing.wu@intel.com>
> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v4 1/3] ethdev: add enum type for loop on
> Rx/Tx offloads
> 
> Hi Daiwei:
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wei Dai
> > Sent: Monday, March 19, 2018 8:41 PM
> > To: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>
> > Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> > Subject: [dpdk-dev] [PATCH v4 1/3] ethdev: add enum type for loop on
> > Rx/Tx offloads
> >
> > This patch adds enum rte_eth_rx_offload_type and enum
> > rte_eth_tx_offload_type. For a loop on all Rx offloads, it is
> > convenient to begin with the first enum member
> > ETH_RX_OFFLOAD_FIRST_FEATURE and to end at
> ETH_RX_OFFLOAD_TOTAL_NUM.
> > A loop on all Tx offloads can begin with
> ETH_TX_OFFLOAD_FIRST_FEATURE
> > and end at ETH_TX_OFFLOAD_TOTAL_NUM.
> >
> > Signed-off-by: Wei Dai <wei.dai@intel.com>
> > ---
> >  lib/librte_ether/rte_ethdev.h | 44
> > +++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 44 insertions(+)
> >
> > diff --git a/lib/librte_ether/rte_ethdev.h
> > b/lib/librte_ether/rte_ethdev.h index 0361533..0089ea3 100644
> > --- a/lib/librte_ether/rte_ethdev.h
> > +++ b/lib/librte_ether/rte_ethdev.h
> > @@ -946,6 +946,27 @@ struct rte_eth_conf {
> >  			     DEV_RX_OFFLOAD_VLAN_FILTER | \
> >  			     DEV_RX_OFFLOAD_VLAN_EXTEND)
> >
> > +enum rte_eth_rx_offload_type {
> > +	ETH_RX_OFFLOAD_FIRST_FEATURE = 0,
> > +	ETH_RX_OFFLOAD_VLAN_STRIP = ETH_RX_OFFLOAD_FIRST_FEATURE,
> > +	ETH_RX_OFFLOAD_IPV4_CKSUM,
> > +	ETH_RX_OFFLOAD_UDP_CKSUM,
> > +	ETH_RX_OFFLOAD_TCP_CKSUM,
> > +	ETH_RX_OFFLOAD_TCP_LRO,
> > +	ETH_RX_OFFLOAD_QINQ_STRIP,
> > +	ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM,
> > +	ETH_RX_OFFLOAD_MACSEC_STRIP,
> > +	ETH_RX_OFFLOAD_HEADER_SPLIT,
> > +	ETH_RX_OFFLOAD_VLAN_FILTER,
> > +	ETH_RX_OFFLOAD_VLAN_EXTEND,
> > +	ETH_RX_OFFLOAD_JUMBO_FRAME,
> > +	ETH_RX_OFFLOAD_CRC_STRIP,
> > +	ETH_RX_OFFLOAD_SCATTER,
> > +	ETH_RX_OFFLOAD_TIMESTAMP,
> > +	ETH_RX_OFFLOAD_SECURITY,
> > +	ETH_RX_OFFLOAD_TOTAL_NUM
> > +};
> 
> This looks a little duplicate with rte_rx_offload_names in rte_ethdev.c
rte_rx_offload_names is a static string array defined in rte_ethdev.c, if it can be referred by other files,
the "static" must be removed.

> 
> In patch 2/3 and 3/3, I think if you simply loop from offload bit 0 to bit 63 to
> check the name, that should still work right?
> then this patch could be unnecessary.
Yes, using loop from bit 0 to bit 63 in patch 2/3 and 3/3 can work right.
But I think this enum type is still useful for other application which need to loop on
all possible offloads. 
I will submit this patch as a standalone one and using loop from bit 0 to bit 63 in next version of patch set.

> Regards
> Qi
> > +
> >  /*
> >   * If new Rx offload capabilities are defined, they also must be
> >   * mentioned in rte_rx_offload_names in rte_ethdev.c file.
> > @@ -981,6 +1002,29 @@ struct rte_eth_conf {
> >   */
> >  #define DEV_TX_OFFLOAD_SECURITY         0x00020000
> >
> > +enum rte_eth_tx_offload_type {
> > +	ETH_TX_OFFLOAD_FIRST_FEATURE = 0,
> > +	ETH_TX_OFFLOAD_VLAN_INSERT = ETH_TX_OFFLOAD_FIRST_FEATURE,
> > +	ETH_TX_OFFLOAD_IPV4_CKSUM,
> > +	ETH_TX_OFFLOAD_UDP_CKSUM,
> > +	ETH_TX_OFFLOAD_TCP_CKSUM,
> > +	ETH_TX_OFFLOAD_SCTP_CKSUM,
> > +	ETH_TX_OFFLOAD_TCP_TSO,
> > +	ETH_TX_OFFLOAD_UDP_TSO,
> > +	ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM,
> > +	ETH_TX_OFFLOAD_QINQ_INSERT,
> > +	ETH_TX_OFFLOAD_VXLAN_TNL_TSO,
> > +	ETH_TX_OFFLOAD_GRE_TNL_TSO,
> > +	ETH_TX_OFFLOAD_IPIP_TNL_TSO,
> > +	ETH_TX_OFFLOAD_GENEVE_TNL_TSO,
> > +	ETH_TX_OFFLOAD_MACSEC_INSERT,
> > +	ETH_TX_OFFLOAD_MT_LOCKFREE,
> > +	ETH_TX_OFFLOAD_MULTI_SEGS,
> > +	ETH_TX_OFFLOAD_MBUF_FAST_FREE,
> > +	ETH_TX_OFFLOAD_SECURITY,
> > +	ETH_TX_OFFLOAD_TOTAL_NUM
> > +};
> > +
> >  /*
> >   * If new Tx offload capabilities are defined, they also must be
> >   * mentioned in rte_tx_offload_names in rte_ethdev.c file.
> > --
> > 2.7.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v5 0/2] app/testpmd: add new commands to test new Tx/Rx offloads
  2018-03-19 12:40     ` [PATCH v4 0/3] app/testpmd: add new commands to test new Tx/Rx offload Wei Dai
                         ` (2 preceding siblings ...)
  2018-03-19 12:40       ` [PATCH v4 3/3] app/testpmd: add commands to test new Tx " Wei Dai
@ 2018-03-20  3:09       ` Wei Dai
  2018-03-20  3:09         ` [PATCH v5 1/2] app/testpmd: add commands to test new Rx offload API Wei Dai
                           ` (2 more replies)
  3 siblings, 3 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-20  3:09 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Existed testpmd commands can't support per queue offload configuration.
And there are different commands to enable or disable different offloading.
This patch set add following commands to support new Tx/Rx offloading API test.

To get Rx offload capability of a port, please run:
testpmd > rx_offload get capability <port_id>

To get current Rx offload per queue and per port configuration of a port, run:
tesstpmd > rx_offload get configuration <port_id>

To enable or disable a Rx per port offloading, please run:
testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>
This command will set|clear the associated bit in dev->dev_conf.rxmode.offloads
for rte_eth_dev_configure and tx_conf->offloads of all Rx queues for 
rte_eth_rx_queue_setup( ).

To enable or disable a Tx per port offloading, please run:
testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>

Same commands like "tx_offload ..." are also added to support new Tx offload API test.

---
v5:
   don't depend on enum types defined in rte_ethdev.
v4:
   improve testpmd command per port offload to set or clear the port configuration
   and the queue configuration of all queues.
v3:
   add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
   free memory of port->rx_offloads and port->tx_offloads when testpmd is existed
v2: 
   use rte_eth_dev_rx_offload_name() and rte_eth_dev_tx_offload_name().
   remove static const strings of Rx/Tx offload names.


Wei Dai (2):
  app/testpmd: add commands to test new Rx offload API
  app/testpmd: add commands to test new Tx offload API

 app/test-pmd/cmdline.c | 751 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  34 ++-
 app/test-pmd/testpmd.h |   2 +
 3 files changed, 783 insertions(+), 4 deletions(-)

-- 
2.7.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v5 1/2] app/testpmd: add commands to test new Rx offload API
  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         ` 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
  2 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-20  3:09 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Rx offload API:
rx_offload get capability <port_id>
rx_offload get configuration <port_id>
rx_offload enable|disable per_port <offload> <port_id>
rx_offload enable|disable per_queue <offload> <port_id> <queue_id>

Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_strip", "ipv4_cksum", ...

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 app/test-pmd/cmdline.c | 373 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  19 ++-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 391 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 40b31ad..017416b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -15996,6 +15996,375 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
 	},
 };
 
+/* Get Rx offloads capability */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "rx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_get,
+		(void *)&cmd_rx_offload_get_capa_capability,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "rx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_get,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_rx_queues = dev_info.nb_rx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.rxmode.offloads |= single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.rxmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] &= ~single_offload;
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
+	.f = cmd_config_per_port_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_port 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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_rx_offload_result_per_port,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	single_offload = search_rx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->rx_offloads[queue_id] |= single_offload;
+	else
+		port->rx_offloads[queue_id] &= ~single_offload;
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
+	.f = cmd_config_per_queue_rx_offload_parsed,
+	.data = NULL,
+	.help_str = "rx_offload enable|disable per_queue 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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_rx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16272,6 +16641,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+	(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,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e258..e5de40a 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -656,6 +656,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);
 
@@ -707,6 +708,17 @@ init_config(void)
 			}
 		}
 
+		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
+						sizeof(port->rx_offloads[0]) *
+						port->dev_info.max_rx_queues,
+						sizeof(port->rx_offloads[0]));
+		if (port->rx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->rx_offload[0]) "
+				 "failed\n", port->dev_info.max_rx_queues);
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1615,10 +1627,9 @@ start_port(portid_t pid)
 				port->need_reconfig_queues = 1;
 				return -1;
 			}
-			/* Apply Rx offloads configuration */
-			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
 			/* setup rx queues */
 			for (qi = 0; qi < nb_rxq; qi++) {
+				port->rx_conf.offloads = port->rx_offloads[qi];
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
 					struct rte_mempool * mp =
@@ -1915,6 +1926,7 @@ detach_port(portid_t port_id)
 void
 pmd_test_exit(void)
 {
+	struct rte_port *port;
 	portid_t pt_id;
 
 	if (test_done == 0)
@@ -1927,6 +1939,9 @@ pmd_test_exit(void)
 			fflush(stdout);
 			stop_port(pt_id);
 			close_port(pt_id);
+			port = &ports[pt_id];
+			rte_free(port->rx_offloads);
+			port->rx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea..dcad260 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -183,6 +183,7 @@ struct rte_port {
 	uint8_t                 dcb_flag;   /**< enable dcb */
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
+	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v5 2/2] app/testpmd: add commands to test new Tx offload API
  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         ` Wei Dai
  2018-03-22  8:00         ` [PATCH v6 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Wei Dai
  2 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-20  3:09 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Tx offload API:
tx_offload get capability <port_id>
tx_offload get configuration <port_id>
tx_offload enable|disable per_port <offload> <port_id>
tx_offload enable|disable per_queue <offload> <port_id> <queue_id>

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>
---
 app/test-pmd/cmdline.c | 378 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  15 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 392 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 017416b..20b4397 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16365,6 +16365,380 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
 	}
 };
 
+/* Get Tx offloads capability */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "tx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_get,
+		(void *)&cmd_tx_offload_get_capa_capability,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "tx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_get,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_tx_queues = dev_info.nb_tx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.txmode.offloads |= single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.txmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] &= ~single_offload;
+	}
+}
+
+cmdline_parse_inst_t cmd_config_per_port_tx_offload = {
+	.f = cmd_config_per_port_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_port "
+		    "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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_tx_offload_result_per_port,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	single_offload = search_tx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->tx_offloads[queue_id] |= single_offload;
+	else
+		port->tx_offloads[queue_id] &= ~single_offload;
+}
+
+cmdline_parse_inst_t cmd_config_per_queue_tx_offload = {
+	.f = cmd_config_per_queue_tx_offload_parsed,
+	.data = NULL,
+	.help_str = "tx_offload enable|disable per_queue "
+		    "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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_tx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16645,6 +17019,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(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 e5de40a..d7d5d4c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -718,6 +718,16 @@ init_config(void)
 				 "failed\n", port->dev_info.max_rx_queues);
 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
 			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+		port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads",
+						sizeof(port->tx_offloads[0]) *
+						port->dev_info.max_tx_queues,
+						sizeof(port->tx_offloads[0]));
+		if (port->tx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->tx_offload[0]) "
+				 "failed\n", port->dev_info.max_tx_queues);
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_offloads[k] = port->dev_conf.txmode.offloads;
 
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
@@ -1599,10 +1609,9 @@ start_port(portid_t pid)
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
-			/* Apply Tx offloads configuration */
-			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+				port->tx_conf.offloads = port->tx_offloads[qi];
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1942,6 +1951,8 @@ pmd_test_exit(void)
 			port = &ports[pt_id];
 			rte_free(port->rx_offloads);
 			port->rx_offloads = NULL;
+			rte_free(port->tx_offloads);
+			port->tx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index dcad260..b0bd14e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -184,6 +184,7 @@ struct rte_port {
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
+	uint64_t		*tx_offloads; /**< offloads of each Tx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v6 0/2] app/testpmd: add new commands to test new Tx/Rx offloads
  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         ` Wei Dai
  2018-03-22  8:00           ` [PATCH v6 1/2] app/testpmd: add commands to test new Rx offload API Wei Dai
                             ` (2 more replies)
  2 siblings, 3 replies; 44+ messages in thread
From: Wei Dai @ 2018-03-22  8:00 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Existed testpmd commands can't support per queue offload configuration.
And there are different commands to enable or disable different offloading.
This patch set add following commands to support new Tx/Rx offloading API test.

To get Rx offload capability of a port, please run:
testpmd > rx_offload get capability <port_id>

To get current Rx offload per queue and per port configuration of a port, run:
tesstpmd > rx_offload get configuration <port_id>

To enable or disable a Rx per port offloading, please run:
testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>
This command will set|clear the associated bit in dev->dev_conf.rxmode.offloads
for rte_eth_dev_configure and tx_conf->offloads of all Rx queues for 
rte_eth_rx_queue_setup( ).

To enable or disable a Tx per port offloading, please run:
testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>

Same commands like "tx_offload ..." are also added to support new Tx offload API test.

---
v6:
   reconfig port and queues if offloading is enabled or disabled
v5:
   don't depend on enum types defined in rte_ethdev.
v4:
   improve testpmd command per port offload to set or clear the port configuration
   and the queue configuration of all queues.
v3:
   add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
   free memory of port->rx_offloads and port->tx_offloads when testpmd is existed
v2: 
   use rte_eth_dev_rx_offload_name() and rte_eth_dev_tx_offload_name().
   remove static const strings of Rx/Tx offload names.


Wei Dai (2):
  app/testpmd: add commands to test new Rx offload API
  app/testpmd: add commands to test new Tx offload API

 app/test-pmd/cmdline.c | 759 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  34 ++-
 app/test-pmd/testpmd.h |   2 +
 3 files changed, 791 insertions(+), 4 deletions(-)

-- 
2.9.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v6 1/2] app/testpmd: add commands to test new Rx offload API
  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           ` 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-04-03  8:57           ` [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Wei Dai
  2 siblings, 1 reply; 44+ messages in thread
From: Wei Dai @ 2018-03-22  8:00 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Rx offload API:
rx_offload get capability <port_id>
rx_offload get configuration <port_id>
rx_offload enable|disable per_port <offload> <port_id>
rx_offload enable|disable per_queue <offload> <port_id> <queue_id>

Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_strip", "ipv4_cksum", ...

Signed-off-by: Wei Dai <wei.dai@intel.com>
---
 app/test-pmd/cmdline.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  19 ++-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 395 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 40b31ad..a6cecba 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -15996,6 +15996,379 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
 	},
 };
 
+/* Get Rx offloads capability */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "rx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_get,
+		(void *)&cmd_rx_offload_get_capa_capability,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "rx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_get,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_rx_queues = dev_info.nb_rx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.rxmode.offloads |= single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.rxmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] &= ~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 = "rx_offload enable|disable per_port 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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_rx_offload_result_per_port,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	single_offload = search_rx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->rx_offloads[queue_id] |= single_offload;
+	else
+		port->rx_offloads[queue_id] &= ~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 = "rx_offload enable|disable per_queue 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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_rx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16272,6 +16645,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+	(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,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e258..e5de40a 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -656,6 +656,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);
 
@@ -707,6 +708,17 @@ init_config(void)
 			}
 		}
 
+		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
+						sizeof(port->rx_offloads[0]) *
+						port->dev_info.max_rx_queues,
+						sizeof(port->rx_offloads[0]));
+		if (port->rx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->rx_offload[0]) "
+				 "failed\n", port->dev_info.max_rx_queues);
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1615,10 +1627,9 @@ start_port(portid_t pid)
 				port->need_reconfig_queues = 1;
 				return -1;
 			}
-			/* Apply Rx offloads configuration */
-			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
 			/* setup rx queues */
 			for (qi = 0; qi < nb_rxq; qi++) {
+				port->rx_conf.offloads = port->rx_offloads[qi];
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
 					struct rte_mempool * mp =
@@ -1915,6 +1926,7 @@ detach_port(portid_t port_id)
 void
 pmd_test_exit(void)
 {
+	struct rte_port *port;
 	portid_t pt_id;
 
 	if (test_done == 0)
@@ -1927,6 +1939,9 @@ pmd_test_exit(void)
 			fflush(stdout);
 			stop_port(pt_id);
 			close_port(pt_id);
+			port = &ports[pt_id];
+			rte_free(port->rx_offloads);
+			port->rx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea..dcad260 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -183,6 +183,7 @@ struct rte_port {
 	uint8_t                 dcb_flag;   /**< enable dcb */
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
+	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v6 2/2] app/testpmd: add commands to test new Tx offload API
  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-22  8:00           ` 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
  2 siblings, 1 reply; 44+ messages in thread
From: Wei Dai @ 2018-03-22  8:00 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Tx offload API:
tx_offload get capability <port_id>
tx_offload get configuration <port_id>
tx_offload enable|disable per_port <offload> <port_id>
tx_offload enable|disable per_queue <offload> <port_id> <queue_id>

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>
---
 app/test-pmd/cmdline.c | 382 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |  15 +-
 app/test-pmd/testpmd.h |   1 +
 3 files changed, 396 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index a6cecba..c28edb6 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16369,6 +16369,384 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
 	}
 };
 
+/* Get Tx offloads capability */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "tx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_get,
+		(void *)&cmd_tx_offload_get_capa_capability,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "tx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_get,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_tx_queues = dev_info.nb_tx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.txmode.offloads |= single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.txmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] &= ~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 = "tx_offload enable|disable per_port "
+		    "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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_tx_offload_result_per_port,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	single_offload = search_tx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->tx_offloads[queue_id] |= single_offload;
+	else
+		port->tx_offloads[queue_id] &= ~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 = "tx_offload enable|disable per_queue "
+		    "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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_tx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16649,6 +17027,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(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 e5de40a..d7d5d4c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -718,6 +718,16 @@ init_config(void)
 				 "failed\n", port->dev_info.max_rx_queues);
 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
 			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+		port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads",
+						sizeof(port->tx_offloads[0]) *
+						port->dev_info.max_tx_queues,
+						sizeof(port->tx_offloads[0]));
+		if (port->tx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->tx_offload[0]) "
+				 "failed\n", port->dev_info.max_tx_queues);
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_offloads[k] = port->dev_conf.txmode.offloads;
 
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
@@ -1599,10 +1609,9 @@ start_port(portid_t pid)
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
-			/* Apply Tx offloads configuration */
-			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+				port->tx_conf.offloads = port->tx_offloads[qi];
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1942,6 +1951,8 @@ pmd_test_exit(void)
 			port = &ports[pt_id];
 			rte_free(port->rx_offloads);
 			port->rx_offloads = NULL;
+			rte_free(port->tx_offloads);
+			port->tx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index dcad260..b0bd14e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -184,6 +184,7 @@ struct rte_port {
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
+	uint64_t		*tx_offloads; /**< offloads of each Tx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v6 1/2] app/testpmd: add commands to test new Rx offload API
  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
  0 siblings, 0 replies; 44+ messages in thread
From: Wu, Jingjing @ 2018-03-30  8:40 UTC (permalink / raw)
  To: Dai, Wei, Lu, Wenzhuo; +Cc: dev



> -----Original Message-----
> From: Dai, Wei
> Sent: Thursday, March 22, 2018 1:00 AM
> To: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> Subject: [PATCH v6 1/2] app/testpmd: add commands to test new Rx offload API
> 
> Add following testpmd run-time commands to support test of
> new Rx offload API:
> rx_offload get capability <port_id>
> rx_offload get configuration <port_id>
> rx_offload enable|disable per_port <offload> <port_id>
> rx_offload enable|disable per_queue <offload> <port_id> <queue_id>
> 
> Above last 2 commands should be run when the port is stopped.
> And <offload> can be one of "vlan_strip", "ipv4_cksum", ...
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>

Please update doc for new commands.

Acked-by: Jingjing Wu <jingjing.wu@intel.com>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v6 2/2] app/testpmd: add commands to test new Tx offload API
  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
  0 siblings, 0 replies; 44+ messages in thread
From: Wu, Jingjing @ 2018-03-30 23:05 UTC (permalink / raw)
  To: Dai, Wei, Lu, Wenzhuo; +Cc: dev



> -----Original Message-----
> From: Dai, Wei
> Sent: Thursday, March 22, 2018 1:00 AM
> To: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> Subject: [PATCH v6 2/2] app/testpmd: add commands to test new Tx offload API
> 
> Add following testpmd run-time commands to support test of
> new Tx offload API:
> tx_offload get capability <port_id>
> tx_offload get configuration <port_id>
> tx_offload enable|disable per_port <offload> <port_id>
> tx_offload enable|disable per_queue <offload> <port_id> <queue_id>
> 
> 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>

Please don't forget to update doc for new commands.

Acked-by: Jingjing Wu <jingjing.wu@intel.com>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads
  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-22  8:00           ` [PATCH v6 2/2] app/testpmd: add commands to test new Tx " Wei Dai
@ 2018-04-03  8:57           ` Wei Dai
  2018-04-03  8:57             ` [PATCH v7 1/2] app/testpmd: add commands to test new Rx offload API Wei Dai
                               ` (4 more replies)
  2 siblings, 5 replies; 44+ messages in thread
From: Wei Dai @ 2018-04-03  8:57 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Existed testpmd commands can't support per queue offload configuration.
And there are different commands to enable or disable different offloading.
This patch set add following commands to support new Tx/Rx offloading API test.

To get Rx offload capability of a port, please run:
testpmd > rx_offload get capability <port_id>

To get current Rx offload per queue and per port configuration of a port, run:
tesstpmd > rx_offload get configuration <port_id>

To enable or disable a Rx per port offloading, please run:
testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>
This command will set|clear the associated bit in dev->dev_conf.rxmode.offloads
for rte_eth_dev_configure and tx_conf->offloads of all Rx queues for
rte_eth_rx_queue_setup( ).

To enable or disable a Tx per port offloading, please run:
testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>

Same commands like "tx_offload ..." are also added to support new Tx offload API test.

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

---
v7:
   update testpmd document
v6:
   reconfig port and queues if offloading is enabled or disabled
v5:
   don't depend on enum types defined in rte_ethdev.
v4:
   improve testpmd command per port offload to set or clear the port configuration
   and the queue configuration of all queues.
v3:
   add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
   free memory of port->rx_offloads and port->tx_offloads when testpmd is existed
v2:
   use rte_eth_dev_rx_offload_name() and rte_eth_dev_tx_offload_name().
   remove static const strings of Rx/Tx offload names.


Wei Dai (2):
  app/testpmd: add commands to test new Rx offload API
  app/testpmd: add commands to test new Tx offload API

 app/test-pmd/cmdline.c                      | 759 ++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c                      |  34 +-
 app/test-pmd/testpmd.h                      |   2 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  87 ++++
 4 files changed, 878 insertions(+), 4 deletions(-)

-- 
2.9.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v7 1/2] app/testpmd: add commands to test new Rx offload API
  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             ` Wei Dai
  2018-04-03  8:57             ` [PATCH v7 2/2] app/testpmd: add commands to test new Tx " Wei Dai
                               ` (3 subsequent siblings)
  4 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-04-03  8:57 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Rx offload API:
rx_offload get capability <port_id>
rx_offload get configuration <port_id>
rx_offload enable|disable per_port <offload> <port_id>
rx_offload enable|disable per_queue <offload> <port_id> <queue_id>

Above last 2 commands should be run when the port is stopped.
And <offload> can be one of "vlan_strip", "ipv4_cksum", ...

Signed-off-by: Wei Dai <wei.dai@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 377 ++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c                      |  19 +-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  43 ++++
 4 files changed, 438 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 40b31ad..a6cecba 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -15996,6 +15996,379 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = {
 	},
 };
 
+/* Get Rx offloads capability */
+struct cmd_rx_offload_get_capa_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "rx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_capa_rx_offload,
+		(void *)&cmd_rx_offload_get_capa_get,
+		(void *)&cmd_rx_offload_get_capa_capability,
+		(void *)&cmd_rx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Rx offloads configuration */
+struct cmd_rx_offload_get_configuration_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_rx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "rx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_rx_offload_get_configuration_rx_offload,
+		(void *)&cmd_rx_offload_get_configuration_get,
+		(void *)&cmd_rx_offload_get_configuration_configuration,
+		(void *)&cmd_rx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_rx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_rx_queues = dev_info.nb_rx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.rxmode.offloads |= single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.rxmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_rx_queues; q++)
+			port->rx_offloads[q] &= ~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 = "rx_offload enable|disable per_port 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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_rx_offload_result_per_port,
+		(void *)&cmd_config_per_port_rx_offload_result_offload,
+		(void *)&cmd_config_per_port_rx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_rx_offload_result {
+	cmdline_fixed_string_t rx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_rx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_rx_queues - 1);
+		return;
+	}
+
+	single_offload = search_rx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->rx_offloads[queue_id] |= single_offload;
+	else
+		port->rx_offloads[queue_id] &= ~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 = "rx_offload enable|disable per_queue 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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_rx_offload_result_rx_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_rx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_rx_offload_result_offload,
+		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16272,6 +16645,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+	(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,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e258..e5de40a 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -656,6 +656,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);
 
@@ -707,6 +708,17 @@ init_config(void)
 			}
 		}
 
+		port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads",
+						sizeof(port->rx_offloads[0]) *
+						port->dev_info.max_rx_queues,
+						sizeof(port->rx_offloads[0]));
+		if (port->rx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->rx_offload[0]) "
+				 "failed\n", port->dev_info.max_rx_queues);
+		for (k = 0; k < port->dev_info.max_rx_queues; k++)
+			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
 		port->need_reconfig_queues = 1;
@@ -1615,10 +1627,9 @@ start_port(portid_t pid)
 				port->need_reconfig_queues = 1;
 				return -1;
 			}
-			/* Apply Rx offloads configuration */
-			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
 			/* setup rx queues */
 			for (qi = 0; qi < nb_rxq; qi++) {
+				port->rx_conf.offloads = port->rx_offloads[qi];
 				if ((numa_support) &&
 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
 					struct rte_mempool * mp =
@@ -1915,6 +1926,7 @@ detach_port(portid_t port_id)
 void
 pmd_test_exit(void)
 {
+	struct rte_port *port;
 	portid_t pt_id;
 
 	if (test_done == 0)
@@ -1927,6 +1939,9 @@ pmd_test_exit(void)
 			fflush(stdout);
 			stop_port(pt_id);
 			close_port(pt_id);
+			port = &ports[pt_id];
+			rte_free(port->rx_offloads);
+			port->rx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea..dcad260 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -183,6 +183,7 @@ struct rte_port {
 	uint8_t                 dcb_flag;   /**< enable dcb */
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
+	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a766ac7..c388663 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -393,6 +393,20 @@ List all items from the pctype mapping table::
 
    testpmd> show port (port_id) pctype mapping
 
+show rx offloading capability
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List all per queue and per port Rx offloading capabilities of a port::
+
+   testpmd> rx_offload get capability (port_id)
+
+show rx offloading configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List port level and all queue level Rx offloading configuration::
+
+   testpmd> rx_offload get configuration (port_id)
+
 
 Configuration Functions
 -----------------------
@@ -1444,6 +1458,35 @@ 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> rx_offload (enable|disable) per_port (offloading) (port_id)
+
+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> rx_offload (enable|disable) per_queue (offloading) (port_id) (queue_id)
+
+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.
+
+
 Port Functions
 --------------
 
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v7 2/2] app/testpmd: add commands to test new Tx offload API
  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             ` Wei Dai
  2018-04-12 17:53             ` [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Ferruh Yigit
                               ` (2 subsequent siblings)
  4 siblings, 0 replies; 44+ messages in thread
From: Wei Dai @ 2018-04-03  8:57 UTC (permalink / raw)
  To: wenzhuo.lu, jingjing.wu; +Cc: dev, Wei Dai

Add following testpmd run-time commands to support test of
new Tx offload API:
tx_offload get capability <port_id>
tx_offload get configuration <port_id>
tx_offload enable|disable per_port <offload> <port_id>
tx_offload enable|disable per_queue <offload> <port_id> <queue_id>

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>
---
 app/test-pmd/cmdline.c                      | 382 ++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c                      |  15 +-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  44 ++++
 4 files changed, 440 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index a6cecba..c28edb6 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -16369,6 +16369,384 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
 	}
 };
 
+/* Get Tx offloads capability */
+struct cmd_tx_offload_get_capa_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t capability;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_capa_result,
+		 capability, "capability");
+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);
+
+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 = "tx_offload get capability <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_capa_tx_offload,
+		(void *)&cmd_tx_offload_get_capa_get,
+		(void *)&cmd_tx_offload_get_capa_capability,
+		(void *)&cmd_tx_offload_get_capa_port_id,
+		NULL,
+	}
+};
+
+/* Get Tx offloads configuration */
+struct cmd_tx_offload_get_configuration_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t configuration;
+	portid_t port_id;
+};
+
+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_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 get, "get");
+cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_offload_get_configuration_result,
+		 configuration, "configuration");
+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);
+
+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_offloads[q];
+		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 = "tx_offload get configuration <port_id>",
+	.tokens = {
+		(void *)&cmd_tx_offload_get_configuration_tx_offload,
+		(void *)&cmd_tx_offload_get_configuration_get,
+		(void *)&cmd_tx_offload_get_configuration_configuration,
+		(void *)&cmd_tx_offload_get_configuration_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per port offloading */
+struct cmd_config_per_port_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_port;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+};
+
+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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_port_tx_offload_result,
+		 per_port, "per_port");
+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_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);
+
+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", res->offload);
+		return;
+	}
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	nb_tx_queues = dev_info.nb_tx_queues;
+	if (!strcmp(res->en_dis, "enable")) {
+		port->dev_conf.txmode.offloads |= single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] |= single_offload;
+	} else {
+		port->dev_conf.txmode.offloads &= ~single_offload;
+		for (q = 0; q < nb_tx_queues; q++)
+			port->tx_offloads[q] &= ~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 = "tx_offload enable|disable per_port "
+		    "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 "
+		    "<port_id>",
+	.tokens = {
+		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_port_tx_offload_result_per_port,
+		(void *)&cmd_config_per_port_tx_offload_result_offload,
+		(void *)&cmd_config_per_port_tx_offload_result_port_id,
+		NULL,
+	}
+};
+
+/* Enable/Disable a per queue offloading */
+struct cmd_config_per_queue_tx_offload_result {
+	cmdline_fixed_string_t tx_offload;
+	cmdline_fixed_string_t en_dis;
+	cmdline_fixed_string_t per_queue;
+	cmdline_fixed_string_t offload;
+	portid_t port_id;
+	uint16_t queue_id;
+};
+
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload =
+	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_en_dis =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 en_dis, "enable#disable");
+cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_config_per_queue_tx_offload_result,
+		 per_queue, "per_queue");
+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_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_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);
+
+
+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", dev_info.nb_tx_queues - 1);
+		return;
+	}
+
+	single_offload = search_tx_offload(res->offload);
+	if (single_offload == 0) {
+		printf("Unknown offload name: %s", res->offload);
+		return;
+	}
+
+	if (!strcmp(res->en_dis, "enable"))
+		port->tx_offloads[queue_id] |= single_offload;
+	else
+		port->tx_offloads[queue_id] &= ~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 = "tx_offload enable|disable per_queue "
+		    "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 "
+		    "<port_id> <queue_id>",
+	.tokens = {
+		(void *)&cmd_config_per_queue_tx_offload_result_tx_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_en_dis,
+		(void *)&cmd_config_per_queue_tx_offload_result_per_queue,
+		(void *)&cmd_config_per_queue_tx_offload_result_offload,
+		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
+		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
+		NULL,
+	}
+};
+
 /* Common result structure for file commands */
 struct cmd_cmdfile_result {
 	cmdline_fixed_string_t load;
@@ -16649,6 +17027,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(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 e5de40a..d7d5d4c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -718,6 +718,16 @@ init_config(void)
 				 "failed\n", port->dev_info.max_rx_queues);
 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
 			port->rx_offloads[k] = port->dev_conf.rxmode.offloads;
+		port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads",
+						sizeof(port->tx_offloads[0]) *
+						port->dev_info.max_tx_queues,
+						sizeof(port->tx_offloads[0]));
+		if (port->tx_offloads == NULL)
+			rte_exit(EXIT_FAILURE,
+				 "rte_zmalloc(%d port->tx_offload[0]) "
+				 "failed\n", port->dev_info.max_tx_queues);
+		for (k = 0; k < port->dev_info.max_tx_queues; k++)
+			port->tx_offloads[k] = port->dev_conf.txmode.offloads;
 
 		/* set flag to initialize port/queue */
 		port->need_reconfig = 1;
@@ -1599,10 +1609,9 @@ start_port(portid_t pid)
 		if (port->need_reconfig_queues > 0) {
 			port->need_reconfig_queues = 0;
 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
-			/* Apply Tx offloads configuration */
-			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
 			/* setup tx queues */
 			for (qi = 0; qi < nb_txq; qi++) {
+				port->tx_conf.offloads = port->tx_offloads[qi];
 				if ((numa_support) &&
 					(txring_numa[pi] != NUMA_NO_CONFIG))
 					diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1942,6 +1951,8 @@ pmd_test_exit(void)
 			port = &ports[pt_id];
 			rte_free(port->rx_offloads);
 			port->rx_offloads = NULL;
+			rte_free(port->tx_offloads);
+			port->tx_offloads = NULL;
 		}
 	}
 	printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index dcad260..b0bd14e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -184,6 +184,7 @@ struct rte_port {
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 	uint64_t		*rx_offloads; /**< offloads of each Rx queue */
+	uint64_t		*tx_offloads; /**< offloads of each Tx queue */
 	struct ether_addr       *mc_addr_pool; /**< pool of multicast addrs */
 	uint32_t                mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
 	uint8_t                 slave_flag; /**< bonding slave port */
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index c388663..5eb91d7 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -407,6 +407,20 @@ List port level and all queue level Rx offloading configuration::
 
    testpmd> rx_offload get configuration (port_id)
 
+show tx offloading capability
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List all per queue and per port Tx offloading capabilities of a port::
+
+   testpmd> tx_offload get capability (port_id)
+
+show tx offloading configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List port level and all queue level Tx offloading configuration::
+
+   testpmd> tx_offload get configuration (port_id)
+
 
 Configuration Functions
 -----------------------
@@ -1486,6 +1500,36 @@ Where:
                   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> tx_offload (enable|disable) per_port (offloading) (port_id)
+
+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> tx_offload (enable|disable) per_queue (offloading) (port_id) (queue_id)
+
+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.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads
  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             ` Ferruh Yigit
  2018-05-08 13:30             ` Dai, Wei
  2018-05-09 12:13             ` [PATCH v8] app/testpmd: add commands to test new offload API Wei Dai
  4 siblings, 0 replies; 44+ messages in thread
From: Ferruh Yigit @ 2018-04-12 17:53 UTC (permalink / raw)
  To: Wei Dai, wenzhuo.lu, jingjing.wu; +Cc: dev, Qi Zhang

On 4/3/2018 9:57 AM, Wei Dai wrote:
> Existed testpmd commands can't support per queue offload configuration.
> And there are different commands to enable or disable different offloading.
> This patch set add following commands to support new Tx/Rx offloading API test.
> 
> To get Rx offload capability of a port, please run:
> testpmd > rx_offload get capability <port_id>
> 
> To get current Rx offload per queue and per port configuration of a port, run:
> tesstpmd > rx_offload get configuration <port_id>
> 
> To enable or disable a Rx per port offloading, please run:
> testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|... <port_id>
> This command will set|clear the associated bit in dev->dev_conf.rxmode.offloads
> for rte_eth_dev_configure and tx_conf->offloads of all Rx queues for
> rte_eth_rx_queue_setup( ).
> 
> To enable or disable a Tx per port offloading, please run:
> testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|... <port_id> <queue_id>


Hi Wei,

When each feature adds its own command testpmd becomes harder to use and
commands get harder to remember.

I am against adding a new set of "[rt]x_offload" high level commands. This a
feature of ports and should be a sub-command of port commands.

>From scope of this patch it is hard to see the problem, but that becomes more
clear as you look into whole testpmd command line.

There is already a command
"port config <port_id> ...",
"show port <...> <port_id>"

so we can re-use them like:
"show port rx_offload_cap <port_id>"

There is already "show port cap <port_id>" to get configured offloads!

"port config <port_id> rx_offload vlan_strip|ipv4_cksum|... on|off"
"port config <port_id> queue <queue_id> rx_offload vlan_strip|ipv4_cksum|... on|off"


or something similar but main idea is lets not create a new command, what do you
think?

> 
> Same commands like "tx_offload ..." are also added to support new Tx offload API test.
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> Acked-by: Jingjing Wu <jingjing.wu@intel.com>
> 
> ---
> v7:
>    update testpmd document
> v6:
>    reconfig port and queues if offloading is enabled or disabled
> v5:
>    don't depend on enum types defined in rte_ethdev.
> v4:
>    improve testpmd command per port offload to set or clear the port configuration
>    and the queue configuration of all queues.
> v3:
>    add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
>    free memory of port->rx_offloads and port->tx_offloads when testpmd is existed
> v2:
>    use rte_eth_dev_rx_offload_name() and rte_eth_dev_tx_offload_name().
>    remove static const strings of Rx/Tx offload names.
> 
> 
> Wei Dai (2):
>   app/testpmd: add commands to test new Rx offload API
>   app/testpmd: add commands to test new Tx offload API
> 
>  app/test-pmd/cmdline.c                      | 759 ++++++++++++++++++++++++++++
>  app/test-pmd/testpmd.c                      |  34 +-
>  app/test-pmd/testpmd.h                      |   2 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  87 ++++
>  4 files changed, 878 insertions(+), 4 deletions(-)
> 

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads
  2018-04-03  8:57           ` [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Wei Dai
                               ` (2 preceding siblings ...)
  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             ` [PATCH v8] app/testpmd: add commands to test new offload API Wei Dai
  4 siblings, 1 reply; 44+ messages in thread
From: Dai, Wei @ 2018-05-08 13:30 UTC (permalink / raw)
  To: Lu, Wenzhuo, Wu, Jingjing, Yigit, Ferruh; +Cc: dev

Hi, Ferruh

Thanks for your feedback.
I lost your mail but I can found it in http://dpdk.org/ml/archives/dev/2018-April/096900.html
I will update new version of this patch for new offload API in my v8 big patch for ethdev: check offloads.
As my command to get offload capablites and configuration return all results on port level and all queues,
I'd like to adopt your suggestion to use 'show port ...'
I search '.help_str' in app/test-pmd/cmdline.c and find all existed 'port config ...' is for port level configuration.
So if it is used to add new commands to enable/disable per-queue offloading,  the style will be broken.
I'd like to use 'port config <port_id> <offload> on|off ' to enable/disable offloading on all queues.
I also would like to use 'port <port_id> rxq|txq <queue_id> <offload> on|off' to enable/disable offloading on a queue.
All above my plan want to keep the style of current command and avoid to introduce more commands.
Can you agree it ?

Thanks & Best Regards
-Wei

> -----Original Message-----
> From: Dai, Wei
> Sent: Tuesday, April 3, 2018 4:58 PM
> To: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>
> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> Subject: [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx
> offloads
> 
> Existed testpmd commands can't support per queue offload configuration.
> And there are different commands to enable or disable different offloading.
> This patch set add following commands to support new Tx/Rx offloading API
> test.
> 
> To get Rx offload capability of a port, please run:
> testpmd > rx_offload get capability <port_id>
> 
> To get current Rx offload per queue and per port configuration of a port,
> run:
> tesstpmd > rx_offload get configuration <port_id>
> 
> To enable or disable a Rx per port offloading, please run:
> testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|...
> <port_id>
> This command will set|clear the associated bit in
> dev->dev_conf.rxmode.offloads
> for rte_eth_dev_configure and tx_conf->offloads of all Rx queues for
> rte_eth_rx_queue_setup( ).
> 
> To enable or disable a Tx per port offloading, please run:
> testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|...
> <port_id> <queue_id>
> 
> Same commands like "tx_offload ..." are also added to support new Tx
> offload API test.
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> Acked-by: Jingjing Wu <jingjing.wu@intel.com>
> 
> ---
> v7:
>    update testpmd document
> v6:
>    reconfig port and queues if offloading is enabled or disabled
> v5:
>    don't depend on enum types defined in rte_ethdev.
> v4:
>    improve testpmd command per port offload to set or clear the port
> configuration
>    and the queue configuration of all queues.
> v3:
>    add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
>    free memory of port->rx_offloads and port->tx_offloads when testpmd
> is existed
> v2:
>    use rte_eth_dev_rx_offload_name() and
> rte_eth_dev_tx_offload_name().
>    remove static const strings of Rx/Tx offload names.
> 
> 
> Wei Dai (2):
>   app/testpmd: add commands to test new Rx offload API
>   app/testpmd: add commands to test new Tx offload API
> 
>  app/test-pmd/cmdline.c                      | 759
> ++++++++++++++++++++++++++++
>  app/test-pmd/testpmd.c                      |  34 +-
>  app/test-pmd/testpmd.h                      |   2 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  87 ++++
>  4 files changed, 878 insertions(+), 4 deletions(-)
> 
> --
> 2.9.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads
  2018-05-08 13:30             ` Dai, Wei
@ 2018-05-08 15:33               ` Ferruh Yigit
  0 siblings, 0 replies; 44+ messages in thread
From: Ferruh Yigit @ 2018-05-08 15:33 UTC (permalink / raw)
  To: Dai, Wei, Lu, Wenzhuo, Wu, Jingjing; +Cc: dev

On 5/8/2018 2:30 PM, Dai, Wei wrote:
> Hi, Ferruh
> 
> Thanks for your feedback.
> I lost your mail but I can found it in http://dpdk.org/ml/archives/dev/2018-April/096900.html
> I will update new version of this patch for new offload API in my v8 big patch for ethdev: check offloads.
> As my command to get offload capablites and configuration return all results on port level and all queues,
> I'd like to adopt your suggestion to use 'show port ...'
> I search '.help_str' in app/test-pmd/cmdline.c and find all existed 'port config ...' is for port level configuration.
> So if it is used to add new commands to enable/disable per-queue offloading,  the style will be broken.
> I'd like to use 'port config <port_id> <offload> on|off ' to enable/disable offloading on all queues.
> I also would like to use 'port <port_id> rxq|txq <queue_id> <offload> on|off' to enable/disable offloading on a queue.
> All above my plan want to keep the style of current command and avoid to introduce more commands.
> Can you agree it ?

Yes, thanks for the update.

Just to group the command what do you think using "offload" keyword before
offload value, like:

port config <port_id> offload <offload> on|off

same for queue offloads.

> 
> Thanks & Best Regards
> -Wei
> 
>> -----Original Message-----
>> From: Dai, Wei
>> Sent: Tuesday, April 3, 2018 4:58 PM
>> To: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
>> <jingjing.wu@intel.com>
>> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
>> Subject: [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx
>> offloads
>>
>> Existed testpmd commands can't support per queue offload configuration.
>> And there are different commands to enable or disable different offloading.
>> This patch set add following commands to support new Tx/Rx offloading API
>> test.
>>
>> To get Rx offload capability of a port, please run:
>> testpmd > rx_offload get capability <port_id>
>>
>> To get current Rx offload per queue and per port configuration of a port,
>> run:
>> tesstpmd > rx_offload get configuration <port_id>
>>
>> To enable or disable a Rx per port offloading, please run:
>> testpmd > rx_offload enable|disable per_port vlan_strip|ipv4_cksum|...
>> <port_id>
>> This command will set|clear the associated bit in
>> dev->dev_conf.rxmode.offloads
>> for rte_eth_dev_configure and tx_conf->offloads of all Rx queues for
>> rte_eth_rx_queue_setup( ).
>>
>> To enable or disable a Tx per port offloading, please run:
>> testpmd > rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|...
>> <port_id> <queue_id>
>>
>> Same commands like "tx_offload ..." are also added to support new Tx
>> offload API test.
>>
>> Signed-off-by: Wei Dai <wei.dai@intel.com>
>> Acked-by: Jingjing Wu <jingjing.wu@intel.com>
>>
>> ---
>> v7:
>>    update testpmd document
>> v6:
>>    reconfig port and queues if offloading is enabled or disabled
>> v5:
>>    don't depend on enum types defined in rte_ethdev.
>> v4:
>>    improve testpmd command per port offload to set or clear the port
>> configuration
>>    and the queue configuration of all queues.
>> v3:
>>    add enum rte_eth_rx_offload_type and enum rte_eth_tx_offload_type
>>    free memory of port->rx_offloads and port->tx_offloads when testpmd
>> is existed
>> v2:
>>    use rte_eth_dev_rx_offload_name() and
>> rte_eth_dev_tx_offload_name().
>>    remove static const strings of Rx/Tx offload names.
>>
>>
>> Wei Dai (2):
>>   app/testpmd: add commands to test new Rx offload API
>>   app/testpmd: add commands to test new Tx offload API
>>
>>  app/test-pmd/cmdline.c                      | 759
>> ++++++++++++++++++++++++++++
>>  app/test-pmd/testpmd.c                      |  34 +-
>>  app/test-pmd/testpmd.h                      |   2 +
>>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  87 ++++
>>  4 files changed, 878 insertions(+), 4 deletions(-)
>>
>> --
>> 2.9.5
> 

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v8] app/testpmd: add commands to test new offload API
  2018-04-03  8:57           ` [PATCH v7 0/2] app/testpmd: add new commands to test new Tx/Rx offloads Wei Dai
                               ` (3 preceding siblings ...)
  2018-05-08 13:30             ` Dai, Wei
@ 2018-05-09 12:13             ` Wei Dai
  2018-05-11  0:00               ` Ferruh Yigit
  4 siblings, 1 reply; 44+ messages in thread
From: Wei Dai @ 2018-05-09 12:13 UTC (permalink / raw)
  To: ferruh.yigit, jingjing.wu, wenzhuo.lu; +Cc: dev, Wei Dai

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

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v8] app/testpmd: add commands to test new offload API
  2018-05-09 12:13             ` [PATCH v8] app/testpmd: add commands to test new offload API Wei Dai
@ 2018-05-11  0:00               ` Ferruh Yigit
  2018-05-11  0:10                 ` Ferruh Yigit
  0 siblings, 1 reply; 44+ messages in thread
From: Ferruh Yigit @ 2018-05-11  0:00 UTC (permalink / raw)
  To: Wei Dai, jingjing.wu, wenzhuo.lu; +Cc: dev

On 5/9/2018 1:13 PM, Wei Dai wrote:
> 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>

Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

Thanks for the work, there are some doc warnings which can be fixed while merging.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v8] app/testpmd: add commands to test new offload API
  2018-05-11  0:00               ` Ferruh Yigit
@ 2018-05-11  0:10                 ` Ferruh Yigit
  0 siblings, 0 replies; 44+ messages in thread
From: Ferruh Yigit @ 2018-05-11  0:10 UTC (permalink / raw)
  To: Wei Dai, jingjing.wu, wenzhuo.lu; +Cc: dev

On 5/11/2018 1:00 AM, Ferruh Yigit wrote:
> On 5/9/2018 1:13 PM, Wei Dai wrote:
>> 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>
> 
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> 
> Thanks for the work, there are some doc warnings which can be fixed while merging.

Applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2018-05-11  0:11 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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             ` [PATCH v8] app/testpmd: add commands to test new offload API Wei Dai
2018-05-11  0:00               ` Ferruh Yigit
2018-05-11  0:10                 ` Ferruh Yigit

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.