#include <rte_pmd_bnxt.h>
#endif
#include <rte_gro.h>
-#include <cmdline_parse_etheraddr.h>
+#include <rte_config.h>
#include "testpmd.h"
};
const struct rss_type_info rss_type_table[] = {
+ { "all", ETH_RSS_IP | ETH_RSS_TCP |
+ ETH_RSS_UDP | ETH_RSS_SCTP |
+ ETH_RSS_L2_PAYLOAD },
+ { "none", 0 },
{ "ipv4", ETH_RSS_IPV4 },
{ "ipv4-frag", ETH_RSS_FRAG_IPV4 },
{ "ipv4-tcp", ETH_RSS_NONFRAG_IPV4_TCP },
};
static void
-print_ethaddr(const char *name, struct ether_addr *eth_addr)
+print_ethaddr(const char *name, struct rte_ether_addr *eth_addr)
{
- char buf[ETHER_ADDR_FMT_SIZE];
- ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr);
+ char buf[RTE_ETHER_ADDR_FMT_SIZE];
+ rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr);
printf("%s%s", name, buf);
}
void
nic_xstats_clear(portid_t port_id)
{
- rte_eth_xstats_reset(port_id);
+ int ret;
+
+ ret = rte_eth_xstats_reset(port_id);
+ if (ret != 0) {
+ printf("%s: Error: failed to reset xstats (port %u): %s",
+ __func__, port_id, strerror(ret));
+ }
}
void
printf("\n");
}
+static int bus_match_all(const struct rte_bus *bus, const void *data)
+{
+ RTE_SET_USED(bus);
+ RTE_SET_USED(data);
+ return 0;
+}
+
+void
+device_infos_display(const char *identifier)
+{
+ static const char *info_border = "*********************";
+ struct rte_bus *start = NULL, *next;
+ struct rte_dev_iterator dev_iter;
+ char name[RTE_ETH_NAME_MAX_LEN];
+ struct rte_ether_addr mac_addr;
+ struct rte_device *dev;
+ struct rte_devargs da;
+ portid_t port_id;
+ char devstr[128];
+
+ memset(&da, 0, sizeof(da));
+ if (!identifier)
+ goto skip_parse;
+
+ if (rte_devargs_parsef(&da, "%s", identifier)) {
+ printf("cannot parse identifier\n");
+ if (da.args)
+ free(da.args);
+ return;
+ }
+
+skip_parse:
+ while ((next = rte_bus_find(start, bus_match_all, NULL)) != NULL) {
+
+ start = next;
+ if (identifier && da.bus != next)
+ continue;
+
+ /* Skip buses that don't have iterate method */
+ if (!next->dev_iterate)
+ continue;
+
+ snprintf(devstr, sizeof(devstr), "bus=%s", next->name);
+ RTE_DEV_FOREACH(dev, devstr, &dev_iter) {
+
+ if (!dev->driver)
+ continue;
+ /* Check for matching device if identifier is present */
+ if (identifier &&
+ strncmp(da.name, dev->name, strlen(dev->name)))
+ continue;
+ printf("\n%s Infos for device %s %s\n",
+ info_border, dev->name, info_border);
+ printf("Bus name: %s", dev->bus->name);
+ printf("\nDriver name: %s", dev->driver->name);
+ printf("\nDevargs: %s",
+ dev->devargs ? dev->devargs->args : "");
+ printf("\nConnect to socket: %d", dev->numa_node);
+ printf("\n");
+
+ /* List ports with matching device name */
+ RTE_ETH_FOREACH_DEV_OF(port_id, dev) {
+ printf("\n\tPort id: %-2d", port_id);
+ if (eth_macaddr_get_print_err(port_id,
+ &mac_addr) == 0)
+ print_ethaddr("\n\tMAC address: ",
+ &mac_addr);
+ rte_eth_dev_get_name_by_port(port_id, name);
+ printf("\n\tDevice name: %s", name);
+ printf("\n");
+ }
+ }
+ };
+}
+
void
port_infos_display(portid_t port_id)
{
struct rte_port *port;
- struct ether_addr mac_addr;
+ struct rte_ether_addr mac_addr;
struct rte_eth_link link;
struct rte_eth_dev_info dev_info;
int vlan_offload;
static const char *info_border = "*********************";
uint16_t mtu;
char name[RTE_ETH_NAME_MAX_LEN];
+ int ret;
if (port_id_is_invalid(port_id, ENABLED_WARN)) {
print_valid_ports();
return;
}
port = &ports[port_id];
- rte_eth_link_get_nowait(port_id, &link);
- memset(&dev_info, 0, sizeof(dev_info));
- rte_eth_dev_info_get(port_id, &dev_info);
+ ret = eth_link_get_nowait_print_err(port_id, &link);
+ if (ret < 0)
+ return;
+
+ ret = eth_dev_info_get_print_err(port_id, &dev_info);
+ if (ret != 0)
+ return;
+
printf("\n%s Infos for port %-2d %s\n",
info_border, port_id, info_border);
- rte_eth_macaddr_get(port_id, &mac_addr);
- print_ethaddr("MAC address: ", &mac_addr);
+ if (eth_macaddr_get_print_err(port_id, &mac_addr) == 0)
+ print_ethaddr("MAC address: ", &mac_addr);
rte_eth_dev_get_name_by_port(port_id, name);
printf("\nDevice name: %s", name);
printf("\nDriver name: %s", dev_info.driver_name);
+ if (dev_info.device->devargs && dev_info.device->devargs->args)
+ printf("\nDevargs: %s", dev_info.device->devargs->args);
printf("\nConnect to socket: %u", port->socket_id);
if (port_numa[port_id] != NUMA_NO_CONFIG) {
printf("Min possible number of TXDs per queue: %hu\n",
dev_info.tx_desc_lim.nb_min);
printf("TXDs number alignment: %hu\n", dev_info.tx_desc_lim.nb_align);
+ printf("Max segment number per packet: %hu\n",
+ dev_info.tx_desc_lim.nb_seg_max);
+ printf("Max segment number per MTU/TSO: %hu\n",
+ dev_info.tx_desc_lim.nb_mtu_seg_max);
/* Show switch info only if valid switch domain and port id is set */
if (dev_info.switch_info.domain_id !=
}
}
+void
+port_summary_header_display(void)
+{
+ uint16_t port_number;
+
+ port_number = rte_eth_dev_count_avail();
+ printf("Number of available ports: %i\n", port_number);
+ printf("%-4s %-17s %-12s %-14s %-8s %s\n", "Port", "MAC Address", "Name",
+ "Driver", "Status", "Link");
+}
+
+void
+port_summary_display(portid_t port_id)
+{
+ struct rte_ether_addr mac_addr;
+ struct rte_eth_link link;
+ struct rte_eth_dev_info dev_info;
+ char name[RTE_ETH_NAME_MAX_LEN];
+ int ret;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN)) {
+ print_valid_ports();
+ return;
+ }
+
+ ret = eth_link_get_nowait_print_err(port_id, &link);
+ if (ret < 0)
+ return;
+
+ ret = eth_dev_info_get_print_err(port_id, &dev_info);
+ if (ret != 0)
+ return;
+
+ rte_eth_dev_get_name_by_port(port_id, name);
+ ret = eth_macaddr_get_print_err(port_id, &mac_addr);
+ if (ret != 0)
+ return;
+
+ printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n",
+ port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
+ mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
+ mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
+ dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
+ (unsigned int) link.link_speed);
+}
+
void
port_offload_cap_display(portid_t port_id)
{
struct rte_eth_dev_info dev_info;
static const char *info_border = "************";
+ int ret;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
- rte_eth_dev_info_get(port_id, &dev_info);
+ ret = eth_dev_info_get_print_err(port_id, &dev_info);
+ if (ret != 0)
+ return;
printf("\n%s Port %d supported offload features: %s\n",
info_border, port_id, info_border);
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_QINQ_STRIP) {
printf("Double VLANs stripped: ");
if (ports[port_id].dev_conf.rxmode.offloads &
- DEV_RX_OFFLOAD_VLAN_EXTEND)
+ DEV_RX_OFFLOAD_QINQ_STRIP)
printf("on\n");
else
printf("off\n");
printf("off\n");
}
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_UDP_CKSUM) {
+ printf("RX Outer UDP checksum: ");
+ if (ports[port_id].dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_OUTER_UDP_CKSUM)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) {
printf("Large receive offload: ");
if (ports[port_id].dev_conf.rxmode.offloads &
else
printf("off\n");
}
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) {
+ printf("TX Outer UDP checksum: ");
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_OUTER_UDP_CKSUM)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
}
int
port_mtu_set(portid_t port_id, uint16_t mtu)
{
int diag;
+ struct rte_eth_dev_info dev_info;
+ int ret;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
+
+ ret = eth_dev_info_get_print_err(port_id, &dev_info);
+ if (ret != 0)
+ return;
+
+ if (mtu > dev_info.max_mtu || mtu < dev_info.min_mtu) {
+ printf("Set MTU failed. MTU:%u is not in valid range, min:%u - max:%u\n",
+ mtu, dev_info.min_mtu, dev_info.max_mtu);
+ return;
+ }
diag = rte_eth_dev_set_mtu(port_id, mtu);
if (diag == 0)
return;
char mz_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
- snprintf(mz_name, sizeof(mz_name), "%s_%s_%d_%d",
- ports[port_id].dev_info.driver_name, ring_name, port_id, q_id);
+ snprintf(mz_name, sizeof(mz_name), "eth_p%d_q%d_%s",
+ port_id, q_id, ring_name);
mz = rte_memzone_lookup(mz_name);
if (mz == NULL)
printf("%s ring memory zoneof (port %d, queue %d) not"
struct igb_ring_desc_16_bytes *ring =
(struct igb_ring_desc_16_bytes *)ring_mz->addr;
#ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
+ int ret;
struct rte_eth_dev_info dev_info;
- memset(&dev_info, 0, sizeof(dev_info));
- rte_eth_dev_info_get(port_id, &dev_info);
+ ret = eth_dev_info_get_print_err(port_id, &dev_info);
+ if (ret != 0)
+ return;
+
if (strstr(dev_info.driver_name, "i40e") != NULL) {
/* 32 bytes RX descriptor, i40e only */
struct igb_ring_desc_32_bytes *ring =
* key of the port.
*/
void
-port_rss_hash_conf_show(portid_t port_id, char rss_info[], int show_rss_key)
+port_rss_hash_conf_show(portid_t port_id, int show_rss_key)
{
- struct rte_eth_rss_conf rss_conf;
+ struct rte_eth_rss_conf rss_conf = {0};
uint8_t rss_key[RSS_HASH_KEY_LENGTH];
uint64_t rss_hf;
uint8_t i;
int diag;
struct rte_eth_dev_info dev_info;
uint8_t hash_key_size;
+ int ret;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
- memset(&dev_info, 0, sizeof(dev_info));
- rte_eth_dev_info_get(port_id, &dev_info);
+ ret = eth_dev_info_get_print_err(port_id, &dev_info);
+ if (ret != 0)
+ return;
+
if (dev_info.hash_key_size > 0 &&
dev_info.hash_key_size <= sizeof(rss_key))
hash_key_size = dev_info.hash_key_size;
return;
}
- rss_conf.rss_hf = 0;
- for (i = 0; rss_type_table[i].str; i++) {
- if (!strcmp(rss_info, rss_type_table[i].str))
- rss_conf.rss_hf = rss_type_table[i].rss_type;
- }
-
/* Get RSS hash key if asked to display it */
rss_conf.rss_key = (show_rss_key) ? rss_key : NULL;
rss_conf.rss_key_len = hash_key_size;
void
set_fwd_eth_peer(portid_t port_id, char *peer_addr)
{
- uint8_t c, new_peer_addr[6];
+ struct rte_ether_addr new_peer_addr;
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) {
+ if (rte_ether_unformat_addr(peer_addr, &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];
+ peer_eth_addrs[port_id] = new_peer_addr;
}
int
* Check that each segment length is greater or equal than
* the mbuf data sise.
* Check also that the total packet length is greater or equal than the
- * size of an empty UDP/IP packet (sizeof(struct ether_hdr) + 20 + 8).
+ * size of an empty UDP/IP packet (sizeof(struct rte_ether_hdr) +
+ * 20 + 8).
*/
tx_pkt_len = 0;
for (i = 0; i < nb_segs; i++) {
}
tx_pkt_len = (uint16_t)(tx_pkt_len + seg_lengths[i]);
}
- if (tx_pkt_len < (sizeof(struct ether_hdr) + 20 + 8)) {
+ if (tx_pkt_len < (sizeof(struct rte_ether_hdr) + 20 + 8)) {
printf("total packet length=%u < %d - give up\n",
(unsigned) tx_pkt_len,
- (int)(sizeof(struct ether_hdr) + 20 + 8));
+ (int)(sizeof(struct rte_ether_hdr) + 20 + 8));
return;
}
printf("Invalid %s packet forwarding mode\n", fwd_mode_name);
}
+void
+add_rx_dump_callbacks(portid_t portid)
+{
+ struct rte_eth_dev_info dev_info;
+ uint16_t queue;
+ int ret;
+
+ if (port_id_is_invalid(portid, ENABLED_WARN))
+ return;
+
+ ret = eth_dev_info_get_print_err(portid, &dev_info);
+ if (ret != 0)
+ return;
+
+ for (queue = 0; queue < dev_info.nb_rx_queues; queue++)
+ if (!ports[portid].rx_dump_cb[queue])
+ ports[portid].rx_dump_cb[queue] =
+ rte_eth_add_rx_callback(portid, queue,
+ dump_rx_pkts, NULL);
+}
+
+void
+add_tx_dump_callbacks(portid_t portid)
+{
+ struct rte_eth_dev_info dev_info;
+ uint16_t queue;
+ int ret;
+
+ if (port_id_is_invalid(portid, ENABLED_WARN))
+ return;
+
+ ret = eth_dev_info_get_print_err(portid, &dev_info);
+ if (ret != 0)
+ return;
+
+ for (queue = 0; queue < dev_info.nb_tx_queues; queue++)
+ if (!ports[portid].tx_dump_cb[queue])
+ ports[portid].tx_dump_cb[queue] =
+ rte_eth_add_tx_callback(portid, queue,
+ dump_tx_pkts, NULL);
+}
+
+void
+remove_rx_dump_callbacks(portid_t portid)
+{
+ struct rte_eth_dev_info dev_info;
+ uint16_t queue;
+ int ret;
+
+ if (port_id_is_invalid(portid, ENABLED_WARN))
+ return;
+
+ ret = eth_dev_info_get_print_err(portid, &dev_info);
+ if (ret != 0)
+ return;
+
+ for (queue = 0; queue < dev_info.nb_rx_queues; queue++)
+ if (ports[portid].rx_dump_cb[queue]) {
+ rte_eth_remove_rx_callback(portid, queue,
+ ports[portid].rx_dump_cb[queue]);
+ ports[portid].rx_dump_cb[queue] = NULL;
+ }
+}
+
+void
+remove_tx_dump_callbacks(portid_t portid)
+{
+ struct rte_eth_dev_info dev_info;
+ uint16_t queue;
+ int ret;
+
+ if (port_id_is_invalid(portid, ENABLED_WARN))
+ return;
+
+ ret = eth_dev_info_get_print_err(portid, &dev_info);
+ if (ret != 0)
+ return;
+
+ for (queue = 0; queue < dev_info.nb_tx_queues; queue++)
+ if (ports[portid].tx_dump_cb[queue]) {
+ rte_eth_remove_tx_callback(portid, queue,
+ ports[portid].tx_dump_cb[queue]);
+ ports[portid].tx_dump_cb[queue] = NULL;
+ }
+}
+
+void
+configure_rxtx_dump_callbacks(uint16_t verbose)
+{
+ portid_t portid;
+
+#ifndef RTE_ETHDEV_RXTX_CALLBACKS
+ TESTPMD_LOG(ERR, "setting rxtx callbacks is not enabled\n");
+ return;
+#endif
+
+ RTE_ETH_FOREACH_DEV(portid)
+ {
+ if (verbose == 1 || verbose > 2)
+ add_rx_dump_callbacks(portid);
+ else
+ remove_rx_dump_callbacks(portid);
+ if (verbose >= 2)
+ add_tx_dump_callbacks(portid);
+ else
+ remove_tx_dump_callbacks(portid);
+ }
+}
+
void
set_verbose_level(uint16_t vb_level)
{
printf("Change verbose level from %u to %u\n",
(unsigned int) verbose_level, (unsigned int) vb_level);
verbose_level = vb_level;
+ configure_rxtx_dump_callbacks(verbose_level);
}
void
void
tx_vlan_set(portid_t port_id, uint16_t vlan_id)
{
- int vlan_offload;
struct rte_eth_dev_info dev_info;
+ int ret;
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) {
+ if (ports[port_id].dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_QINQ_INSERT) {
printf("Error, as QinQ has been enabled.\n");
return;
}
- rte_eth_dev_info_get(port_id, &dev_info);
+
+ ret = eth_dev_info_get_print_err(port_id, &dev_info);
+ if (ret != 0)
+ return;
+
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);
void
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;
+ int ret;
if (port_id_is_invalid(port_id, ENABLED_WARN))
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");
+ ret = eth_dev_info_get_print_err(port_id, &dev_info);
+ if (ret != 0)
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);
}
tx_vlan_reset(port_id);
- ports[port_id].dev_conf.txmode.offloads |= DEV_TX_OFFLOAD_QINQ_INSERT;
+ ports[port_id].dev_conf.txmode.offloads |= (DEV_TX_OFFLOAD_VLAN_INSERT |
+ DEV_TX_OFFLOAD_QINQ_INSERT);
ports[port_id].tx_vlan_id = vlan_id;
ports[port_id].tx_vlan_id_outer = vlan_id_outer;
}
{
int diag;
struct rte_eth_link link;
+ int ret;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return 1;
- rte_eth_link_get_nowait(port_id, &link);
+ ret = eth_link_get_nowait_print_err(port_id, &link);
+ if (ret < 0)
+ return 1;
if (rate > link.link_speed) {
printf("Invalid rate value:%u bigger than link speed: %u\n",
rate, link.link_speed);
static int
mcast_addr_pool_extend(struct rte_port *port)
{
- struct ether_addr *mc_pool;
+ struct rte_ether_addr *mc_pool;
size_t mc_pool_size;
/*
* The previous test guarantees that port->mc_addr_nb is a multiple
* of MCAST_POOL_INC.
*/
- mc_pool_size = sizeof(struct ether_addr) * (port->mc_addr_nb +
+ mc_pool_size = sizeof(struct rte_ether_addr) * (port->mc_addr_nb +
MCAST_POOL_INC);
- mc_pool = (struct ether_addr *) realloc(port->mc_addr_pool,
+ mc_pool = (struct rte_ether_addr *) realloc(port->mc_addr_pool,
mc_pool_size);
if (mc_pool == NULL) {
printf("allocation of pool of %u multicast addresses failed\n",
}
memmove(&port->mc_addr_pool[addr_idx],
&port->mc_addr_pool[addr_idx + 1],
- sizeof(struct ether_addr) * (port->mc_addr_nb - addr_idx));
+ sizeof(struct rte_ether_addr) * (port->mc_addr_nb - addr_idx));
}
static void
}
void
-mcast_addr_add(portid_t port_id, struct ether_addr *mc_addr)
+mcast_addr_add(portid_t port_id, struct rte_ether_addr *mc_addr)
{
struct rte_port *port;
uint32_t i;
* in the pool of multicast addresses.
*/
for (i = 0; i < port->mc_addr_nb; i++) {
- if (is_same_ether_addr(mc_addr, &port->mc_addr_pool[i])) {
+ if (rte_is_same_ether_addr(mc_addr, &port->mc_addr_pool[i])) {
printf("multicast address already filtered by port\n");
return;
}
if (mcast_addr_pool_extend(port) != 0)
return;
- ether_addr_copy(mc_addr, &port->mc_addr_pool[i]);
+ rte_ether_addr_copy(mc_addr, &port->mc_addr_pool[i]);
eth_port_multicast_addr_list_set(port_id);
}
void
-mcast_addr_remove(portid_t port_id, struct ether_addr *mc_addr)
+mcast_addr_remove(portid_t port_id, struct rte_ether_addr *mc_addr)
{
struct rte_port *port;
uint32_t i;
* Search the pool of multicast MAC addresses for the removed address.
*/
for (i = 0; i < port->mc_addr_nb; i++) {
- if (is_same_ether_addr(mc_addr, &port->mc_addr_pool[i]))
+ if (rte_is_same_ether_addr(mc_addr, &port->mc_addr_pool[i]))
break;
}
if (i == port->mc_addr_nb) {