> -----Original Message----- > From: Iremonger, Bernard > Sent: Wednesday, January 18, 2017 12:39 AM > To: dev@dpdk.org; Lu, Wenzhuo <wenzhuo...@intel.com>; Wu, Jingjing > <jingjing...@intel.com>; Zhang, Helin <helin.zh...@intel.com> > Cc: Iremonger, Bernard <bernard.iremon...@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.iremon...@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(ð_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