From patchwork Tue Jan 5 12:31:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Wang X-Patchwork-Id: 9746 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 030039372; Tue, 5 Jan 2016 13:31:51 +0100 (CET) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 7274F936A for ; Tue, 5 Jan 2016 13:31:48 +0100 (CET) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP; 05 Jan 2016 04:31:47 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,525,1444719600"; d="scan'208";a="23882934" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga004.fm.intel.com with ESMTP; 05 Jan 2016 04:31:47 -0800 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id u05CViGk017435; Tue, 5 Jan 2016 20:31:44 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id u05CVgvN024297; Tue, 5 Jan 2016 20:31:44 +0800 Received: (from xiaowan1@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id u05CVfnO024293; Tue, 5 Jan 2016 20:31:41 +0800 From: Wang Xiao W To: jing.d.chen@intel.com, bruce.richardson@intel.com Date: Tue, 5 Jan 2016 20:31:35 +0800 Message-Id: <1451997096-24248-3-git-send-email-xiao.w.wang@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1451997096-24248-1-git-send-email-xiao.w.wang@intel.com> References: <1451997096-24248-1-git-send-email-xiao.w.wang@intel.com> Cc: dev@dpdk.org Subject: [dpdk-dev] [RFC PATCH 2/3] fm10k: add a unit test for FTAG based forwarding X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch adds a unit test case for FTAG functional test. Before running the test, set PORT0_GLORT and PORT1_GLORT environment variables, and ensure two fm10k ports are used for dpdk, glort info for each port can be shown in TestPoint. In the unit test, a packet will be forwarded to the target port by the switch without changing the destination mac address. Signed-off-by: Wang Xiao W --- app/test/Makefile | 1 + app/test/test_fm10k_ftag.c | 253 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 app/test/test_fm10k_ftag.c diff --git a/app/test/Makefile b/app/test/Makefile index ec33e1a..d72be8d 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -57,6 +57,7 @@ SRCS-y += test_memzone.c SRCS-y += test_ring.c SRCS-y += test_ring_perf.c SRCS-y += test_pmd_perf.c +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_FTAG_FWD) += test_fm10k_ftag.c ifeq ($(CONFIG_RTE_LIBRTE_TABLE),y) SRCS-y += test_table.c diff --git a/app/test/test_fm10k_ftag.c b/app/test/test_fm10k_ftag.c new file mode 100644 index 0000000..325a652 --- /dev/null +++ b/app/test/test_fm10k_ftag.c @@ -0,0 +1,253 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define RX_RING_SIZE 128 +#define TX_RING_SIZE 512 + +#define NUM_MBUFS 8191 +#define MBUF_CACHE_SIZE 250 +#define BURST_SIZE 32 + +struct fm10k_ftag { + uint16_t swpri_type_user; + uint16_t vlan; + uint16_t sglort; + uint16_t dglort; +}; + +static const struct rte_eth_conf port_conf_default = { + .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN } +}; + +/* + * Initializes a given port using global settings and with the RX buffers + * coming from the mbuf_pool passed as a parameter. + */ +static inline int +port_init(uint8_t port, struct rte_mempool *mbuf_pool) +{ + struct rte_eth_conf port_conf = port_conf_default; + const uint16_t rx_rings = 1, tx_rings = 1; + int retval; + uint16_t q; + + if (port >= rte_eth_dev_count()) + return -1; + + /* Configure the Ethernet device. */ + retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf); + if (retval != 0) + return retval; + + /* Allocate and set up 1 RX queue per Ethernet port. */ + for (q = 0; q < rx_rings; q++) { + retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, + rte_eth_dev_socket_id(port), NULL, mbuf_pool); + if (retval < 0) + return retval; + } + + /* Allocate and set up 1 TX queue per Ethernet port. */ + for (q = 0; q < tx_rings; q++) { + retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, + rte_eth_dev_socket_id(port), NULL); + if (retval < 0) + return retval; + } + + /* Start the Ethernet port. */ + retval = rte_eth_dev_start(port); + if (retval < 0) + return retval; + + /* Display the port MAC address. */ + struct ether_addr addr; + rte_eth_macaddr_get(port, &addr); + printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 + " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", + (unsigned)port, + addr.addr_bytes[0], addr.addr_bytes[1], + addr.addr_bytes[2], addr.addr_bytes[3], + addr.addr_bytes[4], addr.addr_bytes[5]); + + return 0; +} + +static int set_glort_value(const char *str, uint16_t *glort) +{ + const char *glort_str; + char *end = NULL; + glort_str = getenv(str); + if (glort_str == NULL) { + printf("Please set environment value %s first\n", str); + return -1; + } + *glort = (uint16_t)strtoul(glort_str, &end, 16); + if ((glort_str[0] == '\0') || (end == NULL) || (*end != '\0')) { + printf("Glort value is not valid\n"); + return -1; + } + return 0; +} + +static int test_ftag_rxtx(void) +{ + uint8_t port = 0; + uint16_t glort[2]; + + struct rte_mbuf *bufs[BURST_SIZE]; + uint16_t nb_rx, nb_tx, i; + struct fm10k_ftag *ftag_addr; + int ret = 0; + + /* Get the glort value of the two ports */ + if ((set_glort_value("PORT0_GLORT", &glort[0]) < 0) || + (set_glort_value("PORT1_GLORT", &glort[1]) < 0)) + return -1; + + /* Receive packets coming from EPL on any of the two ports */ + printf("Please send some packets from Ethernet port to one PEP\n"); + do { + port ^= 1; + nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE); + } while (nb_rx <= 0); + printf("Receive %d packets on port %d\n", nb_rx, port); + + /* Check sglort value on mbuf->vlan_tci_outer. */ + for (i = 0; i < nb_rx; i++) { + if (bufs[i]->vlan_tci_outer == 0) { + printf("Find a packet with sglort 0\n"); + return -1; + } + } + printf("test for FTAG RX passed\n"); + + /* Put an FTAG header on each of the packets received */ + for (i = 0; i < nb_rx; i++) { + ftag_addr = (struct fm10k_ftag *)rte_pktmbuf_prepend(bufs[i], + sizeof(struct fm10k_ftag)); + ftag_addr->swpri_type_user = 0; + ftag_addr->vlan = 0; + ftag_addr->dglort = rte_cpu_to_be_16(glort[port ^ 1]); + ftag_addr->sglort = rte_cpu_to_be_16(glort[port]); + } + + /* Send packets to the other port by method of FTAG based forwarding */ + nb_tx = rte_eth_tx_burst(port, 0, bufs, nb_rx); + if (nb_tx <= 0) { + printf("Can not send out packets with FTAG\n"); + return -1; + } + if (unlikely(nb_tx < nb_rx)) { + do { + rte_pktmbuf_free(bufs[nb_tx]); + } while (++nb_tx < nb_rx); + } + printf("Send out %d packets with FTAG on port %d\n", nb_tx, port); + + /* Wait enough time for a burst of packets forwarding */ + rte_delay_us(100); + + nb_rx = rte_eth_rx_burst(port ^ 1, 0, bufs, BURST_SIZE); + printf("Receive %d packets on port %d\n", nb_rx, port ^ 1); + if (nb_rx < nb_tx) { + printf("Packet loss happens in FTAG TX test\n"); + ret = -1; + } + + /* check if the sglort value is right on the other port */ + for (i = 0; i < nb_rx; i++) { + if (bufs[i]->vlan_tci_outer != glort[port]) { + printf("sglort of the received packet is not right\n"); + ret = -1; + break; + } + } + for (i = 0; i < nb_rx; i++) + rte_pktmbuf_free(bufs[i]); + + if (!ret) + printf("test for FTAG TX passed\n"); + return ret; +} + +static int +test_fm10k_ftag(void) +{ + uint16_t nb_ports; + uint16_t portid; + struct rte_mempool *mbuf_pool; + + nb_ports = rte_eth_dev_count(); + if (nb_ports != 2) { + printf("2 ports needed for fm10k ftag based forwarding test\n"); + return -1; + } + + /* Creates a new mempool in memory to hold the mbufs. */ + mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports, + MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + + if (mbuf_pool == NULL) + rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); + + /* Initialize all ports. */ + for (portid = 0; portid < nb_ports; portid++) + if (port_init(portid, mbuf_pool) != 0) + rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n", + portid); + + if (test_ftag_rxtx() < 0) + return -1; + + /* port tear down */ + for (portid = 0; portid < nb_ports; portid++) + rte_eth_dev_stop(portid); + + return 0; +} + +static struct test_command fm10k_ftag_cmd = { + .command = "fm10k_ftag_autotest", + .callback = test_fm10k_ftag, +}; +REGISTER_TEST_COMMAND(fm10k_ftag_cmd);