X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fconfig.c;h=0062484fc582da4a6d31419ded6297d63a9b1395;hb=693f715da45c48ec1ec0fe4ba2f3b5ffd11ba53e;hp=69a83c2637e3fac2fa8fe500786842bbe71b29a6;hpb=44eb94569634c63d789b8a8125e16ed1b92c365c;p=dpdk.git diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 69a83c2637..0062484fc5 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include #include @@ -96,18 +95,48 @@ #include "testpmd.h" -static const char *flowtype_str[RTE_ETH_FLOW_TYPE_MAX] = { - NULL, - "udp4", - "tcp4", - "sctp4", - "ip4", - "ip4-frag", - "udp6", - "tcp6", - "sctp6", - "ip6", - "ip6-frag", +static char *flowtype_to_str(uint16_t flow_type); + +static const struct { + enum tx_pkt_split split; + const char *name; +} tx_split_name[] = { + { + .split = TX_PKT_SPLIT_OFF, + .name = "off", + }, + { + .split = TX_PKT_SPLIT_ON, + .name = "on", + }, + { + .split = TX_PKT_SPLIT_RND, + .name = "rand", + }, +}; + +struct rss_type_info { + char str[32]; + uint64_t rss_type; +}; + +static const struct rss_type_info rss_type_table[] = { + { "ipv4", ETH_RSS_IPV4 }, + { "ipv4-frag", ETH_RSS_FRAG_IPV4 }, + { "ipv4-tcp", ETH_RSS_NONFRAG_IPV4_TCP }, + { "ipv4-udp", ETH_RSS_NONFRAG_IPV4_UDP }, + { "ipv4-sctp", ETH_RSS_NONFRAG_IPV4_SCTP }, + { "ipv4-other", ETH_RSS_NONFRAG_IPV4_OTHER }, + { "ipv6", ETH_RSS_IPV6 }, + { "ipv6-frag", ETH_RSS_FRAG_IPV6 }, + { "ipv6-tcp", ETH_RSS_NONFRAG_IPV6_TCP }, + { "ipv6-udp", ETH_RSS_NONFRAG_IPV6_UDP }, + { "ipv6-sctp", ETH_RSS_NONFRAG_IPV6_SCTP }, + { "ipv6-other", ETH_RSS_NONFRAG_IPV6_OTHER }, + { "l2-payload", ETH_RSS_L2_PAYLOAD }, + { "ipv6-ex", ETH_RSS_IPV6_EX }, + { "ipv6-tcp-ex", ETH_RSS_IPV6_TCP_EX }, + { "ipv6-udp-ex", ETH_RSS_IPV6_UDP_EX }, }; static void @@ -124,11 +153,15 @@ nic_stats_display(portid_t port_id) struct rte_eth_stats stats; struct rte_port *port = &ports[port_id]; uint8_t i; + portid_t pid; static const char *nic_stats_border = "########################"; - if (port_id >= nb_ports) { - printf("Invalid port, range is [0, %d]\n", nb_ports - 1); + if (port_id_is_invalid(port_id, ENABLED_WARN)) { + printf("Valid port range is [0"); + FOREACH_PORT(pid, ports) + printf(", %d", pid); + printf("]\n"); return; } rte_eth_stats_get(port_id, &stats); @@ -139,9 +172,7 @@ nic_stats_display(portid_t port_id) 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: " @@ -152,9 +183,7 @@ nic_stats_display(portid_t port_id) 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 @@ -162,12 +191,6 @@ nic_stats_display(portid_t port_id) 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++) { @@ -186,14 +209,6 @@ nic_stats_display(portid_t port_id) } } - /* 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); - } printf(" %s############################%s\n", nic_stats_border, nic_stats_border); } @@ -201,8 +216,13 @@ nic_stats_display(portid_t port_id) void nic_stats_clear(portid_t port_id) { - if (port_id >= nb_ports) { - printf("Invalid port, range is [0, %d]\n", nb_ports - 1); + portid_t pid; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) { + printf("Valid port range is [0"); + FOREACH_PORT(pid, ports) + printf(", %d", pid); + printf("]\n"); return; } rte_eth_stats_reset(port_id); @@ -249,11 +269,15 @@ nic_stats_mapping_display(portid_t port_id) { struct rte_port *port = &ports[port_id]; uint16_t i; + portid_t pid; static const char *nic_stats_mapping_border = "########################"; - if (port_id >= nb_ports) { - printf("Invalid port, range is [0, %d]\n", nb_ports - 1); + if (port_id_is_invalid(port_id, ENABLED_WARN)) { + printf("Valid port range is [0"); + FOREACH_PORT(pid, ports) + printf(", %d", pid); + printf("]\n"); return; } @@ -292,6 +316,69 @@ nic_stats_mapping_display(portid_t port_id) nic_stats_mapping_border, nic_stats_mapping_border); } +void +rx_queue_infos_display(portid_t port_id, uint16_t queue_id) +{ + struct rte_eth_rxq_info qinfo; + int32_t rc; + static const char *info_border = "*********************"; + + rc = rte_eth_rx_queue_info_get(port_id, queue_id, &qinfo); + if (rc != 0) { + printf("Failed to retrieve information for port: %hhu, " + "RX queue: %hu\nerror desc: %s(%d)\n", + port_id, queue_id, strerror(-rc), rc); + return; + } + + printf("\n%s Infos for port %-2u, RX queue %-2u %s", + info_border, port_id, queue_id, info_border); + + printf("\nMempool: %s", (qinfo.mp == NULL) ? "NULL" : qinfo.mp->name); + printf("\nRX prefetch threshold: %hhu", qinfo.conf.rx_thresh.pthresh); + printf("\nRX host threshold: %hhu", qinfo.conf.rx_thresh.hthresh); + printf("\nRX writeback threshold: %hhu", qinfo.conf.rx_thresh.wthresh); + printf("\nRX free threshold: %hu", qinfo.conf.rx_free_thresh); + printf("\nRX drop packets: %s", + (qinfo.conf.rx_drop_en != 0) ? "on" : "off"); + printf("\nRX deferred start: %s", + (qinfo.conf.rx_deferred_start != 0) ? "on" : "off"); + printf("\nRX scattered packets: %s", + (qinfo.scattered_rx != 0) ? "on" : "off"); + printf("\nNumber of RXDs: %hu", qinfo.nb_desc); + printf("\n"); +} + +void +tx_queue_infos_display(portid_t port_id, uint16_t queue_id) +{ + struct rte_eth_txq_info qinfo; + int32_t rc; + static const char *info_border = "*********************"; + + rc = rte_eth_tx_queue_info_get(port_id, queue_id, &qinfo); + if (rc != 0) { + printf("Failed to retrieve information for port: %hhu, " + "TX queue: %hu\nerror desc: %s(%d)\n", + port_id, queue_id, strerror(-rc), rc); + return; + } + + printf("\n%s Infos for port %-2u, TX queue %-2u %s", + info_border, port_id, queue_id, info_border); + + printf("\nTX prefetch threshold: %hhu", qinfo.conf.tx_thresh.pthresh); + printf("\nTX host threshold: %hhu", qinfo.conf.tx_thresh.hthresh); + 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); + printf("\n"); +} + void port_infos_display(portid_t port_id) { @@ -302,9 +389,13 @@ port_infos_display(portid_t port_id) int vlan_offload; struct rte_mempool * mp; static const char *info_border = "*********************"; + portid_t pid; - if (port_id >= nb_ports) { - printf("Invalid port, range is [0, %d]\n", nb_ports - 1); + if (port_id_is_invalid(port_id, ENABLED_WARN)) { + printf("Valid port range is [0"); + FOREACH_PORT(pid, ports) + printf(", %d", pid); + printf("]\n"); return; } port = &ports[port_id]; @@ -357,16 +448,53 @@ port_infos_display(portid_t port_id) memset(&dev_info, 0, sizeof(dev_info)); rte_eth_dev_info_get(port_id, &dev_info); + if (dev_info.hash_key_size > 0) + printf("Hash key size in bytes: %u\n", dev_info.hash_key_size); if (dev_info.reta_size > 0) printf("Redirection table size: %u\n", dev_info.reta_size); + if (!dev_info.flow_type_rss_offloads) + printf("No flow type is supported.\n"); + else { + uint16_t i; + char *p; + + printf("Supported flow types:\n"); + for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < RTE_ETH_FLOW_MAX; + i++) { + if (!(dev_info.flow_type_rss_offloads & (1ULL << i))) + continue; + p = flowtype_to_str(i); + printf(" %s\n", (p ? p : "unknown")); + } + } + + 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); + printf("Min possible number of RXDs per queue: %hu\n", + dev_info.rx_desc_lim.nb_min); + printf("RXDs number alignment: %hu\n", dev_info.rx_desc_lim.nb_align); + + 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); + 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); } int -port_id_is_invalid(portid_t port_id) +port_id_is_invalid(portid_t port_id, enum print_warning warning) { - if (port_id < nb_ports) + if (port_id == (portid_t)RTE_PORT_ALL) + return 0; + + if (port_id < RTE_MAX_ETHPORTS && ports[port_id].enabled) return 0; - printf("Invalid port %d (must be < nb_ports=%d)\n", port_id, nb_ports); + + if (warning == ENABLED_WARN) + printf("Invalid port %d\n", port_id); + return 1; } @@ -425,7 +553,7 @@ port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_x) uint32_t reg_v; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (port_reg_off_is_invalid(port_id, reg_off)) return; @@ -444,7 +572,7 @@ port_reg_bit_field_display(portid_t port_id, uint32_t reg_off, uint8_t l_bit; uint8_t h_bit; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (port_reg_off_is_invalid(port_id, reg_off)) return; @@ -471,7 +599,7 @@ port_reg_display(portid_t port_id, uint32_t reg_off) { uint32_t reg_v; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (port_reg_off_is_invalid(port_id, reg_off)) return; @@ -485,7 +613,7 @@ port_reg_bit_set(portid_t port_id, uint32_t reg_off, uint8_t bit_pos, { uint32_t reg_v; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (port_reg_off_is_invalid(port_id, reg_off)) return; @@ -513,7 +641,7 @@ port_reg_bit_field_set(portid_t port_id, uint32_t reg_off, uint8_t l_bit; uint8_t h_bit; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (port_reg_off_is_invalid(port_id, reg_off)) return; @@ -547,7 +675,7 @@ port_reg_bit_field_set(portid_t port_id, uint32_t reg_off, void port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t reg_v) { - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (port_reg_off_is_invalid(port_id, reg_off)) return; @@ -560,7 +688,7 @@ port_mtu_set(portid_t port_id, uint16_t mtu) { int diag; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; diag = rte_eth_dev_set_mtu(port_id, mtu); if (diag == 0) @@ -622,7 +750,7 @@ ring_dma_zone_lookup(const char *ring_name, uint8_t port_id, uint16_t q_id) 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 { @@ -723,7 +851,7 @@ rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id) { const struct rte_memzone *rx_mz; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (rx_queue_id_is_invalid(rxq_id)) return; @@ -740,7 +868,7 @@ tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id) { const struct rte_memzone *tx_mz; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (tx_queue_id_is_invalid(txq_id)) return; @@ -774,18 +902,23 @@ rxtx_config_display(void) 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_free_thresh); + nb_rxq, nb_rxd, rx_conf->rx_free_thresh); printf(" RX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n", - rx_thresh.pthresh, rx_thresh.hthresh, rx_thresh.wthresh); + 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_free_thresh); + nb_txq, nb_txd, tx_conf->tx_free_thresh); printf(" TX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n", - tx_thresh.pthresh, tx_thresh.hthresh, tx_thresh.wthresh); + 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_rs_thresh, txq_flags); + tx_conf->tx_rs_thresh, tx_conf->txq_flags); } void @@ -796,7 +929,7 @@ port_rss_reta_info(portid_t port_id, uint16_t i, idx, shift; int ret; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; ret = rte_eth_dev_rss_reta_query(port_id, reta_conf, nb_entries); @@ -820,18 +953,26 @@ port_rss_reta_info(portid_t port_id, * key of the port. */ void -port_rss_hash_conf_show(portid_t port_id, int show_rss_key) +port_rss_hash_conf_show(portid_t port_id, char rss_info[], int show_rss_key) { struct rte_eth_rss_conf rss_conf; - uint8_t rss_key[10 * 4]; + uint8_t rss_key[10 * 4] = ""; uint64_t rss_hf; uint8_t i; int diag; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; + + rss_conf.rss_hf = 0; + for (i = 0; i < RTE_DIM(rss_type_table); 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 = sizeof(rss_key); diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf); if (diag != 0) { switch (diag) { @@ -853,24 +994,10 @@ port_rss_hash_conf_show(portid_t port_id, int show_rss_key) return; } printf("RSS functions:\n "); - if (rss_hf & ETH_RSS_IPV4) - printf("ip4"); - if (rss_hf & ETH_RSS_IPV4_TCP) - printf(" tcp4"); - if (rss_hf & ETH_RSS_IPV4_UDP) - printf(" udp4"); - if (rss_hf & ETH_RSS_IPV6) - printf(" ip6"); - if (rss_hf & ETH_RSS_IPV6_EX) - printf(" ip6-ex"); - if (rss_hf & ETH_RSS_IPV6_TCP) - printf(" tcp6"); - if (rss_hf & ETH_RSS_IPV6_TCP_EX) - printf(" tcp6-ex"); - if (rss_hf & ETH_RSS_IPV6_UDP) - printf(" udp6"); - if (rss_hf & ETH_RSS_IPV6_UDP_EX) - printf(" udp6-ex"); + for (i = 0; i < RTE_DIM(rss_type_table); i++) { + if (rss_hf & rss_type_table[i].rss_type) + printf("%s ", rss_type_table[i].str); + } printf("\n"); if (!show_rss_key) return; @@ -881,12 +1008,20 @@ port_rss_hash_conf_show(portid_t port_id, int show_rss_key) } void -port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key) +port_rss_hash_key_update(portid_t port_id, char rss_type[], uint8_t *hash_key, + uint hash_key_len) { struct rte_eth_rss_conf rss_conf; int diag; + unsigned int i; rss_conf.rss_key = NULL; + rss_conf.rss_key_len = hash_key_len; + rss_conf.rss_hf = 0; + for (i = 0; i < RTE_DIM(rss_type_table); i++) { + if (!strcmp(rss_type_table[i].str, rss_type)) + rss_conf.rss_hf = rss_type_table[i].rss_type; + } diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf); if (diag == 0) { rss_conf.rss_key = hash_key; @@ -1087,113 +1222,89 @@ rss_fwd_config_setup(void) } } -/* - * In DCB and VT on,the mapping of 128 receive queues to 128 transmit queues. - */ -static void -dcb_rxq_2_txq_mapping(queueid_t rxq, queueid_t *txq) -{ - if(dcb_q_mapping == DCB_4_TCS_Q_MAPPING) { - - if (rxq < 32) - /* tc0: 0-31 */ - *txq = rxq; - else if (rxq < 64) { - /* tc1: 64-95 */ - *txq = (uint16_t)(rxq + 32); - } - else { - /* tc2: 96-111;tc3:112-127 */ - *txq = (uint16_t)(rxq/2 + 64); - } - } - else { - if (rxq < 16) - /* tc0 mapping*/ - *txq = rxq; - else if (rxq < 32) { - /* tc1 mapping*/ - *txq = (uint16_t)(rxq + 16); - } - else if (rxq < 64) { - /*tc2,tc3 mapping */ - *txq = (uint16_t)(rxq + 32); - } - else { - /* tc4,tc5,tc6 and tc7 mapping */ - *txq = (uint16_t)(rxq/2 + 64); - } - } -} - /** - * For the DCB forwarding test, each core is assigned on every port multi-transmit - * queue. + * For the DCB forwarding test, each core is assigned on each traffic class. * * Each core is assigned a multi-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. - * 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: - * In VT mode, - * - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd - * - TxQl = RxQj - * In non-VT mode, - * - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd - * There is a mapping of RxQj to TxQl to be required,and the mapping was implemented - * in dcb_rxq_2_txq_mapping function. + * a TX queue of a TX port where to send forwarded packets. All RX and + * TX queues are mapping to the same traffic class. + * If VMDQ and DCB co-exist, each traffic class on different POOLs share + * the same core */ static void dcb_fwd_config_setup(void) { - portid_t rxp; - portid_t txp; - queueid_t rxq; - queueid_t nb_q; + struct rte_eth_dcb_info rxp_dcb_info, txp_dcb_info; + portid_t txp, rxp = 0; + queueid_t txq, rxq = 0; lcoreid_t lc_id; - uint16_t sm_id; - - nb_q = nb_rxq; + uint16_t nb_rx_queue, nb_tx_queue; + uint16_t i, j, k, sm_id = 0; + uint8_t tc = 0; cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores; 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); + (streamid_t) (nb_rxq * cur_fwd_config.nb_fwd_ports); /* reinitialize forwarding streams */ init_fwd_streams(); + sm_id = 0; + 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); - 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++) { - /* a fwd core can run multi-streams */ - for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) - { - struct fwd_stream *fs; - fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id]; - if ((rxp & 0x1) == 0) - txp = (portid_t) (rxp + 1); - else - txp = (portid_t) (rxp - 1); - fs->rx_port = fwd_ports_ids[rxp]; - fs->rx_queue = rxq; - fs->tx_port = fwd_ports_ids[txp]; - if (dcb_q_mapping == DCB_VT_Q_MAPPING) - fs->tx_queue = rxq; - else - dcb_rxq_2_txq_mapping(rxq, &fs->tx_queue); - fs->peer_addr = fs->tx_port; - rxq = (queueid_t) (rxq + 1); - if (rxq < nb_q) - continue; - 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); + fwd_lcores[lc_id]->stream_nb = 0; + fwd_lcores[lc_id]->stream_idx = sm_id; + for (i = 0; i < ETH_MAX_VMDQ_POOL; i++) { + /* if the nb_queue is zero, means this tc is + * not enabled on the POOL + */ + if (rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue == 0) + break; + k = fwd_lcores[lc_id]->stream_nb + + fwd_lcores[lc_id]->stream_idx; + rxq = rxp_dcb_info.tc_queue.tc_rxq[i][tc].base; + txq = txp_dcb_info.tc_queue.tc_txq[i][tc].base; + nb_rx_queue = txp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue; + nb_tx_queue = txp_dcb_info.tc_queue.tc_txq[i][tc].nb_queue; + for (j = 0; j < nb_rx_queue; j++) { + struct fwd_stream *fs; + + fs = fwd_streams[k + j]; + fs->rx_port = fwd_ports_ids[rxp]; + fs->rx_queue = rxq + j; + fs->tx_port = fwd_ports_ids[txp]; + fs->tx_queue = txq + j % nb_tx_queue; + fs->peer_addr = fs->tx_port; + } + fwd_lcores[lc_id]->stream_nb += + rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue; } + sm_id = (streamid_t) (sm_id + fwd_lcores[lc_id]->stream_nb); + + tc++; + if (tc < rxp_dcb_info.nb_tcs) + continue; + /* Restart from TC 0 on next RX port */ + tc = 0; + if (numa_support && (nb_fwd_ports <= (nb_ports >> 1))) + rxp = (portid_t) + (rxp + ((nb_ports >> 1) / nb_fwd_ports)); + else + rxp++; + if (rxp >= nb_fwd_ports) + return; + /* get the dcb information on next RX and TX ports */ + if ((rxp & 0x1) == 0) + txp = (portid_t) (rxp + 1); + else + txp = (portid_t) (rxp - 1); + rte_eth_dev_get_dcb_info(fwd_ports_ids[rxp], &rxp_dcb_info); + rte_eth_dev_get_dcb_info(fwd_ports_ids[txp], &txp_dcb_info); } } @@ -1237,7 +1348,7 @@ icmp_echo_config_setup(void) fs->rx_port = fwd_ports_ids[rxp]; fs->rx_queue = rxq; fs->tx_port = fs->rx_port; - fs->tx_queue = lc_id; + fs->tx_queue = rxq; fs->peer_addr = fs->tx_port; if (verbose_level > 0) printf(" stream=%d port=%d rxq=%d txq=%d\n", @@ -1313,10 +1424,6 @@ pkt_fwd_config_display(struct fwd_config *cfg) void fwd_config_display(void) { - if((dcb_config) && (nb_fwd_lcores == 1)) { - printf("In DCB mode,the nb forwarding cores should be larger than 1\n"); - return; - } fwd_config_setup(); pkt_fwd_config_display(&cur_fwd_config); } @@ -1406,12 +1513,8 @@ set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt) again: for (i = 0; i < nb_pt; i++) { port_id = (portid_t) portlist[i]; - if (port_id >= nb_ports) { - printf("Invalid port id %u >= %u\n", - (unsigned int) port_id, - (unsigned int) nb_ports); + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; - } if (record_now) fwd_ports_ids[i] = port_id; } @@ -1440,7 +1543,7 @@ set_fwd_ports_mask(uint64_t portmask) return; } nb_pt = 0; - for (i = 0; i < 64; i++) { + for (i = 0; i < (unsigned)RTE_MIN(64, RTE_MAX_ETHPORTS); i++) { if (! ((uint64_t)(1ULL << i) & portmask)) continue; portlist[nb_pt++] = i; @@ -1476,6 +1579,49 @@ set_nb_pkt_per_burst(uint16_t nb) (unsigned int) nb_pkt_per_burst); } +static const char * +tx_split_get_name(enum tx_pkt_split split) +{ + uint32_t i; + + for (i = 0; i != RTE_DIM(tx_split_name); i++) { + if (tx_split_name[i].split == split) + return tx_split_name[i].name; + } + return NULL; +} + +void +set_tx_pkt_split(const char *name) +{ + uint32_t i; + + for (i = 0; i != RTE_DIM(tx_split_name); i++) { + if (strcmp(tx_split_name[i].name, name) == 0) { + tx_pkt_split = tx_split_name[i].split; + return; + } + } + printf("unknown value: \"%s\"\n", name); +} + +void +show_tx_pkt_segments(void) +{ + uint32_t i, n; + const char *split; + + n = tx_pkt_nb_segs; + split = tx_split_get_name(tx_pkt_split); + + printf("Number of segments: %u\n", n); + printf("Segment sizes: "); + for (i = 0; i != n - 1; i++) + printf("%hu,", tx_pkt_seg_lengths[i]); + printf("%hu\n", tx_pkt_seg_lengths[i]); + printf("Split packet: %s\n", split); +} + void set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs) { @@ -1569,7 +1715,7 @@ vlan_extend_set(portid_t port_id, int on) int diag; int vlan_offload; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; vlan_offload = rte_eth_dev_get_vlan_offload(port_id); @@ -1591,7 +1737,7 @@ rx_vlan_strip_set(portid_t port_id, int on) int diag; int vlan_offload; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; vlan_offload = rte_eth_dev_get_vlan_offload(port_id); @@ -1612,7 +1758,7 @@ rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on) { int diag; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; diag = rte_eth_dev_set_vlan_strip_on_queue(port_id, queue_id, on); @@ -1627,7 +1773,7 @@ rx_vlan_filter_set(portid_t port_id, int on) int diag; int vlan_offload; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; vlan_offload = rte_eth_dev_get_vlan_offload(port_id); @@ -1643,21 +1789,22 @@ rx_vlan_filter_set(portid_t port_id, int on) "diag=%d\n", port_id, on, diag); } -void +int rx_vft_set(portid_t port_id, uint16_t vlan_id, int on) { int diag; - if (port_id_is_invalid(port_id)) - return; + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return 1; if (vlan_id_is_invalid(vlan_id)) - return; + return 1; diag = rte_eth_dev_vlan_filter(port_id, vlan_id, on); if (diag == 0) - return; + return 0; printf("rte_eth_dev_vlan_filter(port_pi=%d, vlan_id=%d, on=%d) failed " "diag=%d\n", port_id, vlan_id, on, diag); + return -1; } void @@ -1665,17 +1812,19 @@ rx_vlan_all_filter_set(portid_t port_id, int on) { uint16_t vlan_id; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; - for (vlan_id = 0; vlan_id < 4096; vlan_id++) - rx_vft_set(port_id, vlan_id, on); + for (vlan_id = 0; vlan_id < 4096; vlan_id++) { + if (rx_vft_set(port_id, vlan_id, on)) + break; + } } void vlan_tpid_set(portid_t port_id, uint16_t tp_id) { int diag; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id); @@ -1690,26 +1839,45 @@ vlan_tpid_set(portid_t port_id, uint16_t tp_id) void tx_vlan_set(portid_t port_id, uint16_t vlan_id) { - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (vlan_id_is_invalid(vlan_id)) 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) +{ + 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; + tx_vlan_reset(port_id); + ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_QINQ; + ports[port_id].tx_vlan_id = vlan_id; + ports[port_id].tx_vlan_id_outer = vlan_id_outer; +} + void tx_vlan_reset(portid_t port_id) { - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; - ports[port_id].tx_ol_flags &= ~TESTPMD_TX_OFFLOAD_INSERT_VLAN; + ports[port_id].tx_ol_flags &= ~(TESTPMD_TX_OFFLOAD_INSERT_VLAN | + TESTPMD_TX_OFFLOAD_INSERT_QINQ); + ports[port_id].tx_vlan_id = 0; + ports[port_id].tx_vlan_id_outer = 0; } void tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on) { - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; rte_eth_dev_set_vlan_pvid(port_id, vlan_id, on); @@ -1721,7 +1889,7 @@ set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value) uint16_t i; uint8_t existing_mapping_found = 0; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (is_rx ? (rx_queue_id_is_invalid(queue_id)) : (tx_queue_id_is_invalid(queue_id))) @@ -1767,69 +1935,45 @@ set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value) } } -void -fdir_add_signature_filter(portid_t port_id, uint8_t queue_id, - struct rte_fdir_filter *fdir_filter) -{ - int diag; - - if (port_id_is_invalid(port_id)) - return; - - diag = rte_eth_dev_fdir_add_signature_filter(port_id, fdir_filter, - queue_id); - if (diag == 0) - return; - - printf("rte_eth_dev_fdir_add_signature_filter for port_id=%d failed " - "diag=%d\n", port_id, diag); -} - -void -fdir_update_signature_filter(portid_t port_id, uint8_t queue_id, - struct rte_fdir_filter *fdir_filter) -{ - int diag; - - if (port_id_is_invalid(port_id)) - return; - - diag = rte_eth_dev_fdir_update_signature_filter(port_id, fdir_filter, - queue_id); - if (diag == 0) - return; - - printf("rte_eth_dev_fdir_update_signature_filter for port_id=%d failed " - "diag=%d\n", port_id, diag); -} - -void -fdir_remove_signature_filter(portid_t port_id, - struct rte_fdir_filter *fdir_filter) +static inline void +print_fdir_mask(struct rte_eth_fdir_masks *mask) { - int diag; + printf("\n vlan_tci: 0x%04x, ", mask->vlan_tci_mask); - if (port_id_is_invalid(port_id)) - return; - - diag = rte_eth_dev_fdir_remove_signature_filter(port_id, fdir_filter); - if (diag == 0) - return; + if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) + printf("mac_addr: 0x%02x", mask->mac_addr_byte_mask); + else if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_TUNNEL) + printf("mac_addr: 0x%02x, tunnel_type: 0x%01x, tunnel_id: 0x%08x", + mask->mac_addr_byte_mask, mask->tunnel_type_mask, + mask->tunnel_id_mask); + else { + printf("src_ipv4: 0x%08x, dst_ipv4: 0x%08x," + " src_port: 0x%04x, dst_port: 0x%04x", + mask->ipv4_mask.src_ip, mask->ipv4_mask.dst_ip, + mask->src_port_mask, mask->dst_port_mask); - printf("rte_eth_dev_fdir_add_signature_filter for port_id=%d failed " - "diag=%d\n", port_id, diag); + printf("\n src_ipv6: 0x%08x,0x%08x,0x%08x,0x%08x," + " dst_ipv6: 0x%08x,0x%08x,0x%08x,0x%08x", + mask->ipv6_mask.src_ip[0], mask->ipv6_mask.src_ip[1], + mask->ipv6_mask.src_ip[2], mask->ipv6_mask.src_ip[3], + mask->ipv6_mask.dst_ip[0], mask->ipv6_mask.dst_ip[1], + mask->ipv6_mask.dst_ip[2], mask->ipv6_mask.dst_ip[3]); + } + printf("\n"); } static inline void -print_fdir_flex_payload(struct rte_eth_fdir_flex_conf *flex_conf) +print_fdir_flex_payload(struct rte_eth_fdir_flex_conf *flex_conf, uint32_t num) { struct rte_eth_flex_payload_cfg *cfg; - int i, j; + uint32_t i, j; for (i = 0; i < flex_conf->nb_payloads; i++) { cfg = &flex_conf->flex_set[i]; - if (cfg->type == RTE_ETH_L2_PAYLOAD) + if (cfg->type == RTE_ETH_RAW_PAYLOAD) + printf("\n RAW: "); + else if (cfg->type == RTE_ETH_L2_PAYLOAD) printf("\n L2_PAYLOAD: "); else if (cfg->type == RTE_ETH_L3_PAYLOAD) printf("\n L3_PAYLOAD: "); @@ -1837,22 +1981,58 @@ print_fdir_flex_payload(struct rte_eth_fdir_flex_conf *flex_conf) printf("\n L4_PAYLOAD: "); else printf("\n UNKNOWN PAYLOAD(%u): ", cfg->type); - for (j = 0; j < RTE_ETH_FDIR_MAX_FLEXLEN; j++) + for (j = 0; j < num; j++) printf(" %-5u", cfg->src_offset[j]); } printf("\n"); } +static char * +flowtype_to_str(uint16_t flow_type) +{ + struct flow_type_info { + char str[32]; + uint16_t ftype; + }; + + uint8_t i; + static struct flow_type_info flowtype_str_table[] = { + {"raw", RTE_ETH_FLOW_RAW}, + {"ipv4", RTE_ETH_FLOW_IPV4}, + {"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4}, + {"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP}, + {"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP}, + {"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP}, + {"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER}, + {"ipv6", RTE_ETH_FLOW_IPV6}, + {"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6}, + {"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP}, + {"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP}, + {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP}, + {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER}, + {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD}, + }; + + for (i = 0; i < RTE_DIM(flowtype_str_table); i++) { + if (flowtype_str_table[i].ftype == flow_type) + return flowtype_str_table[i].str; + } + + return NULL; +} + static inline void -print_fdir_flex_mask(struct rte_eth_fdir_flex_conf *flex_conf) +print_fdir_flex_mask(struct rte_eth_fdir_flex_conf *flex_conf, uint32_t num) { struct rte_eth_fdir_flex_mask *mask; - int i, j; + uint32_t i, j; + char *p; for (i = 0; i < flex_conf->nb_flexmasks; i++) { mask = &flex_conf->flex_mask[i]; - printf("\n %s:\t", flowtype_str[mask->flow_type]); - for (j = 0; j < RTE_ETH_FDIR_MAX_FLEXLEN; j++) + p = flowtype_to_str(mask->flow_type); + printf("\n %s:\t", p ? p : "unknown"); + for (j = 0; j < num; j++) printf(" %02x", mask->mask[j]); } printf("\n"); @@ -1861,13 +2041,17 @@ print_fdir_flex_mask(struct rte_eth_fdir_flex_conf *flex_conf) static inline void print_fdir_flow_type(uint32_t flow_types_mask) { - int i = 0; + int i; + char *p; - for (i = RTE_ETH_FLOW_TYPE_UDPV4; - i <= RTE_ETH_FLOW_TYPE_FRAG_IPV6; - i++) { - if (flow_types_mask & (1 << i)) - printf(" %s", flowtype_str[i]); + for (i = RTE_ETH_FLOW_UNKNOWN; i < RTE_ETH_FLOW_MAX; i++) { + if (!(flow_types_mask & (1 << i))) + continue; + p = flowtype_to_str(i); + if (p) + printf(" %s", p); + else + printf(" unknown"); } printf("\n"); } @@ -1881,30 +2065,12 @@ fdir_get_infos(portid_t port_id) static const char *fdir_stats_border = "########################"; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; ret = rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_FDIR); if (ret < 0) { - /* use the old fdir APIs to get info */ - struct rte_eth_fdir fdir; - memset(&fdir, 0, sizeof(fdir)); - ret = rte_eth_dev_fdir_get_infos(port_id, &fdir); - if (ret < 0) { - printf("\n getting fdir info fails on port %-2d\n", - port_id); - return; - } - printf("\n %s FDIR infos for port %-2d %s\n", - fdir_stats_border, port_id, fdir_stats_border); - printf(" collision: %-10"PRIu64" free: %"PRIu64"\n" - " maxhash: %-10"PRIu64" maxlen: %"PRIu64"\n" - " add: %-10"PRIu64" remove: %"PRIu64"\n" - " f_add: %-10"PRIu64" f_remove: %"PRIu64"\n", - (uint64_t)(fdir.collision), (uint64_t)(fdir.free), - (uint64_t)(fdir.maxhash), (uint64_t)(fdir.maxlen), - fdir.add, fdir.remove, fdir.f_add, fdir.f_remove); - printf(" %s############################%s\n", - fdir_stats_border, fdir_stats_border); + printf("\n FDIR is not supported on port %-2d\n", + port_id); return; } @@ -1918,13 +2084,20 @@ fdir_get_infos(portid_t port_id) fdir_stats_border, port_id, fdir_stats_border); printf(" MODE: "); if (fdir_info.mode == RTE_FDIR_MODE_PERFECT) - printf(" PERFECT\n"); + printf(" PERFECT\n"); + else if (fdir_info.mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) + printf(" PERFECT-MAC-VLAN\n"); + else if (fdir_info.mode == RTE_FDIR_MODE_PERFECT_TUNNEL) + printf(" PERFECT-TUNNEL\n"); else if (fdir_info.mode == RTE_FDIR_MODE_SIGNATURE) - printf(" SIGNATURE\n"); + printf(" SIGNATURE\n"); else - printf(" DISABLE\n"); - printf(" SUPPORTED FLOW TYPE: "); - print_fdir_flow_type(fdir_info.flow_types_mask[0]); + printf(" DISABLE\n"); + if (fdir_info.mode != RTE_FDIR_MODE_PERFECT_MAC_VLAN + && fdir_info.mode != RTE_FDIR_MODE_PERFECT_TUNNEL) { + printf(" SUPPORTED FLOW TYPE: "); + print_fdir_flow_type(fdir_info.flow_types_mask[0]); + } printf(" FLEX PAYLOAD INFO:\n"); printf(" max_len: %-10"PRIu32" payload_limit: %-10"PRIu32"\n" " payload_unit: %-10"PRIu32" payload_seg: %-10"PRIu32"\n" @@ -1933,92 +2106,32 @@ fdir_get_infos(portid_t port_id) fdir_info.flex_payload_unit, fdir_info.max_flex_payload_segment_num, fdir_info.flex_bitmask_unit, fdir_info.max_flex_bitmask_num); + printf(" MASK: "); + print_fdir_mask(&fdir_info.mask); if (fdir_info.flex_conf.nb_payloads > 0) { printf(" FLEX PAYLOAD SRC OFFSET:"); - print_fdir_flex_payload(&fdir_info.flex_conf); + print_fdir_flex_payload(&fdir_info.flex_conf, fdir_info.max_flexpayload); } if (fdir_info.flex_conf.nb_flexmasks > 0) { printf(" FLEX MASK CFG:"); - print_fdir_flex_mask(&fdir_info.flex_conf); + print_fdir_flex_mask(&fdir_info.flex_conf, fdir_info.max_flexpayload); } - printf(" guarant_count: %-10"PRIu32" best_count: %-10"PRIu32"\n", + printf(" guarant_count: %-10"PRIu32" best_count: %"PRIu32"\n", fdir_stat.guarant_cnt, fdir_stat.best_cnt); - printf(" guarant_space: %-10"PRIu32" best_space: %-10"PRIu32"\n", - fdir_info.guarant_spc, fdir_info.guarant_spc); + printf(" guarant_space: %-10"PRIu32" best_space: %"PRIu32"\n", + fdir_info.guarant_spc, fdir_info.best_spc); + printf(" collision: %-10"PRIu32" free: %"PRIu32"\n" + " maxhash: %-10"PRIu32" maxlen: %"PRIu32"\n" + " add: %-10"PRIu64" remove: %"PRIu64"\n" + " f_add: %-10"PRIu64" f_remove: %"PRIu64"\n", + fdir_stat.collision, fdir_stat.free, + fdir_stat.maxhash, fdir_stat.maxlen, + fdir_stat.add, fdir_stat.remove, + fdir_stat.f_add, fdir_stat.f_remove); printf(" %s############################%s\n", fdir_stats_border, fdir_stats_border); } -void -fdir_add_perfect_filter(portid_t port_id, uint16_t soft_id, uint8_t queue_id, - uint8_t drop, struct rte_fdir_filter *fdir_filter) -{ - int diag; - - if (port_id_is_invalid(port_id)) - return; - - diag = rte_eth_dev_fdir_add_perfect_filter(port_id, fdir_filter, - soft_id, queue_id, drop); - if (diag == 0) - return; - - printf("rte_eth_dev_fdir_add_perfect_filter for port_id=%d failed " - "diag=%d\n", port_id, diag); -} - -void -fdir_update_perfect_filter(portid_t port_id, uint16_t soft_id, uint8_t queue_id, - uint8_t drop, struct rte_fdir_filter *fdir_filter) -{ - int diag; - - if (port_id_is_invalid(port_id)) - return; - - diag = rte_eth_dev_fdir_update_perfect_filter(port_id, fdir_filter, - soft_id, queue_id, drop); - if (diag == 0) - return; - - printf("rte_eth_dev_fdir_update_perfect_filter for port_id=%d failed " - "diag=%d\n", port_id, diag); -} - -void -fdir_remove_perfect_filter(portid_t port_id, uint16_t soft_id, - struct rte_fdir_filter *fdir_filter) -{ - int diag; - - if (port_id_is_invalid(port_id)) - return; - - diag = rte_eth_dev_fdir_remove_perfect_filter(port_id, fdir_filter, - soft_id); - if (diag == 0) - return; - - printf("rte_eth_dev_fdir_update_perfect_filter for port_id=%d failed " - "diag=%d\n", port_id, diag); -} - -void -fdir_set_masks(portid_t port_id, struct rte_fdir_masks *fdir_masks) -{ - int diag; - - if (port_id_is_invalid(port_id)) - return; - - diag = rte_eth_dev_fdir_set_masks(port_id, fdir_masks); - if (diag == 0) - return; - - printf("rte_eth_dev_set_masks_filter for port_id=%d failed " - "diag=%d\n", port_id, diag); -} - void fdir_set_flex_mask(portid_t port_id, struct rte_eth_fdir_flex_mask *cfg) { @@ -2028,13 +2141,13 @@ fdir_set_flex_mask(portid_t port_id, struct rte_eth_fdir_flex_mask *cfg) port = &ports[port_id]; flex_conf = &port->dev_conf.fdir_conf.flex_conf; - for (i = 0; i < RTE_ETH_FLOW_TYPE_MAX; i++) { + for (i = 0; i < RTE_ETH_FLOW_MAX; i++) { if (cfg->flow_type == flex_conf->flex_mask[i].flow_type) { idx = i; break; } } - if (i >= RTE_ETH_FLOW_TYPE_MAX) { + if (i >= RTE_ETH_FLOW_MAX) { if (flex_conf->nb_flexmasks < RTE_DIM(flex_conf->flex_mask)) { idx = flex_conf->nb_flexmasks; flex_conf->nb_flexmasks++; @@ -2085,7 +2198,7 @@ set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on) { int diag; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (is_rx) diag = rte_eth_dev_set_vf_rx(port_id,vf,on); @@ -2107,7 +2220,7 @@ set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on) { int diag; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (vlan_id_is_invalid(vlan_id)) return; @@ -2124,7 +2237,7 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate) int diag; struct rte_eth_link link; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return 1; rte_eth_link_get_nowait(port_id, &link); if (rate > link.link_speed) { @@ -2149,7 +2262,7 @@ set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk) if (q_msk == 0) return 0; - if (port_id_is_invalid(port_id)) + if (port_id_is_invalid(port_id, ENABLED_WARN)) return 1; rte_eth_link_get_nowait(port_id, &link); if (rate > link.link_speed) { @@ -2165,150 +2278,187 @@ set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk) return diag; } -void -get_ethertype_filter(uint8_t port_id, uint16_t index) +/* + * Functions to manage the set of filtered Multicast MAC addresses. + * + * A pool of filtered multicast MAC addresses is associated with each port. + * The pool is allocated in chunks of MCAST_POOL_INC multicast addresses. + * The address of the pool and the number of valid multicast MAC addresses + * recorded in the pool are stored in the fields "mc_addr_pool" and + * "mc_addr_nb" of the "rte_port" data structure. + * + * The function "rte_eth_dev_set_mc_addr_list" of the PMDs API imposes + * to be supplied a contiguous array of multicast MAC addresses. + * To comply with this constraint, the set of multicast addresses recorded + * into the pool are systematically compacted at the beginning of the pool. + * Hence, when a multicast address is removed from the pool, all following + * addresses, if any, are copied back to keep the set contiguous. + */ +#define MCAST_POOL_INC 32 + +static int +mcast_addr_pool_extend(struct rte_port *port) { - struct rte_ethertype_filter filter; - int ret = 0; - uint16_t rx_queue; + struct ether_addr *mc_pool; + size_t mc_pool_size; - memset(&filter, 0, sizeof(filter)); - ret = rte_eth_dev_get_ethertype_filter(port_id, index, - &filter, &rx_queue); - if (ret < 0) { - if (ret == (-ENOENT)) - printf("filter[%d] is not enabled\n", index); - else - printf("get ethertype filter fails(%s)\n", strerror(-ret)); - return; - } else { - printf("filter[%d]:\n", index); - printf(" ethertype: 0x%04x\n", - rte_le_to_cpu_32(filter.ethertype)); - printf(" priority: %s, %d\n", - filter.priority_en ? "enable" : "disable", - filter.priority); - printf(" queue: %d\n", rx_queue); + /* + * If a free entry is available at the end of the pool, just + * increment the number of recorded multicast addresses. + */ + if ((port->mc_addr_nb % MCAST_POOL_INC) != 0) { + port->mc_addr_nb++; + return 0; } -} -void -get_syn_filter(uint8_t port_id) -{ - struct rte_syn_filter filter; - int ret = 0; - uint16_t rx_queue; + /* + * [re]allocate a pool with MCAST_POOL_INC more entries. + * 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 + + MCAST_POOL_INC); + mc_pool = (struct ether_addr *) realloc(port->mc_addr_pool, + mc_pool_size); + if (mc_pool == NULL) { + printf("allocation of pool of %u multicast addresses failed\n", + port->mc_addr_nb + MCAST_POOL_INC); + return -ENOMEM; + } + + port->mc_addr_pool = mc_pool; + port->mc_addr_nb++; + return 0; - memset(&filter, 0, sizeof(filter)); - ret = rte_eth_dev_get_syn_filter(port_id, &filter, &rx_queue); +} - if (ret < 0) { - if (ret == (-ENOENT)) - printf("syn filter is not enabled\n"); - else - printf("get syn filter fails(%s)\n", strerror(-ret)); +static void +mcast_addr_pool_remove(struct rte_port *port, uint32_t addr_idx) +{ + port->mc_addr_nb--; + if (addr_idx == port->mc_addr_nb) { + /* No need to recompact the set of multicast addressses. */ + if (port->mc_addr_nb == 0) { + /* free the pool of multicast addresses. */ + free(port->mc_addr_pool); + port->mc_addr_pool = NULL; + } return; } - printf("syn filter: priority: %s, queue: %d\n", - filter.hig_pri ? "high" : "low", - rx_queue); + memmove(&port->mc_addr_pool[addr_idx], + &port->mc_addr_pool[addr_idx + 1], + sizeof(struct ether_addr) * (port->mc_addr_nb - addr_idx)); } -void -get_2tuple_filter(uint8_t port_id, uint16_t index) + +static void +eth_port_multicast_addr_list_set(uint8_t port_id) { - struct rte_2tuple_filter filter; - int ret = 0; - uint16_t rx_queue; + struct rte_port *port; + int diag; - memset(&filter, 0, sizeof(filter)); - ret = rte_eth_dev_get_2tuple_filter(port_id, index, - &filter, &rx_queue); - if (ret < 0) { - if (ret == (-ENOENT)) - printf("filter[%d] is not enabled\n", index); - else - printf("get 2tuple filter fails(%s)\n", strerror(-ret)); + 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; - } else { - printf("filter[%d]:\n", index); - printf(" Destination Port: 0x%04x mask: %d\n", - rte_be_to_cpu_16(filter.dst_port), - filter.dst_port_mask ? 0 : 1); - printf(" protocol: 0x%02x mask:%d tcp_flags: 0x%02x\n", - filter.protocol, filter.protocol_mask ? 0 : 1, - filter.tcp_flags); - printf(" priority: %d queue: %d\n", - filter.priority, rx_queue); - } + printf("rte_eth_dev_set_mc_addr_list(port=%d, nb=%u) failed. diag=%d\n", + port->mc_addr_nb, port_id, -diag); } void -get_5tuple_filter(uint8_t port_id, uint16_t index) +mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr) { - struct rte_5tuple_filter filter; - int ret = 0; - uint16_t rx_queue; + struct rte_port *port; + uint32_t i; - memset(&filter, 0, sizeof(filter)); - ret = rte_eth_dev_get_5tuple_filter(port_id, index, - &filter, &rx_queue); - if (ret < 0) { - if (ret == (-ENOENT)) - printf("filter[%d] is not enabled\n", index); - else - printf("get 5tuple filter fails(%s)\n", strerror(-ret)); + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; - } else { - printf("filter[%d]:\n", index); - printf(" Destination IP: 0x%08x mask: %d\n", - (unsigned)rte_be_to_cpu_32(filter.dst_ip), - filter.dst_ip_mask ? 0 : 1); - printf(" Source IP: 0x%08x mask: %d\n", - (unsigned)rte_be_to_cpu_32(filter.src_ip), - filter.src_ip_mask ? 0 : 1); - printf(" Destination Port: 0x%04x mask: %d\n", - rte_be_to_cpu_16(filter.dst_port), - filter.dst_port_mask ? 0 : 1); - printf(" Source Port: 0x%04x mask: %d\n", - rte_be_to_cpu_16(filter.src_port), - filter.src_port_mask ? 0 : 1); - printf(" protocol: 0x%02x mask: %d\n", - filter.protocol, - filter.protocol_mask ? 0 : 1); - printf(" priority: %d flags: 0x%02x queue: %d\n", - filter.priority, filter.tcp_flags, rx_queue); + + port = &ports[port_id]; + + /* + * Check that the added multicast MAC address is not already recorded + * 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])) { + 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]); + eth_port_multicast_addr_list_set(port_id); } -void -get_flex_filter(uint8_t port_id, uint16_t index) +void +mcast_addr_remove(uint8_t port_id, struct ether_addr *mc_addr) { - struct rte_flex_filter filter; - int ret = 0; - uint16_t rx_queue; - int i, j; + struct rte_port *port; + uint32_t i; - memset(&filter, 0, sizeof(filter)); - ret = rte_eth_dev_get_flex_filter(port_id, index, - &filter, &rx_queue); - if (ret < 0) { - if (ret == (-ENOENT)) - printf("filter[%d] is not enabled\n", index); - else - printf("get flex filter fails(%s)\n", strerror(-ret)); + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; - } else { - printf("filter[%d]: ", index); - printf("\n length: %d", filter.len); - printf("\n dword[]: 0x"); - for (i = 0; i < 32; i++) - printf("%08x ", (unsigned)rte_be_to_cpu_32(filter.dwords[i])); - printf("\n mask[]: 0b"); - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - printf("%c", (filter.mask[i] & (1 << j)) ? '1' : '0'); - } - printf("\n priority: %d queue: %d\n", - filter.priority, rx_queue); + + port = &ports[port_id]; + + /* + * 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])) + break; } + if (i == port->mc_addr_nb) { + printf("multicast address not filtered by port %d\n", port_id); + return; + } + + mcast_addr_pool_remove(port, i); + eth_port_multicast_addr_list_set(port_id); +} + +void +port_dcb_info_display(uint8_t port_id) +{ + struct rte_eth_dcb_info dcb_info; + uint16_t i; + int ret; + static const char *border = "================"; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; + + ret = rte_eth_dev_get_dcb_info(port_id, &dcb_info); + if (ret) { + printf("\n Failed to get dcb infos on port %-2d\n", + port_id); + return; + } + printf("\n %s DCB infos for port %-2d %s\n", border, port_id, border); + printf(" TC NUMBER: %d\n", dcb_info.nb_tcs); + printf("\n TC : "); + for (i = 0; i < dcb_info.nb_tcs; i++) + printf("\t%4d", i); + printf("\n Priority : "); + for (i = 0; i < dcb_info.nb_tcs; i++) + printf("\t%4d", dcb_info.prio_tc[i]); + printf("\n BW percent :"); + for (i = 0; i < dcb_info.nb_tcs; i++) + printf("\t%4d%%", dcb_info.tc_bws[i]); + printf("\n RXQ base : "); + for (i = 0; i < dcb_info.nb_tcs; i++) + printf("\t%4d", dcb_info.tc_queue.tc_rxq[0][i].base); + printf("\n RXQ number :"); + for (i = 0; i < dcb_info.nb_tcs; i++) + printf("\t%4d", dcb_info.tc_queue.tc_rxq[0][i].nb_queue); + printf("\n TXQ base : "); + for (i = 0; i < dcb_info.nb_tcs; i++) + printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].base); + printf("\n TXQ number :"); + for (i = 0; i < dcb_info.nb_tcs; i++) + printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue); + printf("\n"); }