DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2 0/2] net/i40e: fix segmentation fault
@ 2017-01-09 16:29 Bernard Iremonger
  2017-01-09 16:29 ` [dpdk-dev] [PATCH v2 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
                   ` (4 more replies)
  0 siblings, 5 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-09 16:29 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger

Changes in v2:
These two patches were previously part of the following patchset:
[PATCH v7 00/27] Support VFD on i40e

They are being submitted seperately as they are not needed for VFD.
The net/i40e patch has been revised.
The testpmd patch is needed to setup VMDq in order to test the fix.

Bernard Iremonger (2):
  net/i40e: fix segmentation fault in close
  app/testpmd: add command to configure VMDq

 app/test-pmd/cmdline.c                      |  60 +++++++++++++
 app/test-pmd/testpmd.c                      | 126 ++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
 drivers/net/i40e/i40e_ethdev.c              |  12 +--
 5 files changed, 201 insertions(+), 5 deletions(-)

-- 
2.10.1

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

* [dpdk-dev] [PATCH v2 1/2] net/i40e: fix segmentation fault in close
  2017-01-09 16:29 [dpdk-dev] [PATCH v2 0/2] net/i40e: fix segmentation fault Bernard Iremonger
@ 2017-01-09 16:29 ` Bernard Iremonger
  2017-01-09 16:29 ` [dpdk-dev] [PATCH v2 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-09 16:29 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger, stable

Change the order of releasing the vsi's.
Release the vmdq vsi's first, then release the main vsi.

Fixes: 4861cde46116 ("i40e: new poll mode driver")

CC: stable@dpdk.org

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 46def56..3c233e3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2066,18 +2066,17 @@ i40e_dev_close(struct rte_eth_dev *dev)
 	/* shutdown and destroy the HMC */
 	i40e_shutdown_lan_hmc(hw);
 
-	/* release all the existing VSIs and VEBs */
-	i40e_fdir_teardown(pf);
-	i40e_vsi_release(pf->main_vsi);
-
 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
 		i40e_vsi_release(pf->vmdq[i].vsi);
 		pf->vmdq[i].vsi = NULL;
 	}
-
 	rte_free(pf->vmdq);
 	pf->vmdq = NULL;
 
+	/* release all the existing VSIs and VEBs */
+	i40e_fdir_teardown(pf);
+	i40e_vsi_release(pf->main_vsi);
+
 	/* shutdown the adminq */
 	i40e_aq_queue_shutdown(hw, true);
 	i40e_shutdown_adminq(hw);
@@ -4335,6 +4334,9 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	if (!vsi)
 		return I40E_SUCCESS;
 
+	if (!vsi->adapter)
+		return I40E_ERR_BAD_PTR;
+
 	user_param = vsi->user_param;
 
 	pf = I40E_VSI_TO_PF(vsi);
-- 
2.10.1

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

* [dpdk-dev] [PATCH v2 2/2] app/testpmd: add command to configure VMDq
  2017-01-09 16:29 [dpdk-dev] [PATCH v2 0/2] net/i40e: fix segmentation fault Bernard Iremonger
  2017-01-09 16:29 ` [dpdk-dev] [PATCH v2 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
@ 2017-01-09 16:29 ` Bernard Iremonger
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: fix segmentation fault Bernard Iremonger
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-09 16:29 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger

Add the following command to configure VMDq:
port config <port> vmdq

Add new command to testpmd user guide.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      |  60 +++++++++++++
 app/test-pmd/testpmd.c                      | 126 ++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
 4 files changed, 194 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4e8b0d8..b780f3f 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -604,6 +604,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" pfc (on|off)\n"
 			"    Set the DCB mode.\n\n"
 
+			"port config (port_id) vmdq\n"
+			"    Configure VMDq.\n\n"
+
 			"port config all burst (value)\n"
 			"    Set the number of packets per burst.\n\n"
 
@@ -2297,6 +2300,62 @@ cmdline_parse_inst_t cmd_config_dcb = {
         },
 };
 
+/* *** Configure VMDq *** */
+struct cmd_config_vmdq {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t vmdq;
+};
+
+static void
+cmd_config_vmdq_parsed(void *parsed_result,
+		       __attribute__((unused)) struct cmdline *cl,
+		       __attribute__((unused)) void *data)
+{
+	struct cmd_config_vmdq *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_port *port;
+	int ret;
+
+	port = &ports[port_id];
+	/** Check if the port is not started **/
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Please stop port %d first\n", port_id);
+		return;
+	}
+
+	ret = init_port_vmdq_config(port_id);
+	if (ret != 0) {
+		printf("Cannot initialize network ports.\n");
+		return;
+	}
+
+	cmd_reconfig_device_queue(port_id, 0, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_vmdq_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, port, "port");
+cmdline_parse_token_string_t cmd_config_vmdq_config =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, config, "config");
+cmdline_parse_token_num_t cmd_config_vmdq_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_vmdq, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_vmdq_vmdq =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, vmdq, "vmdq");
+
+cmdline_parse_inst_t cmd_config_vmdq = {
+	.f = cmd_config_vmdq_parsed,
+	.data = NULL,
+	.help_str = "port config <port-id> vmdq",
+	.tokens = {
+		(void *)&cmd_config_vmdq_port,
+		(void *)&cmd_config_vmdq_config,
+		(void *)&cmd_config_vmdq_port_id,
+		(void *)&cmd_config_vmdq_vmdq,
+		NULL,
+	},
+};
+
 /* *** configure number of packets per burst *** */
 struct cmd_config_burst {
 	cmdline_fixed_string_t port;
@@ -11572,6 +11631,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
 	(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
 	(cmdline_parse_inst_t *)&cmd_config_dcb,
+	(cmdline_parse_inst_t *)&cmd_config_vmdq,
 	(cmdline_parse_inst_t *)&cmd_read_reg,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit,
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index bfb2f8e..9850b7f 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -196,6 +196,34 @@ uint8_t dcb_test = 0;
 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
 
+static const struct rte_eth_conf vmdq_conf_default = {
+	.rxmode = {
+		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
+		.split_hdr_size = 0,
+		.header_split   = 0, /**< Header Split disabled */
+		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
+		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
+		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
+	},
+
+	.txmode = {
+		.mq_mode = ETH_MQ_TX_NONE,
+	},
+	.rx_adv_conf = {
+		/*
+		 * should be overridden separately in code with
+		 * appropriate values
+		 */
+		.vmdq_rx_conf = {
+			.nb_queue_pools = ETH_8_POOLS,
+			.enable_default_pool = 0,
+			.default_pool = 0,
+			.nb_pool_maps = 0,
+			.pool_map = {{0, 0},},
+		},
+	},
+};
+
 /*
  * Configurable number of RX/TX ring descriptors.
  */
@@ -1895,6 +1923,104 @@ const uint16_t vlan_tags[] = {
 		24, 25, 26, 27, 28, 29, 30, 31
 };
 
+const uint16_t num_vlans = RTE_DIM(vlan_tags);
+static uint16_t num_pf_queues, num_vmdq_queues;
+static uint16_t vmdq_pool_base, vmdq_queue_base;
+/* number of pools (if user does not specify any, 8 by default */
+static uint32_t num_queues = 8;
+static uint32_t num_pools = 8;
+
+/**
+ * Builds up the correct configuration for vmdq based on the vlan tags array
+ * given above, and determine the queue number and pool map number according to
+ * valid pool number
+ */
+static int
+get_eth_vmdq_conf(struct rte_eth_conf *eth_conf, uint32_t num_pools)
+{
+	struct rte_eth_vmdq_rx_conf conf;
+	unsigned i;
+
+	conf.nb_queue_pools = (enum rte_eth_nb_pools)num_pools;
+	conf.nb_pool_maps = num_pools;
+	conf.enable_default_pool = 0;
+	conf.default_pool = 0; /* set explicit value, even if not used */
+
+	for (i = 0; i < conf.nb_pool_maps; i++) {
+		conf.pool_map[i].vlan_id = vlan_tags[i];
+		conf.pool_map[i].pools = (1UL << (i % num_pools));
+	}
+
+	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
+	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
+	       sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
+	return 0;
+}
+
+/**
+ * Configures VMDq for  a given port using global settings.
+ */
+int
+init_port_vmdq_config(uint8_t port)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_conf port_conf;
+	uint16_t rx_queues, tx_queues;
+	int retval;
+	uint16_t queues_per_pool;
+	uint32_t max_nb_pools;
+
+	if (port >= rte_eth_dev_count())
+		return -1;
+	/**
+	 * The max pool number from dev_info will be used to validate the pool
+	 * number.
+	 */
+	rte_eth_dev_info_get(port, &dev_info);
+	max_nb_pools = (uint32_t)dev_info.max_vmdq_pools;
+	/**
+	 * We allow to process part of VMDQ pools specified by num_pools in
+	 * command line.
+	 */
+	if (num_pools > max_nb_pools) {
+		printf("num_pools %d >max_nb_pools %d\n",
+			num_pools, max_nb_pools);
+		return -1;
+	}
+
+	retval = get_eth_vmdq_conf(&port_conf, num_pools);
+	if (retval < 0)
+		return retval;
+
+	/*
+	 * NIC queues are divided into pf queues and vmdq queues.
+	 */
+	/* There is assumption here all ports have the same configuration! */
+	num_pf_queues = dev_info.max_rx_queues - dev_info.vmdq_queue_num;
+	queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;
+	num_vmdq_queues = num_pools * queues_per_pool;
+	num_queues = num_pf_queues + num_vmdq_queues;
+	vmdq_queue_base = dev_info.vmdq_queue_base;
+	vmdq_pool_base  = dev_info.vmdq_pool_base;
+
+	printf("pf queue num: %u, configured vmdq pool num: %u,"
+		" each vmdq pool has %u queues\n",
+		num_pf_queues, num_pools, queues_per_pool);
+	printf("vmdq queue base: %d pool base %d\n",
+		vmdq_queue_base, vmdq_pool_base);
+
+	/*
+	 * All queues including pf queues are setup.
+	 * This is because VMDQ queues doesn't always start from zero, and the
+	 * PMD layer doesn't support selectively initialising part of rx/tx
+	 * queues.
+	 */
+	rx_queues = (uint16_t)dev_info.max_rx_queues;
+	tx_queues = (uint16_t)dev_info.max_tx_queues;
+	retval = rte_eth_dev_configure(port, rx_queues, tx_queues, &port_conf);
+	return retval;
+}
+
 static  int
 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
 		 enum dcb_mode_enable dcb_mode,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 22ce2d6..6e72420 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -580,6 +580,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid);
 int init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode,
 		     enum rte_eth_nb_tcs num_tcs,
 		     uint8_t pfc_en);
+int init_port_vmdq_config(uint8_t port);
 int start_port(portid_t pid);
 void stop_port(portid_t pid);
 void close_port(portid_t pid);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index c611dc5..d9839cc 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1374,6 +1374,13 @@ Set the DCB mode for an individual port::
 
 The traffic class should be 4 or 8.
 
+port config - VMDq
+~~~~~~~~~~~~~~~~~~
+
+Configure VMDq for an individual port::
+
+   testpmd> port config (port_id) vmdq
+
 port config - Burst
 ~~~~~~~~~~~~~~~~~~~
 
-- 
2.10.1

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

* [dpdk-dev] [PATCH v3 0/2] net/i40e: fix segmentation fault
  2017-01-09 16:29 [dpdk-dev] [PATCH v2 0/2] net/i40e: fix segmentation fault Bernard Iremonger
  2017-01-09 16:29 ` [dpdk-dev] [PATCH v2 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
  2017-01-09 16:29 ` [dpdk-dev] [PATCH v2 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
@ 2017-01-12 13:58 ` Bernard Iremonger
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 " Bernard Iremonger
                     ` (2 more replies)
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
  4 siblings, 3 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-12 13:58 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger

Changes in v3:
Fix checkpatch  warning in testpmd.c
Tidy debug code in testpmd.c

Changes in v2: 
These two patches were previously part of the following patchset:
[PATCH v7 00/27] Support VFD on i40e

They are being submitted seperately as they are not needed for VFD.
The net/i40e patch has been revised.
The testpmd patch is needed to setup VMDq in order to test the fix.

Bernard Iremonger (2):
  net/i40e: fix segmentation fault in close
  app/testpmd: add command to configure VMDq

 app/test-pmd/cmdline.c                      |  60 +++++++++++++
 app/test-pmd/testpmd.c                      | 126 +++++++++++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
 drivers/net/i40e/i40e_ethdev.c              |  12 +--
 5 files changed, 200 insertions(+), 6 deletions(-)

-- 
2.10.1

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

* [dpdk-dev] [PATCH v3 1/2] net/i40e: fix segmentation fault in close
  2017-01-09 16:29 [dpdk-dev] [PATCH v2 0/2] net/i40e: fix segmentation fault Bernard Iremonger
                   ` (2 preceding siblings ...)
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: fix segmentation fault Bernard Iremonger
@ 2017-01-12 13:58 ` Bernard Iremonger
  2017-01-17 14:34   ` Wu, Jingjing
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
  4 siblings, 1 reply; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-12 13:58 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger, stable

Change the order of releasing the vsi's.
Release the vmdq vsi's first, then release the main vsi.

Fixes: 4861cde46116 ("i40e: new poll mode driver")

CC: stable@dpdk.org

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f13e61b..e8cfec8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2068,18 +2068,17 @@ i40e_dev_close(struct rte_eth_dev *dev)
 	/* shutdown and destroy the HMC */
 	i40e_shutdown_lan_hmc(hw);
 
-	/* release all the existing VSIs and VEBs */
-	i40e_fdir_teardown(pf);
-	i40e_vsi_release(pf->main_vsi);
-
 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
 		i40e_vsi_release(pf->vmdq[i].vsi);
 		pf->vmdq[i].vsi = NULL;
 	}
-
 	rte_free(pf->vmdq);
 	pf->vmdq = NULL;
 
+	/* release all the existing VSIs and VEBs */
+	i40e_fdir_teardown(pf);
+	i40e_vsi_release(pf->main_vsi);
+
 	/* shutdown the adminq */
 	i40e_aq_queue_shutdown(hw, true);
 	i40e_shutdown_adminq(hw);
@@ -4342,6 +4341,9 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	if (!vsi)
 		return I40E_SUCCESS;
 
+	if (!vsi->adapter)
+		return I40E_ERR_BAD_PTR;
+
 	user_param = vsi->user_param;
 
 	pf = I40E_VSI_TO_PF(vsi);
-- 
2.10.1

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

* [dpdk-dev] [PATCH v3 2/2] app/testpmd: add command to configure VMDq
  2017-01-09 16:29 [dpdk-dev] [PATCH v2 0/2] net/i40e: fix segmentation fault Bernard Iremonger
                   ` (3 preceding siblings ...)
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
@ 2017-01-12 13:58 ` Bernard Iremonger
  4 siblings, 0 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-12 13:58 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger

Add the following command to configure VMDq:
port config <port> vmdq

Add new command to testpmd user guide.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      |  60 +++++++++++++
 app/test-pmd/testpmd.c                      | 126 +++++++++++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
 4 files changed, 193 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4e8b0d8..b780f3f 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -604,6 +604,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" pfc (on|off)\n"
 			"    Set the DCB mode.\n\n"
 
+			"port config (port_id) vmdq\n"
+			"    Configure VMDq.\n\n"
+
 			"port config all burst (value)\n"
 			"    Set the number of packets per burst.\n\n"
 
@@ -2297,6 +2300,62 @@ cmdline_parse_inst_t cmd_config_dcb = {
         },
 };
 
+/* *** Configure VMDq *** */
+struct cmd_config_vmdq {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t vmdq;
+};
+
+static void
+cmd_config_vmdq_parsed(void *parsed_result,
+		       __attribute__((unused)) struct cmdline *cl,
+		       __attribute__((unused)) void *data)
+{
+	struct cmd_config_vmdq *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_port *port;
+	int ret;
+
+	port = &ports[port_id];
+	/** Check if the port is not started **/
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Please stop port %d first\n", port_id);
+		return;
+	}
+
+	ret = init_port_vmdq_config(port_id);
+	if (ret != 0) {
+		printf("Cannot initialize network ports.\n");
+		return;
+	}
+
+	cmd_reconfig_device_queue(port_id, 0, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_vmdq_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, port, "port");
+cmdline_parse_token_string_t cmd_config_vmdq_config =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, config, "config");
+cmdline_parse_token_num_t cmd_config_vmdq_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_vmdq, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_vmdq_vmdq =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, vmdq, "vmdq");
+
+cmdline_parse_inst_t cmd_config_vmdq = {
+	.f = cmd_config_vmdq_parsed,
+	.data = NULL,
+	.help_str = "port config <port-id> vmdq",
+	.tokens = {
+		(void *)&cmd_config_vmdq_port,
+		(void *)&cmd_config_vmdq_config,
+		(void *)&cmd_config_vmdq_port_id,
+		(void *)&cmd_config_vmdq_vmdq,
+		NULL,
+	},
+};
+
 /* *** configure number of packets per burst *** */
 struct cmd_config_burst {
 	cmdline_fixed_string_t port;
@@ -11572,6 +11631,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
 	(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
 	(cmdline_parse_inst_t *)&cmd_config_dcb,
+	(cmdline_parse_inst_t *)&cmd_config_vmdq,
 	(cmdline_parse_inst_t *)&cmd_read_reg,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit,
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index bfb2f8e..11d263d 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -196,6 +196,34 @@ uint8_t dcb_test = 0;
 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
 
+static const struct rte_eth_conf vmdq_conf_default = {
+	.rxmode = {
+		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
+		.split_hdr_size = 0,
+		.header_split   = 0, /**< Header Split disabled */
+		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
+		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
+		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
+	},
+
+	.txmode = {
+		.mq_mode = ETH_MQ_TX_NONE,
+	},
+	.rx_adv_conf = {
+		/*
+		 * should be overridden separately in code with
+		 * appropriate values
+		 */
+		.vmdq_rx_conf = {
+			.nb_queue_pools = ETH_8_POOLS,
+			.enable_default_pool = 0,
+			.default_pool = 0,
+			.nb_pool_maps = 0,
+			.pool_map = {{0, 0},},
+		},
+	},
+};
+
 /*
  * Configurable number of RX/TX ring descriptors.
  */
@@ -1895,6 +1923,102 @@ const uint16_t vlan_tags[] = {
 		24, 25, 26, 27, 28, 29, 30, 31
 };
 
+const uint16_t num_vlans = RTE_DIM(vlan_tags);
+static uint16_t num_pf_queues, num_vmdq_queues;
+static uint16_t vmdq_pool_base, vmdq_queue_base;
+/* number of pools (if user does not specify any, 8 by default */
+static uint32_t num_queues = 8;
+static uint32_t num_pools = 8;
+
+/**
+ * Builds up the correct configuration for vmdq based on the vlan tags array
+ * given above, and determine the queue number and pool map number according to
+ * valid pool number
+ */
+static int
+get_eth_vmdq_conf(struct rte_eth_conf *eth_conf, uint32_t num_pools)
+{
+	struct rte_eth_vmdq_rx_conf conf;
+	uint8_t i;
+
+	conf.nb_queue_pools = (enum rte_eth_nb_pools)num_pools;
+	conf.nb_pool_maps = num_pools;
+	conf.enable_default_pool = 0;
+	conf.default_pool = 0; /* set explicit value, even if not used */
+
+	for (i = 0; i < conf.nb_pool_maps; i++) {
+		conf.pool_map[i].vlan_id = vlan_tags[i];
+		conf.pool_map[i].pools = (1UL << (i % num_pools));
+	}
+
+	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
+	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
+	       sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
+	return 0;
+}
+
+/**
+ * Configures VMDq for  a given port using global settings.
+ */
+int
+init_port_vmdq_config(uint8_t port)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_conf port_conf;
+	uint16_t rx_queues, tx_queues;
+	int retval;
+	uint16_t queues_per_pool;
+	uint32_t max_nb_pools;
+
+	if (port >= rte_eth_dev_count())
+		return -1;
+	/**
+	 * The max pool number from dev_info will be used to validate the pool
+	 * number.
+	 */
+	rte_eth_dev_info_get(port, &dev_info);
+	max_nb_pools = (uint32_t)dev_info.max_vmdq_pools;
+	/**
+	 * We allow to process part of VMDQ pools specified by num_pools in
+	 * command line.
+	 */
+	if (num_pools > max_nb_pools) {
+		printf("num_pools %d >max_nb_pools %d\n",
+			num_pools, max_nb_pools);
+		return -1;
+	}
+
+	retval = get_eth_vmdq_conf(&port_conf, num_pools);
+	if (retval < 0)
+		return retval;
+
+	/*
+	 * NIC queues are divided into pf queues and vmdq queues.
+	 */
+	/* There is assumption here all ports have the same configuration! */
+	num_pf_queues = dev_info.max_rx_queues - dev_info.vmdq_queue_num;
+	queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;
+	num_vmdq_queues = num_pools * queues_per_pool;
+	num_queues = num_pf_queues + num_vmdq_queues;
+	vmdq_queue_base = dev_info.vmdq_queue_base;
+	vmdq_pool_base  = dev_info.vmdq_pool_base;
+
+	printf("num_pf_queues: %u num_pools: %u\n", num_pf_queues, num_pools);
+	printf("each vmdq pool has %u queues\n", queues_per_pool);
+	printf("vmdq_queue_base: %d vmdq_pool_base: %d\n", vmdq_queue_base, vmdq_pool_base);
+
+	/*
+	 * All queues including pf queues are setup.
+	 * This is because VMDQ queues doesn't always start from zero, and the
+	 * PMD layer doesn't support selectively initialising part of rx/tx
+	 * queues.
+	 */
+	rx_queues = (uint16_t)dev_info.max_rx_queues;
+	tx_queues = (uint16_t)dev_info.max_tx_queues;
+	retval = rte_eth_dev_configure(port, rx_queues, tx_queues, &port_conf);
+	return retval;
+}
+
 static  int
 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
 		 enum dcb_mode_enable dcb_mode,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 22ce2d6..6e72420 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -580,6 +580,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid);
 int init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode,
 		     enum rte_eth_nb_tcs num_tcs,
 		     uint8_t pfc_en);
+int init_port_vmdq_config(uint8_t port);
 int start_port(portid_t pid);
 void stop_port(portid_t pid);
 void close_port(portid_t pid);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index c611dc5..d9839cc 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1374,6 +1374,13 @@ Set the DCB mode for an individual port::
 
 The traffic class should be 4 or 8.
 
+port config - VMDq
+~~~~~~~~~~~~~~~~~~
+
+Configure VMDq for an individual port::
+
+   testpmd> port config (port_id) vmdq
+
 port config - Burst
 ~~~~~~~~~~~~~~~~~~~
 
-- 
2.10.1

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

* Re: [dpdk-dev] [PATCH v3 1/2] net/i40e: fix segmentation fault in close
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
@ 2017-01-17 14:34   ` Wu, Jingjing
  2017-01-17 16:30     ` Iremonger, Bernard
  0 siblings, 1 reply; 27+ messages in thread
From: Wu, Jingjing @ 2017-01-17 14:34 UTC (permalink / raw)
  To: Iremonger, Bernard, dev, Lu, Wenzhuo, Zhang, Helin; +Cc: stable



> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Thursday, January 12, 2017 9:58 PM
> To: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Zhang, Helin <helin.zhang@intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; stable@dpdk.org
> Subject: [PATCH v3 1/2] net/i40e: fix segmentation fault in close
> 
> Change the order of releasing the vsi's.
> Release the vmdq vsi's first, then release the main vsi.
> 
> Fixes: 4861cde46116 ("i40e: new poll mode driver")
> 
> CC: stable@dpdk.org
> 
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index f13e61b..e8cfec8 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -2068,18 +2068,17 @@ i40e_dev_close(struct rte_eth_dev *dev)
>  	/* shutdown and destroy the HMC */
>  	i40e_shutdown_lan_hmc(hw);
> 
> -	/* release all the existing VSIs and VEBs */
> -	i40e_fdir_teardown(pf);
> -	i40e_vsi_release(pf->main_vsi);
> -
>  	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
>  		i40e_vsi_release(pf->vmdq[i].vsi);
>  		pf->vmdq[i].vsi = NULL;
>  	}
> -
>  	rte_free(pf->vmdq);
>  	pf->vmdq = NULL;
> 
> +	/* release all the existing VSIs and VEBs */
> +	i40e_fdir_teardown(pf);
> +	i40e_vsi_release(pf->main_vsi);
> +
>  	/* shutdown the adminq */
>  	i40e_aq_queue_shutdown(hw, true);
>  	i40e_shutdown_adminq(hw);
> @@ -4342,6 +4341,9 @@ i40e_vsi_release(struct i40e_vsi *vsi)
>  	if (!vsi)
>  		return I40E_SUCCESS;
> 
> +	if (!vsi->adapter)
> +		return I40E_ERR_BAD_PTR;
> +

The change looks fine to me.
Only minor comments like:
The dev_close is ethdev level ops, I40E_XX error code need to be replaced by 
The error code defined in ethedev level.

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

* Re: [dpdk-dev] [PATCH v3 1/2] net/i40e: fix segmentation fault in close
  2017-01-17 14:34   ` Wu, Jingjing
@ 2017-01-17 16:30     ` Iremonger, Bernard
  0 siblings, 0 replies; 27+ messages in thread
From: Iremonger, Bernard @ 2017-01-17 16:30 UTC (permalink / raw)
  To: Wu, Jingjing, dev, Lu, Wenzhuo, Zhang, Helin; +Cc: stable

Hi Jingjing,

<snip>

> > Subject: [PATCH v3 1/2] net/i40e: fix segmentation fault in close
> >
> > Change the order of releasing the vsi's.
> > Release the vmdq vsi's first, then release the main vsi.
> >
> > Fixes: 4861cde46116 ("i40e: new poll mode driver")
> >
> > CC: stable@dpdk.org
> >
> > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > ---
> >  drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
> >  1 file changed, 7 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/net/i40e/i40e_ethdev.c
> > b/drivers/net/i40e/i40e_ethdev.c index f13e61b..e8cfec8 100644
> > --- a/drivers/net/i40e/i40e_ethdev.c
> > +++ b/drivers/net/i40e/i40e_ethdev.c
> > @@ -2068,18 +2068,17 @@ i40e_dev_close(struct rte_eth_dev *dev)
> >  	/* shutdown and destroy the HMC */
> >  	i40e_shutdown_lan_hmc(hw);
> >
> > -	/* release all the existing VSIs and VEBs */
> > -	i40e_fdir_teardown(pf);
> > -	i40e_vsi_release(pf->main_vsi);
> > -
> >  	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
> >  		i40e_vsi_release(pf->vmdq[i].vsi);
> >  		pf->vmdq[i].vsi = NULL;
> >  	}
> > -
> >  	rte_free(pf->vmdq);
> >  	pf->vmdq = NULL;
> >
> > +	/* release all the existing VSIs and VEBs */
> > +	i40e_fdir_teardown(pf);
> > +	i40e_vsi_release(pf->main_vsi);
> > +
> >  	/* shutdown the adminq */
> >  	i40e_aq_queue_shutdown(hw, true);
> >  	i40e_shutdown_adminq(hw);
> > @@ -4342,6 +4341,9 @@ i40e_vsi_release(struct i40e_vsi *vsi)
> >  	if (!vsi)
> >  		return I40E_SUCCESS;
> >
> > +	if (!vsi->adapter)
> > +		return I40E_ERR_BAD_PTR;
> > +
> 
> The change looks fine to me.
> Only minor comments like:
> The dev_close is ethdev level ops, I40E_XX error code need to be replaced
> by The error code defined in ethedev level.

I will replace I40E_ERR_BAD_PTR with -EFAULT in v4.

Regards,

Bernard.

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

* [dpdk-dev] [PATCH v4 0/2] net/i40e: fix segmentation fault
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: fix segmentation fault Bernard Iremonger
@ 2017-01-17 16:39   ` Bernard Iremonger
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 0/3] " Bernard Iremonger
                       ` (3 more replies)
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
  2 siblings, 4 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-17 16:39 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger

Changes in v4:
Rebase to latest dpdk-next-net
Replaced I40E_ERR_BAD_PTR with -EFAULT.

Changes in v3
Fix checkpatch  warning in testpmd.c
Tidy debug code in testpmd.c

Changes in v2:
These two patches were previously part of the following patchset:
[PATCH v7 00/27] Support VFD on i40e

They are being submitted seperately as they are not needed for VFD.
The net/i40e patch has been revised.
The testpmd patch is needed to setup VMDq in order to test the fix.

Bernard Iremonger (2):
  net/i40e: fix segmentation fault in close
  app/testpmd: add command to configure VMDq

 app/test-pmd/cmdline.c                      |  60 +++++++++++++
 app/test-pmd/testpmd.c                      | 126 +++++++++++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
 drivers/net/i40e/i40e_ethdev.c              |  12 +--
 5 files changed, 200 insertions(+), 6 deletions(-)

-- 
2.10.1

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

* [dpdk-dev] [PATCH v4 1/2] net/i40e: fix segmentation fault in close
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: fix segmentation fault Bernard Iremonger
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 " Bernard Iremonger
@ 2017-01-17 16:39   ` Bernard Iremonger
  2017-01-20 13:15     ` Wu, Jingjing
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
  2 siblings, 1 reply; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-17 16:39 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger, stable

Change the order of releasing the vsi's.
Release the vmdq vsi's first, then release the main vsi.

Fixes: 4861cde46116 ("i40e: new poll mode driver")

CC: stable@dpdk.org

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f92f148..08caea6 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2069,18 +2069,17 @@ i40e_dev_close(struct rte_eth_dev *dev)
 	/* shutdown and destroy the HMC */
 	i40e_shutdown_lan_hmc(hw);
 
-	/* release all the existing VSIs and VEBs */
-	i40e_fdir_teardown(pf);
-	i40e_vsi_release(pf->main_vsi);
-
 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
 		i40e_vsi_release(pf->vmdq[i].vsi);
 		pf->vmdq[i].vsi = NULL;
 	}
-
 	rte_free(pf->vmdq);
 	pf->vmdq = NULL;
 
+	/* release all the existing VSIs and VEBs */
+	i40e_fdir_teardown(pf);
+	i40e_vsi_release(pf->main_vsi);
+
 	/* shutdown the adminq */
 	i40e_aq_queue_shutdown(hw, true);
 	i40e_shutdown_adminq(hw);
@@ -4343,6 +4342,9 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	if (!vsi)
 		return I40E_SUCCESS;
 
+	if (!vsi->adapter)
+		return -EFAULT;
+
 	user_param = vsi->user_param;
 
 	pf = I40E_VSI_TO_PF(vsi);
-- 
2.10.1

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

* [dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq
  2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: fix segmentation fault Bernard Iremonger
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 " Bernard Iremonger
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
@ 2017-01-17 16:39   ` Bernard Iremonger
  2017-01-20 13:33     ` Wu, Jingjing
  2 siblings, 1 reply; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-17 16:39 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu, helin.zhang; +Cc: Bernard Iremonger

Add the following command to configure VMDq:
port config <port> vmdq

Add new command to testpmd user guide.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      |  60 +++++++++++++
 app/test-pmd/testpmd.c                      | 126 +++++++++++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
 4 files changed, 193 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 21d10e4..30969b4 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -629,6 +629,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" pfc (on|off)\n"
 			"    Set the DCB mode.\n\n"
 
+			"port config (port_id) vmdq\n"
+			"    Configure VMDq.\n\n"
+
 			"port config all burst (value)\n"
 			"    Set the number of packets per burst.\n\n"
 
@@ -2322,6 +2325,62 @@ cmdline_parse_inst_t cmd_config_dcb = {
         },
 };
 
+/* *** Configure VMDq *** */
+struct cmd_config_vmdq {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t vmdq;
+};
+
+static void
+cmd_config_vmdq_parsed(void *parsed_result,
+		       __attribute__((unused)) struct cmdline *cl,
+		       __attribute__((unused)) void *data)
+{
+	struct cmd_config_vmdq *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_port *port;
+	int ret;
+
+	port = &ports[port_id];
+	/** Check if the port is not started **/
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Please stop port %d first\n", port_id);
+		return;
+	}
+
+	ret = init_port_vmdq_config(port_id);
+	if (ret != 0) {
+		printf("Cannot initialize network ports.\n");
+		return;
+	}
+
+	cmd_reconfig_device_queue(port_id, 0, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_vmdq_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, port, "port");
+cmdline_parse_token_string_t cmd_config_vmdq_config =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, config, "config");
+cmdline_parse_token_num_t cmd_config_vmdq_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_vmdq, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_vmdq_vmdq =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, vmdq, "vmdq");
+
+cmdline_parse_inst_t cmd_config_vmdq = {
+	.f = cmd_config_vmdq_parsed,
+	.data = NULL,
+	.help_str = "port config <port-id> vmdq",
+	.tokens = {
+		(void *)&cmd_config_vmdq_port,
+		(void *)&cmd_config_vmdq_config,
+		(void *)&cmd_config_vmdq_port_id,
+		(void *)&cmd_config_vmdq_vmdq,
+		NULL,
+	},
+};
+
 /* *** configure number of packets per burst *** */
 struct cmd_config_burst {
 	cmdline_fixed_string_t port;
@@ -12438,6 +12497,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
 	(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
 	(cmdline_parse_inst_t *)&cmd_config_dcb,
+	(cmdline_parse_inst_t *)&cmd_config_vmdq,
 	(cmdline_parse_inst_t *)&cmd_read_reg,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit,
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index bfb2f8e..11d263d 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -196,6 +196,34 @@ uint8_t dcb_test = 0;
 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
 
+static const struct rte_eth_conf vmdq_conf_default = {
+	.rxmode = {
+		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
+		.split_hdr_size = 0,
+		.header_split   = 0, /**< Header Split disabled */
+		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
+		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
+		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
+	},
+
+	.txmode = {
+		.mq_mode = ETH_MQ_TX_NONE,
+	},
+	.rx_adv_conf = {
+		/*
+		 * should be overridden separately in code with
+		 * appropriate values
+		 */
+		.vmdq_rx_conf = {
+			.nb_queue_pools = ETH_8_POOLS,
+			.enable_default_pool = 0,
+			.default_pool = 0,
+			.nb_pool_maps = 0,
+			.pool_map = {{0, 0},},
+		},
+	},
+};
+
 /*
  * Configurable number of RX/TX ring descriptors.
  */
@@ -1895,6 +1923,102 @@ const uint16_t vlan_tags[] = {
 		24, 25, 26, 27, 28, 29, 30, 31
 };
 
+const uint16_t num_vlans = RTE_DIM(vlan_tags);
+static uint16_t num_pf_queues, num_vmdq_queues;
+static uint16_t vmdq_pool_base, vmdq_queue_base;
+/* number of pools (if user does not specify any, 8 by default */
+static uint32_t num_queues = 8;
+static uint32_t num_pools = 8;
+
+/**
+ * Builds up the correct configuration for vmdq based on the vlan tags array
+ * given above, and determine the queue number and pool map number according to
+ * valid pool number
+ */
+static int
+get_eth_vmdq_conf(struct rte_eth_conf *eth_conf, uint32_t num_pools)
+{
+	struct rte_eth_vmdq_rx_conf conf;
+	uint8_t i;
+
+	conf.nb_queue_pools = (enum rte_eth_nb_pools)num_pools;
+	conf.nb_pool_maps = num_pools;
+	conf.enable_default_pool = 0;
+	conf.default_pool = 0; /* set explicit value, even if not used */
+
+	for (i = 0; i < conf.nb_pool_maps; i++) {
+		conf.pool_map[i].vlan_id = vlan_tags[i];
+		conf.pool_map[i].pools = (1UL << (i % num_pools));
+	}
+
+	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
+	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
+	       sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
+	return 0;
+}
+
+/**
+ * Configures VMDq for  a given port using global settings.
+ */
+int
+init_port_vmdq_config(uint8_t port)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_conf port_conf;
+	uint16_t rx_queues, tx_queues;
+	int retval;
+	uint16_t queues_per_pool;
+	uint32_t max_nb_pools;
+
+	if (port >= rte_eth_dev_count())
+		return -1;
+	/**
+	 * The max pool number from dev_info will be used to validate the pool
+	 * number.
+	 */
+	rte_eth_dev_info_get(port, &dev_info);
+	max_nb_pools = (uint32_t)dev_info.max_vmdq_pools;
+	/**
+	 * We allow to process part of VMDQ pools specified by num_pools in
+	 * command line.
+	 */
+	if (num_pools > max_nb_pools) {
+		printf("num_pools %d >max_nb_pools %d\n",
+			num_pools, max_nb_pools);
+		return -1;
+	}
+
+	retval = get_eth_vmdq_conf(&port_conf, num_pools);
+	if (retval < 0)
+		return retval;
+
+	/*
+	 * NIC queues are divided into pf queues and vmdq queues.
+	 */
+	/* There is assumption here all ports have the same configuration! */
+	num_pf_queues = dev_info.max_rx_queues - dev_info.vmdq_queue_num;
+	queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;
+	num_vmdq_queues = num_pools * queues_per_pool;
+	num_queues = num_pf_queues + num_vmdq_queues;
+	vmdq_queue_base = dev_info.vmdq_queue_base;
+	vmdq_pool_base  = dev_info.vmdq_pool_base;
+
+	printf("num_pf_queues: %u num_pools: %u\n", num_pf_queues, num_pools);
+	printf("each vmdq pool has %u queues\n", queues_per_pool);
+	printf("vmdq_queue_base: %d vmdq_pool_base: %d\n", vmdq_queue_base, vmdq_pool_base);
+
+	/*
+	 * All queues including pf queues are setup.
+	 * This is because VMDQ queues doesn't always start from zero, and the
+	 * PMD layer doesn't support selectively initialising part of rx/tx
+	 * queues.
+	 */
+	rx_queues = (uint16_t)dev_info.max_rx_queues;
+	tx_queues = (uint16_t)dev_info.max_tx_queues;
+	retval = rte_eth_dev_configure(port, rx_queues, tx_queues, &port_conf);
+	return retval;
+}
+
 static  int
 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
 		 enum dcb_mode_enable dcb_mode,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index ee59460..67bb641 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -582,6 +582,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid);
 int init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode,
 		     enum rte_eth_nb_tcs num_tcs,
 		     uint8_t pfc_en);
+int init_port_vmdq_config(uint8_t port);
 int start_port(portid_t pid);
 void stop_port(portid_t pid);
 void close_port(portid_t pid);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 60f30bb..ddc4016 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1438,6 +1438,13 @@ Set the DCB mode for an individual port::
 
 The traffic class should be 4 or 8.
 
+port config - VMDq
+~~~~~~~~~~~~~~~~~~
+
+Configure VMDq for an individual port::
+
+   testpmd> port config (port_id) vmdq
+
 port config - Burst
 ~~~~~~~~~~~~~~~~~~~
 
-- 
2.10.1

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

* Re: [dpdk-dev] [PATCH v4 1/2] net/i40e: fix segmentation fault in close
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
@ 2017-01-20 13:15     ` Wu, Jingjing
  0 siblings, 0 replies; 27+ messages in thread
From: Wu, Jingjing @ 2017-01-20 13:15 UTC (permalink / raw)
  To: Iremonger, Bernard, dev, Lu, Wenzhuo, Zhang, Helin; +Cc: stable



> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Wednesday, January 18, 2017 12:39 AM
> To: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Zhang, Helin <helin.zhang@intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; stable@dpdk.org
> Subject: [PATCH v4 1/2] net/i40e: fix segmentation fault in close
> 
> Change the order of releasing the vsi's.
> Release the vmdq vsi's first, then release the main vsi.
> 
> Fixes: 4861cde46116 ("i40e: new poll mode driver")
> 
> CC: stable@dpdk.org
> 
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>

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

* Re: [dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
@ 2017-01-20 13:33     ` Wu, Jingjing
  2017-01-20 15:22       ` Iremonger, Bernard
  0 siblings, 1 reply; 27+ messages in thread
From: Wu, Jingjing @ 2017-01-20 13:33 UTC (permalink / raw)
  To: Iremonger, Bernard, dev, Lu, Wenzhuo, Zhang, Helin



> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Wednesday, January 18, 2017 12:39 AM
> To: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Zhang, Helin <helin.zhang@intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>
> Subject: [PATCH v4 2/2] app/testpmd: add command to configure VMDq
> 
> Add the following command to configure VMDq:
> port config <port> vmdq
> 
> Add new command to testpmd user guide.
> 
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> ---
>  app/test-pmd/cmdline.c                      |  60 +++++++++++++
>  app/test-pmd/testpmd.c                      | 126 +++++++++++++++++++++++++++-
>  app/test-pmd/testpmd.h                      |   1 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
>  4 files changed, 193 insertions(+), 1 deletion(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> 21d10e4..30969b4 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -629,6 +629,9 @@ static void cmd_help_long_parsed(void *parsed_result,
>  			" pfc (on|off)\n"
>  			"    Set the DCB mode.\n\n"
> 
> +			"port config (port_id) vmdq\n"
> +			"    Configure VMDq.\n\n"
> +
>  			"port config all burst (value)\n"
>  			"    Set the number of packets per burst.\n\n"
> 
> @@ -2322,6 +2325,62 @@ cmdline_parse_inst_t cmd_config_dcb = {
>          },
>  };
> 
> +/* *** Configure VMDq *** */
> +struct cmd_config_vmdq {
> +	cmdline_fixed_string_t port;
> +	cmdline_fixed_string_t config;
> +	uint8_t port_id;
> +	cmdline_fixed_string_t vmdq;
> +};
> +
> +static void
> +cmd_config_vmdq_parsed(void *parsed_result,
> +		       __attribute__((unused)) struct cmdline *cl,
> +		       __attribute__((unused)) void *data) {
> +	struct cmd_config_vmdq *res = parsed_result;
> +	portid_t port_id = res->port_id;
> +	struct rte_port *port;
> +	int ret;
> +
> +	port = &ports[port_id];
> +	/** Check if the port is not started **/
> +	if (port->port_status != RTE_PORT_STOPPED) {
> +		printf("Please stop port %d first\n", port_id);
> +		return;
> +	}
> +
> +	ret = init_port_vmdq_config(port_id);
> +	if (ret != 0) {
> +		printf("Cannot initialize network ports.\n");
> +		return;
> +	}
> +
> +	cmd_reconfig_device_queue(port_id, 0, 1); }
I think the device also need to be reconfigured, it should be
cmd_reconfig_device_queue(port_id, 1, 1);

> +
> +cmdline_parse_token_string_t cmd_config_vmdq_port =
> +	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, port, "port");
> +cmdline_parse_token_string_t cmd_config_vmdq_config =
> +	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, config, "config");
> +cmdline_parse_token_num_t cmd_config_vmdq_port_id =
> +	TOKEN_NUM_INITIALIZER(struct cmd_config_vmdq, port_id, UINT8);
> +cmdline_parse_token_string_t cmd_config_vmdq_vmdq =
> +	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, vmdq, "vmdq");
> +
> +cmdline_parse_inst_t cmd_config_vmdq = {
> +	.f = cmd_config_vmdq_parsed,
> +	.data = NULL,
> +	.help_str = "port config <port-id> vmdq",
> +	.tokens = {
> +		(void *)&cmd_config_vmdq_port,
> +		(void *)&cmd_config_vmdq_config,
> +		(void *)&cmd_config_vmdq_port_id,
> +		(void *)&cmd_config_vmdq_vmdq,
> +		NULL,
> +	},
> +};
> +
>  /* *** configure number of packets per burst *** */  struct cmd_config_burst {
>  	cmdline_fixed_string_t port;
> @@ -12438,6 +12497,7 @@ cmdline_parse_ctx_t main_ctx[] = {
>  	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
>  	(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
>  	(cmdline_parse_inst_t *)&cmd_config_dcb,
> +	(cmdline_parse_inst_t *)&cmd_config_vmdq,
>  	(cmdline_parse_inst_t *)&cmd_read_reg,
>  	(cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
>  	(cmdline_parse_inst_t *)&cmd_read_reg_bit, diff --git a/app/test-
> pmd/testpmd.c b/app/test-pmd/testpmd.c index bfb2f8e..11d263d 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -1,7 +1,7 @@
>  /*-
>   *   BSD LICENSE
>   *
> - *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
> + *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
>   *   All rights reserved.
>   *
>   *   Redistribution and use in source and binary forms, with or without
> @@ -196,6 +196,34 @@ uint8_t dcb_test = 0;  queueid_t nb_rxq = 1; /**<
> Number of RX queues per port. */  queueid_t nb_txq = 1; /**< Number of TX
> queues per port. */
> 
> +static const struct rte_eth_conf vmdq_conf_default = {
> +	.rxmode = {
> +		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
> +		.split_hdr_size = 0,
> +		.header_split   = 0, /**< Header Split disabled */
> +		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
> +		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
> +		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
> +	},
> +
> +	.txmode = {
> +		.mq_mode = ETH_MQ_TX_NONE,
> +	},
> +	.rx_adv_conf = {
> +		/*
> +		 * should be overridden separately in code with
> +		 * appropriate values
> +		 */
> +		.vmdq_rx_conf = {
> +			.nb_queue_pools = ETH_8_POOLS,
> +			.enable_default_pool = 0,
> +			.default_pool = 0,
> +			.nb_pool_maps = 0,
> +			.pool_map = {{0, 0},},
> +		},
> +	},
> +};
> +
>  /*
>   * Configurable number of RX/TX ring descriptors.
>   */
> @@ -1895,6 +1923,102 @@ const uint16_t vlan_tags[] = {
>  		24, 25, 26, 27, 28, 29, 30, 31
>  };
> 
> +const uint16_t num_vlans = RTE_DIM(vlan_tags); static uint16_t
> +num_pf_queues, num_vmdq_queues; static uint16_t vmdq_pool_base,
> +vmdq_queue_base;
> +/* number of pools (if user does not specify any, 8 by default */
> +static uint32_t num_queues = 8; static uint32_t num_pools = 8;
> +
> +/**
> + * Builds up the correct configuration for vmdq based on the vlan tags
> +array
> + * given above, and determine the queue number and pool map number
> +according to
> + * valid pool number
> + */
> +static int
> +get_eth_vmdq_conf(struct rte_eth_conf *eth_conf, uint32_t num_pools) {
> +	struct rte_eth_vmdq_rx_conf conf;
> +	uint8_t i;
> +
> +	conf.nb_queue_pools = (enum rte_eth_nb_pools)num_pools;
> +	conf.nb_pool_maps = num_pools;
> +	conf.enable_default_pool = 0;
> +	conf.default_pool = 0; /* set explicit value, even if not used */
> +
> +	for (i = 0; i < conf.nb_pool_maps; i++) {
> +		conf.pool_map[i].vlan_id = vlan_tags[i];
> +		conf.pool_map[i].pools = (1UL << (i % num_pools));
> +	}
> +
> +	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
> +	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
> +	       sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
> +	return 0;
> +}
> +
> +/**
> + * Configures VMDq for  a given port using global settings.
> + */
> +int
> +init_port_vmdq_config(uint8_t port)
> +{
> +	struct rte_eth_dev_info dev_info;
> +	struct rte_eth_conf port_conf;
> +	uint16_t rx_queues, tx_queues;
> +	int retval;
> +	uint16_t queues_per_pool;
> +	uint32_t max_nb_pools;
> +
> +	if (port >= rte_eth_dev_count())
> +		return -1;
> +	/**
> +	 * The max pool number from dev_info will be used to validate the pool
> +	 * number.
> +	 */
> +	rte_eth_dev_info_get(port, &dev_info);
> +	max_nb_pools = (uint32_t)dev_info.max_vmdq_pools;
> +	/**
> +	 * We allow to process part of VMDQ pools specified by num_pools in
> +	 * command line.
> +	 */
Only found "static uint32_t num_pools = 8;", haven't found any code related
with the num_pools as command arguments.

> +	if (num_pools > max_nb_pools) {
> +		printf("num_pools %d >max_nb_pools %d\n",
> +			num_pools, max_nb_pools);
> +		return -1;
> +	}
> +
> +	retval = get_eth_vmdq_conf(&port_conf, num_pools);
> +	if (retval < 0)
> +		return retval;
> +
> +	/*
> +	 * NIC queues are divided into pf queues and vmdq queues.
> +	 */
> +	/* There is assumption here all ports have the same configuration! */
> +	num_pf_queues = dev_info.max_rx_queues -
> dev_info.vmdq_queue_num;
> +	queues_per_pool = dev_info.vmdq_queue_num /
> dev_info.max_vmdq_pools;
> +	num_vmdq_queues = num_pools * queues_per_pool;
> +	num_queues = num_pf_queues + num_vmdq_queues;
> +	vmdq_queue_base = dev_info.vmdq_queue_base;
> +	vmdq_pool_base  = dev_info.vmdq_pool_base;

The variable is set only for printing?
> +
> +	printf("num_pf_queues: %u num_pools: %u\n", num_pf_queues,
> num_pools);
> +	printf("each vmdq pool has %u queues\n", queues_per_pool);
> +	printf("vmdq_queue_base: %d vmdq_pool_base: %d\n",
> vmdq_queue_base,
> +vmdq_pool_base);
> +
> +	/*
> +	 * All queues including pf queues are setup.
> +	 * This is because VMDQ queues doesn't always start from zero, and the
> +	 * PMD layer doesn't support selectively initialising part of rx/tx
> +	 * queues.
> +	 */
> +	rx_queues = (uint16_t)dev_info.max_rx_queues;
> +	tx_queues = (uint16_t)dev_info.max_tx_queues;
> +	retval = rte_eth_dev_configure(port, rx_queues, tx_queues,
> &port_conf);
> +	return retval;
> +}
> +
>  static  int
>  get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
>  		 enum dcb_mode_enable dcb_mode,
> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index
> ee59460..67bb641 100644
> --- a/app/test-pmd/testpmd.h
> +++ b/app/test-pmd/testpmd.h
> @@ -582,6 +582,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid);  int
> init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode,
>  		     enum rte_eth_nb_tcs num_tcs,
>  		     uint8_t pfc_en);
> +int init_port_vmdq_config(uint8_t port);
>  int start_port(portid_t pid);
>  void stop_port(portid_t pid);
>  void close_port(portid_t pid);
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 60f30bb..ddc4016 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -1438,6 +1438,13 @@ Set the DCB mode for an individual port::
> 
>  The traffic class should be 4 or 8.
> 
> +port config - VMDq
> +~~~~~~~~~~~~~~~~~~
> +
> +Configure VMDq for an individual port::
> +
> +   testpmd> port config (port_id) vmdq
> +
>  port config - Burst
>  ~~~~~~~~~~~~~~~~~~~
> 
> --
> 2.10.1

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

* Re: [dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq
  2017-01-20 13:33     ` Wu, Jingjing
@ 2017-01-20 15:22       ` Iremonger, Bernard
  0 siblings, 0 replies; 27+ messages in thread
From: Iremonger, Bernard @ 2017-01-20 15:22 UTC (permalink / raw)
  To: Wu, Jingjing, dev, Lu, Wenzhuo, Zhang, Helin

Hi Jingjing,

<snip>

> > Subject: [PATCH v4 2/2] app/testpmd: add command to configure VMDq
> >
> > Add the following command to configure VMDq:
> > port config <port> vmdq
> >
> > Add new command to testpmd user guide.
> >
> > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > ---
> >  app/test-pmd/cmdline.c                      |  60 +++++++++++++
> >  app/test-pmd/testpmd.c                      | 126
> +++++++++++++++++++++++++++-
> >  app/test-pmd/testpmd.h                      |   1 +
> >  doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
> >  4 files changed, 193 insertions(+), 1 deletion(-)
> >
> > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> > 21d10e4..30969b4 100644
> > --- a/app/test-pmd/cmdline.c
> > +++ b/app/test-pmd/cmdline.c
> > @@ -629,6 +629,9 @@ static void cmd_help_long_parsed(void
> *parsed_result,
> >  			" pfc (on|off)\n"
> >  			"    Set the DCB mode.\n\n"
> >
> > +			"port config (port_id) vmdq\n"
> > +			"    Configure VMDq.\n\n"
> > +
> >  			"port config all burst (value)\n"
> >  			"    Set the number of packets per burst.\n\n"
> >
> > @@ -2322,6 +2325,62 @@ cmdline_parse_inst_t cmd_config_dcb = {
> >          },
> >  };
> >
> > +/* *** Configure VMDq *** */
> > +struct cmd_config_vmdq {
> > +	cmdline_fixed_string_t port;
> > +	cmdline_fixed_string_t config;
> > +	uint8_t port_id;
> > +	cmdline_fixed_string_t vmdq;
> > +};
> > +
> > +static void
> > +cmd_config_vmdq_parsed(void *parsed_result,
> > +		       __attribute__((unused)) struct cmdline *cl,
> > +		       __attribute__((unused)) void *data) {
> > +	struct cmd_config_vmdq *res = parsed_result;
> > +	portid_t port_id = res->port_id;
> > +	struct rte_port *port;
> > +	int ret;
> > +
> > +	port = &ports[port_id];
> > +	/** Check if the port is not started **/
> > +	if (port->port_status != RTE_PORT_STOPPED) {
> > +		printf("Please stop port %d first\n", port_id);
> > +		return;
> > +	}
> > +
> > +	ret = init_port_vmdq_config(port_id);
> > +	if (ret != 0) {
> > +		printf("Cannot initialize network ports.\n");
> > +		return;
> > +	}
> > +
> > +	cmd_reconfig_device_queue(port_id, 0, 1); }
> I think the device also need to be reconfigured, it should be
> cmd_reconfig_device_queue(port_id, 1, 1);

The device has just been configured by the VMDq command so I think it is ok, but I will check it.

 
> > +
> > +cmdline_parse_token_string_t cmd_config_vmdq_port =
> > +	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, port, "port");
> > +cmdline_parse_token_string_t cmd_config_vmdq_config =
> > +	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, config,
> "config");
> > +cmdline_parse_token_num_t cmd_config_vmdq_port_id =
> > +	TOKEN_NUM_INITIALIZER(struct cmd_config_vmdq, port_id,
> UINT8);
> > +cmdline_parse_token_string_t cmd_config_vmdq_vmdq =
> > +	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, vmdq,
> "vmdq");
> > +
> > +cmdline_parse_inst_t cmd_config_vmdq = {
> > +	.f = cmd_config_vmdq_parsed,
> > +	.data = NULL,
> > +	.help_str = "port config <port-id> vmdq",
> > +	.tokens = {
> > +		(void *)&cmd_config_vmdq_port,
> > +		(void *)&cmd_config_vmdq_config,
> > +		(void *)&cmd_config_vmdq_port_id,
> > +		(void *)&cmd_config_vmdq_vmdq,
> > +		NULL,
> > +	},
> > +};
> > +
> >  /* *** configure number of packets per burst *** */  struct
> cmd_config_burst {
> >  	cmdline_fixed_string_t port;
> > @@ -12438,6 +12497,7 @@ cmdline_parse_ctx_t main_ctx[] = {
> >  	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
> >  	(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
> >  	(cmdline_parse_inst_t *)&cmd_config_dcb,
> > +	(cmdline_parse_inst_t *)&cmd_config_vmdq,
> >  	(cmdline_parse_inst_t *)&cmd_read_reg,
> >  	(cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
> >  	(cmdline_parse_inst_t *)&cmd_read_reg_bit, diff --git a/app/test-
> > pmd/testpmd.c b/app/test-pmd/testpmd.c index bfb2f8e..11d263d 100644
> > --- a/app/test-pmd/testpmd.c
> > +++ b/app/test-pmd/testpmd.c
> > @@ -1,7 +1,7 @@
> >  /*-
> >   *   BSD LICENSE
> >   *
> > - *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
> > + *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
> >   *   All rights reserved.
> >   *
> >   *   Redistribution and use in source and binary forms, with or without
> > @@ -196,6 +196,34 @@ uint8_t dcb_test = 0;  queueid_t nb_rxq = 1; /**<
> > Number of RX queues per port. */  queueid_t nb_txq = 1; /**< Number of
> > TX queues per port. */
> >
> > +static const struct rte_eth_conf vmdq_conf_default = {
> > +	.rxmode = {
> > +		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
> > +		.split_hdr_size = 0,
> > +		.header_split   = 0, /**< Header Split disabled */
> > +		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
> > +		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
> > +		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
> > +	},
> > +
> > +	.txmode = {
> > +		.mq_mode = ETH_MQ_TX_NONE,
> > +	},
> > +	.rx_adv_conf = {
> > +		/*
> > +		 * should be overridden separately in code with
> > +		 * appropriate values
> > +		 */
> > +		.vmdq_rx_conf = {
> > +			.nb_queue_pools = ETH_8_POOLS,
> > +			.enable_default_pool = 0,
> > +			.default_pool = 0,
> > +			.nb_pool_maps = 0,
> > +			.pool_map = {{0, 0},},
> > +		},
> > +	},
> > +};
> > +
> >  /*
> >   * Configurable number of RX/TX ring descriptors.
> >   */
> > @@ -1895,6 +1923,102 @@ const uint16_t vlan_tags[] = {
> >  		24, 25, 26, 27, 28, 29, 30, 31
> >  };
> >
> > +const uint16_t num_vlans = RTE_DIM(vlan_tags); static uint16_t
> > +num_pf_queues, num_vmdq_queues; static uint16_t vmdq_pool_base,
> > +vmdq_queue_base;
> > +/* number of pools (if user does not specify any, 8 by default */
> > +static uint32_t num_queues = 8; static uint32_t num_pools = 8;
> > +
> > +/**
> > + * Builds up the correct configuration for vmdq based on the vlan
> > +tags array
> > + * given above, and determine the queue number and pool map number
> > +according to
> > + * valid pool number
> > + */
> > +static int
> > +get_eth_vmdq_conf(struct rte_eth_conf *eth_conf, uint32_t
> num_pools) {
> > +	struct rte_eth_vmdq_rx_conf conf;
> > +	uint8_t i;
> > +
> > +	conf.nb_queue_pools = (enum rte_eth_nb_pools)num_pools;
> > +	conf.nb_pool_maps = num_pools;
> > +	conf.enable_default_pool = 0;
> > +	conf.default_pool = 0; /* set explicit value, even if not used */
> > +
> > +	for (i = 0; i < conf.nb_pool_maps; i++) {
> > +		conf.pool_map[i].vlan_id = vlan_tags[i];
> > +		conf.pool_map[i].pools = (1UL << (i % num_pools));
> > +	}
> > +
> > +	(void)(rte_memcpy(eth_conf, &vmdq_conf_default,
> sizeof(*eth_conf)));
> > +	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf,
> &conf,
> > +	       sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
> > +	return 0;
> > +}
> > +
> > +/**
> > + * Configures VMDq for  a given port using global settings.
> > + */
> > +int
> > +init_port_vmdq_config(uint8_t port)
> > +{
> > +	struct rte_eth_dev_info dev_info;
> > +	struct rte_eth_conf port_conf;
> > +	uint16_t rx_queues, tx_queues;
> > +	int retval;
> > +	uint16_t queues_per_pool;
> > +	uint32_t max_nb_pools;
> > +
> > +	if (port >= rte_eth_dev_count())
> > +		return -1;
> > +	/**
> > +	 * The max pool number from dev_info will be used to validate the
> pool
> > +	 * number.
> > +	 */
> > +	rte_eth_dev_info_get(port, &dev_info);
> > +	max_nb_pools = (uint32_t)dev_info.max_vmdq_pools;
> > +	/**
> > +	 * We allow to process part of VMDQ pools specified by num_pools in
> > +	 * command line.
> > +	 */
> Only found "static uint32_t num_pools = 8;", haven't found any code related
> with the num_pools as command arguments.
> 

The default value is 8. I will check if num_pools can be changed with from the command line.
 
> > +	if (num_pools > max_nb_pools) {
> > +		printf("num_pools %d >max_nb_pools %d\n",
> > +			num_pools, max_nb_pools);
> > +		return -1;
> > +	}
> > +
> > +	retval = get_eth_vmdq_conf(&port_conf, num_pools);
> > +	if (retval < 0)
> > +		return retval;
> > +
> > +	/*
> > +	 * NIC queues are divided into pf queues and vmdq queues.
> > +	 */
> > +	/* There is assumption here all ports have the same configuration! */
> > +	num_pf_queues = dev_info.max_rx_queues -
> > dev_info.vmdq_queue_num;
> > +	queues_per_pool = dev_info.vmdq_queue_num /
> > dev_info.max_vmdq_pools;
> > +	num_vmdq_queues = num_pools * queues_per_pool;
> > +	num_queues = num_pf_queues + num_vmdq_queues;
> > +	vmdq_queue_base = dev_info.vmdq_queue_base;
> > +	vmdq_pool_base  = dev_info.vmdq_pool_base;
> 
> The variable is set only for printing?

Yes, this is just debug information, similar to sample VMDq code. 

> > +
> > +	printf("num_pf_queues: %u num_pools: %u\n", num_pf_queues,
> > num_pools);
> > +	printf("each vmdq pool has %u queues\n", queues_per_pool);
> > +	printf("vmdq_queue_base: %d vmdq_pool_base: %d\n",
> > vmdq_queue_base,
> > +vmdq_pool_base);
> > +
> > +	/*
> > +	 * All queues including pf queues are setup.
> > +	 * This is because VMDQ queues doesn't always start from zero, and
> the
> > +	 * PMD layer doesn't support selectively initialising part of rx/tx
> > +	 * queues.
> > +	 */
> > +	rx_queues = (uint16_t)dev_info.max_rx_queues;
> > +	tx_queues = (uint16_t)dev_info.max_tx_queues;
> > +	retval = rte_eth_dev_configure(port, rx_queues, tx_queues,
> > &port_conf);
> > +	return retval;
> > +}
> > +
> >  static  int
> >  get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
> >  		 enum dcb_mode_enable dcb_mode,
> > diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index
> > ee59460..67bb641 100644
> > --- a/app/test-pmd/testpmd.h
> > +++ b/app/test-pmd/testpmd.h
> > @@ -582,6 +582,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid);
> > int init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode,
> >  		     enum rte_eth_nb_tcs num_tcs,
> >  		     uint8_t pfc_en);
> > +int init_port_vmdq_config(uint8_t port);
> >  int start_port(portid_t pid);
> >  void stop_port(portid_t pid);
> >  void close_port(portid_t pid);
> > diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> > b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> > index 60f30bb..ddc4016 100644
> > --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> > +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> > @@ -1438,6 +1438,13 @@ Set the DCB mode for an individual port::
> >
> >  The traffic class should be 4 or 8.
> >
> > +port config - VMDq
> > +~~~~~~~~~~~~~~~~~~
> > +
> > +Configure VMDq for an individual port::
> > +
> > +   testpmd> port config (port_id) vmdq
> > +
> >  port config - Burst
> >  ~~~~~~~~~~~~~~~~~~~
> >
> > --
> > 2.10.1

Regards,

Bernard.

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

* [dpdk-dev] [PATCH v5 0/3] net/i40e: fix segmentation fault
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 " Bernard Iremonger
@ 2017-01-25 14:36     ` Bernard Iremonger
  2017-01-27 10:49       ` [dpdk-dev] [PATCH v6 0/2] app/testpmd: enable VMDq in testpmd Bernard Iremonger
                         ` (2 more replies)
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 1/3] net/i40e: fix segmentation fault in close Bernard Iremonger
                       ` (2 subsequent siblings)
  3 siblings, 3 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-25 14:36 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu; +Cc: Bernard Iremonger

Changes in v5:
Rebase to latest dpdk-next-net
Reworked init_port_vmdq_config() function in testpmd.
Added patch 3, fix to  stop_port() function in testpmd.

Changes in v4:
Rebase to latest dpdk-next-net
Replaced I40E_ERR_BAD_PTR with -EFAULT.

Changes in v3
Fix checkpatch  warning in testpmd.c
Tidy debug code in testpmd.c

Changes in v2:
These two patches were previously part of the following patchset:
[PATCH v7 00/27] Support VFD on i40e

They are being submitted seperately as they are not needed for VFD.
The net/i40e patch has been revised.
The testpmd patch is needed to setup VMDq in order to test the fix.

Bernard Iremonger (3):
  net/i40e: fix segmentation fault in close
  app/testpmd: add command to configure VMDq
  app/testpmd: fix port stop

 app/test-pmd/cmdline.c                      |  72 ++++++++-
 app/test-pmd/config.c                       |  14 +-
 app/test-pmd/parameters.c                   |  15 +-
 app/test-pmd/testpmd.c                      | 225 +++++++++++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   7 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  18 ++-
 drivers/net/i40e/i40e_ethdev.c              |  14 +-
 7 files changed, 345 insertions(+), 20 deletions(-)

-- 
2.10.1

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

* [dpdk-dev] [PATCH v5 1/3] net/i40e: fix segmentation fault in close
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 " Bernard Iremonger
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 0/3] " Bernard Iremonger
@ 2017-01-25 14:36     ` Bernard Iremonger
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 2/3] app/testpmd: add command to configure VMDq Bernard Iremonger
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: fix port stop Bernard Iremonger
  3 siblings, 0 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-25 14:36 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu; +Cc: Bernard Iremonger, stable

Change the order of releasing the vsi's.
Release the vmdq vsi's first, then release the main vsi.

Fixes: 4861cde46116 ("i40e: new poll mode driver")

CC: stable@dpdk.org

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index a818998..0937dc4 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -2072,18 +2072,17 @@ i40e_dev_close(struct rte_eth_dev *dev)
 	/* shutdown and destroy the HMC */
 	i40e_shutdown_lan_hmc(hw);
 
-	/* release all the existing VSIs and VEBs */
-	i40e_fdir_teardown(pf);
-	i40e_vsi_release(pf->main_vsi);
-
 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
 		i40e_vsi_release(pf->vmdq[i].vsi);
 		pf->vmdq[i].vsi = NULL;
 	}
-
 	rte_free(pf->vmdq);
 	pf->vmdq = NULL;
 
+	/* release all the existing VSIs and VEBs */
+	i40e_fdir_teardown(pf);
+	i40e_vsi_release(pf->main_vsi);
+
 	/* shutdown the adminq */
 	i40e_aq_queue_shutdown(hw, true);
 	i40e_shutdown_adminq(hw);
@@ -4374,6 +4373,9 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	if (!vsi)
 		return I40E_SUCCESS;
 
+	if (!vsi->adapter)
+		return -EFAULT;
+
 	user_param = vsi->user_param;
 
 	pf = I40E_VSI_TO_PF(vsi);
-- 
2.10.1

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

* [dpdk-dev] [PATCH v5 2/3] app/testpmd: add command to configure VMDq
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 " Bernard Iremonger
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 0/3] " Bernard Iremonger
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 1/3] net/i40e: fix segmentation fault in close Bernard Iremonger
@ 2017-01-25 14:36     ` Bernard Iremonger
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: fix port stop Bernard Iremonger
  3 siblings, 0 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-25 14:36 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu; +Cc: Bernard Iremonger

Add the following command to configure VMDq:
port config <port> vmdq

Add the following command to set number of pools:
set nbpool <N>

Add new commands to testpmd user guide.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      |  72 ++++++++-
 app/test-pmd/config.c                       |  14 +-
 app/test-pmd/parameters.c                   |  15 +-
 app/test-pmd/testpmd.c                      | 221 +++++++++++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   7 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  18 ++-
 6 files changed, 335 insertions(+), 12 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 2fd862f..f017833 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  *
@@ -238,6 +238,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set nbcore (num)\n"
 			"    Set number of cores.\n\n"
 
+			"set nbpool (num)\n"
+			"    Set number of VMDq pools.\n\n"
+
 			"set coremask (mask)\n"
 			"    Set the forwarding cores hexadecimal mask.\n\n"
 
@@ -629,6 +632,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" pfc (on|off)\n"
 			"    Set the DCB mode.\n\n"
 
+			"port config (port_id) vmdq\n"
+			"    Configure VMDq for a port.\n\n"
+
 			"port config all burst (value)\n"
 			"    Set the number of packets per burst.\n\n"
 
@@ -2322,6 +2328,61 @@ cmdline_parse_inst_t cmd_config_dcb = {
         },
 };
 
+/* *** Configure VMDq *** */
+struct cmd_config_vmdq {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t vmdq;
+};
+
+static void
+cmd_config_vmdq_parsed(void *parsed_result,
+		       __attribute__((unused)) struct cmdline *cl,
+		       __attribute__((unused)) void *data)
+{
+	struct cmd_config_vmdq *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_port *port;
+	int ret;
+
+	port = &ports[port_id];
+	/** Check if the port is not started **/
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Please stop port %d first\n", port_id);
+		return;
+	}
+
+	ret = init_port_vmdq_config(port_id);
+	if (ret != 0) {
+		printf("Cannot configure VMDQ for port %d.\n", port_id);
+		return;
+	}
+	cmd_reconfig_device_queue(port_id, 0, 0);
+}
+
+cmdline_parse_token_string_t cmd_config_vmdq_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, port, "port");
+cmdline_parse_token_string_t cmd_config_vmdq_config =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, config, "config");
+cmdline_parse_token_num_t cmd_config_vmdq_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_vmdq, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_vmdq_vmdq =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, vmdq, "vmdq");
+
+cmdline_parse_inst_t cmd_config_vmdq = {
+	.f = cmd_config_vmdq_parsed,
+	.data = NULL,
+	.help_str = "port config <port-id> vmdq",
+	.tokens = {
+		(void *)&cmd_config_vmdq_port,
+		(void *)&cmd_config_vmdq_config,
+		(void *)&cmd_config_vmdq_port_id,
+		(void *)&cmd_config_vmdq_vmdq,
+		NULL,
+	},
+};
+
 /* *** configure number of packets per burst *** */
 struct cmd_config_burst {
 	cmdline_fixed_string_t port;
@@ -2722,7 +2783,7 @@ cmdline_parse_inst_t cmd_set_fwd_mask = {
 };
 
 /*
- * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
+ * SET NBPORT, NBCORE, NBPOOL, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
  */
 struct cmd_set_result {
 	cmdline_fixed_string_t set;
@@ -2741,6 +2802,8 @@ static void cmd_set_parsed(void *parsed_result,
 	} else if (!strcmp(res->what, "nbcore")) {
 		set_fwd_lcores_number(res->value);
 		fwd_config_setup();
+	} else if (!strcmp(res->what, "nbpool")) {
+		set_vmdq_pool_number(res->value);
 	} else if (!strcmp(res->what, "burst"))
 		set_nb_pkt_per_burst(res->value);
 	else if (!strcmp(res->what, "verbose"))
@@ -2751,14 +2814,14 @@ cmdline_parse_token_string_t cmd_set_set =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
 cmdline_parse_token_string_t cmd_set_what =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
-				 "nbport#nbcore#burst#verbose");
+				 "nbport#nbcore#nbpool#burst#verbose");
 cmdline_parse_token_num_t cmd_set_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
 
 cmdline_parse_inst_t cmd_set_numbers = {
 	.f = cmd_set_parsed,
 	.data = NULL,
-	.help_str = "set nbport|nbcore|burst|verbose <value>",
+	.help_str = "set nbport|nbcore|nbpool|burst|verbose <value>",
 	.tokens = {
 		(void *)&cmd_set_set,
 		(void *)&cmd_set_what,
@@ -12462,6 +12525,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
 	(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
 	(cmdline_parse_inst_t *)&cmd_config_dcb,
+	(cmdline_parse_inst_t *)&cmd_config_vmdq,
 	(cmdline_parse_inst_t *)&cmd_read_reg,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 5834498..2df501f 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -2063,6 +2063,18 @@ set_fwd_lcores_number(uint16_t nb_lc)
 }
 
 void
+set_vmdq_pool_number(uint32_t nbpool)
+{
+	if (nbpool <= ETH_64_POOLS) {
+		nb_pools = nbpool;
+		printf("Number of VMDq pools set to %u\n", nb_pools);
+	} else {
+		printf("invalid nbpool %u ignored\n", nbpool);
+		return;
+	}
+}
+
+void
 set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt)
 {
 	unsigned int i;
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 28db8cd..5674f94 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -90,7 +90,7 @@ usage(char* progname)
 	       "[--help|-h] | [--auto-start|-a] | ["
 	       "--coremask=COREMASK --portmask=PORTMASK --numa "
 	       "--mbuf-size= | --total-num-mbufs= | "
-	       "--nb-cores= | --nb-ports= | "
+	       "--nb-cores= | --nb-ports= | --nb-pools |"
 #ifdef RTE_LIBRTE_CMDLINE
 	       "--eth-peers-configfile= | "
 	       "--eth-peer=X,M:M:M:M:M:M | "
@@ -196,6 +196,7 @@ usage(char* progname)
 		" or total packet length.\n");
 	printf("  --disable-link-check: disable check on link status when "
 	       "starting/stopping ports.\n");
+	printf("  --nb-pools=N: set the number of VMDq pools (N < 64).\n");
 }
 
 #ifdef RTE_LIBRTE_CMDLINE
@@ -561,6 +562,7 @@ launch_args_parse(int argc, char** argv)
 		{ "no-flush-rx",	0, 0, 0 },
 		{ "txpkts",			1, 0, 0 },
 		{ "disable-link-check",		0, 0, 0 },
+		{ "nb-pools",		1, 0, 0 },
 		{ 0, 0, 0, 0 },
 	};
 
@@ -978,7 +980,14 @@ launch_args_parse(int argc, char** argv)
 				no_flush_rx = 1;
 			if (!strcmp(lgopts[opt_idx].name, "disable-link-check"))
 				no_link_check = 1;
-
+			if (!strcmp(lgopts[opt_idx].name, "nb-pools")) {
+				n = atoi(optarg);
+				if (n <= ETH_64_POOLS)
+					nb_pools = (uint32_t)n;
+				else
+					rte_exit(EXIT_FAILURE,
+						 "Invalid number of pools %d\n", n);
+			}
 			break;
 		case 'h':
 			usage(argv[0]);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index bfb2f8e..ed7d83c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -1888,13 +1888,230 @@ uint8_t port_is_bonding_slave(portid_t slave_pid)
 	return port->slave_flag;
 }
 
+static const struct rte_eth_conf vmdq_conf_default = {
+	.rxmode = {
+		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
+		.split_hdr_size = 0,
+		.header_split   = 0, /**< Header Split disabled */
+		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
+		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
+		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
+	},
+
+	.txmode = {
+		.mq_mode = ETH_MQ_TX_NONE,
+	},
+	.rx_adv_conf = {
+		/*
+		 * should be overridden separately in code with
+		 * appropriate values
+		 */
+		.vmdq_rx_conf = {
+			.nb_queue_pools = ETH_8_POOLS,
+			.enable_default_pool = 0,
+			.default_pool = 0,
+			.nb_pool_maps = 0,
+			.pool_map = {{0, 0},},
+		},
+	},
+};
+
 const uint16_t vlan_tags[] = {
 		0,  1,  2,  3,  4,  5,  6,  7,
 		8,  9, 10, 11,  12, 13, 14, 15,
 		16, 17, 18, 19, 20, 21, 22, 23,
-		24, 25, 26, 27, 28, 29, 30, 31
+		24, 25, 26, 27, 28, 29, 30, 31,
+		32, 33, 34, 35, 36, 37, 38, 39,
+		40, 41, 42, 43, 44, 45, 46, 47,
+		48, 49, 50, 51, 52, 53, 54, 55,
+		56, 57, 58, 59, 60, 61, 62, 63,
+};
+
+const uint16_t num_vlans = RTE_DIM(vlan_tags);
+static uint16_t num_pf_queues, num_vmdq_queues;
+static uint16_t vmdq_pool_base, vmdq_queue_base;
+static uint32_t num_queues;
+/* number of pools (if user does not specify any, 8 by default */
+uint32_t nb_pools = ETH_8_POOLS;
+/* ethernet addresses of ports */
+static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS];
+/* pool mac addr template, pool mac addr is like: 52 54 00 12 port# pool# */
+static struct ether_addr pool_addr_template = {
+	.addr_bytes = {0x52, 0x54, 0x00, 0x12, 0x00, 0x00}
 };
 
+/**
+ * Builds up the correct configuration for vmdq based on the vlan tags array
+ * given above, and determine the queue number and pool map number according to
+ * valid pool number
+ */
+static int
+get_eth_vmdq_conf(struct rte_eth_conf *eth_conf, uint32_t nb_pools)
+{
+	struct rte_eth_vmdq_rx_conf conf;
+	uint8_t i;
+
+	conf.nb_queue_pools = (enum rte_eth_nb_pools)nb_pools;
+	conf.nb_pool_maps = nb_pools;
+	conf.enable_default_pool = 0;
+	conf.default_pool = 0; /* set explicit value, even if not used */
+
+	for (i = 0; i < conf.nb_pool_maps; i++) {
+		conf.pool_map[i].vlan_id = vlan_tags[i];
+		conf.pool_map[i].pools = (1UL << (i % nb_pools));
+	}
+
+	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
+	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
+	       sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
+	return 0;
+}
+
+/**
+ * Configures VMDq for a given port using global settings.
+ */
+int
+init_port_vmdq_config(uint8_t port)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_rxconf *rxconf;
+	struct rte_eth_conf port_conf;
+	struct rte_mempool *mbp;
+	uint16_t rx_queues, tx_queues;
+	const uint16_t rx_queue_size = RTE_TEST_RX_DESC_DEFAULT;
+	const uint16_t tx_queue_size = RTE_TEST_TX_DESC_DEFAULT;
+	int retval;
+	uint16_t q;
+	uint16_t queues_per_pool;
+	uint32_t max_nb_pools;
+
+	if (port >= rte_eth_dev_count())
+		return -1;
+	/**
+	 * The max pool number from dev_info will be used to validate the pool
+	 * number.
+	 */
+	rte_eth_dev_info_get(port, &dev_info);
+	max_nb_pools = (uint32_t)dev_info.max_vmdq_pools;
+	/**
+	 * We allow to process part of VMDQ pools specified by nb_pools in
+	 * command line.
+	 */
+	if (nb_pools > max_nb_pools) {
+		printf("nb_pools %d > max_nb_pools %d\n",
+			nb_pools, max_nb_pools);
+		return -1;
+	}
+
+	retval = get_eth_vmdq_conf(&port_conf, max_nb_pools);
+	if (retval < 0)
+		return retval;
+
+	/*
+	 * NIC queues are divided into pf queues and vmdq queues.
+	 */
+	/* There is assumption here all ports have the same configuration! */
+	num_pf_queues = dev_info.max_rx_queues - dev_info.vmdq_queue_num;
+	queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;
+	num_vmdq_queues = nb_pools * queues_per_pool;
+	num_queues = num_pf_queues + num_vmdq_queues;
+	vmdq_queue_base = dev_info.vmdq_queue_base;
+	vmdq_pool_base  = dev_info.vmdq_pool_base;
+
+	printf("num_pf_queues: %u nb_pools: %u\n", num_pf_queues, nb_pools);
+	printf("each vmdq pool has %u queues\n", queues_per_pool);
+	printf("vmdq_queue_base: %d vmdq_pool_base: %d\n", vmdq_queue_base, vmdq_pool_base);
+
+	/*
+	 * All queues including pf queues are setup.
+	 * This is because VMDQ queues doesn't always start from zero, and the
+	 * PMD layer doesn't support selectively initialising part of rx/tx
+	 * queues.
+	 */
+	rx_queues = (uint16_t)dev_info.max_rx_queues;
+	tx_queues = (uint16_t)dev_info.max_tx_queues;
+	retval = rte_eth_dev_configure(port, rx_queues, tx_queues, &port_conf);
+	if (retval < 0) {
+		printf("rte_eth_dev_configure %d failed\n", retval);
+		return retval;
+	}
+
+	mbp = mbuf_pool_find(0);
+	if (mbp == NULL) {
+		printf("mbuf_pool_find failed\n");
+		return -1;
+	}
+
+	rte_eth_dev_info_get(port, &dev_info);
+	rxconf = &dev_info.default_rxconf;
+	rxconf->rx_drop_en = 1;
+	for (q = 0; q < rx_queues; q++) {
+		retval = rte_eth_rx_queue_setup(port, q, rx_queue_size,
+					rte_eth_dev_socket_id(port),
+					rxconf,
+					mbp);
+		if (retval < 0) {
+			printf("initialise rx queue %d failed\n", q);
+			return retval;
+		}
+	}
+
+	for (q = 0; q < tx_queues; q++) {
+		retval = rte_eth_tx_queue_setup(port, q, tx_queue_size,
+					rte_eth_dev_socket_id(port),
+					NULL);
+		if (retval < 0) {
+			printf("initialise tx queue %d failed\n", q);
+			return retval;
+		}
+	}
+
+	retval  = rte_eth_dev_start(port);
+	if (retval < 0) {
+		printf("rte_eth_dev_start %d failed\n", retval);
+		return retval;
+	}
+	printf("port %d started\n", port);
+
+	rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);
+
+	printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
+			" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
+			(unsigned)port,
+			vmdq_ports_eth_addr[port].addr_bytes[0],
+			vmdq_ports_eth_addr[port].addr_bytes[1],
+			vmdq_ports_eth_addr[port].addr_bytes[2],
+			vmdq_ports_eth_addr[port].addr_bytes[3],
+			vmdq_ports_eth_addr[port].addr_bytes[4],
+			vmdq_ports_eth_addr[port].addr_bytes[5]);
+
+	/*
+	 * Set mac for each pool.
+	 * There is no default mac for the pools in i40.
+	 * Removes this after i40e fixes this issue.
+	 */
+	for (q = 0; q < nb_pools; q++) {
+		struct ether_addr mac;
+
+		mac = pool_addr_template;
+		mac.addr_bytes[4] = port;
+		mac.addr_bytes[5] = q;
+		printf("Port %u vmdq pool %u set mac %02x:%02x:%02x:%02x:%02x:%02x\n",
+			port, q,
+			mac.addr_bytes[0], mac.addr_bytes[1],
+			mac.addr_bytes[2], mac.addr_bytes[3],
+			mac.addr_bytes[4], mac.addr_bytes[5]);
+		retval = rte_eth_dev_mac_addr_add(port, &mac,
+				q + vmdq_pool_base);
+		if (retval) {
+			printf("mac addr add failed at pool %d\n", q);
+			return retval;
+		}
+	}
+
+	return 0;
+}
+
 static  int
 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
 		 enum dcb_mode_enable dcb_mode,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index ee59460..eadb1c2 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -368,6 +368,8 @@ extern queueid_t nb_txq;
 extern uint16_t nb_rxd;
 extern uint16_t nb_txd;
 
+extern uint32_t nb_pools;
+
 extern int16_t rx_free_thresh;
 extern int8_t rx_drop_en;
 extern int16_t tx_free_thresh;
@@ -546,6 +548,8 @@ void set_fwd_ports_mask(uint64_t portmask);
 void set_fwd_ports_number(uint16_t nb_pt);
 int port_is_forwarding(portid_t port_id);
 
+void set_vmdq_pool_number(uint32_t nbpool);
+
 void rx_vlan_strip_set(portid_t port_id, int on);
 void rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on);
 
@@ -582,6 +586,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid);
 int init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode,
 		     enum rte_eth_nb_tcs num_tcs,
 		     uint8_t pfc_en);
+int init_port_vmdq_config(uint8_t port);
 int start_port(portid_t pid);
 void stop_port(portid_t pid);
 void close_port(portid_t pid);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 16ac097..37bf7b1 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -360,6 +360,15 @@ set nbport (num)
 
 This is equivalent to the ``--nb-ports`` command-line option.
 
+set nbpool
+~~~~~~~~~~
+
+Set the number of pools used by the application::
+
+   testpmd> set nbpool (num)
+
+This is equivalent to the ``--nb-pools`` command-line option.
+
 set nbcore
 ~~~~~~~~~~
 
@@ -1438,6 +1447,13 @@ Set the DCB mode for an individual port::
 
 The traffic class should be 4 or 8.
 
+port config - VMDq
+~~~~~~~~~~~~~~~~~~
+
+Configure VMDq for an individual port::
+
+   testpmd> port config (port_id) vmdq
+
 port config - Burst
 ~~~~~~~~~~~~~~~~~~~
 
-- 
2.10.1

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

* [dpdk-dev] [PATCH v5 3/3] app/testpmd: fix port stop
  2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 " Bernard Iremonger
                       ` (2 preceding siblings ...)
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 2/3] app/testpmd: add command to configure VMDq Bernard Iremonger
@ 2017-01-25 14:36     ` Bernard Iremonger
  3 siblings, 0 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-25 14:36 UTC (permalink / raw)
  To: dev, wenzhuo.lu, jingjing.wu; +Cc: Bernard Iremonger

The rte_eth_dev_stop function is not called if the port_status is
not RTE_PORT_STARTED. This can happen if the rte_eth_dev_start
function is called directly, ie not through the start_port function.

Make sure rte_eth_dev_stop is always called in stop_port function.

Fixes: ce8d561418d4 ("app/testpmd: add port configuration settings")
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/testpmd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index ed7d83c..2d0ca3f 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1490,13 +1490,13 @@ stop_port(portid_t pid)
 			continue;
 		}
 
+		rte_eth_dev_stop(pi);
+
 		port = &ports[pi];
 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
 						RTE_PORT_HANDLING) == 0)
 			continue;
 
-		rte_eth_dev_stop(pi);
-
 		if (rte_atomic16_cmpset(&(port->port_status),
 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
 			printf("Port %d can not be set into stopped\n", pi);
-- 
2.10.1

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

* [dpdk-dev] [PATCH v6 0/2] app/testpmd: enable VMDq in testpmd
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 0/3] " Bernard Iremonger
@ 2017-01-27 10:49       ` Bernard Iremonger
  2017-01-27 10:49       ` [dpdk-dev] [PATCH v6 1/2] app/testpmd: add command to configure VMDq Bernard Iremonger
  2017-01-27 10:50       ` [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop Bernard Iremonger
  2 siblings, 0 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-27 10:49 UTC (permalink / raw)
  To: dev, jingjing.wu; +Cc: Bernard Iremonger

Changes in v6:
Rebased to latest dpdk-next-net
Removed i40e patch from this patchset and sent it as a standalone patch.
Fixed checkpatch warning in testpmd.c.

Changes in v5:
Rebase to latest dpdk-next-net
Reworked init_port_vmdq_config() function in testpmd.
Added patch 3, fix to  stop_port() function in testpmd.

Changes in v4:
Rebase to latest dpdk-next-net
Replaced I40E_ERR_BAD_PTR with -EFAULT.

Changes in v3
Fix checkpatch  warning in testpmd.c
Tidy debug code in testpmd.c

Changes in v2:
These two patches were previously part of the following patchset:
[PATCH v7 00/27] Support VFD on i40e

They are being submitted seperately as they are not needed for VFD.
The net/i40e patch has been revised.
The testpmd patch is needed to setup VMDq in order to test the fix.

Bernard Iremonger (2):
  app/testpmd: add command to configure VMDq
  app/testpmd: fix port stop

 app/test-pmd/cmdline.c                      |  72 ++++++++-
 app/test-pmd/config.c                       |  14 +-
 app/test-pmd/parameters.c                   |  15 +-
 app/test-pmd/testpmd.c                      | 224 +++++++++++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   7 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  18 ++-
 6 files changed, 336 insertions(+), 14 deletions(-)

-- 
2.10.1

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

* [dpdk-dev] [PATCH v6 1/2] app/testpmd: add command to configure VMDq
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 0/3] " Bernard Iremonger
  2017-01-27 10:49       ` [dpdk-dev] [PATCH v6 0/2] app/testpmd: enable VMDq in testpmd Bernard Iremonger
@ 2017-01-27 10:49       ` Bernard Iremonger
  2017-01-27 10:50       ` [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop Bernard Iremonger
  2 siblings, 0 replies; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-27 10:49 UTC (permalink / raw)
  To: dev, jingjing.wu; +Cc: Bernard Iremonger

Add the following command to configure VMDq:
port config <port> vmdq

Add the following command to set number of pools:
set nbpool <N>

Add new commands to testpmd user guide.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      |  72 ++++++++-
 app/test-pmd/config.c                       |  14 +-
 app/test-pmd/parameters.c                   |  15 +-
 app/test-pmd/testpmd.c                      | 220 +++++++++++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   7 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  18 ++-
 6 files changed, 334 insertions(+), 12 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 2fd862f..f017833 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  *
@@ -238,6 +238,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set nbcore (num)\n"
 			"    Set number of cores.\n\n"
 
+			"set nbpool (num)\n"
+			"    Set number of VMDq pools.\n\n"
+
 			"set coremask (mask)\n"
 			"    Set the forwarding cores hexadecimal mask.\n\n"
 
@@ -629,6 +632,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" pfc (on|off)\n"
 			"    Set the DCB mode.\n\n"
 
+			"port config (port_id) vmdq\n"
+			"    Configure VMDq for a port.\n\n"
+
 			"port config all burst (value)\n"
 			"    Set the number of packets per burst.\n\n"
 
@@ -2322,6 +2328,61 @@ cmdline_parse_inst_t cmd_config_dcb = {
         },
 };
 
+/* *** Configure VMDq *** */
+struct cmd_config_vmdq {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t vmdq;
+};
+
+static void
+cmd_config_vmdq_parsed(void *parsed_result,
+		       __attribute__((unused)) struct cmdline *cl,
+		       __attribute__((unused)) void *data)
+{
+	struct cmd_config_vmdq *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_port *port;
+	int ret;
+
+	port = &ports[port_id];
+	/** Check if the port is not started **/
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Please stop port %d first\n", port_id);
+		return;
+	}
+
+	ret = init_port_vmdq_config(port_id);
+	if (ret != 0) {
+		printf("Cannot configure VMDQ for port %d.\n", port_id);
+		return;
+	}
+	cmd_reconfig_device_queue(port_id, 0, 0);
+}
+
+cmdline_parse_token_string_t cmd_config_vmdq_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, port, "port");
+cmdline_parse_token_string_t cmd_config_vmdq_config =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, config, "config");
+cmdline_parse_token_num_t cmd_config_vmdq_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_vmdq, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_vmdq_vmdq =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, vmdq, "vmdq");
+
+cmdline_parse_inst_t cmd_config_vmdq = {
+	.f = cmd_config_vmdq_parsed,
+	.data = NULL,
+	.help_str = "port config <port-id> vmdq",
+	.tokens = {
+		(void *)&cmd_config_vmdq_port,
+		(void *)&cmd_config_vmdq_config,
+		(void *)&cmd_config_vmdq_port_id,
+		(void *)&cmd_config_vmdq_vmdq,
+		NULL,
+	},
+};
+
 /* *** configure number of packets per burst *** */
 struct cmd_config_burst {
 	cmdline_fixed_string_t port;
@@ -2722,7 +2783,7 @@ cmdline_parse_inst_t cmd_set_fwd_mask = {
 };
 
 /*
- * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
+ * SET NBPORT, NBCORE, NBPOOL, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
  */
 struct cmd_set_result {
 	cmdline_fixed_string_t set;
@@ -2741,6 +2802,8 @@ static void cmd_set_parsed(void *parsed_result,
 	} else if (!strcmp(res->what, "nbcore")) {
 		set_fwd_lcores_number(res->value);
 		fwd_config_setup();
+	} else if (!strcmp(res->what, "nbpool")) {
+		set_vmdq_pool_number(res->value);
 	} else if (!strcmp(res->what, "burst"))
 		set_nb_pkt_per_burst(res->value);
 	else if (!strcmp(res->what, "verbose"))
@@ -2751,14 +2814,14 @@ cmdline_parse_token_string_t cmd_set_set =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
 cmdline_parse_token_string_t cmd_set_what =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
-				 "nbport#nbcore#burst#verbose");
+				 "nbport#nbcore#nbpool#burst#verbose");
 cmdline_parse_token_num_t cmd_set_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
 
 cmdline_parse_inst_t cmd_set_numbers = {
 	.f = cmd_set_parsed,
 	.data = NULL,
-	.help_str = "set nbport|nbcore|burst|verbose <value>",
+	.help_str = "set nbport|nbcore|nbpool|burst|verbose <value>",
 	.tokens = {
 		(void *)&cmd_set_set,
 		(void *)&cmd_set_what,
@@ -12462,6 +12525,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
 	(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
 	(cmdline_parse_inst_t *)&cmd_config_dcb,
+	(cmdline_parse_inst_t *)&cmd_config_vmdq,
 	(cmdline_parse_inst_t *)&cmd_read_reg,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
 	(cmdline_parse_inst_t *)&cmd_read_reg_bit,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 5834498..2df501f 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -2063,6 +2063,18 @@ set_fwd_lcores_number(uint16_t nb_lc)
 }
 
 void
+set_vmdq_pool_number(uint32_t nbpool)
+{
+	if (nbpool <= ETH_64_POOLS) {
+		nb_pools = nbpool;
+		printf("Number of VMDq pools set to %u\n", nb_pools);
+	} else {
+		printf("invalid nbpool %u ignored\n", nbpool);
+		return;
+	}
+}
+
+void
 set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt)
 {
 	unsigned int i;
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 28db8cd..5674f94 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -90,7 +90,7 @@ usage(char* progname)
 	       "[--help|-h] | [--auto-start|-a] | ["
 	       "--coremask=COREMASK --portmask=PORTMASK --numa "
 	       "--mbuf-size= | --total-num-mbufs= | "
-	       "--nb-cores= | --nb-ports= | "
+	       "--nb-cores= | --nb-ports= | --nb-pools |"
 #ifdef RTE_LIBRTE_CMDLINE
 	       "--eth-peers-configfile= | "
 	       "--eth-peer=X,M:M:M:M:M:M | "
@@ -196,6 +196,7 @@ usage(char* progname)
 		" or total packet length.\n");
 	printf("  --disable-link-check: disable check on link status when "
 	       "starting/stopping ports.\n");
+	printf("  --nb-pools=N: set the number of VMDq pools (N < 64).\n");
 }
 
 #ifdef RTE_LIBRTE_CMDLINE
@@ -561,6 +562,7 @@ launch_args_parse(int argc, char** argv)
 		{ "no-flush-rx",	0, 0, 0 },
 		{ "txpkts",			1, 0, 0 },
 		{ "disable-link-check",		0, 0, 0 },
+		{ "nb-pools",		1, 0, 0 },
 		{ 0, 0, 0, 0 },
 	};
 
@@ -978,7 +980,14 @@ launch_args_parse(int argc, char** argv)
 				no_flush_rx = 1;
 			if (!strcmp(lgopts[opt_idx].name, "disable-link-check"))
 				no_link_check = 1;
-
+			if (!strcmp(lgopts[opt_idx].name, "nb-pools")) {
+				n = atoi(optarg);
+				if (n <= ETH_64_POOLS)
+					nb_pools = (uint32_t)n;
+				else
+					rte_exit(EXIT_FAILURE,
+						 "Invalid number of pools %d\n", n);
+			}
 			break;
 		case 'h':
 			usage(argv[0]);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index bfb2f8e..3d25436 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -1888,13 +1888,229 @@ uint8_t port_is_bonding_slave(portid_t slave_pid)
 	return port->slave_flag;
 }
 
+static const struct rte_eth_conf vmdq_conf_default = {
+	.rxmode = {
+		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
+		.split_hdr_size = 0,
+		.header_split   = 0, /**< Header Split disabled */
+		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
+		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
+		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
+	},
+
+	.txmode = {
+		.mq_mode = ETH_MQ_TX_NONE,
+	},
+	.rx_adv_conf = {
+		/*
+		 * should be overridden separately in code with
+		 * appropriate values
+		 */
+		.vmdq_rx_conf = {
+			.nb_queue_pools = ETH_8_POOLS,
+			.enable_default_pool = 0,
+			.default_pool = 0,
+			.nb_pool_maps = 0,
+			.pool_map = {{0, 0},},
+		},
+	},
+};
+
 const uint16_t vlan_tags[] = {
 		0,  1,  2,  3,  4,  5,  6,  7,
 		8,  9, 10, 11,  12, 13, 14, 15,
 		16, 17, 18, 19, 20, 21, 22, 23,
-		24, 25, 26, 27, 28, 29, 30, 31
+		24, 25, 26, 27, 28, 29, 30, 31,
+		32, 33, 34, 35, 36, 37, 38, 39,
+		40, 41, 42, 43, 44, 45, 46, 47,
+		48, 49, 50, 51, 52, 53, 54, 55,
+		56, 57, 58, 59, 60, 61, 62, 63,
+};
+
+const uint16_t num_vlans = RTE_DIM(vlan_tags);
+static uint16_t num_pf_queues, num_vmdq_queues;
+static uint16_t vmdq_pool_base, vmdq_queue_base;
+static uint32_t num_queues;
+/* number of pools (if user does not specify any, 8 by default */
+uint32_t nb_pools = ETH_8_POOLS;
+/* ethernet addresses of ports */
+static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS];
+/* pool mac addr template, pool mac addr is like: 52 54 00 12 port# pool# */
+static struct ether_addr pool_addr_template = {
+	.addr_bytes = {0x52, 0x54, 0x00, 0x12, 0x00, 0x00}
 };
 
+/**
+ * Builds up the correct configuration for vmdq based on the vlan tags array
+ * given above, and determine the queue number and pool map number according to
+ * valid pool number
+ */
+static int
+get_eth_vmdq_conf(struct rte_eth_conf *eth_conf, uint32_t nb_pools)
+{
+	struct rte_eth_vmdq_rx_conf conf;
+	uint8_t i;
+
+	conf.nb_queue_pools = (enum rte_eth_nb_pools)nb_pools;
+	conf.nb_pool_maps = nb_pools;
+	conf.enable_default_pool = 0;
+	conf.default_pool = 0; /* set explicit value, even if not used */
+
+	for (i = 0; i < conf.nb_pool_maps; i++) {
+		conf.pool_map[i].vlan_id = vlan_tags[i];
+		conf.pool_map[i].pools = (1UL << (i % nb_pools));
+	}
+
+	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
+	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
+	       sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
+	return 0;
+}
+
+/**
+ * Configures VMDq for a given port using global settings.
+ */
+int
+init_port_vmdq_config(uint8_t port)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_rxconf *rxconf;
+	struct rte_eth_conf port_conf;
+	struct rte_mempool *mbp;
+	uint16_t rx_queues, tx_queues;
+	const uint16_t rx_queue_size = RTE_TEST_RX_DESC_DEFAULT;
+	const uint16_t tx_queue_size = RTE_TEST_TX_DESC_DEFAULT;
+	int retval;
+	uint16_t q;
+	uint16_t queues_per_pool;
+	uint32_t max_nb_pools;
+
+	if (port >= rte_eth_dev_count())
+		return -1;
+	/**
+	 * The max pool number from dev_info will be used to validate the pool
+	 * number.
+	 */
+	rte_eth_dev_info_get(port, &dev_info);
+	max_nb_pools = (uint32_t)dev_info.max_vmdq_pools;
+	/**
+	 * We allow to process part of VMDQ pools specified by nb_pools in
+	 * command line.
+	 */
+	if (nb_pools > max_nb_pools) {
+		printf("nb_pools %d > max_nb_pools %d\n",
+			nb_pools, max_nb_pools);
+		return -1;
+	}
+
+	retval = get_eth_vmdq_conf(&port_conf, max_nb_pools);
+	if (retval < 0)
+		return retval;
+
+	/*
+	 * NIC queues are divided into pf queues and vmdq queues.
+	 */
+	/* There is assumption here all ports have the same configuration! */
+	num_pf_queues = dev_info.max_rx_queues - dev_info.vmdq_queue_num;
+	queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;
+	num_vmdq_queues = nb_pools * queues_per_pool;
+	num_queues = num_pf_queues + num_vmdq_queues;
+	vmdq_queue_base = dev_info.vmdq_queue_base;
+	vmdq_pool_base  = dev_info.vmdq_pool_base;
+
+	printf("num_pf_queues: %u nb_pools: %u\n", num_pf_queues, nb_pools);
+	printf("each vmdq pool has %u queues\n", queues_per_pool);
+	printf("vmdq_queue_base: %d vmdq_pool_base: %d\n", vmdq_queue_base, vmdq_pool_base);
+
+	/*
+	 * All queues including pf queues are setup.
+	 * This is because VMDQ queues doesn't always start from zero, and the
+	 * PMD layer doesn't support selectively initialising part of rx/tx
+	 * queues.
+	 */
+	rx_queues = (uint16_t)dev_info.max_rx_queues;
+	tx_queues = (uint16_t)dev_info.max_tx_queues;
+	retval = rte_eth_dev_configure(port, rx_queues, tx_queues, &port_conf);
+	if (retval < 0) {
+		printf("rte_eth_dev_configure %d failed\n", retval);
+		return retval;
+	}
+
+	mbp = mbuf_pool_find(0);
+	if (mbp == NULL) {
+		printf("mbuf_pool_find failed\n");
+		return -1;
+	}
+
+	rte_eth_dev_info_get(port, &dev_info);
+	rxconf = &dev_info.default_rxconf;
+	rxconf->rx_drop_en = 1;
+	for (q = 0; q < rx_queues; q++) {
+		retval = rte_eth_rx_queue_setup(port, q, rx_queue_size,
+					rte_eth_dev_socket_id(port),
+					rxconf,
+					mbp);
+		if (retval < 0) {
+			printf("initialise rx queue %d failed\n", q);
+			return retval;
+		}
+	}
+
+	for (q = 0; q < tx_queues; q++) {
+		retval = rte_eth_tx_queue_setup(port, q, tx_queue_size,
+					rte_eth_dev_socket_id(port),
+					NULL);
+		if (retval < 0) {
+			printf("initialise tx queue %d failed\n", q);
+			return retval;
+		}
+	}
+
+	retval  = rte_eth_dev_start(port);
+	if (retval < 0) {
+		printf("rte_eth_dev_start %d failed\n", retval);
+		return retval;
+	}
+	printf("port %d started\n", port);
+
+	rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);
+
+	printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
+			" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", port,
+			vmdq_ports_eth_addr[port].addr_bytes[0],
+			vmdq_ports_eth_addr[port].addr_bytes[1],
+			vmdq_ports_eth_addr[port].addr_bytes[2],
+			vmdq_ports_eth_addr[port].addr_bytes[3],
+			vmdq_ports_eth_addr[port].addr_bytes[4],
+			vmdq_ports_eth_addr[port].addr_bytes[5]);
+
+	/*
+	 * Set mac for each pool.
+	 * There is no default mac for the pools in i40.
+	 * Removes this after i40e fixes this issue.
+	 */
+	for (q = 0; q < nb_pools; q++) {
+		struct ether_addr mac;
+
+		mac = pool_addr_template;
+		mac.addr_bytes[4] = port;
+		mac.addr_bytes[5] = q;
+		printf("Port %u vmdq pool %u set mac %02x:%02x:%02x:%02x:%02x:%02x\n",
+			port, q,
+			mac.addr_bytes[0], mac.addr_bytes[1],
+			mac.addr_bytes[2], mac.addr_bytes[3],
+			mac.addr_bytes[4], mac.addr_bytes[5]);
+		retval = rte_eth_dev_mac_addr_add(port, &mac,
+				q + vmdq_pool_base);
+		if (retval) {
+			printf("mac addr add failed at pool %d\n", q);
+			return retval;
+		}
+	}
+
+	return 0;
+}
+
 static  int
 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
 		 enum dcb_mode_enable dcb_mode,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index ee59460..eadb1c2 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -368,6 +368,8 @@ extern queueid_t nb_txq;
 extern uint16_t nb_rxd;
 extern uint16_t nb_txd;
 
+extern uint32_t nb_pools;
+
 extern int16_t rx_free_thresh;
 extern int8_t rx_drop_en;
 extern int16_t tx_free_thresh;
@@ -546,6 +548,8 @@ void set_fwd_ports_mask(uint64_t portmask);
 void set_fwd_ports_number(uint16_t nb_pt);
 int port_is_forwarding(portid_t port_id);
 
+void set_vmdq_pool_number(uint32_t nbpool);
+
 void rx_vlan_strip_set(portid_t port_id, int on);
 void rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on);
 
@@ -582,6 +586,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid);
 int init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode,
 		     enum rte_eth_nb_tcs num_tcs,
 		     uint8_t pfc_en);
+int init_port_vmdq_config(uint8_t port);
 int start_port(portid_t pid);
 void stop_port(portid_t pid);
 void close_port(portid_t pid);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 16ac097..37bf7b1 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -360,6 +360,15 @@ set nbport (num)
 
 This is equivalent to the ``--nb-ports`` command-line option.
 
+set nbpool
+~~~~~~~~~~
+
+Set the number of pools used by the application::
+
+   testpmd> set nbpool (num)
+
+This is equivalent to the ``--nb-pools`` command-line option.
+
 set nbcore
 ~~~~~~~~~~
 
@@ -1438,6 +1447,13 @@ Set the DCB mode for an individual port::
 
 The traffic class should be 4 or 8.
 
+port config - VMDq
+~~~~~~~~~~~~~~~~~~
+
+Configure VMDq for an individual port::
+
+   testpmd> port config (port_id) vmdq
+
 port config - Burst
 ~~~~~~~~~~~~~~~~~~~
 
-- 
2.10.1

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

* [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop
  2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 0/3] " Bernard Iremonger
  2017-01-27 10:49       ` [dpdk-dev] [PATCH v6 0/2] app/testpmd: enable VMDq in testpmd Bernard Iremonger
  2017-01-27 10:49       ` [dpdk-dev] [PATCH v6 1/2] app/testpmd: add command to configure VMDq Bernard Iremonger
@ 2017-01-27 10:50       ` Bernard Iremonger
  2017-02-03  8:21         ` Wu, Jingjing
  2 siblings, 1 reply; 27+ messages in thread
From: Bernard Iremonger @ 2017-01-27 10:50 UTC (permalink / raw)
  To: dev, jingjing.wu; +Cc: Bernard Iremonger, stable

The rte_eth_dev_stop function is not called if the port_status is
not RTE_PORT_STARTED. This can happen if the rte_eth_dev_start
function is called directly, ie not through the start_port function.

Make sure rte_eth_dev_stop is always called in stop_port function.

Fixes: ce8d561418d4 ("app/testpmd: add port configuration settings")

CC: stable@dpdk.org
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/testpmd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 3d25436..0d7a4d4 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1490,13 +1490,13 @@ stop_port(portid_t pid)
 			continue;
 		}
 
+		rte_eth_dev_stop(pi);
+
 		port = &ports[pi];
 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
 						RTE_PORT_HANDLING) == 0)
 			continue;
 
-		rte_eth_dev_stop(pi);
-
 		if (rte_atomic16_cmpset(&(port->port_status),
 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
 			printf("Port %d can not be set into stopped\n", pi);
-- 
2.10.1

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

* Re: [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop
  2017-01-27 10:50       ` [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop Bernard Iremonger
@ 2017-02-03  8:21         ` Wu, Jingjing
  2017-02-03 10:37           ` Iremonger, Bernard
  0 siblings, 1 reply; 27+ messages in thread
From: Wu, Jingjing @ 2017-02-03  8:21 UTC (permalink / raw)
  To: Iremonger, Bernard, dev; +Cc: stable



> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Friday, January 27, 2017 6:50 PM
> To: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; stable@dpdk.org
> Subject: [PATCH v6 2/2] app/testpmd: fix port stop
> 
> The rte_eth_dev_stop function is not called if the port_status is not
> RTE_PORT_STARTED. This can happen if the rte_eth_dev_start function is
> called directly, ie not through the start_port function.
> 
> Make sure rte_eth_dev_stop is always called in stop_port function.
> 
> Fixes: ce8d561418d4 ("app/testpmd: add port configuration settings")
> 
> CC: stable@dpdk.org
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> ---
>  app/test-pmd/testpmd.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index
> 3d25436..0d7a4d4 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -1490,13 +1490,13 @@ stop_port(portid_t pid)
>  			continue;
>  		}
> 
> +		rte_eth_dev_stop(pi);
> +
>  		port = &ports[pi];
>  		if (rte_atomic16_cmpset(&(port->port_status),
> RTE_PORT_STARTED,
>  						RTE_PORT_HANDLING) == 0)
>  			continue;
> 
> -		rte_eth_dev_stop(pi);
> -

I don't think this fix is correct to move rte_eth_dev_stop above.

We need to make sure rte_eth_dev_start is called in start_port. For vmdq configuration,
You just need to change the configuration when port is stopped.

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

* Re: [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop
  2017-02-03  8:21         ` Wu, Jingjing
@ 2017-02-03 10:37           ` Iremonger, Bernard
  2017-02-12  4:34             ` Wu, Jingjing
  0 siblings, 1 reply; 27+ messages in thread
From: Iremonger, Bernard @ 2017-02-03 10:37 UTC (permalink / raw)
  To: Wu, Jingjing, dev; +Cc: stable

Hi Jingjing

> -----Original Message-----
> From: Wu, Jingjing
> Sent: Friday, February 3, 2017 8:22 AM
> To: Iremonger, Bernard <bernard.iremonger@intel.com>; dev@dpdk.org
> Cc: stable@dpdk.org
> Subject: RE: [PATCH v6 2/2] app/testpmd: fix port stop
> 
> 
> 
> > -----Original Message-----
> > From: Iremonger, Bernard
> > Sent: Friday, January 27, 2017 6:50 PM
> > To: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>
> > Cc: Iremonger, Bernard <bernard.iremonger@intel.com>;
> stable@dpdk.org
> > Subject: [PATCH v6 2/2] app/testpmd: fix port stop
> >
> > The rte_eth_dev_stop function is not called if the port_status is not
> > RTE_PORT_STARTED. This can happen if the rte_eth_dev_start function is
> > called directly, ie not through the start_port function.
> >
> > Make sure rte_eth_dev_stop is always called in stop_port function.
> >
> > Fixes: ce8d561418d4 ("app/testpmd: add port configuration settings")
> >
> > CC: stable@dpdk.org
> > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > ---
> >  app/test-pmd/testpmd.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index
> > 3d25436..0d7a4d4 100644
> > --- a/app/test-pmd/testpmd.c
> > +++ b/app/test-pmd/testpmd.c
> > @@ -1490,13 +1490,13 @@ stop_port(portid_t pid)
> >  			continue;
> >  		}
> >
> > +		rte_eth_dev_stop(pi);
> > +
> >  		port = &ports[pi];
> >  		if (rte_atomic16_cmpset(&(port->port_status),
> > RTE_PORT_STARTED,
> >  						RTE_PORT_HANDLING) == 0)
> >  			continue;
> >
> > -		rte_eth_dev_stop(pi);
> > -
> 
> I don't think this fix is correct to move rte_eth_dev_stop above.
> 
> We need to make sure rte_eth_dev_start is called in start_port. For vmdq
> configuration, You just need to change the configuration when port is
> stopped.

I think the stop_port() function should always stop the port even if the port_status is not correct for any reason.
At present stop_port() returns without stopping the port if the port_status is not RTE_PORT_STARTED.

The VMDq configuration is done whet the port is stopped, however to the complete the VMDq configuration the port must be started.

Regards,

Bernard.

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

* Re: [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop
  2017-02-03 10:37           ` Iremonger, Bernard
@ 2017-02-12  4:34             ` Wu, Jingjing
  2017-03-10 13:17               ` Thomas Monjalon
  0 siblings, 1 reply; 27+ messages in thread
From: Wu, Jingjing @ 2017-02-12  4:34 UTC (permalink / raw)
  To: Iremonger, Bernard, dev; +Cc: stable



> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Friday, February 3, 2017 6:38 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; dev@dpdk.org
> Cc: stable@dpdk.org
> Subject: RE: [PATCH v6 2/2] app/testpmd: fix port stop
> 
> Hi Jingjing
> 
> > -----Original Message-----
> > From: Wu, Jingjing
> > Sent: Friday, February 3, 2017 8:22 AM
> > To: Iremonger, Bernard <bernard.iremonger@intel.com>; dev@dpdk.org
> > Cc: stable@dpdk.org
> > Subject: RE: [PATCH v6 2/2] app/testpmd: fix port stop
> >
> >
> >
> > > -----Original Message-----
> > > From: Iremonger, Bernard
> > > Sent: Friday, January 27, 2017 6:50 PM
> > > To: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>
> > > Cc: Iremonger, Bernard <bernard.iremonger@intel.com>;
> > stable@dpdk.org
> > > Subject: [PATCH v6 2/2] app/testpmd: fix port stop
> > >
> > > The rte_eth_dev_stop function is not called if the port_status is
> > > not RTE_PORT_STARTED. This can happen if the rte_eth_dev_start
> > > function is called directly, ie not through the start_port function.
> > >
> > > Make sure rte_eth_dev_stop is always called in stop_port function.
> > >
> > > Fixes: ce8d561418d4 ("app/testpmd: add port configuration settings")
> > >
> > > CC: stable@dpdk.org
> > > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > > ---
> > >  app/test-pmd/testpmd.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index
> > > 3d25436..0d7a4d4 100644
> > > --- a/app/test-pmd/testpmd.c
> > > +++ b/app/test-pmd/testpmd.c
> > > @@ -1490,13 +1490,13 @@ stop_port(portid_t pid)
> > >  			continue;
> > >  		}
> > >
> > > +		rte_eth_dev_stop(pi);
> > > +
> > >  		port = &ports[pi];
> > >  		if (rte_atomic16_cmpset(&(port->port_status),
> > > RTE_PORT_STARTED,
> > >  						RTE_PORT_HANDLING) == 0)
> > >  			continue;
> > >
> > > -		rte_eth_dev_stop(pi);
> > > -
> >
> > I don't think this fix is correct to move rte_eth_dev_stop above.
> >
> > We need to make sure rte_eth_dev_start is called in start_port. For
> > vmdq configuration, You just need to change the configuration when
> > port is stopped.
> 
> I think the stop_port() function should always stop the port even if the
> port_status is not correct for any reason.
> At present stop_port() returns without stopping the port if the port_status is not
> RTE_PORT_STARTED.
>
This is testpmd's design. If you think it is an issue, maybe you need to prepare patch to optimize it. But for VMDQ configuration, I'd like to make it independent but not mixed.
 
> The VMDq configuration is done whet the port is stopped, however to the
> complete the VMDq configuration the port must be started.
> 

To change minor, we can stop port, then configure VMDQ and then start port.

You make port started in VMDQ config, the Symmetry of stop/start command is broken and it is not easy to maintain.

> Regards,
> 
> Bernard.

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

* Re: [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop
  2017-02-12  4:34             ` Wu, Jingjing
@ 2017-03-10 13:17               ` Thomas Monjalon
  2017-03-10 16:56                 ` Wu, Jingjing
  0 siblings, 1 reply; 27+ messages in thread
From: Thomas Monjalon @ 2017-03-10 13:17 UTC (permalink / raw)
  To: Wu, Jingjing, Iremonger, Bernard; +Cc: dev

2017-02-12 04:34, Wu, Jingjing:
> > > > --- a/app/test-pmd/testpmd.c
> > > > +++ b/app/test-pmd/testpmd.c
> > > > @@ -1490,13 +1490,13 @@ stop_port(portid_t pid)
> > > >  			continue;
> > > >  		}
> > > >
> > > > +		rte_eth_dev_stop(pi);
> > > > +
> > > >  		port = &ports[pi];
> > > >  		if (rte_atomic16_cmpset(&(port->port_status),
> > > > RTE_PORT_STARTED,
> > > >  						RTE_PORT_HANDLING) == 0)
> > > >  			continue;
> > > >
> > > > -		rte_eth_dev_stop(pi);
> > > > -
> > >
> > > I don't think this fix is correct to move rte_eth_dev_stop above.
> > >
> > > We need to make sure rte_eth_dev_start is called in start_port. For
> > > vmdq configuration, You just need to change the configuration when
> > > port is stopped.
> > 
> > I think the stop_port() function should always stop the port even if the
> > port_status is not correct for any reason.
> > At present stop_port() returns without stopping the port if the port_status is not
> > RTE_PORT_STARTED.
> >
> This is testpmd's design. If you think it is an issue, maybe you need to prepare patch to optimize it. But for VMDQ configuration, I'd like to make it independent but not mixed.
>  
> > The VMDq configuration is done whet the port is stopped, however to the
> > complete the VMDq configuration the port must be started.
> > 
> 
> To change minor, we can stop port, then configure VMDQ and then start port.
> 
> You make port started in VMDQ config, the Symmetry of stop/start command is broken and it is not easy to maintain.

Should we close this patch in patchwork?

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

* Re: [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop
  2017-03-10 13:17               ` Thomas Monjalon
@ 2017-03-10 16:56                 ` Wu, Jingjing
  2017-03-10 16:59                   ` Iremonger, Bernard
  0 siblings, 1 reply; 27+ messages in thread
From: Wu, Jingjing @ 2017-03-10 16:56 UTC (permalink / raw)
  To: Thomas Monjalon, Iremonger, Bernard; +Cc: dev

> > To change minor, we can stop port, then configure VMDQ and then start port.
> >
> > You make port started in VMDQ config, the Symmetry of stop/start command
> is broken and it is not easy to maintain.
> 
> Should we close this patch in patchwork?

Yes, I think so.

Thanks
Jingjing

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

* Re: [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop
  2017-03-10 16:56                 ` Wu, Jingjing
@ 2017-03-10 16:59                   ` Iremonger, Bernard
  0 siblings, 0 replies; 27+ messages in thread
From: Iremonger, Bernard @ 2017-03-10 16:59 UTC (permalink / raw)
  To: Wu, Jingjing, Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Friday, March 10, 2017 4:56 PM
> To: Thomas Monjalon <thomas.monjalon@6wind.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop
> 
> > > To change minor, we can stop port, then configure VMDQ and then start
> port.
> > >
> > > You make port started in VMDQ config, the Symmetry of stop/start
> command
> > is broken and it is not easy to maintain.
> >
> > Should we close this patch in patchwork?
> 
> Yes, I think so.
> 
> Thanks
> Jingjing

Agreed.

Regards,

Bernard.

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

end of thread, other threads:[~2017-03-10 16:59 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-09 16:29 [dpdk-dev] [PATCH v2 0/2] net/i40e: fix segmentation fault Bernard Iremonger
2017-01-09 16:29 ` [dpdk-dev] [PATCH v2 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
2017-01-09 16:29 ` [dpdk-dev] [PATCH v2 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: fix segmentation fault Bernard Iremonger
2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 " Bernard Iremonger
2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 0/3] " Bernard Iremonger
2017-01-27 10:49       ` [dpdk-dev] [PATCH v6 0/2] app/testpmd: enable VMDq in testpmd Bernard Iremonger
2017-01-27 10:49       ` [dpdk-dev] [PATCH v6 1/2] app/testpmd: add command to configure VMDq Bernard Iremonger
2017-01-27 10:50       ` [dpdk-dev] [PATCH v6 2/2] app/testpmd: fix port stop Bernard Iremonger
2017-02-03  8:21         ` Wu, Jingjing
2017-02-03 10:37           ` Iremonger, Bernard
2017-02-12  4:34             ` Wu, Jingjing
2017-03-10 13:17               ` Thomas Monjalon
2017-03-10 16:56                 ` Wu, Jingjing
2017-03-10 16:59                   ` Iremonger, Bernard
2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 1/3] net/i40e: fix segmentation fault in close Bernard Iremonger
2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 2/3] app/testpmd: add command to configure VMDq Bernard Iremonger
2017-01-25 14:36     ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: fix port stop Bernard Iremonger
2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
2017-01-20 13:15     ` Wu, Jingjing
2017-01-17 16:39   ` [dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger
2017-01-20 13:33     ` Wu, Jingjing
2017-01-20 15:22       ` Iremonger, Bernard
2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 1/2] net/i40e: fix segmentation fault in close Bernard Iremonger
2017-01-17 14:34   ` Wu, Jingjing
2017-01-17 16:30     ` Iremonger, Bernard
2017-01-12 13:58 ` [dpdk-dev] [PATCH v3 2/2] app/testpmd: add command to configure VMDq Bernard Iremonger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).