X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fconfig.c;h=4ac763849bc23a5c35396abc3a81f0f8ab6efac8;hb=4a83876faeb6d9e7e19e3b9ee212e55b8d637c3d;hp=ba43be52ef6435ee605a1ccd81719b2f15ebfcd7;hpb=a1be9d7dfc0c1ae6bf70fe234458ad4f90cf14f4;p=dpdk.git diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index ba43be52ef..4ac763849b 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -103,6 +103,10 @@ const struct rss_type_info rss_type_table[] = { { "tcp", ETH_RSS_TCP }, { "sctp", ETH_RSS_SCTP }, { "tunnel", ETH_RSS_TUNNEL }, + { "l3-src-only", ETH_RSS_L3_SRC_ONLY }, + { "l3-dst-only", ETH_RSS_L3_DST_ONLY }, + { "l4-src-only", ETH_RSS_L4_SRC_ONLY }, + { "l4-dst-only", ETH_RSS_L4_DST_ONLY }, { NULL, 0 }, }; @@ -119,9 +123,12 @@ 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_bytes_rx[RTE_MAX_ETHPORTS]; + static uint64_t prev_bytes_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; + uint64_t diff_pkts_rx, diff_pkts_tx, diff_bytes_rx, diff_bytes_tx, + diff_cycles; + uint64_t mpps_rx, mpps_tx, mbps_rx, mbps_tx; struct rte_eth_stats stats; struct rte_port *port = &ports[port_id]; uint8_t i; @@ -192,9 +199,22 @@ nic_stats_display(portid_t port_id) 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; + + diff_bytes_rx = (stats.ibytes > prev_bytes_rx[port_id]) ? + (stats.ibytes - prev_bytes_rx[port_id]) : 0; + diff_bytes_tx = (stats.obytes > prev_bytes_tx[port_id]) ? + (stats.obytes - prev_bytes_tx[port_id]) : 0; + prev_bytes_rx[port_id] = stats.ibytes; + prev_bytes_tx[port_id] = stats.obytes; + mbps_rx = diff_cycles > 0 ? + diff_bytes_rx * rte_get_tsc_hz() / diff_cycles : 0; + mbps_tx = diff_cycles > 0 ? + diff_bytes_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(" Rx-pps: %12"PRIu64" Rx-bps: %12"PRIu64"\n Tx-pps: %12" + PRIu64" Tx-bps: %12"PRIu64"\n", mpps_rx, mbps_rx * 8, + mpps_tx, mbps_tx * 8); printf(" %s############################%s\n", nic_stats_border, nic_stats_border); @@ -218,6 +238,10 @@ nic_xstats_display(portid_t port_id) int cnt_xstats, idx_xstat; struct rte_eth_xstat_name *xstats_names; + if (port_id_is_invalid(port_id, ENABLED_WARN)) { + print_valid_ports(); + return; + } 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); @@ -273,7 +297,17 @@ nic_xstats_display(portid_t port_id) void nic_xstats_clear(portid_t port_id) { - rte_eth_xstats_reset(port_id); + int ret; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) { + print_valid_ports(); + return; + } + 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 @@ -327,6 +361,7 @@ nic_stats_mapping_display(portid_t port_id) void rx_queue_infos_display(portid_t port_id, uint16_t queue_id) { + struct rte_eth_burst_mode mode; struct rte_eth_rxq_info qinfo; int32_t rc; static const char *info_border = "*********************"; @@ -354,12 +389,20 @@ rx_queue_infos_display(portid_t port_id, uint16_t queue_id) printf("\nRX scattered packets: %s", (qinfo.scattered_rx != 0) ? "on" : "off"); printf("\nNumber of RXDs: %hu", qinfo.nb_desc); + + if (rte_eth_rx_burst_mode_get(port_id, queue_id, &mode) == 0) + printf("\nBurst mode: %s%s", + mode.info, + mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ? + " (per queue)" : ""); + printf("\n"); } void tx_queue_infos_display(portid_t port_id, uint16_t queue_id) { + struct rte_eth_burst_mode mode; struct rte_eth_txq_info qinfo; int32_t rc; static const char *info_border = "*********************"; @@ -383,9 +426,91 @@ tx_queue_infos_display(portid_t port_id, uint16_t queue_id) printf("\nTX deferred start: %s", (qinfo.conf.tx_deferred_start != 0) ? "on" : "off"); printf("\nNumber of TXDs: %hu", qinfo.nb_desc); + + if (rte_eth_tx_burst_mode_get(port_id, queue_id, &mode) == 0) + printf("\nBurst mode: %s%s", + mode.info, + mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ? + " (per queue)" : ""); + 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) { @@ -398,19 +523,25 @@ port_infos_display(portid_t port_id) 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); @@ -447,19 +578,24 @@ port_infos_display(portid_t port_id) if (vlan_offload >= 0){ printf("VLAN offload: \n"); if (vlan_offload & ETH_VLAN_STRIP_OFFLOAD) - printf(" strip on \n"); + printf(" strip on, "); else - printf(" strip off \n"); + printf(" strip off, "); if (vlan_offload & ETH_VLAN_FILTER_OFFLOAD) - printf(" filter on \n"); + printf("filter on, "); else - printf(" filter off \n"); + printf("filter off, "); if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD) - printf(" qinq(extend) on \n"); + printf("extend on, "); + else + printf("extend off, "); + + if (vlan_offload & ETH_QINQ_STRIP_OFFLOAD) + printf("qinq strip on\n"); else - printf(" qinq(extend) off \n"); + printf("qinq strip off\n"); } if (dev_info.hash_key_size > 0) @@ -488,6 +624,8 @@ port_infos_display(portid_t port_id) 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); + printf("Maximum configurable size of LRO aggregated packet: %u\n", + dev_info.max_lro_pkt_size); if (dev_info.max_vfs) printf("Maximum number of VFs: %u\n", dev_info.max_vfs); if (dev_info.max_vmdq_pools) @@ -545,16 +683,25 @@ port_summary_display(portid_t port_id) 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; } - rte_eth_link_get_nowait(port_id, &link); - 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; + rte_eth_dev_get_name_by_port(port_id, name); - rte_eth_macaddr_get(port_id, &mac_addr); + 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], @@ -569,11 +716,14 @@ 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); @@ -1067,10 +1217,15 @@ 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; - 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 (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); @@ -1148,7 +1303,7 @@ port_flow_complain(struct rte_flow_error *error) errstr = "unknown type"; else errstr = errstrlist[error->type]; - printf("Caught error type %d (%s): %s%s: %s\n", + printf("%s(): Caught PMD error type %d (%s): %s%s: %s\n", __func__, error->type, errstr, error->cause ? (snprintf(buf, sizeof(buf), "cause: %p, ", error->cause), buf) : "", @@ -1548,10 +1703,13 @@ ring_rx_descriptor_display(const struct rte_memzone *ring_mz, 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 = @@ -1761,11 +1919,15 @@ port_rss_hash_conf_show(portid_t port_id, int show_rss_key) 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; - 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; @@ -2723,11 +2885,15 @@ 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; - rte_eth_dev_info_get(portid, &dev_info); + 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] = @@ -2740,10 +2906,15 @@ 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; - rte_eth_dev_info_get(portid, &dev_info); + + 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] = @@ -2756,10 +2927,15 @@ 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; - rte_eth_dev_info_get(portid, &dev_info); + + 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, @@ -2773,10 +2949,15 @@ 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; - rte_eth_dev_info_get(portid, &dev_info); + + 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, @@ -2912,6 +3093,33 @@ rx_vlan_filter_set(portid_t port_id, int on) ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads; } +void +rx_vlan_qinq_strip_set(portid_t port_id, int on) +{ + 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) { + vlan_offload |= ETH_QINQ_STRIP_OFFLOAD; + port_rx_offloads |= DEV_RX_OFFLOAD_QINQ_STRIP; + } else { + vlan_offload &= ~ETH_QINQ_STRIP_OFFLOAD; + port_rx_offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP; + } + + diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload); + if (diag < 0) + printf("%s(port_pi=%d, on=%d) failed " + "diag=%d\n", __func__, port_id, on, diag); + ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads; +} + int rx_vft_set(portid_t port_id, uint16_t vlan_id, int on) { @@ -2964,6 +3172,7 @@ void tx_vlan_set(portid_t port_id, uint16_t vlan_id) { struct rte_eth_dev_info dev_info; + int ret; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; @@ -2975,7 +3184,11 @@ tx_vlan_set(portid_t port_id, uint16_t vlan_id) 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); @@ -2991,6 +3204,7 @@ void tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer) { struct rte_eth_dev_info dev_info; + int ret; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; @@ -2999,7 +3213,10 @@ tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer) if (vlan_id_is_invalid(vlan_id_outer)) 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_QINQ_INSERT) == 0) { printf("Error: qinq insert not supported by port %d\n", port_id); @@ -3390,10 +3607,13 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate) { 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); @@ -3487,6 +3707,14 @@ mcast_addr_pool_extend(struct rte_port *port) } +static void +mcast_addr_pool_append(struct rte_port *port, struct rte_ether_addr *mc_addr) +{ + if (mcast_addr_pool_extend(port) != 0) + return; + rte_ether_addr_copy(mc_addr, &port->mc_addr_pool[port->mc_addr_nb - 1]); +} + static void mcast_addr_pool_remove(struct rte_port *port, uint32_t addr_idx) { @@ -3505,7 +3733,7 @@ mcast_addr_pool_remove(struct rte_port *port, uint32_t addr_idx) sizeof(struct rte_ether_addr) * (port->mc_addr_nb - addr_idx)); } -static void +static int eth_port_multicast_addr_list_set(portid_t port_id) { struct rte_port *port; @@ -3514,10 +3742,11 @@ eth_port_multicast_addr_list_set(portid_t port_id) port = &ports[port_id]; diag = rte_eth_dev_set_mc_addr_list(port_id, port->mc_addr_pool, port->mc_addr_nb); - if (diag == 0) - return; - printf("rte_eth_dev_set_mc_addr_list(port=%d, nb=%u) failed. diag=%d\n", - port->mc_addr_nb, port_id, -diag); + if (diag < 0) + printf("rte_eth_dev_set_mc_addr_list(port=%d, nb=%u) failed. diag=%d\n", + port_id, port->mc_addr_nb, diag); + + return diag; } void @@ -3542,10 +3771,10 @@ mcast_addr_add(portid_t port_id, struct rte_ether_addr *mc_addr) } } - if (mcast_addr_pool_extend(port) != 0) - return; - rte_ether_addr_copy(mc_addr, &port->mc_addr_pool[i]); - eth_port_multicast_addr_list_set(port_id); + mcast_addr_pool_append(port, mc_addr); + if (eth_port_multicast_addr_list_set(port_id) < 0) + /* Rollback on failure, remove the address from the pool */ + mcast_addr_pool_remove(port, i); } void @@ -3572,7 +3801,9 @@ mcast_addr_remove(portid_t port_id, struct rte_ether_addr *mc_addr) } mcast_addr_pool_remove(port, i); - eth_port_multicast_addr_list_set(port_id); + if (eth_port_multicast_addr_list_set(port_id) < 0) + /* Rollback on failure, add the address back into the pool */ + mcast_addr_pool_append(port, mc_addr); } void @@ -3745,3 +3976,60 @@ port_queue_region_info_display(portid_t port_id, void *buf) printf("\n\n"); } + +void +show_macs(portid_t port_id) +{ + char buf[RTE_ETHER_ADDR_FMT_SIZE]; + struct rte_eth_dev_info dev_info; + struct rte_ether_addr *addr; + uint32_t i, num_macs = 0; + struct rte_eth_dev *dev; + + dev = &rte_eth_devices[port_id]; + + rte_eth_dev_info_get(port_id, &dev_info); + + for (i = 0; i < dev_info.max_mac_addrs; i++) { + addr = &dev->data->mac_addrs[i]; + + /* skip zero address */ + if (rte_is_zero_ether_addr(addr)) + continue; + + num_macs++; + } + + printf("Number of MAC address added: %d\n", num_macs); + + for (i = 0; i < dev_info.max_mac_addrs; i++) { + addr = &dev->data->mac_addrs[i]; + + /* skip zero address */ + if (rte_is_zero_ether_addr(addr)) + continue; + + rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, addr); + printf(" %s\n", buf); + } +} + +void +show_mcast_macs(portid_t port_id) +{ + char buf[RTE_ETHER_ADDR_FMT_SIZE]; + struct rte_ether_addr *addr; + struct rte_port *port; + uint32_t i; + + port = &ports[port_id]; + + printf("Number of Multicast MAC address added: %d\n", port->mc_addr_nb); + + for (i = 0; i < port->mc_addr_nb; i++) { + addr = &port->mc_addr_pool[i]; + + rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, addr); + printf(" %s\n", buf); + } +}