From patchwork Tue Jan 17 16:39:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iremonger, Bernard" X-Patchwork-Id: 19630 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 0D0FA2E8B; Tue, 17 Jan 2017 17:39:54 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id C954E1094 for ; Tue, 17 Jan 2017 17:39:33 +0100 (CET) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP; 17 Jan 2017 08:39:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,245,1477983600"; d="scan'208";a="54311282" Received: from sivswdev01.ir.intel.com (HELO localhost.localdomain) ([10.237.217.45]) by fmsmga005.fm.intel.com with ESMTP; 17 Jan 2017 08:39:32 -0800 From: Bernard Iremonger To: dev@dpdk.org, wenzhuo.lu@intel.com, jingjing.wu@intel.com, helin.zhang@intel.com Cc: Bernard Iremonger Date: Tue, 17 Jan 2017 16:39:22 +0000 Message-Id: <1484671162-18493-3-git-send-email-bernard.iremonger@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1484229492-18902-1-git-send-email-bernard.iremonger@intel.com> References: <1484229492-18902-1-git-send-email-bernard.iremonger@intel.com> Subject: [dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add the following command to configure VMDq: port config vmdq Add new command to testpmd user guide. Signed-off-by: Bernard Iremonger --- 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 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. + */ + 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 ~~~~~~~~~~~~~~~~~~~