-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
- * Copyright 2013-2014 6WIND S.A.
- * 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.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2016 Intel Corporation.
+ * Copyright 2013-2014 6WIND S.A.
*/
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
-#include <stdarg.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#ifdef RTE_LIBRTE_IXGBE_PMD
#include <rte_pmd_ixgbe.h>
#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+#include <rte_pmd_i40e.h>
+#endif
#ifdef RTE_LIBRTE_BNXT_PMD
#include <rte_pmd_bnxt.h>
#endif
#include <rte_gro.h>
+#include <cmdline_parse_etheraddr.h>
#include "testpmd.h"
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];
+ diff_pkts_rx = (stats.ipackets > prev_pkts_rx[port_id]) ?
+ (stats.ipackets - prev_pkts_rx[port_id]) : 0;
+ diff_pkts_tx = (stats.opackets > prev_pkts_tx[port_id]) ?
+ (stats.opackets - prev_pkts_tx[port_id]) : 0;
prev_pkts_rx[port_id] = stats.ipackets;
prev_pkts_tx[port_id] = stats.opackets;
mpps_rx = diff_cycles > 0 ?
}
/* Display xstats */
- for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++)
+ for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
+ if (xstats_hide_zero && !xstats[idx_xstat].value)
+ continue;
printf("%s: %"PRIu64"\n",
xstats_names[idx_xstat].name,
xstats[idx_xstat].value);
+ }
free(xstats_names);
free(xstats);
}
rc = rte_eth_rx_queue_info_get(port_id, queue_id, &qinfo);
if (rc != 0) {
- printf("Failed to retrieve information for port: %hhu, "
+ printf("Failed to retrieve information for port: %u, "
"RX queue: %hu\nerror desc: %s(%d)\n",
port_id, queue_id, strerror(-rc), rc);
return;
rc = rte_eth_tx_queue_info_get(port_id, queue_id, &qinfo);
if (rc != 0) {
- printf("Failed to retrieve information for port: %hhu, "
+ printf("Failed to retrieve information for port: %u, "
"TX queue: %hu\nerror desc: %s(%d)\n",
port_id, queue_id, strerror(-rc), rc);
return;
printf("\nTX writeback threshold: %hhu", qinfo.conf.tx_thresh.wthresh);
printf("\nTX RS threshold: %hu", qinfo.conf.tx_rs_thresh);
printf("\nTX free threshold: %hu", qinfo.conf.tx_free_thresh);
- printf("\nTX flags: %#x", qinfo.conf.txq_flags);
printf("\nTX deferred start: %s",
(qinfo.conf.tx_deferred_start != 0) ? "on" : "off");
printf("\nNumber of TXDs: %hu", qinfo.nb_desc);
char *p;
printf("Supported flow types:\n");
- for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < RTE_ETH_FLOW_MAX;
- i++) {
+ for (i = RTE_ETH_FLOW_UNKNOWN + 1;
+ i < sizeof(dev_info.flow_type_rss_offloads) * CHAR_BIT; i++) {
if (!(dev_info.flow_type_rss_offloads & (1ULL << i)))
continue;
p = flowtype_to_str(i);
- printf(" %s\n", (p ? p : "unknown"));
+ if (p)
+ printf(" %s\n", p);
+ else
+ printf(" user defined %d\n", i);
}
}
+ printf("Minimum size of RX buffer: %u\n", dev_info.min_rx_bufsize);
+ printf("Maximum configurable length of RX packet: %u\n",
+ dev_info.max_rx_pktlen);
+ if (dev_info.max_vfs)
+ printf("Maximum number of VFs: %u\n", dev_info.max_vfs);
+ if (dev_info.max_vmdq_pools)
+ printf("Maximum number of VMDq pools: %u\n",
+ dev_info.max_vmdq_pools);
+
+ printf("Current number of RX queues: %u\n", dev_info.nb_rx_queues);
printf("Max possible RX queues: %u\n", dev_info.max_rx_queues);
printf("Max possible number of RXDs per queue: %hu\n",
dev_info.rx_desc_lim.nb_max);
dev_info.rx_desc_lim.nb_min);
printf("RXDs number alignment: %hu\n", dev_info.rx_desc_lim.nb_align);
+ printf("Current number of TX queues: %u\n", dev_info.nb_tx_queues);
printf("Max possible TX queues: %u\n", dev_info.max_tx_queues);
printf("Max possible number of TXDs per queue: %hu\n",
dev_info.tx_desc_lim.nb_max);
void
port_offload_cap_display(portid_t port_id)
{
- struct rte_eth_dev *dev;
struct rte_eth_dev_info dev_info;
static const char *info_border = "************";
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
- dev = &rte_eth_devices[port_id];
rte_eth_dev_info_get(port_id, &dev_info);
printf("\n%s Port %d supported offload features: %s\n",
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_VLAN_STRIP) {
printf("VLAN stripped: ");
- if (dev->data->dev_conf.rxmode.hw_vlan_strip)
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_VLAN_STRIP)
printf("on\n");
else
printf("off\n");
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_QINQ_STRIP) {
printf("Double VLANs stripped: ");
- if (dev->data->dev_conf.rxmode.hw_vlan_extend)
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_VLAN_EXTEND)
printf("on\n");
else
printf("off\n");
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM) {
printf("RX IPv4 checksum: ");
- if (dev->data->dev_conf.rxmode.hw_ip_checksum)
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_IPV4_CKSUM)
printf("on\n");
else
printf("off\n");
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM) {
printf("RX UDP checksum: ");
- if (dev->data->dev_conf.rxmode.hw_ip_checksum)
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_UDP_CKSUM)
printf("on\n");
else
printf("off\n");
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM) {
printf("RX TCP checksum: ");
- if (dev->data->dev_conf.rxmode.hw_ip_checksum)
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_TCP_CKSUM)
printf("on\n");
else
printf("off\n");
}
- if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM)
- printf("RX Outer IPv4 checksum: on");
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
+ printf("RX Outer IPv4 checksum: ");
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) {
printf("Large receive offload: ");
- if (dev->data->dev_conf.rxmode.enable_lro)
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_TCP_LRO)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT) {
printf("VLAN insert: ");
- if (ports[port_id].tx_ol_flags &
- TESTPMD_TX_OFFLOAD_INSERT_VLAN)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_VLAN_INSERT)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TIMESTAMP) {
+ printf("HW timestamp: ");
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_TIMESTAMP)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_QINQ_INSERT) {
printf("Double VLANs insert: ");
- if (ports[port_id].tx_ol_flags &
- TESTPMD_TX_OFFLOAD_INSERT_QINQ)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_QINQ_INSERT)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) {
printf("TX IPv4 checksum: ");
- if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_IPV4_CKSUM)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) {
printf("TX UDP checksum: ");
- if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_UDP_CKSUM)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) {
printf("TX TCP checksum: ");
- if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_TCP_CKSUM)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) {
printf("TX SCTP checksum: ");
- if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_SCTP_CKSUM)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
printf("TX Outer IPv4 checksum: ");
- if (ports[port_id].tx_ol_flags &
- TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) {
printf("TX TCP segmentation: ");
- if (ports[port_id].tso_segsz != 0)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_TCP_TSO)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_TSO) {
printf("TX UDP segmentation: ");
- if (ports[port_id].tso_segsz != 0)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_UDP_TSO)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO) {
printf("TSO for VXLAN tunnel packet: ");
- if (ports[port_id].tunnel_tso_segsz)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_VXLAN_TNL_TSO)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GRE_TNL_TSO) {
printf("TSO for GRE tunnel packet: ");
- if (ports[port_id].tunnel_tso_segsz)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_GRE_TNL_TSO)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPIP_TNL_TSO) {
printf("TSO for IPIP tunnel packet: ");
- if (ports[port_id].tunnel_tso_segsz)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_IPIP_TNL_TSO)
printf("on\n");
else
printf("off\n");
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
printf("TSO for GENEVE tunnel packet: ");
- if (ports[port_id].tunnel_tso_segsz)
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_GENEVE_TNL_TSO)
printf("on\n");
else
printf("off\n");
int
port_id_is_invalid(portid_t port_id, enum print_warning warning)
{
+ uint16_t pid;
+
if (port_id == (portid_t)RTE_PORT_ALL)
return 0;
- if (rte_eth_dev_is_valid_port(port_id))
- return 0;
+ RTE_ETH_FOREACH_DEV(pid)
+ if (port_id == pid)
+ return 0;
if (warning == ENABLED_WARN)
printf("Invalid port %d\n", port_id);
static int
port_reg_off_is_invalid(portid_t port_id, uint32_t reg_off)
{
+ const struct rte_pci_device *pci_dev;
+ const struct rte_bus *bus;
uint64_t pci_len;
if (reg_off & 0x3) {
(unsigned)reg_off);
return 1;
}
- pci_len = ports[port_id].dev_info.pci_dev->mem_resource[0].len;
+
+ if (!ports[port_id].dev_info.device) {
+ printf("Invalid device\n");
+ return 0;
+ }
+
+ bus = rte_bus_find_by_device(ports[port_id].dev_info.device);
+ if (bus && !strcmp(bus->name, "pci")) {
+ pci_dev = RTE_DEV_TO_PCI(ports[port_id].dev_info.device);
+ } else {
+ printf("Not a PCI device\n");
+ return 1;
+ }
+
+ pci_len = pci_dev->mem_resource[0].len;
if (reg_off >= pci_len) {
printf("Port %d: register offset %u (0x%X) out of port PCI "
"resource (length=%"PRIu64")\n",
MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
MK_FLOW_ITEM(FUZZY, sizeof(struct rte_flow_item_fuzzy)),
+ MK_FLOW_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
+ MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
+ MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
+ MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
};
/** Compute storage space needed by item specification. */
flow_item_spec_size(const struct rte_flow_item *item,
size_t *size, size_t *pad)
{
- if (!item->spec)
+ if (!item->spec) {
+ *size = 0;
goto empty;
+ }
switch (item->type) {
union {
const struct rte_flow_item_raw *raw;
spec.raw->length * sizeof(*spec.raw->pattern);
break;
default:
-empty:
- *size = 0;
+ *size = flow_item[item->type].size;
break;
}
+empty:
*pad = RTE_ALIGN_CEIL(*size, sizeof(double)) - *size;
}
MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */
MK_FLOW_ACTION(PF, 0),
MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
+ MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
};
/** Compute storage space needed by action configuration. */
flow_action_conf_size(const struct rte_flow_action *action,
size_t *size, size_t *pad)
{
- if (!action->conf)
+ if (!action->conf) {
+ *size = 0;
goto empty;
+ }
switch (action->type) {
union {
const struct rte_flow_action_rss *rss;
conf.rss->num * sizeof(*conf.rss->queue);
break;
default:
-empty:
- *size = 0;
+ *size = flow_action[action->type].size;
break;
}
+empty:
*pad = RTE_ALIGN_CEIL(*size, sizeof(double)) - *size;
}
}
static const struct rte_memzone *
-ring_dma_zone_lookup(const char *ring_name, uint8_t port_id, uint16_t q_id)
+ring_dma_zone_lookup(const char *ring_name, portid_t port_id, uint16_t q_id)
{
char mz_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
static void
ring_rx_descriptor_display(const struct rte_memzone *ring_mz,
#ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
- uint8_t port_id,
+ portid_t port_id,
#else
- __rte_unused uint8_t port_id,
+ __rte_unused portid_t port_id,
#endif
uint16_t desc_id)
{
void
rxtx_config_display(void)
{
- printf(" %s packet forwarding%s - CRC stripping %s - "
- "packets/burst=%d\n", cur_fwd_eng->fwd_mode_name,
+ portid_t pid;
+
+ printf(" %s packet forwarding%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);
if (cur_fwd_eng == &tx_only_engine || cur_fwd_eng == &flow_gen_engine)
printf(" packet len=%u - nb packet segments=%d\n",
(unsigned)tx_pkt_length, (int) tx_pkt_nb_segs);
- struct rte_eth_rxconf *rx_conf = &ports[0].rx_conf;
- struct rte_eth_txconf *tx_conf = &ports[0].tx_conf;
-
printf(" nb forwarding cores=%d - nb forwarding ports=%d\n",
nb_fwd_lcores, nb_fwd_ports);
- printf(" RX queues=%d - RX desc=%d - RX free threshold=%d\n",
- nb_rxq, nb_rxd, rx_conf->rx_free_thresh);
- printf(" RX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n",
- rx_conf->rx_thresh.pthresh, rx_conf->rx_thresh.hthresh,
- rx_conf->rx_thresh.wthresh);
- printf(" TX queues=%d - TX desc=%d - TX free threshold=%d\n",
- nb_txq, nb_txd, tx_conf->tx_free_thresh);
- printf(" TX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n",
- tx_conf->tx_thresh.pthresh, tx_conf->tx_thresh.hthresh,
- tx_conf->tx_thresh.wthresh);
- printf(" TX RS bit threshold=%d - TXQ flags=0x%"PRIx32"\n",
- tx_conf->tx_rs_thresh, tx_conf->txq_flags);
+
+ RTE_ETH_FOREACH_DEV(pid) {
+ struct rte_eth_rxconf *rx_conf = &ports[pid].rx_conf;
+ struct rte_eth_txconf *tx_conf = &ports[pid].tx_conf;
+
+ printf(" port %d:\n", (unsigned int)pid);
+ printf(" CRC stripping %s\n",
+ (ports[pid].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_CRC_STRIP) ?
+ "enabled" : "disabled");
+ printf(" RX queues=%d - RX desc=%d - RX free threshold=%d\n",
+ nb_rxq, nb_rxd, rx_conf->rx_free_thresh);
+ printf(" RX threshold registers: pthresh=%d hthresh=%d "
+ " wthresh=%d\n",
+ rx_conf->rx_thresh.pthresh,
+ rx_conf->rx_thresh.hthresh,
+ rx_conf->rx_thresh.wthresh);
+ printf(" TX queues=%d - TX desc=%d - TX free threshold=%d\n",
+ nb_txq, nb_txd, tx_conf->tx_free_thresh);
+ printf(" TX threshold registers: pthresh=%d hthresh=%d "
+ " wthresh=%d\n",
+ tx_conf->tx_thresh.pthresh,
+ tx_conf->tx_thresh.hthresh,
+ tx_conf->tx_thresh.wthresh);
+ printf(" TX RS bit threshold=%d - TXQ offloads=0x%"PRIx64"\n",
+ tx_conf->tx_rs_thresh, tx_conf->offloads);
+ }
}
void
}
}
+static portid_t
+fwd_topology_tx_port_get(portid_t rxp)
+{
+ static int warning_once = 1;
+
+ RTE_ASSERT(rxp < cur_fwd_config.nb_fwd_ports);
+
+ switch (port_topology) {
+ default:
+ case PORT_TOPOLOGY_PAIRED:
+ if ((rxp & 0x1) == 0) {
+ if (rxp + 1 < cur_fwd_config.nb_fwd_ports)
+ return rxp + 1;
+ if (warning_once) {
+ printf("\nWarning! port-topology=paired"
+ " and odd forward ports number,"
+ " the last port will pair with"
+ " itself.\n\n");
+ warning_once = 0;
+ }
+ return rxp;
+ }
+ return rxp - 1;
+ case PORT_TOPOLOGY_CHAINED:
+ return (rxp + 1) % cur_fwd_config.nb_fwd_ports;
+ case PORT_TOPOLOGY_LOOP:
+ return rxp;
+ }
+}
+
static void
simple_fwd_config_setup(void)
{
portid_t i;
- portid_t j;
- portid_t inc = 2;
-
- if (port_topology == PORT_TOPOLOGY_CHAINED ||
- port_topology == PORT_TOPOLOGY_LOOP) {
- inc = 1;
- } else if (nb_fwd_ports % 2) {
- printf("\nWarning! Cannot handle an odd number of ports "
- "with the current port topology. Configuration "
- "must be changed to have an even number of ports, "
- "or relaunch application with "
- "--port-topology=chained\n\n");
- }
cur_fwd_config.nb_fwd_ports = (portid_t) nb_fwd_ports;
cur_fwd_config.nb_fwd_streams =
(lcoreid_t) cur_fwd_config.nb_fwd_ports;
setup_fwd_config_of_each_lcore(&cur_fwd_config);
- for (i = 0; i < cur_fwd_config.nb_fwd_ports; i = (portid_t) (i + inc)) {
- if (port_topology != PORT_TOPOLOGY_LOOP)
- j = (portid_t) ((i + 1) % cur_fwd_config.nb_fwd_ports);
- else
- j = i;
+ for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
fwd_streams[i]->rx_port = fwd_ports_ids[i];
fwd_streams[i]->rx_queue = 0;
- fwd_streams[i]->tx_port = fwd_ports_ids[j];
+ fwd_streams[i]->tx_port =
+ fwd_ports_ids[fwd_topology_tx_port_get(i)];
fwd_streams[i]->tx_queue = 0;
- fwd_streams[i]->peer_addr = j;
+ fwd_streams[i]->peer_addr = fwd_streams[i]->tx_port;
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]->rx_queue = 0;
- 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 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:
- * - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd
- * - TxQl = RxQj
*/
static void
rss_fwd_config_setup(void)
struct fwd_stream *fs;
fs = fwd_streams[sm_id];
-
- if ((rxp & 0x1) == 0)
- txp = (portid_t) (rxp + 1);
- else
- txp = (portid_t) (rxp - 1);
- /*
- * if we are in loopback, simply send stuff out through the
- * ingress port
- */
- if (port_topology == PORT_TOPOLOGY_LOOP)
- txp = rxp;
-
+ txp = fwd_topology_tx_port_get(rxp);
fs->rx_port = fwd_ports_ids[rxp];
fs->rx_queue = rxq;
fs->tx_port = fwd_ports_ids[txp];
* Restart from RX queue 0 on next RX port
*/
rxq = 0;
- if (numa_support && (nb_fwd_ports <= (nb_ports >> 1)))
- rxp = (portid_t)
- (rxp + ((nb_ports >> 1) / nb_fwd_ports));
- else
- rxp = (portid_t) (rxp + 1);
+ rxp++;
}
}
printf("\n");
}
+void
+set_fwd_eth_peer(portid_t port_id, char *peer_addr)
+{
+ uint8_t c, new_peer_addr[6];
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ printf("Error: Invalid port number %i\n", port_id);
+ return;
+ }
+ if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
+ sizeof(new_peer_addr)) < 0) {
+ printf("Error: Invalid ethernet address: %s\n", peer_addr);
+ return;
+ }
+ for (c = 0; c < 6; c++)
+ peer_eth_addrs[port_id].addr_bytes[c] =
+ new_peer_addr[c];
+}
+
int
set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc)
{
}
void
-setup_gro(const char *mode, uint8_t port_id)
+setup_gro(const char *onoff, portid_t port_id)
{
if (!rte_eth_dev_is_valid_port(port_id)) {
printf("invalid port id %u\n", port_id);
" please stop forwarding first\n");
return;
}
- if (strcmp(mode, "on") == 0) {
- if (gro_ports[port_id].enable) {
- printf("port %u has enabled GRO\n", port_id);
+ if (strcmp(onoff, "on") == 0) {
+ if (gro_ports[port_id].enable != 0) {
+ printf("Port %u has enabled GRO. Please"
+ " disable GRO first\n", port_id);
return;
}
- gro_ports[port_id].enable = 1;
- gro_ports[port_id].param.gro_types = RTE_GRO_TCP_IPV4;
-
- if (gro_ports[port_id].param.max_flow_num == 0)
+ if (gro_flush_cycles == GRO_DEFAULT_FLUSH_CYCLES) {
+ gro_ports[port_id].param.gro_types = RTE_GRO_TCP_IPV4;
gro_ports[port_id].param.max_flow_num =
GRO_DEFAULT_FLOW_NUM;
- if (gro_ports[port_id].param.max_item_per_flow == 0)
gro_ports[port_id].param.max_item_per_flow =
GRO_DEFAULT_ITEM_NUM_PER_FLOW;
+ }
+ gro_ports[port_id].enable = 1;
} else {
if (gro_ports[port_id].enable == 0) {
- printf("port %u has disabled GRO\n", port_id);
+ printf("Port %u has disabled GRO\n", port_id);
return;
}
gro_ports[port_id].enable = 0;
}
}
+void
+setup_gro_flush_cycles(uint8_t cycles)
+{
+ if (test_done == 0) {
+ printf("Before change flush interval for GRO,"
+ " please stop forwarding first.\n");
+ return;
+ }
+
+ if (cycles > GRO_MAX_FLUSH_CYCLES || cycles <
+ GRO_DEFAULT_FLUSH_CYCLES) {
+ printf("The flushing cycle be in the range"
+ " of 1 to %u. Revert to the default"
+ " value %u.\n",
+ GRO_MAX_FLUSH_CYCLES,
+ GRO_DEFAULT_FLUSH_CYCLES);
+ cycles = GRO_DEFAULT_FLUSH_CYCLES;
+ }
+
+ gro_flush_cycles = cycles;
+}
+
+void
+show_gro(portid_t port_id)
+{
+ struct rte_gro_param *param;
+ uint32_t max_pkts_num;
+
+ param = &gro_ports[port_id].param;
+
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ printf("Invalid port id %u.\n", port_id);
+ return;
+ }
+ if (gro_ports[port_id].enable) {
+ printf("GRO type: TCP/IPv4\n");
+ if (gro_flush_cycles == GRO_DEFAULT_FLUSH_CYCLES) {
+ max_pkts_num = param->max_flow_num *
+ param->max_item_per_flow;
+ } else
+ max_pkts_num = MAX_PKT_BURST * GRO_MAX_FLUSH_CYCLES;
+ printf("Max number of packets to perform GRO: %u\n",
+ max_pkts_num);
+ printf("Flushing cycles: %u\n", gro_flush_cycles);
+ } else
+ printf("Port %u doesn't enable GRO.\n", port_id);
+}
+
+void
+setup_gso(const char *mode, portid_t port_id)
+{
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ printf("invalid port id %u\n", port_id);
+ return;
+ }
+ if (strcmp(mode, "on") == 0) {
+ if (test_done == 0) {
+ printf("before enabling GSO,"
+ " please stop forwarding first\n");
+ return;
+ }
+ gso_ports[port_id].enable = 1;
+ } else if (strcmp(mode, "off") == 0) {
+ if (test_done == 0) {
+ printf("before disabling GSO,"
+ " please stop forwarding first\n");
+ return;
+ }
+ gso_ports[port_id].enable = 0;
+ }
+}
+
char*
list_pkt_forwarding_modes(void)
{
{
int diag;
int vlan_offload;
+ uint64_t port_rx_offloads = ports[port_id].dev_conf.rxmode.offloads;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
- if (on)
+ if (on) {
vlan_offload |= ETH_VLAN_EXTEND_OFFLOAD;
- else
+ port_rx_offloads |= DEV_RX_OFFLOAD_VLAN_EXTEND;
+ } else {
vlan_offload &= ~ETH_VLAN_EXTEND_OFFLOAD;
+ port_rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_EXTEND;
+ }
diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
if (diag < 0)
printf("rx_vlan_extend_set(port_pi=%d, on=%d) failed "
"diag=%d\n", port_id, on, diag);
+ ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads;
}
void
{
int diag;
int vlan_offload;
+ uint64_t port_rx_offloads = ports[port_id].dev_conf.rxmode.offloads;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
- if (on)
+ if (on) {
vlan_offload |= ETH_VLAN_STRIP_OFFLOAD;
- else
+ port_rx_offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
+ } else {
vlan_offload &= ~ETH_VLAN_STRIP_OFFLOAD;
+ port_rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
+ }
diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
if (diag < 0)
printf("rx_vlan_strip_set(port_pi=%d, on=%d) failed "
"diag=%d\n", port_id, on, diag);
+ ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads;
}
void
{
int diag;
int vlan_offload;
+ uint64_t port_rx_offloads = ports[port_id].dev_conf.rxmode.offloads;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
- if (on)
+ if (on) {
vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
- else
+ port_rx_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
+ } else {
vlan_offload &= ~ETH_VLAN_FILTER_OFFLOAD;
+ port_rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
+ }
diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
if (diag < 0)
printf("rx_vlan_filter_set(port_pi=%d, on=%d) failed "
"diag=%d\n", port_id, on, diag);
+ ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads;
}
int
tx_vlan_set(portid_t port_id, uint16_t vlan_id)
{
int vlan_offload;
+ struct rte_eth_dev_info dev_info;
+
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
if (vlan_id_is_invalid(vlan_id))
printf("Error, as QinQ has been enabled.\n");
return;
}
+ rte_eth_dev_info_get(port_id, &dev_info);
+ if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT) == 0) {
+ printf("Error: vlan insert is not supported by port %d\n",
+ port_id);
+ return;
+ }
tx_vlan_reset(port_id);
- ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_VLAN;
+ ports[port_id].dev_conf.txmode.offloads |= DEV_TX_OFFLOAD_VLAN_INSERT;
ports[port_id].tx_vlan_id = vlan_id;
}
tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer)
{
int vlan_offload;
+ struct rte_eth_dev_info dev_info;
+
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
if (vlan_id_is_invalid(vlan_id))
printf("Error, as QinQ hasn't been enabled.\n");
return;
}
+ rte_eth_dev_info_get(port_id, &dev_info);
+ if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_QINQ_INSERT) == 0) {
+ printf("Error: qinq insert not supported by port %d\n",
+ port_id);
+ return;
+ }
tx_vlan_reset(port_id);
- ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_QINQ;
+ ports[port_id].dev_conf.txmode.offloads |= DEV_TX_OFFLOAD_QINQ_INSERT;
ports[port_id].tx_vlan_id = vlan_id;
ports[port_id].tx_vlan_id_outer = vlan_id_outer;
}
{
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
- ports[port_id].tx_ol_flags &= ~(TESTPMD_TX_OFFLOAD_INSERT_VLAN |
- TESTPMD_TX_OFFLOAD_INSERT_QINQ);
+ ports[port_id].dev_conf.txmode.offloads &=
+ ~(DEV_TX_OFFLOAD_VLAN_INSERT |
+ DEV_TX_OFFLOAD_QINQ_INSERT);
ports[port_id].tx_vlan_id = 0;
ports[port_id].tx_vlan_id_outer = 0;
}
}
}
+void
+set_xstats_hide_zero(uint8_t on_off)
+{
+ xstats_hide_zero = on_off;
+}
+
static inline void
print_fdir_mask(struct rte_eth_fdir_masks *mask)
{
return;
}
}
- (void)rte_memcpy(&flex_conf->flex_mask[idx],
+ rte_memcpy(&flex_conf->flex_mask[idx],
cfg,
sizeof(struct rte_eth_fdir_flex_mask));
}
return;
}
}
- (void)rte_memcpy(&flex_conf->flex_set[idx],
+ rte_memcpy(&flex_conf->flex_set[idx],
cfg,
sizeof(struct rte_eth_flex_payload_cfg));
{
int diag = -ENOTSUP;
+ RTE_SET_USED(vf);
+ RTE_SET_USED(rate);
+ RTE_SET_USED(q_msk);
+
#ifdef RTE_LIBRTE_IXGBE_PMD
if (diag == -ENOTSUP)
diag = rte_pmd_ixgbe_set_vf_rate_limit(port_id, vf, rate,
}
static void
-eth_port_multicast_addr_list_set(uint8_t port_id)
+eth_port_multicast_addr_list_set(portid_t port_id)
{
struct rte_port *port;
int diag;
}
void
-mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr)
+mcast_addr_add(portid_t port_id, struct ether_addr *mc_addr)
{
struct rte_port *port;
uint32_t i;
}
void
-mcast_addr_remove(uint8_t port_id, struct ether_addr *mc_addr)
+mcast_addr_remove(portid_t port_id, struct ether_addr *mc_addr)
{
struct rte_port *port;
uint32_t i;
}
void
-port_dcb_info_display(uint8_t port_id)
+port_dcb_info_display(portid_t port_id)
{
struct rte_eth_dcb_info dcb_info;
uint16_t i;
}
uint8_t *
-open_ddp_package_file(const char *file_path, uint32_t *size)
+open_file(const char *file_path, uint32_t *size)
{
- FILE *fh = fopen(file_path, "rb");
- uint32_t pkg_size;
+ int fd = open(file_path, O_RDONLY);
+ off_t pkg_size;
uint8_t *buf = NULL;
int ret = 0;
+ struct stat st_buf;
if (size)
*size = 0;
- if (fh == NULL) {
+ if (fd == -1) {
printf("%s: Failed to open %s\n", __func__, file_path);
return buf;
}
- ret = fseek(fh, 0, SEEK_END);
- if (ret < 0) {
- fclose(fh);
+ if ((fstat(fd, &st_buf) != 0) || (!S_ISREG(st_buf.st_mode))) {
+ close(fd);
printf("%s: File operations failed\n", __func__);
return buf;
}
- pkg_size = ftell(fh);
+ pkg_size = st_buf.st_size;
+ if (pkg_size < 0) {
+ close(fd);
+ printf("%s: File operations failed\n", __func__);
+ return buf;
+ }
buf = (uint8_t *)malloc(pkg_size);
if (!buf) {
- fclose(fh);
+ close(fd);
printf("%s: Failed to malloc memory\n", __func__);
return buf;
}
- ret = fseek(fh, 0, SEEK_SET);
- if (ret < 0) {
- fclose(fh);
- printf("%s: File seek operation failed\n", __func__);
- close_ddp_package_file(buf);
- return NULL;
- }
-
- ret = fread(buf, 1, pkg_size, fh);
+ ret = read(fd, buf, pkg_size);
if (ret < 0) {
- fclose(fh);
+ close(fd);
printf("%s: File read operation failed\n", __func__);
- close_ddp_package_file(buf);
+ close_file(buf);
return NULL;
}
if (size)
*size = pkg_size;
- fclose(fh);
+ close(fd);
return buf;
}
int
-save_ddp_package_file(const char *file_path, uint8_t *buf, uint32_t size)
+save_file(const char *file_path, uint8_t *buf, uint32_t size)
{
FILE *fh = fopen(file_path, "wb");
}
int
-close_ddp_package_file(uint8_t *buf)
+close_file(uint8_t *buf)
{
if (buf) {
free((void *)buf);
return -1;
}
+
+void
+port_queue_region_info_display(portid_t port_id, void *buf)
+{
+#ifdef RTE_LIBRTE_I40E_PMD
+ uint16_t i, j;
+ struct rte_pmd_i40e_queue_regions *info =
+ (struct rte_pmd_i40e_queue_regions *)buf;
+ static const char *queue_region_info_stats_border = "-------";
+
+ if (!info->queue_region_number)
+ printf("there is no region has been set before");
+
+ printf("\n %s All queue region info for port=%2d %s",
+ queue_region_info_stats_border, port_id,
+ queue_region_info_stats_border);
+ printf("\n queue_region_number: %-14u \n",
+ info->queue_region_number);
+
+ for (i = 0; i < info->queue_region_number; i++) {
+ printf("\n region_id: %-14u queue_number: %-14u "
+ "queue_start_index: %-14u \n",
+ info->region[i].region_id,
+ info->region[i].queue_num,
+ info->region[i].queue_start_index);
+
+ printf(" user_priority_num is %-14u :",
+ info->region[i].user_priority_num);
+ for (j = 0; j < info->region[i].user_priority_num; j++)
+ printf(" %-14u ", info->region[i].user_priority[j]);
+
+ printf("\n flowtype_num is %-14u :",
+ info->region[i].flowtype_num);
+ for (j = 0; j < info->region[i].flowtype_num; j++)
+ printf(" %-14u ", info->region[i].hw_flowtype[j]);
+ }
+#else
+ RTE_SET_USED(port_id);
+ RTE_SET_USED(buf);
+#endif
+
+ printf("\n\n");
+}