/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
-#include <rte_ring.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_interrupts.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_string_fns.h>
+#include <rte_cycles.h>
#include "testpmd.h"
{ "ipv6-ex", ETH_RSS_IPV6_EX },
{ "ipv6-tcp-ex", ETH_RSS_IPV6_TCP_EX },
{ "ipv6-udp-ex", ETH_RSS_IPV6_UDP_EX },
+ { "port", ETH_RSS_PORT },
+ { "vxlan", ETH_RSS_VXLAN },
+ { "geneve", ETH_RSS_GENEVE },
+ { "nvgre", ETH_RSS_NVGRE },
+
};
static void
void
nic_stats_display(portid_t port_id)
{
+ static uint64_t prev_pkts_rx[RTE_MAX_ETHPORTS];
+ static uint64_t prev_pkts_tx[RTE_MAX_ETHPORTS];
+ static uint64_t prev_cycles[RTE_MAX_ETHPORTS];
+ uint64_t diff_pkts_rx, diff_pkts_tx, diff_cycles;
+ uint64_t mpps_rx, mpps_tx;
struct rte_eth_stats stats;
struct rte_port *port = &ports[port_id];
uint8_t i;
printf(" RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes: "
"%-"PRIu64"\n",
stats.ipackets, stats.imissed, stats.ibytes);
- printf(" RX-badcrc: %-10"PRIu64" RX-badlen: %-10"PRIu64" RX-errors: "
- "%-"PRIu64"\n",
- stats.ibadcrc, stats.ibadlen, stats.ierrors);
+ printf(" RX-errors: %-"PRIu64"\n", stats.ierrors);
printf(" RX-nombuf: %-10"PRIu64"\n",
stats.rx_nombuf);
printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes: "
printf(" RX-packets: %10"PRIu64" RX-errors: %10"PRIu64
" RX-bytes: %10"PRIu64"\n",
stats.ipackets, stats.ierrors, stats.ibytes);
- printf(" RX-badcrc: %10"PRIu64" RX-badlen: %10"PRIu64
- " RX-errors: %10"PRIu64"\n",
- stats.ibadcrc, stats.ibadlen, stats.ierrors);
+ printf(" RX-errors: %10"PRIu64"\n", stats.ierrors);
printf(" RX-nombuf: %10"PRIu64"\n",
stats.rx_nombuf);
printf(" TX-packets: %10"PRIu64" TX-errors: %10"PRIu64
stats.opackets, stats.oerrors, stats.obytes);
}
- /* stats fdir */
- if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
- printf(" Fdirmiss: %-10"PRIu64" Fdirmatch: %-10"PRIu64"\n",
- stats.fdirmiss,
- stats.fdirmatch);
-
if (port->rx_queue_stats_mapping_enabled) {
printf("\n");
for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
}
}
- /* 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: %-10"PRIu64" RX-XON: %-10"PRIu64"\n",
- stats.rx_pause_xoff, stats.rx_pause_xon);
- printf(" TX-XOFF: %-10"PRIu64" TX-XON: %-10"PRIu64"\n",
- stats.tx_pause_xoff, stats.tx_pause_xon);
- }
+ diff_cycles = prev_cycles[port_id];
+ prev_cycles[port_id] = rte_rdtsc();
+ if (diff_cycles > 0)
+ diff_cycles = prev_cycles[port_id] - diff_cycles;
+
+ diff_pkts_rx = stats.ipackets - prev_pkts_rx[port_id];
+ diff_pkts_tx = stats.opackets - prev_pkts_tx[port_id];
+ prev_pkts_rx[port_id] = stats.ipackets;
+ prev_pkts_tx[port_id] = stats.opackets;
+ mpps_rx = diff_cycles > 0 ?
+ diff_pkts_rx * rte_get_tsc_hz() / diff_cycles : 0;
+ mpps_tx = diff_cycles > 0 ?
+ diff_pkts_tx * rte_get_tsc_hz() / diff_cycles : 0;
+ printf("\n Throughput (since last show)\n");
+ printf(" Rx-pps: %12"PRIu64"\n Tx-pps: %12"PRIu64"\n",
+ mpps_rx, mpps_tx);
+
printf(" %s############################%s\n",
nic_stats_border, nic_stats_border);
}
void
nic_xstats_display(portid_t port_id)
{
- struct rte_eth_xstats *xstats;
- int len, ret, i;
+ struct rte_eth_xstat *xstats;
+ int cnt_xstats, idx_xstat;
+ struct rte_eth_xstat_name *xstats_names;
printf("###### NIC extended statistics for port %-2d\n", port_id);
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ printf("Error: Invalid port number %i\n", port_id);
+ return;
+ }
+
+ /* Get count */
+ cnt_xstats = rte_eth_xstats_get_names(port_id, NULL, 0);
+ if (cnt_xstats < 0) {
+ printf("Error: Cannot get count of xstats\n");
+ return;
+ }
- len = rte_eth_xstats_get(port_id, NULL, 0);
- if (len < 0) {
- printf("Cannot get xstats count\n");
+ /* Get id-name lookup table */
+ xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * cnt_xstats);
+ if (xstats_names == NULL) {
+ printf("Cannot allocate memory for xstats lookup\n");
return;
}
- xstats = malloc(sizeof(xstats[0]) * len);
+ if (cnt_xstats != rte_eth_xstats_get_names(
+ port_id, xstats_names, cnt_xstats)) {
+ printf("Error: Cannot get xstats lookup\n");
+ free(xstats_names);
+ return;
+ }
+
+ /* Get stats themselves */
+ xstats = malloc(sizeof(struct rte_eth_xstat) * cnt_xstats);
if (xstats == NULL) {
printf("Cannot allocate memory for xstats\n");
+ free(xstats_names);
return;
}
- ret = rte_eth_xstats_get(port_id, xstats, len);
- if (ret < 0 || ret > len) {
- printf("Cannot get xstats\n");
+ if (cnt_xstats != rte_eth_xstats_get(port_id, xstats, cnt_xstats)) {
+ printf("Error: Unable to get xstats\n");
+ free(xstats_names);
free(xstats);
return;
}
- for (i = 0; i < len; i++)
- printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value);
+
+ /* Display xstats */
+ for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++)
+ printf("%s: %"PRIu64"\n",
+ xstats_names[idx_xstat].name,
+ xstats[idx_xstat].value);
+ free(xstats_names);
free(xstats);
}
printf("%s ring memory zoneof (port %d, queue %d) not"
"found (zone name = %s\n",
ring_name, port_id, q_id, mz_name);
- return (mz);
+ return mz;
}
union igb_ring_dword {
void
rxtx_config_display(void)
{
- printf(" %s packet forwarding - CRC stripping %s - "
+ printf(" %s packet forwarding%s - CRC stripping %s - "
"packets/burst=%d\n", cur_fwd_eng->fwd_mode_name,
+ retry_enabled == 0 ? "" : " with retry",
rx_mode.hw_strip_crc ? "enabled" : "disabled",
nb_pkt_per_burst);
fwd_streams[i]->tx_port = fwd_ports_ids[j];
fwd_streams[i]->tx_queue = 0;
fwd_streams[i]->peer_addr = j;
+ fwd_streams[i]->retry_enabled = retry_enabled;
if (port_topology == PORT_TOPOLOGY_PAIRED) {
fwd_streams[j]->rx_port = fwd_ports_ids[j];
fwd_streams[j]->tx_port = fwd_ports_ids[i];
fwd_streams[j]->tx_queue = 0;
fwd_streams[j]->peer_addr = i;
+ fwd_streams[j]->retry_enabled = retry_enabled;
}
}
}
/**
- * For the RSS forwarding test, each core is assigned on every port a transmit
- * queue whose index is the index of the core itself. This approach limits the
- * maximumm number of processing cores of the RSS test to the maximum number of
- * TX queues supported by the devices.
- *
- * Each core is assigned a single stream, each stream being composed of
- * a RX queue to poll on a RX port for input messages, associated with
- * a TX queue of a TX port where to send forwarded packets.
+ * For the RSS forwarding test all streams distributed over lcores. Each stream
+ * being composed of a RX queue to poll on a RX port for input messages,
+ * associated with a TX queue of a TX port where to send forwarded packets.
* All packets received on the RX queue of index "RxQj" of the RX port "RxPi"
* are sent on the TX queue "TxQl" of the TX port "TxPk" according to the two
* following rules:
portid_t txp;
queueid_t rxq;
queueid_t nb_q;
- lcoreid_t lc_id;
+ streamid_t sm_id;
nb_q = nb_rxq;
if (nb_q > nb_txq)
cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
cur_fwd_config.nb_fwd_streams =
(streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports);
- if (cur_fwd_config.nb_fwd_streams > cur_fwd_config.nb_fwd_lcores)
- cur_fwd_config.nb_fwd_streams =
- (streamid_t)cur_fwd_config.nb_fwd_lcores;
- else
+
+ if (cur_fwd_config.nb_fwd_streams < cur_fwd_config.nb_fwd_lcores)
cur_fwd_config.nb_fwd_lcores =
(lcoreid_t)cur_fwd_config.nb_fwd_streams;
setup_fwd_config_of_each_lcore(&cur_fwd_config);
rxp = 0; rxq = 0;
- for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
+ for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
struct fwd_stream *fs;
- fs = fwd_streams[lc_id];
+ fs = fwd_streams[sm_id];
if ((rxp & 0x1) == 0)
txp = (portid_t) (rxp + 1);
fs->tx_port = fwd_ports_ids[txp];
fs->tx_queue = rxq;
fs->peer_addr = fs->tx_port;
+ fs->retry_enabled = retry_enabled;
rxq = (queueid_t) (rxq + 1);
if (rxq < nb_q)
continue;
/* reinitialize forwarding streams */
init_fwd_streams();
sm_id = 0;
- if ((rxp & 0x1) == 0)
- txp = (portid_t) (rxp + 1);
- else
- txp = (portid_t) (rxp - 1);
+ txp = 1;
/* get the dcb info on the first RX and TX ports */
(void)rte_eth_dev_get_dcb_info(fwd_ports_ids[rxp], &rxp_dcb_info);
(void)rte_eth_dev_get_dcb_info(fwd_ports_ids[txp], &txp_dcb_info);
fs->tx_port = fwd_ports_ids[txp];
fs->tx_queue = txq + j % nb_tx_queue;
fs->peer_addr = fs->tx_port;
+ fs->retry_enabled = retry_enabled;
}
fwd_lcores[lc_id]->stream_nb +=
rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue;
fs->tx_port = fs->rx_port;
fs->tx_queue = rxq;
fs->peer_addr = fs->tx_port;
+ fs->retry_enabled = retry_enabled;
if (verbose_level > 0)
printf(" stream=%d port=%d rxq=%d txq=%d\n",
sm_id, fs->rx_port, fs->rx_queue,
simple_fwd_config_setup();
}
-static void
+void
pkt_fwd_config_display(struct fwd_config *cfg)
{
struct fwd_stream *fs;
lcoreid_t lc_id;
streamid_t sm_id;
- printf("%s packet forwarding - ports=%d - cores=%d - streams=%d - "
+ printf("%s packet forwarding%s - ports=%d - cores=%d - streams=%d - "
"NUMA support %s, MP over anonymous pages %s\n",
cfg->fwd_eng->fwd_mode_name,
+ retry_enabled == 0 ? "" : " with retry",
cfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams,
numa_support == 1 ? "enabled" : "disabled",
mp_anon != 0 ? "enabled" : "disabled");
- if (strcmp(cfg->fwd_eng->fwd_mode_name, "mac_retry") == 0)
+ if (retry_enabled)
printf("TX retry num: %u, delay between TX retries: %uus\n",
burst_tx_retry_num, burst_tx_delay_time);
for (lc_id = 0; lc_id < cfg->nb_fwd_lcores; lc_id++) {
printf("\n");
}
-
-void
-fwd_config_display(void)
-{
- fwd_config_setup();
- pkt_fwd_config_display(&cur_fwd_config);
-}
-
int
set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc)
{
(unsigned int) nb_fwd_ports);
}
+int
+port_is_forwarding(portid_t port_id)
+{
+ unsigned int i;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return -1;
+
+ for (i = 0; i < nb_fwd_ports; i++) {
+ if (fwd_ports_ids[i] == port_id)
+ return 1;
+ }
+
+ return 0;
+}
+
void
set_nb_pkt_per_burst(uint16_t nb)
{
if (strlen (fwd_modes) == 0) {
while ((fwd_eng = fwd_engines[i++]) != NULL) {
- strcat(fwd_modes, fwd_eng->fwd_mode_name);
- strcat(fwd_modes, separator);
+ strncat(fwd_modes, fwd_eng->fwd_mode_name,
+ sizeof(fwd_modes) - strlen(fwd_modes) - 1);
+ strncat(fwd_modes, separator,
+ sizeof(fwd_modes) - strlen(fwd_modes) - 1);
+ }
+ fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0';
+ }
+
+ return fwd_modes;
+}
+
+char*
+list_pkt_forwarding_retry_modes(void)
+{
+ static char fwd_modes[128] = "";
+ const char *separator = "|";
+ struct fwd_engine *fwd_eng;
+ unsigned i = 0;
+
+ if (strlen(fwd_modes) == 0) {
+ while ((fwd_eng = fwd_engines[i++]) != NULL) {
+ if (fwd_eng == &rx_only_engine)
+ continue;
+ strncat(fwd_modes, fwd_eng->fwd_mode_name,
+ sizeof(fwd_modes) -
+ strlen(fwd_modes) - 1);
+ strncat(fwd_modes, separator,
+ sizeof(fwd_modes) -
+ strlen(fwd_modes) - 1);
}
fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0';
}
i = 0;
while ((fwd_eng = fwd_engines[i]) != NULL) {
if (! strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) {
- printf("Set %s packet forwarding mode\n",
- fwd_mode_name);
+ printf("Set %s packet forwarding mode%s\n",
+ fwd_mode_name,
+ retry_enabled == 0 ? "" : " with retry");
cur_fwd_eng = fwd_eng;
return;
}
}
void
-vlan_tpid_set(portid_t port_id, uint16_t tp_id)
+vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type, uint16_t tp_id)
{
int diag;
+
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
- diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id);
+ diag = rte_eth_dev_set_vlan_ether_type(port_id, vlan_type, tp_id);
if (diag == 0)
return;
- printf("tx_vlan_tpid_set(port_pi=%d, tpid=%d) failed "
+ printf("tx_vlan_tpid_set(port_pi=%d, vlan_type=%d, tpid=%d) failed "
"diag=%d\n",
- port_id, tp_id, diag);
+ port_id, vlan_type, tp_id, diag);
}
void
tx_vlan_set(portid_t port_id, uint16_t vlan_id)
{
+ int vlan_offload;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
if (vlan_id_is_invalid(vlan_id))
return;
+
+ vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
+ if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD) {
+ printf("Error, as QinQ has been enabled.\n");
+ return;
+ }
+
tx_vlan_reset(port_id);
ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_VLAN;
ports[port_id].tx_vlan_id = vlan_id;
void
tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer)
{
+ int vlan_offload;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
if (vlan_id_is_invalid(vlan_id))
return;
if (vlan_id_is_invalid(vlan_id_outer))
return;
+
+ vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
+ if (!(vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)) {
+ printf("Error, as QinQ hasn't been enabled.\n");
+ return;
+ }
+
tx_vlan_reset(port_id);
ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_QINQ;
ports[port_id].tx_vlan_id = vlan_id;
{"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
{"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
{"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
+ {"port", RTE_ETH_FLOW_PORT},
+ {"vxlan", RTE_ETH_FLOW_VXLAN},
+ {"geneve", RTE_ETH_FLOW_GENEVE},
+ {"nvgre", RTE_ETH_FLOW_NVGRE},
};
for (i = 0; i < RTE_DIM(flowtype_str_table); i++) {