/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_string_fns.h>
+#ifdef RTE_LIBRTE_PMD_XENVIRT
+#include <rte_eth_xenvirt.h>
+#endif
#include "testpmd.h"
+#include "mempool_osdep.h"
uint16_t verbose_level = 0; /**< Silent by default. */
/* use master core for command line ? */
uint8_t interactive = 0;
+uint8_t auto_start = 0;
/*
* NUMA support configuration.
*/
uint8_t socket_num = UMA_NO_CONFIG;
+/*
+ * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
+ */
+uint8_t mp_anon = 0;
+
/*
* Record the Ethernet address of peer target ports to which packets are
* forwarded.
struct fwd_engine * fwd_engines[] = {
&io_fwd_engine,
&mac_fwd_engine,
+ &mac_retry_fwd_engine,
+ &mac_swap_engine,
+ &flow_gen_engine,
&rx_only_engine,
&tx_only_engine,
&csum_fwd_engine,
+ &icmp_echo_engine,
#ifdef RTE_LIBRTE_IEEE1588
&ieee1588_fwd_engine,
#endif
*/
uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
+/*
+ * Avoids to flush all the RX streams before starts forwarding.
+ */
+uint8_t no_flush_rx = 0; /* flush by default */
+
+/*
+ * Avoids to check link status when starting/stopping a port.
+ */
+uint8_t no_link_check = 0; /* check by default */
+
+/*
+ * NIC bypass mode configuration options.
+ */
+#ifdef RTE_NIC_BYPASS
+
+/* The NIC bypass watchdog timeout. */
+uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
+
+#endif
+
/*
* Ethernet device configuration.
*/
return;
}
mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
- mbp_priv = (struct rte_pktmbuf_pool_private *)
- ((char *)mp + sizeof(struct rte_mempool));
+ mbp_priv = rte_mempool_get_priv(mp);
mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
}
mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
- rte_mp = rte_mempool_create(pool_name, nb_mbuf, (unsigned) mb_size,
+
+#ifdef RTE_LIBRTE_PMD_XENVIRT
+ rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
+ (unsigned) mb_mempool_cache,
+ sizeof(struct rte_pktmbuf_pool_private),
+ testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
+ testpmd_mbuf_ctor, &mb_ctor_arg,
+ socket_id, 0);
+
+
+
+#else
+ if (mp_anon != 0)
+ rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
+ (unsigned) mb_mempool_cache,
+ sizeof(struct rte_pktmbuf_pool_private),
+ testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
+ testpmd_mbuf_ctor, &mb_ctor_arg,
+ socket_id, 0);
+ else
+ rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
(unsigned) mb_mempool_cache,
sizeof(struct rte_pktmbuf_pool_private),
testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
testpmd_mbuf_ctor, &mb_ctor_arg,
socket_id, 0);
+
+#endif
+
if (rte_mp == NULL) {
rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u "
"failed\n", socket_id);
+ } else if (verbose_level > 0) {
+ rte_mempool_dump(rte_mp);
}
}
+/*
+ * Check given socket id is valid or not with NUMA mode,
+ * if valid, return 0, else return -1
+ */
+static int
+check_socket_id(const unsigned int socket_id)
+{
+ static int warning_once = 0;
+
+ if (socket_id >= MAX_SOCKET) {
+ if (!warning_once && numa_support)
+ printf("Warning: NUMA should be configured manually by"
+ " using --port-numa-config and"
+ " --ring-numa-config parameters along with"
+ " --numa.\n");
+ warning_once = 1;
+ return -1;
+ }
+ return 0;
+}
+
static void
init_config(void)
{
mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
socket_num);
}
- /*
- * Records which Mbuf pool to use by each logical core, if needed.
- */
- for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
- mbp = mbuf_pool_find(rte_lcore_to_socket_id(lc_id));
- if (mbp == NULL)
- mbp = mbuf_pool_find(0);
- fwd_lcores[lc_id]->mbp = mbp;
- }
/* Configuration of Ethernet ports. */
ports = rte_zmalloc("testpmd: ports",
port_per_socket[port_numa[pid]]++;
else {
uint32_t socket_id = rte_eth_dev_socket_id(pid);
+
+ /* if socket_id is invalid, set to 0 */
+ if (check_socket_id(socket_id) < 0)
+ socket_id = 0;
port_per_socket[socket_id]++;
}
}
}
}
init_port_config();
+
+ /*
+ * Records which Mbuf pool to use by each logical core, if needed.
+ */
+ for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
+ mbp = mbuf_pool_find(rte_lcore_to_socket_id(lc_id));
+ if (mbp == NULL)
+ mbp = mbuf_pool_find(0);
+ fwd_lcores[lc_id]->mbp = mbp;
+ }
+
/* Configuration of packet forwarding streams. */
if (init_fwd_streams() < 0)
rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
port->dev_info.max_tx_queues);
return -1;
}
- if (numa_support)
- port->socket_id = rte_eth_dev_socket_id(pid);
+ if (numa_support) {
+ if (port_numa[pid] != NUMA_NO_CONFIG)
+ port->socket_id = port_numa[pid];
+ else {
+ port->socket_id = rte_eth_dev_socket_id(pid);
+
+ /* if socket_id is invalid, set to 0 */
+ if (check_socket_id(port->socket_id) < 0)
+ port->socket_id = 0;
+ }
+ }
else {
if (socket_num == UMA_NO_CONFIG)
port->socket_id = 0;
if (stats->rx_nombuf > 0)
printf(" RX-nombufs:%14"PRIu64"\n", stats->rx_nombuf);
}
+
+ /* Display statistics of XON/XOFF pause frames, if any. */
+ if ((stats->tx_pause_xon | stats->rx_pause_xon |
+ stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
+ printf(" RX-XOFF: %-14"PRIu64" RX-XON: %-14"PRIu64"\n",
+ stats->rx_pause_xoff, stats->rx_pause_xon);
+ printf(" TX-XOFF: %-14"PRIu64" TX-XON: %-14"PRIu64"\n",
+ stats->tx_pause_xoff, stats->tx_pause_xon);
+ }
+
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
if (port->rx_stream)
pkt_burst_stats_display("RX",
}
static void
-flush_all_rx_queues(void)
+flush_fwd_rx_queues(void)
{
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
portid_t rxp;
+ portid_t port_id;
queueid_t rxq;
uint16_t nb_rx;
uint16_t i;
uint8_t j;
for (j = 0; j < 2; j++) {
- for (rxp = 0; rxp < nb_ports; rxp++) {
+ for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
for (rxq = 0; rxq < nb_rxq; rxq++) {
+ port_id = fwd_ports_ids[rxp];
do {
- nb_rx = rte_eth_rx_burst(rxp, rxq,
+ nb_rx = rte_eth_rx_burst(port_id, rxq,
pkts_burst, MAX_PKT_BURST);
for (i = 0; i < nb_rx; i++)
rte_pktmbuf_free(pkts_burst[i]);
printf("Packet forwarding already started\n");
return;
}
- if((dcb_test) && (nb_fwd_lcores == 1)) {
- printf("In DCB mode,the nb forwarding cores should be larger than 1.\n");
- return;
+ if(dcb_test) {
+ for (i = 0; i < nb_fwd_ports; i++) {
+ pt_id = fwd_ports_ids[i];
+ port = &ports[pt_id];
+ if (!port->dcb_flag) {
+ printf("In DCB mode, all forwarding ports must "
+ "be configured in this mode.\n");
+ return;
+ }
+ }
+ if (nb_fwd_lcores == 1) {
+ printf("In DCB mode,the nb forwarding cores "
+ "should be larger than 1.\n");
+ return;
+ }
}
test_done = 0;
- flush_all_rx_queues();
+
+ if(!no_flush_rx)
+ flush_fwd_rx_queues();
+
fwd_config_setup();
rxtx_config_display();
total_rx_dropped = 0;
total_tx_dropped = 0;
total_rx_nombuf = 0;
- for (i = 0; i < ((cur_fwd_config.nb_fwd_ports + 1) & ~0x1); i++) {
+ for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
pt_id = fwd_ports_ids[i];
port = &ports[pt_id];
return 1;
}
-void
+int
start_port(portid_t pid)
{
int diag, need_check_link_status = 0;
portid_t pi;
queueid_t qi;
struct rte_port *port;
+ uint8_t *mac_addr;
if (test_done == 0) {
printf("Please stop forwarding first\n");
- return;
+ return -1;
}
if (init_fwd_streams() < 0) {
printf("Fail from init_fwd_streams()\n");
- return;
+ return -1;
}
if(dcb_config)
if (port->need_reconfig > 0) {
port->need_reconfig = 0;
- printf("Configuring Port %d (socket %d)\n", pi,
- rte_eth_dev_socket_id(pi));
+ printf("Configuring Port %d (socket %u)\n", pi,
+ port->socket_id);
/* configure port */
diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
&(port->dev_conf));
printf("Fail to configure port %d\n", pi);
/* try to reconfigure port next time */
port->need_reconfig = 1;
- return;
+ return -1;
}
}
if (port->need_reconfig_queues > 0) {
printf("Fail to configure port %d tx queues\n", pi);
/* try to reconfigure queues next time */
port->need_reconfig_queues = 1;
- return;
+ return -1;
}
/* setup rx queues */
for (qi = 0; qi < nb_rxq; qi++) {
"No mempool allocation"
"on the socket %d\n",
rxring_numa[pi]);
- return;
+ return -1;
}
diag = rte_eth_rx_queue_setup(pi, qi,
printf("Fail to configure port %d rx queues\n", pi);
/* try to reconfigure queues next time */
port->need_reconfig_queues = 1;
- return;
+ return -1;
}
}
/* start port */
RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
printf("Port %d can not be set into started\n", pi);
+ mac_addr = port->eth_addr.addr_bytes;
+ printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
+ mac_addr[0], mac_addr[1], mac_addr[2],
+ mac_addr[3], mac_addr[4], mac_addr[5]);
+
/* at least one port started, need checking link status */
need_check_link_status = 1;
}
- if (need_check_link_status)
+ if (need_check_link_status && !no_link_check)
check_all_ports_link_status(nb_ports, RTE_PORT_ALL);
else
printf("Please stop the ports first\n");
printf("Done\n");
+ return 0;
}
void
printf("Port %d can not be set into stopped\n", pi);
need_check_link_status = 1;
}
- if (need_check_link_status)
+ if (need_check_link_status && !no_link_check)
check_all_ports_link_status(nb_ports, RTE_PORT_ALL);
printf("Done\n");
port = &ports[pid];
port->dev_conf.rxmode = rx_mode;
port->dev_conf.fdir_conf = fdir_conf;
- if (nb_rxq > 0) {
+ if (nb_rxq > 1) {
port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
} else {
port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
}
+
+ /* In SR-IOV mode, RSS mode is not available */
+ if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
+ if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
+ port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
+ else
+ port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
+ }
+
port->rx_conf.rx_thresh = rx_thresh;
port->rx_conf.rx_free_thresh = rx_free_thresh;
port->rx_conf.rx_drop_en = rx_drop_en;
rte_eth_macaddr_get(pid, &port->eth_addr);
map_port_queue_stats_mapping_registers(pid, port);
+#ifdef RTE_NIC_BYPASS
+ rte_eth_dev_bypass_init(pid);
+#endif
}
}
rte_eth_macaddr_get(pid, &rte_port->eth_addr);
map_port_queue_stats_mapping_registers(pid, rte_port);
+
+ rte_port->dcb_flag = 1;
return 0;
}
nb_rxq, nb_txq);
init_config();
- start_port(RTE_PORT_ALL);
+ if (start_port(RTE_PORT_ALL) != 0)
+ rte_exit(EXIT_FAILURE, "Start ports failed\n");
/* set all ports to promiscuous mode by default */
for (port_id = 0; port_id < nb_ports; port_id++)
rte_eth_promiscuous_enable(port_id);
- if (interactive == 1)
+#ifdef RTE_LIBRTE_CMDLINE
+ if (interactive == 1) {
+ if (auto_start) {
+ printf("Start automatic packet forwarding\n");
+ start_packet_forwarding(0);
+ }
prompt();
- else {
+ } else
+#endif
+ {
char c;
int rc;