app/testpmd: support flow aging
[dpdk.git] / app / test-pmd / config.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation.
3  * Copyright 2013-2014 6WIND S.A.
4  */
5
6 #include <stdarg.h>
7 #include <errno.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdint.h>
11 #include <inttypes.h>
12
13 #include <sys/queue.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18
19 #include <rte_common.h>
20 #include <rte_byteorder.h>
21 #include <rte_debug.h>
22 #include <rte_log.h>
23 #include <rte_memory.h>
24 #include <rte_memcpy.h>
25 #include <rte_memzone.h>
26 #include <rte_launch.h>
27 #include <rte_eal.h>
28 #include <rte_per_lcore.h>
29 #include <rte_lcore.h>
30 #include <rte_atomic.h>
31 #include <rte_branch_prediction.h>
32 #include <rte_mempool.h>
33 #include <rte_mbuf.h>
34 #include <rte_interrupts.h>
35 #include <rte_pci.h>
36 #include <rte_ether.h>
37 #include <rte_ethdev.h>
38 #include <rte_string_fns.h>
39 #include <rte_cycles.h>
40 #include <rte_flow.h>
41 #include <rte_errno.h>
42 #ifdef RTE_LIBRTE_IXGBE_PMD
43 #include <rte_pmd_ixgbe.h>
44 #endif
45 #ifdef RTE_LIBRTE_I40E_PMD
46 #include <rte_pmd_i40e.h>
47 #endif
48 #ifdef RTE_LIBRTE_BNXT_PMD
49 #include <rte_pmd_bnxt.h>
50 #endif
51 #include <rte_gro.h>
52
53 #include "testpmd.h"
54
55 #define ETHDEV_FWVERS_LEN 32
56
57 static char *flowtype_to_str(uint16_t flow_type);
58
59 static const struct {
60         enum tx_pkt_split split;
61         const char *name;
62 } tx_split_name[] = {
63         {
64                 .split = TX_PKT_SPLIT_OFF,
65                 .name = "off",
66         },
67         {
68                 .split = TX_PKT_SPLIT_ON,
69                 .name = "on",
70         },
71         {
72                 .split = TX_PKT_SPLIT_RND,
73                 .name = "rand",
74         },
75 };
76
77 const struct rss_type_info rss_type_table[] = {
78         { "all", ETH_RSS_ETH | ETH_RSS_VLAN | ETH_RSS_IP | ETH_RSS_TCP |
79                 ETH_RSS_UDP | ETH_RSS_SCTP | ETH_RSS_L2_PAYLOAD |
80                 ETH_RSS_L2TPV3 | ETH_RSS_ESP | ETH_RSS_AH | ETH_RSS_PFCP},
81         { "none", 0 },
82         { "eth", ETH_RSS_ETH },
83         { "l2-src-only", ETH_RSS_L2_SRC_ONLY },
84         { "l2-dst-only", ETH_RSS_L2_DST_ONLY },
85         { "vlan", ETH_RSS_VLAN },
86         { "s-vlan", ETH_RSS_S_VLAN },
87         { "c-vlan", ETH_RSS_C_VLAN },
88         { "ipv4", ETH_RSS_IPV4 },
89         { "ipv4-frag", ETH_RSS_FRAG_IPV4 },
90         { "ipv4-tcp", ETH_RSS_NONFRAG_IPV4_TCP },
91         { "ipv4-udp", ETH_RSS_NONFRAG_IPV4_UDP },
92         { "ipv4-sctp", ETH_RSS_NONFRAG_IPV4_SCTP },
93         { "ipv4-other", ETH_RSS_NONFRAG_IPV4_OTHER },
94         { "ipv6", ETH_RSS_IPV6 },
95         { "ipv6-frag", ETH_RSS_FRAG_IPV6 },
96         { "ipv6-tcp", ETH_RSS_NONFRAG_IPV6_TCP },
97         { "ipv6-udp", ETH_RSS_NONFRAG_IPV6_UDP },
98         { "ipv6-sctp", ETH_RSS_NONFRAG_IPV6_SCTP },
99         { "ipv6-other", ETH_RSS_NONFRAG_IPV6_OTHER },
100         { "l2-payload", ETH_RSS_L2_PAYLOAD },
101         { "ipv6-ex", ETH_RSS_IPV6_EX },
102         { "ipv6-tcp-ex", ETH_RSS_IPV6_TCP_EX },
103         { "ipv6-udp-ex", ETH_RSS_IPV6_UDP_EX },
104         { "port", ETH_RSS_PORT },
105         { "vxlan", ETH_RSS_VXLAN },
106         { "geneve", ETH_RSS_GENEVE },
107         { "nvgre", ETH_RSS_NVGRE },
108         { "ip", ETH_RSS_IP },
109         { "udp", ETH_RSS_UDP },
110         { "tcp", ETH_RSS_TCP },
111         { "sctp", ETH_RSS_SCTP },
112         { "tunnel", ETH_RSS_TUNNEL },
113         { "l3-src-only", ETH_RSS_L3_SRC_ONLY },
114         { "l3-dst-only", ETH_RSS_L3_DST_ONLY },
115         { "l4-src-only", ETH_RSS_L4_SRC_ONLY },
116         { "l4-dst-only", ETH_RSS_L4_DST_ONLY },
117         { "esp", ETH_RSS_ESP },
118         { "ah", ETH_RSS_AH },
119         { "l2tpv3", ETH_RSS_L2TPV3 },
120         { "pfcp", ETH_RSS_PFCP },
121         { NULL, 0 },
122 };
123
124 static void
125 print_ethaddr(const char *name, struct rte_ether_addr *eth_addr)
126 {
127         char buf[RTE_ETHER_ADDR_FMT_SIZE];
128         rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr);
129         printf("%s%s", name, buf);
130 }
131
132 void
133 nic_stats_display(portid_t port_id)
134 {
135         static uint64_t prev_pkts_rx[RTE_MAX_ETHPORTS];
136         static uint64_t prev_pkts_tx[RTE_MAX_ETHPORTS];
137         static uint64_t prev_bytes_rx[RTE_MAX_ETHPORTS];
138         static uint64_t prev_bytes_tx[RTE_MAX_ETHPORTS];
139         static uint64_t prev_cycles[RTE_MAX_ETHPORTS];
140         uint64_t diff_pkts_rx, diff_pkts_tx, diff_bytes_rx, diff_bytes_tx,
141                                                                 diff_cycles;
142         uint64_t mpps_rx, mpps_tx, mbps_rx, mbps_tx;
143         struct rte_eth_stats stats;
144         struct rte_port *port = &ports[port_id];
145         uint8_t i;
146
147         static const char *nic_stats_border = "########################";
148
149         if (port_id_is_invalid(port_id, ENABLED_WARN)) {
150                 print_valid_ports();
151                 return;
152         }
153         rte_eth_stats_get(port_id, &stats);
154         printf("\n  %s NIC statistics for port %-2d %s\n",
155                nic_stats_border, port_id, nic_stats_border);
156
157         if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
158                 printf("  RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes:  "
159                        "%-"PRIu64"\n",
160                        stats.ipackets, stats.imissed, stats.ibytes);
161                 printf("  RX-errors: %-"PRIu64"\n", stats.ierrors);
162                 printf("  RX-nombuf:  %-10"PRIu64"\n",
163                        stats.rx_nombuf);
164                 printf("  TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes:  "
165                        "%-"PRIu64"\n",
166                        stats.opackets, stats.oerrors, stats.obytes);
167         }
168         else {
169                 printf("  RX-packets:              %10"PRIu64"    RX-errors: %10"PRIu64
170                        "    RX-bytes: %10"PRIu64"\n",
171                        stats.ipackets, stats.ierrors, stats.ibytes);
172                 printf("  RX-errors:  %10"PRIu64"\n", stats.ierrors);
173                 printf("  RX-nombuf:               %10"PRIu64"\n",
174                        stats.rx_nombuf);
175                 printf("  TX-packets:              %10"PRIu64"    TX-errors: %10"PRIu64
176                        "    TX-bytes: %10"PRIu64"\n",
177                        stats.opackets, stats.oerrors, stats.obytes);
178         }
179
180         if (port->rx_queue_stats_mapping_enabled) {
181                 printf("\n");
182                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
183                         printf("  Stats reg %2d RX-packets: %10"PRIu64
184                                "    RX-errors: %10"PRIu64
185                                "    RX-bytes: %10"PRIu64"\n",
186                                i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]);
187                 }
188         }
189         if (port->tx_queue_stats_mapping_enabled) {
190                 printf("\n");
191                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
192                         printf("  Stats reg %2d TX-packets: %10"PRIu64
193                                "                             TX-bytes: %10"PRIu64"\n",
194                                i, stats.q_opackets[i], stats.q_obytes[i]);
195                 }
196         }
197
198         diff_cycles = prev_cycles[port_id];
199         prev_cycles[port_id] = rte_rdtsc();
200         if (diff_cycles > 0)
201                 diff_cycles = prev_cycles[port_id] - diff_cycles;
202
203         diff_pkts_rx = (stats.ipackets > prev_pkts_rx[port_id]) ?
204                 (stats.ipackets - prev_pkts_rx[port_id]) : 0;
205         diff_pkts_tx = (stats.opackets > prev_pkts_tx[port_id]) ?
206                 (stats.opackets - prev_pkts_tx[port_id]) : 0;
207         prev_pkts_rx[port_id] = stats.ipackets;
208         prev_pkts_tx[port_id] = stats.opackets;
209         mpps_rx = diff_cycles > 0 ?
210                 diff_pkts_rx * rte_get_tsc_hz() / diff_cycles : 0;
211         mpps_tx = diff_cycles > 0 ?
212                 diff_pkts_tx * rte_get_tsc_hz() / diff_cycles : 0;
213
214         diff_bytes_rx = (stats.ibytes > prev_bytes_rx[port_id]) ?
215                 (stats.ibytes - prev_bytes_rx[port_id]) : 0;
216         diff_bytes_tx = (stats.obytes > prev_bytes_tx[port_id]) ?
217                 (stats.obytes - prev_bytes_tx[port_id]) : 0;
218         prev_bytes_rx[port_id] = stats.ibytes;
219         prev_bytes_tx[port_id] = stats.obytes;
220         mbps_rx = diff_cycles > 0 ?
221                 diff_bytes_rx * rte_get_tsc_hz() / diff_cycles : 0;
222         mbps_tx = diff_cycles > 0 ?
223                 diff_bytes_tx * rte_get_tsc_hz() / diff_cycles : 0;
224
225         printf("\n  Throughput (since last show)\n");
226         printf("  Rx-pps: %12"PRIu64"          Rx-bps: %12"PRIu64"\n  Tx-pps: %12"
227                PRIu64"          Tx-bps: %12"PRIu64"\n", mpps_rx, mbps_rx * 8,
228                mpps_tx, mbps_tx * 8);
229
230         printf("  %s############################%s\n",
231                nic_stats_border, nic_stats_border);
232 }
233
234 void
235 nic_stats_clear(portid_t port_id)
236 {
237         if (port_id_is_invalid(port_id, ENABLED_WARN)) {
238                 print_valid_ports();
239                 return;
240         }
241         rte_eth_stats_reset(port_id);
242         printf("\n  NIC statistics for port %d cleared\n", port_id);
243 }
244
245 void
246 nic_xstats_display(portid_t port_id)
247 {
248         struct rte_eth_xstat *xstats;
249         int cnt_xstats, idx_xstat;
250         struct rte_eth_xstat_name *xstats_names;
251
252         if (port_id_is_invalid(port_id, ENABLED_WARN)) {
253                 print_valid_ports();
254                 return;
255         }
256         printf("###### NIC extended statistics for port %-2d\n", port_id);
257         if (!rte_eth_dev_is_valid_port(port_id)) {
258                 printf("Error: Invalid port number %i\n", port_id);
259                 return;
260         }
261
262         /* Get count */
263         cnt_xstats = rte_eth_xstats_get_names(port_id, NULL, 0);
264         if (cnt_xstats  < 0) {
265                 printf("Error: Cannot get count of xstats\n");
266                 return;
267         }
268
269         /* Get id-name lookup table */
270         xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * cnt_xstats);
271         if (xstats_names == NULL) {
272                 printf("Cannot allocate memory for xstats lookup\n");
273                 return;
274         }
275         if (cnt_xstats != rte_eth_xstats_get_names(
276                         port_id, xstats_names, cnt_xstats)) {
277                 printf("Error: Cannot get xstats lookup\n");
278                 free(xstats_names);
279                 return;
280         }
281
282         /* Get stats themselves */
283         xstats = malloc(sizeof(struct rte_eth_xstat) * cnt_xstats);
284         if (xstats == NULL) {
285                 printf("Cannot allocate memory for xstats\n");
286                 free(xstats_names);
287                 return;
288         }
289         if (cnt_xstats != rte_eth_xstats_get(port_id, xstats, cnt_xstats)) {
290                 printf("Error: Unable to get xstats\n");
291                 free(xstats_names);
292                 free(xstats);
293                 return;
294         }
295
296         /* Display xstats */
297         for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
298                 if (xstats_hide_zero && !xstats[idx_xstat].value)
299                         continue;
300                 printf("%s: %"PRIu64"\n",
301                         xstats_names[idx_xstat].name,
302                         xstats[idx_xstat].value);
303         }
304         free(xstats_names);
305         free(xstats);
306 }
307
308 void
309 nic_xstats_clear(portid_t port_id)
310 {
311         int ret;
312
313         if (port_id_is_invalid(port_id, ENABLED_WARN)) {
314                 print_valid_ports();
315                 return;
316         }
317         ret = rte_eth_xstats_reset(port_id);
318         if (ret != 0) {
319                 printf("%s: Error: failed to reset xstats (port %u): %s",
320                        __func__, port_id, strerror(ret));
321         }
322 }
323
324 void
325 nic_stats_mapping_display(portid_t port_id)
326 {
327         struct rte_port *port = &ports[port_id];
328         uint16_t i;
329
330         static const char *nic_stats_mapping_border = "########################";
331
332         if (port_id_is_invalid(port_id, ENABLED_WARN)) {
333                 print_valid_ports();
334                 return;
335         }
336
337         if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
338                 printf("Port id %d - either does not support queue statistic mapping or"
339                        " no queue statistic mapping set\n", port_id);
340                 return;
341         }
342
343         printf("\n  %s NIC statistics mapping for port %-2d %s\n",
344                nic_stats_mapping_border, port_id, nic_stats_mapping_border);
345
346         if (port->rx_queue_stats_mapping_enabled) {
347                 for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
348                         if (rx_queue_stats_mappings[i].port_id == port_id) {
349                                 printf("  RX-queue %2d mapped to Stats Reg %2d\n",
350                                        rx_queue_stats_mappings[i].queue_id,
351                                        rx_queue_stats_mappings[i].stats_counter_id);
352                         }
353                 }
354                 printf("\n");
355         }
356
357
358         if (port->tx_queue_stats_mapping_enabled) {
359                 for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
360                         if (tx_queue_stats_mappings[i].port_id == port_id) {
361                                 printf("  TX-queue %2d mapped to Stats Reg %2d\n",
362                                        tx_queue_stats_mappings[i].queue_id,
363                                        tx_queue_stats_mappings[i].stats_counter_id);
364                         }
365                 }
366         }
367
368         printf("  %s####################################%s\n",
369                nic_stats_mapping_border, nic_stats_mapping_border);
370 }
371
372 void
373 rx_queue_infos_display(portid_t port_id, uint16_t queue_id)
374 {
375         struct rte_eth_burst_mode mode;
376         struct rte_eth_rxq_info qinfo;
377         int32_t rc;
378         static const char *info_border = "*********************";
379
380         rc = rte_eth_rx_queue_info_get(port_id, queue_id, &qinfo);
381         if (rc != 0) {
382                 printf("Failed to retrieve information for port: %u, "
383                         "RX queue: %hu\nerror desc: %s(%d)\n",
384                         port_id, queue_id, strerror(-rc), rc);
385                 return;
386         }
387
388         printf("\n%s Infos for port %-2u, RX queue %-2u %s",
389                info_border, port_id, queue_id, info_border);
390
391         printf("\nMempool: %s", (qinfo.mp == NULL) ? "NULL" : qinfo.mp->name);
392         printf("\nRX prefetch threshold: %hhu", qinfo.conf.rx_thresh.pthresh);
393         printf("\nRX host threshold: %hhu", qinfo.conf.rx_thresh.hthresh);
394         printf("\nRX writeback threshold: %hhu", qinfo.conf.rx_thresh.wthresh);
395         printf("\nRX free threshold: %hu", qinfo.conf.rx_free_thresh);
396         printf("\nRX drop packets: %s",
397                 (qinfo.conf.rx_drop_en != 0) ? "on" : "off");
398         printf("\nRX deferred start: %s",
399                 (qinfo.conf.rx_deferred_start != 0) ? "on" : "off");
400         printf("\nRX scattered packets: %s",
401                 (qinfo.scattered_rx != 0) ? "on" : "off");
402         printf("\nNumber of RXDs: %hu", qinfo.nb_desc);
403
404         if (rte_eth_rx_burst_mode_get(port_id, queue_id, &mode) == 0)
405                 printf("\nBurst mode: %s%s",
406                        mode.info,
407                        mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
408                                 " (per queue)" : "");
409
410         printf("\n");
411 }
412
413 void
414 tx_queue_infos_display(portid_t port_id, uint16_t queue_id)
415 {
416         struct rte_eth_burst_mode mode;
417         struct rte_eth_txq_info qinfo;
418         int32_t rc;
419         static const char *info_border = "*********************";
420
421         rc = rte_eth_tx_queue_info_get(port_id, queue_id, &qinfo);
422         if (rc != 0) {
423                 printf("Failed to retrieve information for port: %u, "
424                         "TX queue: %hu\nerror desc: %s(%d)\n",
425                         port_id, queue_id, strerror(-rc), rc);
426                 return;
427         }
428
429         printf("\n%s Infos for port %-2u, TX queue %-2u %s",
430                info_border, port_id, queue_id, info_border);
431
432         printf("\nTX prefetch threshold: %hhu", qinfo.conf.tx_thresh.pthresh);
433         printf("\nTX host threshold: %hhu", qinfo.conf.tx_thresh.hthresh);
434         printf("\nTX writeback threshold: %hhu", qinfo.conf.tx_thresh.wthresh);
435         printf("\nTX RS threshold: %hu", qinfo.conf.tx_rs_thresh);
436         printf("\nTX free threshold: %hu", qinfo.conf.tx_free_thresh);
437         printf("\nTX deferred start: %s",
438                 (qinfo.conf.tx_deferred_start != 0) ? "on" : "off");
439         printf("\nNumber of TXDs: %hu", qinfo.nb_desc);
440
441         if (rte_eth_tx_burst_mode_get(port_id, queue_id, &mode) == 0)
442                 printf("\nBurst mode: %s%s",
443                        mode.info,
444                        mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
445                                 " (per queue)" : "");
446
447         printf("\n");
448 }
449
450 static int bus_match_all(const struct rte_bus *bus, const void *data)
451 {
452         RTE_SET_USED(bus);
453         RTE_SET_USED(data);
454         return 0;
455 }
456
457 void
458 device_infos_display(const char *identifier)
459 {
460         static const char *info_border = "*********************";
461         struct rte_bus *start = NULL, *next;
462         struct rte_dev_iterator dev_iter;
463         char name[RTE_ETH_NAME_MAX_LEN];
464         struct rte_ether_addr mac_addr;
465         struct rte_device *dev;
466         struct rte_devargs da;
467         portid_t port_id;
468         char devstr[128];
469
470         memset(&da, 0, sizeof(da));
471         if (!identifier)
472                 goto skip_parse;
473
474         if (rte_devargs_parsef(&da, "%s", identifier)) {
475                 printf("cannot parse identifier\n");
476                 if (da.args)
477                         free(da.args);
478                 return;
479         }
480
481 skip_parse:
482         while ((next = rte_bus_find(start, bus_match_all, NULL)) != NULL) {
483
484                 start = next;
485                 if (identifier && da.bus != next)
486                         continue;
487
488                 /* Skip buses that don't have iterate method */
489                 if (!next->dev_iterate)
490                         continue;
491
492                 snprintf(devstr, sizeof(devstr), "bus=%s", next->name);
493                 RTE_DEV_FOREACH(dev, devstr, &dev_iter) {
494
495                         if (!dev->driver)
496                                 continue;
497                         /* Check for matching device if identifier is present */
498                         if (identifier &&
499                             strncmp(da.name, dev->name, strlen(dev->name)))
500                                 continue;
501                         printf("\n%s Infos for device %s %s\n",
502                                info_border, dev->name, info_border);
503                         printf("Bus name: %s", dev->bus->name);
504                         printf("\nDriver name: %s", dev->driver->name);
505                         printf("\nDevargs: %s",
506                                dev->devargs ? dev->devargs->args : "");
507                         printf("\nConnect to socket: %d", dev->numa_node);
508                         printf("\n");
509
510                         /* List ports with matching device name */
511                         RTE_ETH_FOREACH_DEV_OF(port_id, dev) {
512                                 printf("\n\tPort id: %-2d", port_id);
513                                 if (eth_macaddr_get_print_err(port_id,
514                                                               &mac_addr) == 0)
515                                         print_ethaddr("\n\tMAC address: ",
516                                                       &mac_addr);
517                                 rte_eth_dev_get_name_by_port(port_id, name);
518                                 printf("\n\tDevice name: %s", name);
519                                 printf("\n");
520                         }
521                 }
522         };
523 }
524
525 void
526 port_infos_display(portid_t port_id)
527 {
528         struct rte_port *port;
529         struct rte_ether_addr mac_addr;
530         struct rte_eth_link link;
531         struct rte_eth_dev_info dev_info;
532         int vlan_offload;
533         struct rte_mempool * mp;
534         static const char *info_border = "*********************";
535         uint16_t mtu;
536         char name[RTE_ETH_NAME_MAX_LEN];
537         int ret;
538         char fw_version[ETHDEV_FWVERS_LEN];
539
540         if (port_id_is_invalid(port_id, ENABLED_WARN)) {
541                 print_valid_ports();
542                 return;
543         }
544         port = &ports[port_id];
545         ret = eth_link_get_nowait_print_err(port_id, &link);
546         if (ret < 0)
547                 return;
548
549         ret = eth_dev_info_get_print_err(port_id, &dev_info);
550         if (ret != 0)
551                 return;
552
553         printf("\n%s Infos for port %-2d %s\n",
554                info_border, port_id, info_border);
555         if (eth_macaddr_get_print_err(port_id, &mac_addr) == 0)
556                 print_ethaddr("MAC address: ", &mac_addr);
557         rte_eth_dev_get_name_by_port(port_id, name);
558         printf("\nDevice name: %s", name);
559         printf("\nDriver name: %s", dev_info.driver_name);
560
561         if (rte_eth_dev_fw_version_get(port_id, fw_version,
562                                                 ETHDEV_FWVERS_LEN) == 0)
563                 printf("\nFirmware-version: %s", fw_version);
564         else
565                 printf("\nFirmware-version: %s", "not available");
566
567         if (dev_info.device->devargs && dev_info.device->devargs->args)
568                 printf("\nDevargs: %s", dev_info.device->devargs->args);
569         printf("\nConnect to socket: %u", port->socket_id);
570
571         if (port_numa[port_id] != NUMA_NO_CONFIG) {
572                 mp = mbuf_pool_find(port_numa[port_id]);
573                 if (mp)
574                         printf("\nmemory allocation on the socket: %d",
575                                                         port_numa[port_id]);
576         } else
577                 printf("\nmemory allocation on the socket: %u",port->socket_id);
578
579         printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
580         printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
581         printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
582                ("full-duplex") : ("half-duplex"));
583
584         if (!rte_eth_dev_get_mtu(port_id, &mtu))
585                 printf("MTU: %u\n", mtu);
586
587         printf("Promiscuous mode: %s\n",
588                rte_eth_promiscuous_get(port_id) ? "enabled" : "disabled");
589         printf("Allmulticast mode: %s\n",
590                rte_eth_allmulticast_get(port_id) ? "enabled" : "disabled");
591         printf("Maximum number of MAC addresses: %u\n",
592                (unsigned int)(port->dev_info.max_mac_addrs));
593         printf("Maximum number of MAC addresses of hash filtering: %u\n",
594                (unsigned int)(port->dev_info.max_hash_mac_addrs));
595
596         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
597         if (vlan_offload >= 0){
598                 printf("VLAN offload: \n");
599                 if (vlan_offload & ETH_VLAN_STRIP_OFFLOAD)
600                         printf("  strip on, ");
601                 else
602                         printf("  strip off, ");
603
604                 if (vlan_offload & ETH_VLAN_FILTER_OFFLOAD)
605                         printf("filter on, ");
606                 else
607                         printf("filter off, ");
608
609                 if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)
610                         printf("extend on, ");
611                 else
612                         printf("extend off, ");
613
614                 if (vlan_offload & ETH_QINQ_STRIP_OFFLOAD)
615                         printf("qinq strip on\n");
616                 else
617                         printf("qinq strip off\n");
618         }
619
620         if (dev_info.hash_key_size > 0)
621                 printf("Hash key size in bytes: %u\n", dev_info.hash_key_size);
622         if (dev_info.reta_size > 0)
623                 printf("Redirection table size: %u\n", dev_info.reta_size);
624         if (!dev_info.flow_type_rss_offloads)
625                 printf("No RSS offload flow type is supported.\n");
626         else {
627                 uint16_t i;
628                 char *p;
629
630                 printf("Supported RSS offload flow types:\n");
631                 for (i = RTE_ETH_FLOW_UNKNOWN + 1;
632                      i < sizeof(dev_info.flow_type_rss_offloads) * CHAR_BIT; i++) {
633                         if (!(dev_info.flow_type_rss_offloads & (1ULL << i)))
634                                 continue;
635                         p = flowtype_to_str(i);
636                         if (p)
637                                 printf("  %s\n", p);
638                         else
639                                 printf("  user defined %d\n", i);
640                 }
641         }
642
643         printf("Minimum size of RX buffer: %u\n", dev_info.min_rx_bufsize);
644         printf("Maximum configurable length of RX packet: %u\n",
645                 dev_info.max_rx_pktlen);
646         printf("Maximum configurable size of LRO aggregated packet: %u\n",
647                 dev_info.max_lro_pkt_size);
648         if (dev_info.max_vfs)
649                 printf("Maximum number of VFs: %u\n", dev_info.max_vfs);
650         if (dev_info.max_vmdq_pools)
651                 printf("Maximum number of VMDq pools: %u\n",
652                         dev_info.max_vmdq_pools);
653
654         printf("Current number of RX queues: %u\n", dev_info.nb_rx_queues);
655         printf("Max possible RX queues: %u\n", dev_info.max_rx_queues);
656         printf("Max possible number of RXDs per queue: %hu\n",
657                 dev_info.rx_desc_lim.nb_max);
658         printf("Min possible number of RXDs per queue: %hu\n",
659                 dev_info.rx_desc_lim.nb_min);
660         printf("RXDs number alignment: %hu\n", dev_info.rx_desc_lim.nb_align);
661
662         printf("Current number of TX queues: %u\n", dev_info.nb_tx_queues);
663         printf("Max possible TX queues: %u\n", dev_info.max_tx_queues);
664         printf("Max possible number of TXDs per queue: %hu\n",
665                 dev_info.tx_desc_lim.nb_max);
666         printf("Min possible number of TXDs per queue: %hu\n",
667                 dev_info.tx_desc_lim.nb_min);
668         printf("TXDs number alignment: %hu\n", dev_info.tx_desc_lim.nb_align);
669         printf("Max segment number per packet: %hu\n",
670                 dev_info.tx_desc_lim.nb_seg_max);
671         printf("Max segment number per MTU/TSO: %hu\n",
672                 dev_info.tx_desc_lim.nb_mtu_seg_max);
673
674         /* Show switch info only if valid switch domain and port id is set */
675         if (dev_info.switch_info.domain_id !=
676                 RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) {
677                 if (dev_info.switch_info.name)
678                         printf("Switch name: %s\n", dev_info.switch_info.name);
679
680                 printf("Switch domain Id: %u\n",
681                         dev_info.switch_info.domain_id);
682                 printf("Switch Port Id: %u\n",
683                         dev_info.switch_info.port_id);
684         }
685 }
686
687 void
688 port_summary_header_display(void)
689 {
690         uint16_t port_number;
691
692         port_number = rte_eth_dev_count_avail();
693         printf("Number of available ports: %i\n", port_number);
694         printf("%-4s %-17s %-12s %-14s %-8s %s\n", "Port", "MAC Address", "Name",
695                         "Driver", "Status", "Link");
696 }
697
698 void
699 port_summary_display(portid_t port_id)
700 {
701         struct rte_ether_addr mac_addr;
702         struct rte_eth_link link;
703         struct rte_eth_dev_info dev_info;
704         char name[RTE_ETH_NAME_MAX_LEN];
705         int ret;
706
707         if (port_id_is_invalid(port_id, ENABLED_WARN)) {
708                 print_valid_ports();
709                 return;
710         }
711
712         ret = eth_link_get_nowait_print_err(port_id, &link);
713         if (ret < 0)
714                 return;
715
716         ret = eth_dev_info_get_print_err(port_id, &dev_info);
717         if (ret != 0)
718                 return;
719
720         rte_eth_dev_get_name_by_port(port_id, name);
721         ret = eth_macaddr_get_print_err(port_id, &mac_addr);
722         if (ret != 0)
723                 return;
724
725         printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n",
726                 port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
727                 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
728                 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
729                 dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
730                 (unsigned int) link.link_speed);
731 }
732
733 void
734 port_offload_cap_display(portid_t port_id)
735 {
736         struct rte_eth_dev_info dev_info;
737         static const char *info_border = "************";
738         int ret;
739
740         if (port_id_is_invalid(port_id, ENABLED_WARN))
741                 return;
742
743         ret = eth_dev_info_get_print_err(port_id, &dev_info);
744         if (ret != 0)
745                 return;
746
747         printf("\n%s Port %d supported offload features: %s\n",
748                 info_border, port_id, info_border);
749
750         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_VLAN_STRIP) {
751                 printf("VLAN stripped:                 ");
752                 if (ports[port_id].dev_conf.rxmode.offloads &
753                     DEV_RX_OFFLOAD_VLAN_STRIP)
754                         printf("on\n");
755                 else
756                         printf("off\n");
757         }
758
759         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_QINQ_STRIP) {
760                 printf("Double VLANs stripped:         ");
761                 if (ports[port_id].dev_conf.rxmode.offloads &
762                     DEV_RX_OFFLOAD_QINQ_STRIP)
763                         printf("on\n");
764                 else
765                         printf("off\n");
766         }
767
768         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM) {
769                 printf("RX IPv4 checksum:              ");
770                 if (ports[port_id].dev_conf.rxmode.offloads &
771                     DEV_RX_OFFLOAD_IPV4_CKSUM)
772                         printf("on\n");
773                 else
774                         printf("off\n");
775         }
776
777         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM) {
778                 printf("RX UDP checksum:               ");
779                 if (ports[port_id].dev_conf.rxmode.offloads &
780                     DEV_RX_OFFLOAD_UDP_CKSUM)
781                         printf("on\n");
782                 else
783                         printf("off\n");
784         }
785
786         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM) {
787                 printf("RX TCP checksum:               ");
788                 if (ports[port_id].dev_conf.rxmode.offloads &
789                     DEV_RX_OFFLOAD_TCP_CKSUM)
790                         printf("on\n");
791                 else
792                         printf("off\n");
793         }
794
795         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_SCTP_CKSUM) {
796                 printf("RX SCTP checksum:              ");
797                 if (ports[port_id].dev_conf.rxmode.offloads &
798                     DEV_RX_OFFLOAD_SCTP_CKSUM)
799                         printf("on\n");
800                 else
801                         printf("off\n");
802         }
803
804         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
805                 printf("RX Outer IPv4 checksum:        ");
806                 if (ports[port_id].dev_conf.rxmode.offloads &
807                     DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM)
808                         printf("on\n");
809                 else
810                         printf("off\n");
811         }
812
813         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_UDP_CKSUM) {
814                 printf("RX Outer UDP checksum:         ");
815                 if (ports[port_id].dev_conf.rxmode.offloads &
816                     DEV_RX_OFFLOAD_OUTER_UDP_CKSUM)
817                         printf("on\n");
818                 else
819                         printf("off\n");
820         }
821
822         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) {
823                 printf("Large receive offload:         ");
824                 if (ports[port_id].dev_conf.rxmode.offloads &
825                     DEV_RX_OFFLOAD_TCP_LRO)
826                         printf("on\n");
827                 else
828                         printf("off\n");
829         }
830
831         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TIMESTAMP) {
832                 printf("HW timestamp:                  ");
833                 if (ports[port_id].dev_conf.rxmode.offloads &
834                     DEV_RX_OFFLOAD_TIMESTAMP)
835                         printf("on\n");
836                 else
837                         printf("off\n");
838         }
839
840         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_KEEP_CRC) {
841                 printf("Rx Keep CRC:                   ");
842                 if (ports[port_id].dev_conf.rxmode.offloads &
843                     DEV_RX_OFFLOAD_KEEP_CRC)
844                         printf("on\n");
845                 else
846                         printf("off\n");
847         }
848
849         if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_SECURITY) {
850                 printf("RX offload security:           ");
851                 if (ports[port_id].dev_conf.rxmode.offloads &
852                     DEV_RX_OFFLOAD_SECURITY)
853                         printf("on\n");
854                 else
855                         printf("off\n");
856         }
857
858         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT) {
859                 printf("VLAN insert:                   ");
860                 if (ports[port_id].dev_conf.txmode.offloads &
861                     DEV_TX_OFFLOAD_VLAN_INSERT)
862                         printf("on\n");
863                 else
864                         printf("off\n");
865         }
866
867         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_QINQ_INSERT) {
868                 printf("Double VLANs insert:           ");
869                 if (ports[port_id].dev_conf.txmode.offloads &
870                     DEV_TX_OFFLOAD_QINQ_INSERT)
871                         printf("on\n");
872                 else
873                         printf("off\n");
874         }
875
876         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) {
877                 printf("TX IPv4 checksum:              ");
878                 if (ports[port_id].dev_conf.txmode.offloads &
879                     DEV_TX_OFFLOAD_IPV4_CKSUM)
880                         printf("on\n");
881                 else
882                         printf("off\n");
883         }
884
885         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) {
886                 printf("TX UDP checksum:               ");
887                 if (ports[port_id].dev_conf.txmode.offloads &
888                     DEV_TX_OFFLOAD_UDP_CKSUM)
889                         printf("on\n");
890                 else
891                         printf("off\n");
892         }
893
894         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) {
895                 printf("TX TCP checksum:               ");
896                 if (ports[port_id].dev_conf.txmode.offloads &
897                     DEV_TX_OFFLOAD_TCP_CKSUM)
898                         printf("on\n");
899                 else
900                         printf("off\n");
901         }
902
903         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) {
904                 printf("TX SCTP checksum:              ");
905                 if (ports[port_id].dev_conf.txmode.offloads &
906                     DEV_TX_OFFLOAD_SCTP_CKSUM)
907                         printf("on\n");
908                 else
909                         printf("off\n");
910         }
911
912         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
913                 printf("TX Outer IPv4 checksum:        ");
914                 if (ports[port_id].dev_conf.txmode.offloads &
915                     DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)
916                         printf("on\n");
917                 else
918                         printf("off\n");
919         }
920
921         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) {
922                 printf("TX TCP segmentation:           ");
923                 if (ports[port_id].dev_conf.txmode.offloads &
924                     DEV_TX_OFFLOAD_TCP_TSO)
925                         printf("on\n");
926                 else
927                         printf("off\n");
928         }
929
930         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_TSO) {
931                 printf("TX UDP segmentation:           ");
932                 if (ports[port_id].dev_conf.txmode.offloads &
933                     DEV_TX_OFFLOAD_UDP_TSO)
934                         printf("on\n");
935                 else
936                         printf("off\n");
937         }
938
939         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO) {
940                 printf("TSO for VXLAN tunnel packet:   ");
941                 if (ports[port_id].dev_conf.txmode.offloads &
942                     DEV_TX_OFFLOAD_VXLAN_TNL_TSO)
943                         printf("on\n");
944                 else
945                         printf("off\n");
946         }
947
948         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GRE_TNL_TSO) {
949                 printf("TSO for GRE tunnel packet:     ");
950                 if (ports[port_id].dev_conf.txmode.offloads &
951                     DEV_TX_OFFLOAD_GRE_TNL_TSO)
952                         printf("on\n");
953                 else
954                         printf("off\n");
955         }
956
957         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPIP_TNL_TSO) {
958                 printf("TSO for IPIP tunnel packet:    ");
959                 if (ports[port_id].dev_conf.txmode.offloads &
960                     DEV_TX_OFFLOAD_IPIP_TNL_TSO)
961                         printf("on\n");
962                 else
963                         printf("off\n");
964         }
965
966         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
967                 printf("TSO for GENEVE tunnel packet:  ");
968                 if (ports[port_id].dev_conf.txmode.offloads &
969                     DEV_TX_OFFLOAD_GENEVE_TNL_TSO)
970                         printf("on\n");
971                 else
972                         printf("off\n");
973         }
974
975         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IP_TNL_TSO) {
976                 printf("IP tunnel TSO:  ");
977                 if (ports[port_id].dev_conf.txmode.offloads &
978                     DEV_TX_OFFLOAD_IP_TNL_TSO)
979                         printf("on\n");
980                 else
981                         printf("off\n");
982         }
983
984         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_TNL_TSO) {
985                 printf("UDP tunnel TSO:  ");
986                 if (ports[port_id].dev_conf.txmode.offloads &
987                     DEV_TX_OFFLOAD_UDP_TNL_TSO)
988                         printf("on\n");
989                 else
990                         printf("off\n");
991         }
992
993         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) {
994                 printf("TX Outer UDP checksum:         ");
995                 if (ports[port_id].dev_conf.txmode.offloads &
996                     DEV_TX_OFFLOAD_OUTER_UDP_CKSUM)
997                         printf("on\n");
998                 else
999                         printf("off\n");
1000         }
1001
1002 }
1003
1004 int
1005 port_id_is_invalid(portid_t port_id, enum print_warning warning)
1006 {
1007         uint16_t pid;
1008
1009         if (port_id == (portid_t)RTE_PORT_ALL)
1010                 return 0;
1011
1012         RTE_ETH_FOREACH_DEV(pid)
1013                 if (port_id == pid)
1014                         return 0;
1015
1016         if (warning == ENABLED_WARN)
1017                 printf("Invalid port %d\n", port_id);
1018
1019         return 1;
1020 }
1021
1022 void print_valid_ports(void)
1023 {
1024         portid_t pid;
1025
1026         printf("The valid ports array is [");
1027         RTE_ETH_FOREACH_DEV(pid) {
1028                 printf(" %d", pid);
1029         }
1030         printf(" ]\n");
1031 }
1032
1033 static int
1034 vlan_id_is_invalid(uint16_t vlan_id)
1035 {
1036         if (vlan_id < 4096)
1037                 return 0;
1038         printf("Invalid vlan_id %d (must be < 4096)\n", vlan_id);
1039         return 1;
1040 }
1041
1042 static int
1043 port_reg_off_is_invalid(portid_t port_id, uint32_t reg_off)
1044 {
1045         const struct rte_pci_device *pci_dev;
1046         const struct rte_bus *bus;
1047         uint64_t pci_len;
1048
1049         if (reg_off & 0x3) {
1050                 printf("Port register offset 0x%X not aligned on a 4-byte "
1051                        "boundary\n",
1052                        (unsigned)reg_off);
1053                 return 1;
1054         }
1055
1056         if (!ports[port_id].dev_info.device) {
1057                 printf("Invalid device\n");
1058                 return 0;
1059         }
1060
1061         bus = rte_bus_find_by_device(ports[port_id].dev_info.device);
1062         if (bus && !strcmp(bus->name, "pci")) {
1063                 pci_dev = RTE_DEV_TO_PCI(ports[port_id].dev_info.device);
1064         } else {
1065                 printf("Not a PCI device\n");
1066                 return 1;
1067         }
1068
1069         pci_len = pci_dev->mem_resource[0].len;
1070         if (reg_off >= pci_len) {
1071                 printf("Port %d: register offset %u (0x%X) out of port PCI "
1072                        "resource (length=%"PRIu64")\n",
1073                        port_id, (unsigned)reg_off, (unsigned)reg_off,  pci_len);
1074                 return 1;
1075         }
1076         return 0;
1077 }
1078
1079 static int
1080 reg_bit_pos_is_invalid(uint8_t bit_pos)
1081 {
1082         if (bit_pos <= 31)
1083                 return 0;
1084         printf("Invalid bit position %d (must be <= 31)\n", bit_pos);
1085         return 1;
1086 }
1087
1088 #define display_port_and_reg_off(port_id, reg_off) \
1089         printf("port %d PCI register at offset 0x%X: ", (port_id), (reg_off))
1090
1091 static inline void
1092 display_port_reg_value(portid_t port_id, uint32_t reg_off, uint32_t reg_v)
1093 {
1094         display_port_and_reg_off(port_id, (unsigned)reg_off);
1095         printf("0x%08X (%u)\n", (unsigned)reg_v, (unsigned)reg_v);
1096 }
1097
1098 void
1099 port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_x)
1100 {
1101         uint32_t reg_v;
1102
1103
1104         if (port_id_is_invalid(port_id, ENABLED_WARN))
1105                 return;
1106         if (port_reg_off_is_invalid(port_id, reg_off))
1107                 return;
1108         if (reg_bit_pos_is_invalid(bit_x))
1109                 return;
1110         reg_v = port_id_pci_reg_read(port_id, reg_off);
1111         display_port_and_reg_off(port_id, (unsigned)reg_off);
1112         printf("bit %d=%d\n", bit_x, (int) ((reg_v & (1 << bit_x)) >> bit_x));
1113 }
1114
1115 void
1116 port_reg_bit_field_display(portid_t port_id, uint32_t reg_off,
1117                            uint8_t bit1_pos, uint8_t bit2_pos)
1118 {
1119         uint32_t reg_v;
1120         uint8_t  l_bit;
1121         uint8_t  h_bit;
1122
1123         if (port_id_is_invalid(port_id, ENABLED_WARN))
1124                 return;
1125         if (port_reg_off_is_invalid(port_id, reg_off))
1126                 return;
1127         if (reg_bit_pos_is_invalid(bit1_pos))
1128                 return;
1129         if (reg_bit_pos_is_invalid(bit2_pos))
1130                 return;
1131         if (bit1_pos > bit2_pos)
1132                 l_bit = bit2_pos, h_bit = bit1_pos;
1133         else
1134                 l_bit = bit1_pos, h_bit = bit2_pos;
1135
1136         reg_v = port_id_pci_reg_read(port_id, reg_off);
1137         reg_v >>= l_bit;
1138         if (h_bit < 31)
1139                 reg_v &= ((1 << (h_bit - l_bit + 1)) - 1);
1140         display_port_and_reg_off(port_id, (unsigned)reg_off);
1141         printf("bits[%d, %d]=0x%0*X (%u)\n", l_bit, h_bit,
1142                ((h_bit - l_bit) / 4) + 1, (unsigned)reg_v, (unsigned)reg_v);
1143 }
1144
1145 void
1146 port_reg_display(portid_t port_id, uint32_t reg_off)
1147 {
1148         uint32_t reg_v;
1149
1150         if (port_id_is_invalid(port_id, ENABLED_WARN))
1151                 return;
1152         if (port_reg_off_is_invalid(port_id, reg_off))
1153                 return;
1154         reg_v = port_id_pci_reg_read(port_id, reg_off);
1155         display_port_reg_value(port_id, reg_off, reg_v);
1156 }
1157
1158 void
1159 port_reg_bit_set(portid_t port_id, uint32_t reg_off, uint8_t bit_pos,
1160                  uint8_t bit_v)
1161 {
1162         uint32_t reg_v;
1163
1164         if (port_id_is_invalid(port_id, ENABLED_WARN))
1165                 return;
1166         if (port_reg_off_is_invalid(port_id, reg_off))
1167                 return;
1168         if (reg_bit_pos_is_invalid(bit_pos))
1169                 return;
1170         if (bit_v > 1) {
1171                 printf("Invalid bit value %d (must be 0 or 1)\n", (int) bit_v);
1172                 return;
1173         }
1174         reg_v = port_id_pci_reg_read(port_id, reg_off);
1175         if (bit_v == 0)
1176                 reg_v &= ~(1 << bit_pos);
1177         else
1178                 reg_v |= (1 << bit_pos);
1179         port_id_pci_reg_write(port_id, reg_off, reg_v);
1180         display_port_reg_value(port_id, reg_off, reg_v);
1181 }
1182
1183 void
1184 port_reg_bit_field_set(portid_t port_id, uint32_t reg_off,
1185                        uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value)
1186 {
1187         uint32_t max_v;
1188         uint32_t reg_v;
1189         uint8_t  l_bit;
1190         uint8_t  h_bit;
1191
1192         if (port_id_is_invalid(port_id, ENABLED_WARN))
1193                 return;
1194         if (port_reg_off_is_invalid(port_id, reg_off))
1195                 return;
1196         if (reg_bit_pos_is_invalid(bit1_pos))
1197                 return;
1198         if (reg_bit_pos_is_invalid(bit2_pos))
1199                 return;
1200         if (bit1_pos > bit2_pos)
1201                 l_bit = bit2_pos, h_bit = bit1_pos;
1202         else
1203                 l_bit = bit1_pos, h_bit = bit2_pos;
1204
1205         if ((h_bit - l_bit) < 31)
1206                 max_v = (1 << (h_bit - l_bit + 1)) - 1;
1207         else
1208                 max_v = 0xFFFFFFFF;
1209
1210         if (value > max_v) {
1211                 printf("Invalid value %u (0x%x) must be < %u (0x%x)\n",
1212                                 (unsigned)value, (unsigned)value,
1213                                 (unsigned)max_v, (unsigned)max_v);
1214                 return;
1215         }
1216         reg_v = port_id_pci_reg_read(port_id, reg_off);
1217         reg_v &= ~(max_v << l_bit); /* Keep unchanged bits */
1218         reg_v |= (value << l_bit); /* Set changed bits */
1219         port_id_pci_reg_write(port_id, reg_off, reg_v);
1220         display_port_reg_value(port_id, reg_off, reg_v);
1221 }
1222
1223 void
1224 port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t reg_v)
1225 {
1226         if (port_id_is_invalid(port_id, ENABLED_WARN))
1227                 return;
1228         if (port_reg_off_is_invalid(port_id, reg_off))
1229                 return;
1230         port_id_pci_reg_write(port_id, reg_off, reg_v);
1231         display_port_reg_value(port_id, reg_off, reg_v);
1232 }
1233
1234 void
1235 port_mtu_set(portid_t port_id, uint16_t mtu)
1236 {
1237         int diag;
1238         struct rte_port *rte_port = &ports[port_id];
1239         struct rte_eth_dev_info dev_info;
1240         uint16_t eth_overhead;
1241         int ret;
1242
1243         if (port_id_is_invalid(port_id, ENABLED_WARN))
1244                 return;
1245
1246         ret = eth_dev_info_get_print_err(port_id, &dev_info);
1247         if (ret != 0)
1248                 return;
1249
1250         if (mtu > dev_info.max_mtu || mtu < dev_info.min_mtu) {
1251                 printf("Set MTU failed. MTU:%u is not in valid range, min:%u - max:%u\n",
1252                         mtu, dev_info.min_mtu, dev_info.max_mtu);
1253                 return;
1254         }
1255         diag = rte_eth_dev_set_mtu(port_id, mtu);
1256         if (diag == 0 &&
1257             dev_info.rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME) {
1258                 /*
1259                  * Ether overhead in driver is equal to the difference of
1260                  * max_rx_pktlen and max_mtu in rte_eth_dev_info when the
1261                  * device supports jumbo frame.
1262                  */
1263                 eth_overhead = dev_info.max_rx_pktlen - dev_info.max_mtu;
1264                 if (mtu > RTE_ETHER_MAX_LEN - eth_overhead) {
1265                         rte_port->dev_conf.rxmode.offloads |=
1266                                                 DEV_RX_OFFLOAD_JUMBO_FRAME;
1267                         rte_port->dev_conf.rxmode.max_rx_pkt_len =
1268                                                 mtu + eth_overhead;
1269                 } else
1270                         rte_port->dev_conf.rxmode.offloads &=
1271                                                 ~DEV_RX_OFFLOAD_JUMBO_FRAME;
1272
1273                 return;
1274         }
1275         printf("Set MTU failed. diag=%d\n", diag);
1276 }
1277
1278 /* Generic flow management functions. */
1279
1280 /** Generate a port_flow entry from attributes/pattern/actions. */
1281 static struct port_flow *
1282 port_flow_new(const struct rte_flow_attr *attr,
1283               const struct rte_flow_item *pattern,
1284               const struct rte_flow_action *actions,
1285               struct rte_flow_error *error)
1286 {
1287         const struct rte_flow_conv_rule rule = {
1288                 .attr_ro = attr,
1289                 .pattern_ro = pattern,
1290                 .actions_ro = actions,
1291         };
1292         struct port_flow *pf;
1293         int ret;
1294
1295         ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, NULL, 0, &rule, error);
1296         if (ret < 0)
1297                 return NULL;
1298         pf = calloc(1, offsetof(struct port_flow, rule) + ret);
1299         if (!pf) {
1300                 rte_flow_error_set
1301                         (error, errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1302                          "calloc() failed");
1303                 return NULL;
1304         }
1305         if (rte_flow_conv(RTE_FLOW_CONV_OP_RULE, &pf->rule, ret, &rule,
1306                           error) >= 0)
1307                 return pf;
1308         free(pf);
1309         return NULL;
1310 }
1311
1312 /** Print a message out of a flow error. */
1313 static int
1314 port_flow_complain(struct rte_flow_error *error)
1315 {
1316         static const char *const errstrlist[] = {
1317                 [RTE_FLOW_ERROR_TYPE_NONE] = "no error",
1318                 [RTE_FLOW_ERROR_TYPE_UNSPECIFIED] = "cause unspecified",
1319                 [RTE_FLOW_ERROR_TYPE_HANDLE] = "flow rule (handle)",
1320                 [RTE_FLOW_ERROR_TYPE_ATTR_GROUP] = "group field",
1321                 [RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY] = "priority field",
1322                 [RTE_FLOW_ERROR_TYPE_ATTR_INGRESS] = "ingress field",
1323                 [RTE_FLOW_ERROR_TYPE_ATTR_EGRESS] = "egress field",
1324                 [RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER] = "transfer field",
1325                 [RTE_FLOW_ERROR_TYPE_ATTR] = "attributes structure",
1326                 [RTE_FLOW_ERROR_TYPE_ITEM_NUM] = "pattern length",
1327                 [RTE_FLOW_ERROR_TYPE_ITEM_SPEC] = "item specification",
1328                 [RTE_FLOW_ERROR_TYPE_ITEM_LAST] = "item specification range",
1329                 [RTE_FLOW_ERROR_TYPE_ITEM_MASK] = "item specification mask",
1330                 [RTE_FLOW_ERROR_TYPE_ITEM] = "specific pattern item",
1331                 [RTE_FLOW_ERROR_TYPE_ACTION_NUM] = "number of actions",
1332                 [RTE_FLOW_ERROR_TYPE_ACTION_CONF] = "action configuration",
1333                 [RTE_FLOW_ERROR_TYPE_ACTION] = "specific action",
1334         };
1335         const char *errstr;
1336         char buf[32];
1337         int err = rte_errno;
1338
1339         if ((unsigned int)error->type >= RTE_DIM(errstrlist) ||
1340             !errstrlist[error->type])
1341                 errstr = "unknown type";
1342         else
1343                 errstr = errstrlist[error->type];
1344         printf("%s(): Caught PMD error type %d (%s): %s%s: %s\n", __func__,
1345                error->type, errstr,
1346                error->cause ? (snprintf(buf, sizeof(buf), "cause: %p, ",
1347                                         error->cause), buf) : "",
1348                error->message ? error->message : "(no stated reason)",
1349                rte_strerror(err));
1350         return -err;
1351 }
1352
1353 /** Validate flow rule. */
1354 int
1355 port_flow_validate(portid_t port_id,
1356                    const struct rte_flow_attr *attr,
1357                    const struct rte_flow_item *pattern,
1358                    const struct rte_flow_action *actions)
1359 {
1360         struct rte_flow_error error;
1361
1362         /* Poisoning to make sure PMDs update it in case of error. */
1363         memset(&error, 0x11, sizeof(error));
1364         if (rte_flow_validate(port_id, attr, pattern, actions, &error))
1365                 return port_flow_complain(&error);
1366         printf("Flow rule validated\n");
1367         return 0;
1368 }
1369
1370 /** Update age action context by port_flow pointer. */
1371 void
1372 update_age_action_context(const struct rte_flow_action *actions,
1373                         struct port_flow *pf)
1374 {
1375         struct rte_flow_action_age *age = NULL;
1376
1377         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
1378                 switch (actions->type) {
1379                 case RTE_FLOW_ACTION_TYPE_AGE:
1380                         age = (struct rte_flow_action_age *)
1381                                 (uintptr_t)actions->conf;
1382                         age->context = pf;
1383                         return;
1384                 default:
1385                         break;
1386                 }
1387         }
1388 }
1389
1390 /** Create flow rule. */
1391 int
1392 port_flow_create(portid_t port_id,
1393                  const struct rte_flow_attr *attr,
1394                  const struct rte_flow_item *pattern,
1395                  const struct rte_flow_action *actions)
1396 {
1397         struct rte_flow *flow;
1398         struct rte_port *port;
1399         struct port_flow *pf;
1400         uint32_t id = 0;
1401         struct rte_flow_error error;
1402
1403         port = &ports[port_id];
1404         if (port->flow_list) {
1405                 if (port->flow_list->id == UINT32_MAX) {
1406                         printf("Highest rule ID is already assigned, delete"
1407                                " it first");
1408                         return -ENOMEM;
1409                 }
1410                 id = port->flow_list->id + 1;
1411         }
1412         pf = port_flow_new(attr, pattern, actions, &error);
1413         if (!pf)
1414                 return port_flow_complain(&error);
1415         update_age_action_context(actions, pf);
1416         /* Poisoning to make sure PMDs update it in case of error. */
1417         memset(&error, 0x22, sizeof(error));
1418         flow = rte_flow_create(port_id, attr, pattern, actions, &error);
1419         if (!flow) {
1420                 free(pf);
1421                 return port_flow_complain(&error);
1422         }
1423         pf->next = port->flow_list;
1424         pf->id = id;
1425         pf->flow = flow;
1426         port->flow_list = pf;
1427         printf("Flow rule #%u created\n", pf->id);
1428         return 0;
1429 }
1430
1431 /** Destroy a number of flow rules. */
1432 int
1433 port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
1434 {
1435         struct rte_port *port;
1436         struct port_flow **tmp;
1437         uint32_t c = 0;
1438         int ret = 0;
1439
1440         if (port_id_is_invalid(port_id, ENABLED_WARN) ||
1441             port_id == (portid_t)RTE_PORT_ALL)
1442                 return -EINVAL;
1443         port = &ports[port_id];
1444         tmp = &port->flow_list;
1445         while (*tmp) {
1446                 uint32_t i;
1447
1448                 for (i = 0; i != n; ++i) {
1449                         struct rte_flow_error error;
1450                         struct port_flow *pf = *tmp;
1451
1452                         if (rule[i] != pf->id)
1453                                 continue;
1454                         /*
1455                          * Poisoning to make sure PMDs update it in case
1456                          * of error.
1457                          */
1458                         memset(&error, 0x33, sizeof(error));
1459                         if (rte_flow_destroy(port_id, pf->flow, &error)) {
1460                                 ret = port_flow_complain(&error);
1461                                 continue;
1462                         }
1463                         printf("Flow rule #%u destroyed\n", pf->id);
1464                         *tmp = pf->next;
1465                         free(pf);
1466                         break;
1467                 }
1468                 if (i == n)
1469                         tmp = &(*tmp)->next;
1470                 ++c;
1471         }
1472         return ret;
1473 }
1474
1475 /** Remove all flow rules. */
1476 int
1477 port_flow_flush(portid_t port_id)
1478 {
1479         struct rte_flow_error error;
1480         struct rte_port *port;
1481         int ret = 0;
1482
1483         /* Poisoning to make sure PMDs update it in case of error. */
1484         memset(&error, 0x44, sizeof(error));
1485         if (rte_flow_flush(port_id, &error)) {
1486                 ret = port_flow_complain(&error);
1487                 if (port_id_is_invalid(port_id, DISABLED_WARN) ||
1488                     port_id == (portid_t)RTE_PORT_ALL)
1489                         return ret;
1490         }
1491         port = &ports[port_id];
1492         while (port->flow_list) {
1493                 struct port_flow *pf = port->flow_list->next;
1494
1495                 free(port->flow_list);
1496                 port->flow_list = pf;
1497         }
1498         return ret;
1499 }
1500
1501 /** Dump all flow rules. */
1502 int
1503 port_flow_dump(portid_t port_id, const char *file_name)
1504 {
1505         int ret = 0;
1506         FILE *file = stdout;
1507         struct rte_flow_error error;
1508
1509         if (file_name && strlen(file_name)) {
1510                 file = fopen(file_name, "w");
1511                 if (!file) {
1512                         printf("Failed to create file %s: %s\n", file_name,
1513                                strerror(errno));
1514                         return -errno;
1515                 }
1516         }
1517         ret = rte_flow_dev_dump(port_id, file, &error);
1518         if (ret) {
1519                 port_flow_complain(&error);
1520                 printf("Failed to dump flow: %s\n", strerror(-ret));
1521         } else
1522                 printf("Flow dump finished\n");
1523         if (file_name && strlen(file_name))
1524                 fclose(file);
1525         return ret;
1526 }
1527
1528 /** Query a flow rule. */
1529 int
1530 port_flow_query(portid_t port_id, uint32_t rule,
1531                 const struct rte_flow_action *action)
1532 {
1533         struct rte_flow_error error;
1534         struct rte_port *port;
1535         struct port_flow *pf;
1536         const char *name;
1537         union {
1538                 struct rte_flow_query_count count;
1539         } query;
1540         int ret;
1541
1542         if (port_id_is_invalid(port_id, ENABLED_WARN) ||
1543             port_id == (portid_t)RTE_PORT_ALL)
1544                 return -EINVAL;
1545         port = &ports[port_id];
1546         for (pf = port->flow_list; pf; pf = pf->next)
1547                 if (pf->id == rule)
1548                         break;
1549         if (!pf) {
1550                 printf("Flow rule #%u not found\n", rule);
1551                 return -ENOENT;
1552         }
1553         ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
1554                             &name, sizeof(name),
1555                             (void *)(uintptr_t)action->type, &error);
1556         if (ret < 0)
1557                 return port_flow_complain(&error);
1558         switch (action->type) {
1559         case RTE_FLOW_ACTION_TYPE_COUNT:
1560                 break;
1561         default:
1562                 printf("Cannot query action type %d (%s)\n",
1563                         action->type, name);
1564                 return -ENOTSUP;
1565         }
1566         /* Poisoning to make sure PMDs update it in case of error. */
1567         memset(&error, 0x55, sizeof(error));
1568         memset(&query, 0, sizeof(query));
1569         if (rte_flow_query(port_id, pf->flow, action, &query, &error))
1570                 return port_flow_complain(&error);
1571         switch (action->type) {
1572         case RTE_FLOW_ACTION_TYPE_COUNT:
1573                 printf("%s:\n"
1574                        " hits_set: %u\n"
1575                        " bytes_set: %u\n"
1576                        " hits: %" PRIu64 "\n"
1577                        " bytes: %" PRIu64 "\n",
1578                        name,
1579                        query.count.hits_set,
1580                        query.count.bytes_set,
1581                        query.count.hits,
1582                        query.count.bytes);
1583                 break;
1584         default:
1585                 printf("Cannot display result for action type %d (%s)\n",
1586                        action->type, name);
1587                 break;
1588         }
1589         return 0;
1590 }
1591
1592 /** List simply and destroy all aged flows. */
1593 void
1594 port_flow_aged(portid_t port_id, uint8_t destroy)
1595 {
1596         void **contexts;
1597         int nb_context, total = 0, idx;
1598         struct rte_flow_error error;
1599         struct port_flow *pf;
1600
1601         if (port_id_is_invalid(port_id, ENABLED_WARN) ||
1602             port_id == (portid_t)RTE_PORT_ALL)
1603                 return;
1604         total = rte_flow_get_aged_flows(port_id, NULL, 0, &error);
1605         printf("Port %u total aged flows: %d\n", port_id, total);
1606         if (total < 0) {
1607                 port_flow_complain(&error);
1608                 return;
1609         }
1610         if (total == 0)
1611                 return;
1612         contexts = malloc(sizeof(void *) * total);
1613         if (contexts == NULL) {
1614                 printf("Cannot allocate contexts for aged flow\n");
1615                 return;
1616         }
1617         printf("ID\tGroup\tPrio\tAttr\n");
1618         nb_context = rte_flow_get_aged_flows(port_id, contexts, total, &error);
1619         if (nb_context != total) {
1620                 printf("Port:%d get aged flows count(%d) != total(%d)\n",
1621                         port_id, nb_context, total);
1622                 free(contexts);
1623                 return;
1624         }
1625         for (idx = 0; idx < nb_context; idx++) {
1626                 pf = (struct port_flow *)contexts[idx];
1627                 if (!pf) {
1628                         printf("Error: get Null context in port %u\n", port_id);
1629                         continue;
1630                 }
1631                 printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c%c\t\n",
1632                        pf->id,
1633                        pf->rule.attr->group,
1634                        pf->rule.attr->priority,
1635                        pf->rule.attr->ingress ? 'i' : '-',
1636                        pf->rule.attr->egress ? 'e' : '-',
1637                        pf->rule.attr->transfer ? 't' : '-');
1638         }
1639         if (destroy) {
1640                 int ret;
1641                 uint32_t flow_id;
1642
1643                 total = 0;
1644                 printf("\n");
1645                 for (idx = 0; idx < nb_context; idx++) {
1646                         pf = (struct port_flow *)contexts[idx];
1647                         if (!pf)
1648                                 continue;
1649                         flow_id = pf->id;
1650                         ret = port_flow_destroy(port_id, 1, &flow_id);
1651                         if (!ret)
1652                                 total++;
1653                 }
1654                 printf("%d flows be destroyed\n", total);
1655         }
1656         free(contexts);
1657 }
1658
1659 /** List flow rules. */
1660 void
1661 port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n])
1662 {
1663         struct rte_port *port;
1664         struct port_flow *pf;
1665         struct port_flow *list = NULL;
1666         uint32_t i;
1667
1668         if (port_id_is_invalid(port_id, ENABLED_WARN) ||
1669             port_id == (portid_t)RTE_PORT_ALL)
1670                 return;
1671         port = &ports[port_id];
1672         if (!port->flow_list)
1673                 return;
1674         /* Sort flows by group, priority and ID. */
1675         for (pf = port->flow_list; pf != NULL; pf = pf->next) {
1676                 struct port_flow **tmp;
1677                 const struct rte_flow_attr *curr = pf->rule.attr;
1678
1679                 if (n) {
1680                         /* Filter out unwanted groups. */
1681                         for (i = 0; i != n; ++i)
1682                                 if (curr->group == group[i])
1683                                         break;
1684                         if (i == n)
1685                                 continue;
1686                 }
1687                 for (tmp = &list; *tmp; tmp = &(*tmp)->tmp) {
1688                         const struct rte_flow_attr *comp = (*tmp)->rule.attr;
1689
1690                         if (curr->group > comp->group ||
1691                             (curr->group == comp->group &&
1692                              curr->priority > comp->priority) ||
1693                             (curr->group == comp->group &&
1694                              curr->priority == comp->priority &&
1695                              pf->id > (*tmp)->id))
1696                                 continue;
1697                         break;
1698                 }
1699                 pf->tmp = *tmp;
1700                 *tmp = pf;
1701         }
1702         printf("ID\tGroup\tPrio\tAttr\tRule\n");
1703         for (pf = list; pf != NULL; pf = pf->tmp) {
1704                 const struct rte_flow_item *item = pf->rule.pattern;
1705                 const struct rte_flow_action *action = pf->rule.actions;
1706                 const char *name;
1707
1708                 printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c%c\t",
1709                        pf->id,
1710                        pf->rule.attr->group,
1711                        pf->rule.attr->priority,
1712                        pf->rule.attr->ingress ? 'i' : '-',
1713                        pf->rule.attr->egress ? 'e' : '-',
1714                        pf->rule.attr->transfer ? 't' : '-');
1715                 while (item->type != RTE_FLOW_ITEM_TYPE_END) {
1716                         if (rte_flow_conv(RTE_FLOW_CONV_OP_ITEM_NAME_PTR,
1717                                           &name, sizeof(name),
1718                                           (void *)(uintptr_t)item->type,
1719                                           NULL) <= 0)
1720                                 name = "[UNKNOWN]";
1721                         if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
1722                                 printf("%s ", name);
1723                         ++item;
1724                 }
1725                 printf("=>");
1726                 while (action->type != RTE_FLOW_ACTION_TYPE_END) {
1727                         if (rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
1728                                           &name, sizeof(name),
1729                                           (void *)(uintptr_t)action->type,
1730                                           NULL) <= 0)
1731                                 name = "[UNKNOWN]";
1732                         if (action->type != RTE_FLOW_ACTION_TYPE_VOID)
1733                                 printf(" %s", name);
1734                         ++action;
1735                 }
1736                 printf("\n");
1737         }
1738 }
1739
1740 /** Restrict ingress traffic to the defined flow rules. */
1741 int
1742 port_flow_isolate(portid_t port_id, int set)
1743 {
1744         struct rte_flow_error error;
1745
1746         /* Poisoning to make sure PMDs update it in case of error. */
1747         memset(&error, 0x66, sizeof(error));
1748         if (rte_flow_isolate(port_id, set, &error))
1749                 return port_flow_complain(&error);
1750         printf("Ingress traffic on port %u is %s to the defined flow rules\n",
1751                port_id,
1752                set ? "now restricted" : "not restricted anymore");
1753         return 0;
1754 }
1755
1756 /*
1757  * RX/TX ring descriptors display functions.
1758  */
1759 int
1760 rx_queue_id_is_invalid(queueid_t rxq_id)
1761 {
1762         if (rxq_id < nb_rxq)
1763                 return 0;
1764         printf("Invalid RX queue %d (must be < nb_rxq=%d)\n", rxq_id, nb_rxq);
1765         return 1;
1766 }
1767
1768 int
1769 tx_queue_id_is_invalid(queueid_t txq_id)
1770 {
1771         if (txq_id < nb_txq)
1772                 return 0;
1773         printf("Invalid TX queue %d (must be < nb_rxq=%d)\n", txq_id, nb_txq);
1774         return 1;
1775 }
1776
1777 static int
1778 rx_desc_id_is_invalid(uint16_t rxdesc_id)
1779 {
1780         if (rxdesc_id < nb_rxd)
1781                 return 0;
1782         printf("Invalid RX descriptor %d (must be < nb_rxd=%d)\n",
1783                rxdesc_id, nb_rxd);
1784         return 1;
1785 }
1786
1787 static int
1788 tx_desc_id_is_invalid(uint16_t txdesc_id)
1789 {
1790         if (txdesc_id < nb_txd)
1791                 return 0;
1792         printf("Invalid TX descriptor %d (must be < nb_txd=%d)\n",
1793                txdesc_id, nb_txd);
1794         return 1;
1795 }
1796
1797 static const struct rte_memzone *
1798 ring_dma_zone_lookup(const char *ring_name, portid_t port_id, uint16_t q_id)
1799 {
1800         char mz_name[RTE_MEMZONE_NAMESIZE];
1801         const struct rte_memzone *mz;
1802
1803         snprintf(mz_name, sizeof(mz_name), "eth_p%d_q%d_%s",
1804                         port_id, q_id, ring_name);
1805         mz = rte_memzone_lookup(mz_name);
1806         if (mz == NULL)
1807                 printf("%s ring memory zoneof (port %d, queue %d) not"
1808                        "found (zone name = %s\n",
1809                        ring_name, port_id, q_id, mz_name);
1810         return mz;
1811 }
1812
1813 union igb_ring_dword {
1814         uint64_t dword;
1815         struct {
1816 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
1817                 uint32_t lo;
1818                 uint32_t hi;
1819 #else
1820                 uint32_t hi;
1821                 uint32_t lo;
1822 #endif
1823         } words;
1824 };
1825
1826 struct igb_ring_desc_32_bytes {
1827         union igb_ring_dword lo_dword;
1828         union igb_ring_dword hi_dword;
1829         union igb_ring_dword resv1;
1830         union igb_ring_dword resv2;
1831 };
1832
1833 struct igb_ring_desc_16_bytes {
1834         union igb_ring_dword lo_dword;
1835         union igb_ring_dword hi_dword;
1836 };
1837
1838 static void
1839 ring_rxd_display_dword(union igb_ring_dword dword)
1840 {
1841         printf("    0x%08X - 0x%08X\n", (unsigned)dword.words.lo,
1842                                         (unsigned)dword.words.hi);
1843 }
1844
1845 static void
1846 ring_rx_descriptor_display(const struct rte_memzone *ring_mz,
1847 #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
1848                            portid_t port_id,
1849 #else
1850                            __rte_unused portid_t port_id,
1851 #endif
1852                            uint16_t desc_id)
1853 {
1854         struct igb_ring_desc_16_bytes *ring =
1855                 (struct igb_ring_desc_16_bytes *)ring_mz->addr;
1856 #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
1857         int ret;
1858         struct rte_eth_dev_info dev_info;
1859
1860         ret = eth_dev_info_get_print_err(port_id, &dev_info);
1861         if (ret != 0)
1862                 return;
1863
1864         if (strstr(dev_info.driver_name, "i40e") != NULL) {
1865                 /* 32 bytes RX descriptor, i40e only */
1866                 struct igb_ring_desc_32_bytes *ring =
1867                         (struct igb_ring_desc_32_bytes *)ring_mz->addr;
1868                 ring[desc_id].lo_dword.dword =
1869                         rte_le_to_cpu_64(ring[desc_id].lo_dword.dword);
1870                 ring_rxd_display_dword(ring[desc_id].lo_dword);
1871                 ring[desc_id].hi_dword.dword =
1872                         rte_le_to_cpu_64(ring[desc_id].hi_dword.dword);
1873                 ring_rxd_display_dword(ring[desc_id].hi_dword);
1874                 ring[desc_id].resv1.dword =
1875                         rte_le_to_cpu_64(ring[desc_id].resv1.dword);
1876                 ring_rxd_display_dword(ring[desc_id].resv1);
1877                 ring[desc_id].resv2.dword =
1878                         rte_le_to_cpu_64(ring[desc_id].resv2.dword);
1879                 ring_rxd_display_dword(ring[desc_id].resv2);
1880
1881                 return;
1882         }
1883 #endif
1884         /* 16 bytes RX descriptor */
1885         ring[desc_id].lo_dword.dword =
1886                 rte_le_to_cpu_64(ring[desc_id].lo_dword.dword);
1887         ring_rxd_display_dword(ring[desc_id].lo_dword);
1888         ring[desc_id].hi_dword.dword =
1889                 rte_le_to_cpu_64(ring[desc_id].hi_dword.dword);
1890         ring_rxd_display_dword(ring[desc_id].hi_dword);
1891 }
1892
1893 static void
1894 ring_tx_descriptor_display(const struct rte_memzone *ring_mz, uint16_t desc_id)
1895 {
1896         struct igb_ring_desc_16_bytes *ring;
1897         struct igb_ring_desc_16_bytes txd;
1898
1899         ring = (struct igb_ring_desc_16_bytes *)ring_mz->addr;
1900         txd.lo_dword.dword = rte_le_to_cpu_64(ring[desc_id].lo_dword.dword);
1901         txd.hi_dword.dword = rte_le_to_cpu_64(ring[desc_id].hi_dword.dword);
1902         printf("    0x%08X - 0x%08X / 0x%08X - 0x%08X\n",
1903                         (unsigned)txd.lo_dword.words.lo,
1904                         (unsigned)txd.lo_dword.words.hi,
1905                         (unsigned)txd.hi_dword.words.lo,
1906                         (unsigned)txd.hi_dword.words.hi);
1907 }
1908
1909 void
1910 rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id)
1911 {
1912         const struct rte_memzone *rx_mz;
1913
1914         if (port_id_is_invalid(port_id, ENABLED_WARN))
1915                 return;
1916         if (rx_queue_id_is_invalid(rxq_id))
1917                 return;
1918         if (rx_desc_id_is_invalid(rxd_id))
1919                 return;
1920         rx_mz = ring_dma_zone_lookup("rx_ring", port_id, rxq_id);
1921         if (rx_mz == NULL)
1922                 return;
1923         ring_rx_descriptor_display(rx_mz, port_id, rxd_id);
1924 }
1925
1926 void
1927 tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id)
1928 {
1929         const struct rte_memzone *tx_mz;
1930
1931         if (port_id_is_invalid(port_id, ENABLED_WARN))
1932                 return;
1933         if (tx_queue_id_is_invalid(txq_id))
1934                 return;
1935         if (tx_desc_id_is_invalid(txd_id))
1936                 return;
1937         tx_mz = ring_dma_zone_lookup("tx_ring", port_id, txq_id);
1938         if (tx_mz == NULL)
1939                 return;
1940         ring_tx_descriptor_display(tx_mz, txd_id);
1941 }
1942
1943 void
1944 fwd_lcores_config_display(void)
1945 {
1946         lcoreid_t lc_id;
1947
1948         printf("List of forwarding lcores:");
1949         for (lc_id = 0; lc_id < nb_cfg_lcores; lc_id++)
1950                 printf(" %2u", fwd_lcores_cpuids[lc_id]);
1951         printf("\n");
1952 }
1953 void
1954 rxtx_config_display(void)
1955 {
1956         portid_t pid;
1957         queueid_t qid;
1958
1959         printf("  %s packet forwarding%s packets/burst=%d\n",
1960                cur_fwd_eng->fwd_mode_name,
1961                retry_enabled == 0 ? "" : " with retry",
1962                nb_pkt_per_burst);
1963
1964         if (cur_fwd_eng == &tx_only_engine || cur_fwd_eng == &flow_gen_engine)
1965                 printf("  packet len=%u - nb packet segments=%d\n",
1966                                 (unsigned)tx_pkt_length, (int) tx_pkt_nb_segs);
1967
1968         printf("  nb forwarding cores=%d - nb forwarding ports=%d\n",
1969                nb_fwd_lcores, nb_fwd_ports);
1970
1971         RTE_ETH_FOREACH_DEV(pid) {
1972                 struct rte_eth_rxconf *rx_conf = &ports[pid].rx_conf[0];
1973                 struct rte_eth_txconf *tx_conf = &ports[pid].tx_conf[0];
1974                 uint16_t *nb_rx_desc = &ports[pid].nb_rx_desc[0];
1975                 uint16_t *nb_tx_desc = &ports[pid].nb_tx_desc[0];
1976                 uint16_t nb_rx_desc_tmp;
1977                 uint16_t nb_tx_desc_tmp;
1978                 struct rte_eth_rxq_info rx_qinfo;
1979                 struct rte_eth_txq_info tx_qinfo;
1980                 int32_t rc;
1981
1982                 /* per port config */
1983                 printf("  port %d: RX queue number: %d Tx queue number: %d\n",
1984                                 (unsigned int)pid, nb_rxq, nb_txq);
1985
1986                 printf("    Rx offloads=0x%"PRIx64" Tx offloads=0x%"PRIx64"\n",
1987                                 ports[pid].dev_conf.rxmode.offloads,
1988                                 ports[pid].dev_conf.txmode.offloads);
1989
1990                 /* per rx queue config only for first queue to be less verbose */
1991                 for (qid = 0; qid < 1; qid++) {
1992                         rc = rte_eth_rx_queue_info_get(pid, qid, &rx_qinfo);
1993                         if (rc)
1994                                 nb_rx_desc_tmp = nb_rx_desc[qid];
1995                         else
1996                                 nb_rx_desc_tmp = rx_qinfo.nb_desc;
1997
1998                         printf("    RX queue: %d\n", qid);
1999                         printf("      RX desc=%d - RX free threshold=%d\n",
2000                                 nb_rx_desc_tmp, rx_conf[qid].rx_free_thresh);
2001                         printf("      RX threshold registers: pthresh=%d hthresh=%d "
2002                                 " wthresh=%d\n",
2003                                 rx_conf[qid].rx_thresh.pthresh,
2004                                 rx_conf[qid].rx_thresh.hthresh,
2005                                 rx_conf[qid].rx_thresh.wthresh);
2006                         printf("      RX Offloads=0x%"PRIx64"\n",
2007                                 rx_conf[qid].offloads);
2008                 }
2009
2010                 /* per tx queue config only for first queue to be less verbose */
2011                 for (qid = 0; qid < 1; qid++) {
2012                         rc = rte_eth_tx_queue_info_get(pid, qid, &tx_qinfo);
2013                         if (rc)
2014                                 nb_tx_desc_tmp = nb_tx_desc[qid];
2015                         else
2016                                 nb_tx_desc_tmp = tx_qinfo.nb_desc;
2017
2018                         printf("    TX queue: %d\n", qid);
2019                         printf("      TX desc=%d - TX free threshold=%d\n",
2020                                 nb_tx_desc_tmp, tx_conf[qid].tx_free_thresh);
2021                         printf("      TX threshold registers: pthresh=%d hthresh=%d "
2022                                 " wthresh=%d\n",
2023                                 tx_conf[qid].tx_thresh.pthresh,
2024                                 tx_conf[qid].tx_thresh.hthresh,
2025                                 tx_conf[qid].tx_thresh.wthresh);
2026                         printf("      TX offloads=0x%"PRIx64" - TX RS bit threshold=%d\n",
2027                                 tx_conf[qid].offloads, tx_conf->tx_rs_thresh);
2028                 }
2029         }
2030 }
2031
2032 void
2033 port_rss_reta_info(portid_t port_id,
2034                    struct rte_eth_rss_reta_entry64 *reta_conf,
2035                    uint16_t nb_entries)
2036 {
2037         uint16_t i, idx, shift;
2038         int ret;
2039
2040         if (port_id_is_invalid(port_id, ENABLED_WARN))
2041                 return;
2042
2043         ret = rte_eth_dev_rss_reta_query(port_id, reta_conf, nb_entries);
2044         if (ret != 0) {
2045                 printf("Failed to get RSS RETA info, return code = %d\n", ret);
2046                 return;
2047         }
2048
2049         for (i = 0; i < nb_entries; i++) {
2050                 idx = i / RTE_RETA_GROUP_SIZE;
2051                 shift = i % RTE_RETA_GROUP_SIZE;
2052                 if (!(reta_conf[idx].mask & (1ULL << shift)))
2053                         continue;
2054                 printf("RSS RETA configuration: hash index=%u, queue=%u\n",
2055                                         i, reta_conf[idx].reta[shift]);
2056         }
2057 }
2058
2059 /*
2060  * Displays the RSS hash functions of a port, and, optionaly, the RSS hash
2061  * key of the port.
2062  */
2063 void
2064 port_rss_hash_conf_show(portid_t port_id, int show_rss_key)
2065 {
2066         struct rte_eth_rss_conf rss_conf = {0};
2067         uint8_t rss_key[RSS_HASH_KEY_LENGTH];
2068         uint64_t rss_hf;
2069         uint8_t i;
2070         int diag;
2071         struct rte_eth_dev_info dev_info;
2072         uint8_t hash_key_size;
2073         int ret;
2074
2075         if (port_id_is_invalid(port_id, ENABLED_WARN))
2076                 return;
2077
2078         ret = eth_dev_info_get_print_err(port_id, &dev_info);
2079         if (ret != 0)
2080                 return;
2081
2082         if (dev_info.hash_key_size > 0 &&
2083                         dev_info.hash_key_size <= sizeof(rss_key))
2084                 hash_key_size = dev_info.hash_key_size;
2085         else {
2086                 printf("dev_info did not provide a valid hash key size\n");
2087                 return;
2088         }
2089
2090         /* Get RSS hash key if asked to display it */
2091         rss_conf.rss_key = (show_rss_key) ? rss_key : NULL;
2092         rss_conf.rss_key_len = hash_key_size;
2093         diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
2094         if (diag != 0) {
2095                 switch (diag) {
2096                 case -ENODEV:
2097                         printf("port index %d invalid\n", port_id);
2098                         break;
2099                 case -ENOTSUP:
2100                         printf("operation not supported by device\n");
2101                         break;
2102                 default:
2103                         printf("operation failed - diag=%d\n", diag);
2104                         break;
2105                 }
2106                 return;
2107         }
2108         rss_hf = rss_conf.rss_hf;
2109         if (rss_hf == 0) {
2110                 printf("RSS disabled\n");
2111                 return;
2112         }
2113         printf("RSS functions:\n ");
2114         for (i = 0; rss_type_table[i].str; i++) {
2115                 if (rss_hf & rss_type_table[i].rss_type)
2116                         printf("%s ", rss_type_table[i].str);
2117         }
2118         printf("\n");
2119         if (!show_rss_key)
2120                 return;
2121         printf("RSS key:\n");
2122         for (i = 0; i < hash_key_size; i++)
2123                 printf("%02X", rss_key[i]);
2124         printf("\n");
2125 }
2126
2127 void
2128 port_rss_hash_key_update(portid_t port_id, char rss_type[], uint8_t *hash_key,
2129                          uint hash_key_len)
2130 {
2131         struct rte_eth_rss_conf rss_conf;
2132         int diag;
2133         unsigned int i;
2134
2135         rss_conf.rss_key = NULL;
2136         rss_conf.rss_key_len = hash_key_len;
2137         rss_conf.rss_hf = 0;
2138         for (i = 0; rss_type_table[i].str; i++) {
2139                 if (!strcmp(rss_type_table[i].str, rss_type))
2140                         rss_conf.rss_hf = rss_type_table[i].rss_type;
2141         }
2142         diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
2143         if (diag == 0) {
2144                 rss_conf.rss_key = hash_key;
2145                 diag = rte_eth_dev_rss_hash_update(port_id, &rss_conf);
2146         }
2147         if (diag == 0)
2148                 return;
2149
2150         switch (diag) {
2151         case -ENODEV:
2152                 printf("port index %d invalid\n", port_id);
2153                 break;
2154         case -ENOTSUP:
2155                 printf("operation not supported by device\n");
2156                 break;
2157         default:
2158                 printf("operation failed - diag=%d\n", diag);
2159                 break;
2160         }
2161 }
2162
2163 /*
2164  * Setup forwarding configuration for each logical core.
2165  */
2166 static void
2167 setup_fwd_config_of_each_lcore(struct fwd_config *cfg)
2168 {
2169         streamid_t nb_fs_per_lcore;
2170         streamid_t nb_fs;
2171         streamid_t sm_id;
2172         lcoreid_t  nb_extra;
2173         lcoreid_t  nb_fc;
2174         lcoreid_t  nb_lc;
2175         lcoreid_t  lc_id;
2176
2177         nb_fs = cfg->nb_fwd_streams;
2178         nb_fc = cfg->nb_fwd_lcores;
2179         if (nb_fs <= nb_fc) {
2180                 nb_fs_per_lcore = 1;
2181                 nb_extra = 0;
2182         } else {
2183                 nb_fs_per_lcore = (streamid_t) (nb_fs / nb_fc);
2184                 nb_extra = (lcoreid_t) (nb_fs % nb_fc);
2185         }
2186
2187         nb_lc = (lcoreid_t) (nb_fc - nb_extra);
2188         sm_id = 0;
2189         for (lc_id = 0; lc_id < nb_lc; lc_id++) {
2190                 fwd_lcores[lc_id]->stream_idx = sm_id;
2191                 fwd_lcores[lc_id]->stream_nb = nb_fs_per_lcore;
2192                 sm_id = (streamid_t) (sm_id + nb_fs_per_lcore);
2193         }
2194
2195         /*
2196          * Assign extra remaining streams, if any.
2197          */
2198         nb_fs_per_lcore = (streamid_t) (nb_fs_per_lcore + 1);
2199         for (lc_id = 0; lc_id < nb_extra; lc_id++) {
2200                 fwd_lcores[nb_lc + lc_id]->stream_idx = sm_id;
2201                 fwd_lcores[nb_lc + lc_id]->stream_nb = nb_fs_per_lcore;
2202                 sm_id = (streamid_t) (sm_id + nb_fs_per_lcore);
2203         }
2204 }
2205
2206 static portid_t
2207 fwd_topology_tx_port_get(portid_t rxp)
2208 {
2209         static int warning_once = 1;
2210
2211         RTE_ASSERT(rxp < cur_fwd_config.nb_fwd_ports);
2212
2213         switch (port_topology) {
2214         default:
2215         case PORT_TOPOLOGY_PAIRED:
2216                 if ((rxp & 0x1) == 0) {
2217                         if (rxp + 1 < cur_fwd_config.nb_fwd_ports)
2218                                 return rxp + 1;
2219                         if (warning_once) {
2220                                 printf("\nWarning! port-topology=paired"
2221                                        " and odd forward ports number,"
2222                                        " the last port will pair with"
2223                                        " itself.\n\n");
2224                                 warning_once = 0;
2225                         }
2226                         return rxp;
2227                 }
2228                 return rxp - 1;
2229         case PORT_TOPOLOGY_CHAINED:
2230                 return (rxp + 1) % cur_fwd_config.nb_fwd_ports;
2231         case PORT_TOPOLOGY_LOOP:
2232                 return rxp;
2233         }
2234 }
2235
2236 static void
2237 simple_fwd_config_setup(void)
2238 {
2239         portid_t i;
2240
2241         cur_fwd_config.nb_fwd_ports = (portid_t) nb_fwd_ports;
2242         cur_fwd_config.nb_fwd_streams =
2243                 (streamid_t) cur_fwd_config.nb_fwd_ports;
2244
2245         /* reinitialize forwarding streams */
2246         init_fwd_streams();
2247
2248         /*
2249          * In the simple forwarding test, the number of forwarding cores
2250          * must be lower or equal to the number of forwarding ports.
2251          */
2252         cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
2253         if (cur_fwd_config.nb_fwd_lcores > cur_fwd_config.nb_fwd_ports)
2254                 cur_fwd_config.nb_fwd_lcores =
2255                         (lcoreid_t) cur_fwd_config.nb_fwd_ports;
2256         setup_fwd_config_of_each_lcore(&cur_fwd_config);
2257
2258         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
2259                 fwd_streams[i]->rx_port   = fwd_ports_ids[i];
2260                 fwd_streams[i]->rx_queue  = 0;
2261                 fwd_streams[i]->tx_port   =
2262                                 fwd_ports_ids[fwd_topology_tx_port_get(i)];
2263                 fwd_streams[i]->tx_queue  = 0;
2264                 fwd_streams[i]->peer_addr = fwd_streams[i]->tx_port;
2265                 fwd_streams[i]->retry_enabled = retry_enabled;
2266         }
2267 }
2268
2269 /**
2270  * For the RSS forwarding test all streams distributed over lcores. Each stream
2271  * being composed of a RX queue to poll on a RX port for input messages,
2272  * associated with a TX queue of a TX port where to send forwarded packets.
2273  */
2274 static void
2275 rss_fwd_config_setup(void)
2276 {
2277         portid_t   rxp;
2278         portid_t   txp;
2279         queueid_t  rxq;
2280         queueid_t  nb_q;
2281         streamid_t  sm_id;
2282
2283         nb_q = nb_rxq;
2284         if (nb_q > nb_txq)
2285                 nb_q = nb_txq;
2286         cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
2287         cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
2288         cur_fwd_config.nb_fwd_streams =
2289                 (streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports);
2290
2291         if (cur_fwd_config.nb_fwd_streams < cur_fwd_config.nb_fwd_lcores)
2292                 cur_fwd_config.nb_fwd_lcores =
2293                         (lcoreid_t)cur_fwd_config.nb_fwd_streams;
2294
2295         /* reinitialize forwarding streams */
2296         init_fwd_streams();
2297
2298         setup_fwd_config_of_each_lcore(&cur_fwd_config);
2299         rxp = 0; rxq = 0;
2300         for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
2301                 struct fwd_stream *fs;
2302
2303                 fs = fwd_streams[sm_id];
2304                 txp = fwd_topology_tx_port_get(rxp);
2305                 fs->rx_port = fwd_ports_ids[rxp];
2306                 fs->rx_queue = rxq;
2307                 fs->tx_port = fwd_ports_ids[txp];
2308                 fs->tx_queue = rxq;
2309                 fs->peer_addr = fs->tx_port;
2310                 fs->retry_enabled = retry_enabled;
2311                 rxp++;
2312                 if (rxp < nb_fwd_ports)
2313                         continue;
2314                 rxp = 0;
2315                 rxq++;
2316         }
2317 }
2318
2319 /**
2320  * For the DCB forwarding test, each core is assigned on each traffic class.
2321  *
2322  * Each core is assigned a multi-stream, each stream being composed of
2323  * a RX queue to poll on a RX port for input messages, associated with
2324  * a TX queue of a TX port where to send forwarded packets. All RX and
2325  * TX queues are mapping to the same traffic class.
2326  * If VMDQ and DCB co-exist, each traffic class on different POOLs share
2327  * the same core
2328  */
2329 static void
2330 dcb_fwd_config_setup(void)
2331 {
2332         struct rte_eth_dcb_info rxp_dcb_info, txp_dcb_info;
2333         portid_t txp, rxp = 0;
2334         queueid_t txq, rxq = 0;
2335         lcoreid_t  lc_id;
2336         uint16_t nb_rx_queue, nb_tx_queue;
2337         uint16_t i, j, k, sm_id = 0;
2338         uint8_t tc = 0;
2339
2340         cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
2341         cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
2342         cur_fwd_config.nb_fwd_streams =
2343                 (streamid_t) (nb_rxq * cur_fwd_config.nb_fwd_ports);
2344
2345         /* reinitialize forwarding streams */
2346         init_fwd_streams();
2347         sm_id = 0;
2348         txp = 1;
2349         /* get the dcb info on the first RX and TX ports */
2350         (void)rte_eth_dev_get_dcb_info(fwd_ports_ids[rxp], &rxp_dcb_info);
2351         (void)rte_eth_dev_get_dcb_info(fwd_ports_ids[txp], &txp_dcb_info);
2352
2353         for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
2354                 fwd_lcores[lc_id]->stream_nb = 0;
2355                 fwd_lcores[lc_id]->stream_idx = sm_id;
2356                 for (i = 0; i < ETH_MAX_VMDQ_POOL; i++) {
2357                         /* if the nb_queue is zero, means this tc is
2358                          * not enabled on the POOL
2359                          */
2360                         if (rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue == 0)
2361                                 break;
2362                         k = fwd_lcores[lc_id]->stream_nb +
2363                                 fwd_lcores[lc_id]->stream_idx;
2364                         rxq = rxp_dcb_info.tc_queue.tc_rxq[i][tc].base;
2365                         txq = txp_dcb_info.tc_queue.tc_txq[i][tc].base;
2366                         nb_rx_queue = txp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue;
2367                         nb_tx_queue = txp_dcb_info.tc_queue.tc_txq[i][tc].nb_queue;
2368                         for (j = 0; j < nb_rx_queue; j++) {
2369                                 struct fwd_stream *fs;
2370
2371                                 fs = fwd_streams[k + j];
2372                                 fs->rx_port = fwd_ports_ids[rxp];
2373                                 fs->rx_queue = rxq + j;
2374                                 fs->tx_port = fwd_ports_ids[txp];
2375                                 fs->tx_queue = txq + j % nb_tx_queue;
2376                                 fs->peer_addr = fs->tx_port;
2377                                 fs->retry_enabled = retry_enabled;
2378                         }
2379                         fwd_lcores[lc_id]->stream_nb +=
2380                                 rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue;
2381                 }
2382                 sm_id = (streamid_t) (sm_id + fwd_lcores[lc_id]->stream_nb);
2383
2384                 tc++;
2385                 if (tc < rxp_dcb_info.nb_tcs)
2386                         continue;
2387                 /* Restart from TC 0 on next RX port */
2388                 tc = 0;
2389                 if (numa_support && (nb_fwd_ports <= (nb_ports >> 1)))
2390                         rxp = (portid_t)
2391                                 (rxp + ((nb_ports >> 1) / nb_fwd_ports));
2392                 else
2393                         rxp++;
2394                 if (rxp >= nb_fwd_ports)
2395                         return;
2396                 /* get the dcb information on next RX and TX ports */
2397                 if ((rxp & 0x1) == 0)
2398                         txp = (portid_t) (rxp + 1);
2399                 else
2400                         txp = (portid_t) (rxp - 1);
2401                 rte_eth_dev_get_dcb_info(fwd_ports_ids[rxp], &rxp_dcb_info);
2402                 rte_eth_dev_get_dcb_info(fwd_ports_ids[txp], &txp_dcb_info);
2403         }
2404 }
2405
2406 static void
2407 icmp_echo_config_setup(void)
2408 {
2409         portid_t  rxp;
2410         queueid_t rxq;
2411         lcoreid_t lc_id;
2412         uint16_t  sm_id;
2413
2414         if ((nb_txq * nb_fwd_ports) < nb_fwd_lcores)
2415                 cur_fwd_config.nb_fwd_lcores = (lcoreid_t)
2416                         (nb_txq * nb_fwd_ports);
2417         else
2418                 cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
2419         cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
2420         cur_fwd_config.nb_fwd_streams =
2421                 (streamid_t) (nb_rxq * cur_fwd_config.nb_fwd_ports);
2422         if (cur_fwd_config.nb_fwd_streams < cur_fwd_config.nb_fwd_lcores)
2423                 cur_fwd_config.nb_fwd_lcores =
2424                         (lcoreid_t)cur_fwd_config.nb_fwd_streams;
2425         if (verbose_level > 0) {
2426                 printf("%s fwd_cores=%d fwd_ports=%d fwd_streams=%d\n",
2427                        __FUNCTION__,
2428                        cur_fwd_config.nb_fwd_lcores,
2429                        cur_fwd_config.nb_fwd_ports,
2430                        cur_fwd_config.nb_fwd_streams);
2431         }
2432
2433         /* reinitialize forwarding streams */
2434         init_fwd_streams();
2435         setup_fwd_config_of_each_lcore(&cur_fwd_config);
2436         rxp = 0; rxq = 0;
2437         for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
2438                 if (verbose_level > 0)
2439                         printf("  core=%d: \n", lc_id);
2440                 for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) {
2441                         struct fwd_stream *fs;
2442                         fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id];
2443                         fs->rx_port = fwd_ports_ids[rxp];
2444                         fs->rx_queue = rxq;
2445                         fs->tx_port = fs->rx_port;
2446                         fs->tx_queue = rxq;
2447                         fs->peer_addr = fs->tx_port;
2448                         fs->retry_enabled = retry_enabled;
2449                         if (verbose_level > 0)
2450                                 printf("  stream=%d port=%d rxq=%d txq=%d\n",
2451                                        sm_id, fs->rx_port, fs->rx_queue,
2452                                        fs->tx_queue);
2453                         rxq = (queueid_t) (rxq + 1);
2454                         if (rxq == nb_rxq) {
2455                                 rxq = 0;
2456                                 rxp = (portid_t) (rxp + 1);
2457                         }
2458                 }
2459         }
2460 }
2461
2462 #if defined RTE_LIBRTE_PMD_SOFTNIC
2463 static void
2464 softnic_fwd_config_setup(void)
2465 {
2466         struct rte_port *port;
2467         portid_t pid, softnic_portid;
2468         queueid_t i;
2469         uint8_t softnic_enable = 0;
2470
2471         RTE_ETH_FOREACH_DEV(pid) {
2472                         port = &ports[pid];
2473                         const char *driver = port->dev_info.driver_name;
2474
2475                         if (strcmp(driver, "net_softnic") == 0) {
2476                                 softnic_portid = pid;
2477                                 softnic_enable = 1;
2478                                 break;
2479                         }
2480         }
2481
2482         if (softnic_enable == 0) {
2483                 printf("Softnic mode not configured(%s)!\n", __func__);
2484                 return;
2485         }
2486
2487         cur_fwd_config.nb_fwd_ports = 1;
2488         cur_fwd_config.nb_fwd_streams = (streamid_t) nb_rxq;
2489
2490         /* Re-initialize forwarding streams */
2491         init_fwd_streams();
2492
2493         /*
2494          * In the softnic forwarding test, the number of forwarding cores
2495          * is set to one and remaining are used for softnic packet processing.
2496          */
2497         cur_fwd_config.nb_fwd_lcores = 1;
2498         setup_fwd_config_of_each_lcore(&cur_fwd_config);
2499
2500         for (i = 0; i < cur_fwd_config.nb_fwd_streams; i++) {
2501                 fwd_streams[i]->rx_port   = softnic_portid;
2502                 fwd_streams[i]->rx_queue  = i;
2503                 fwd_streams[i]->tx_port   = softnic_portid;
2504                 fwd_streams[i]->tx_queue  = i;
2505                 fwd_streams[i]->peer_addr = fwd_streams[i]->tx_port;
2506                 fwd_streams[i]->retry_enabled = retry_enabled;
2507         }
2508 }
2509 #endif
2510
2511 void
2512 fwd_config_setup(void)
2513 {
2514         cur_fwd_config.fwd_eng = cur_fwd_eng;
2515         if (strcmp(cur_fwd_eng->fwd_mode_name, "icmpecho") == 0) {
2516                 icmp_echo_config_setup();
2517                 return;
2518         }
2519
2520 #if defined RTE_LIBRTE_PMD_SOFTNIC
2521         if (strcmp(cur_fwd_eng->fwd_mode_name, "softnic") == 0) {
2522                 softnic_fwd_config_setup();
2523                 return;
2524         }
2525 #endif
2526
2527         if ((nb_rxq > 1) && (nb_txq > 1)){
2528                 if (dcb_config)
2529                         dcb_fwd_config_setup();
2530                 else
2531                         rss_fwd_config_setup();
2532         }
2533         else
2534                 simple_fwd_config_setup();
2535 }
2536
2537 static const char *
2538 mp_alloc_to_str(uint8_t mode)
2539 {
2540         switch (mode) {
2541         case MP_ALLOC_NATIVE:
2542                 return "native";
2543         case MP_ALLOC_ANON:
2544                 return "anon";
2545         case MP_ALLOC_XMEM:
2546                 return "xmem";
2547         case MP_ALLOC_XMEM_HUGE:
2548                 return "xmemhuge";
2549         case MP_ALLOC_XBUF:
2550                 return "xbuf";
2551         default:
2552                 return "invalid";
2553         }
2554 }
2555
2556 void
2557 pkt_fwd_config_display(struct fwd_config *cfg)
2558 {
2559         struct fwd_stream *fs;
2560         lcoreid_t  lc_id;
2561         streamid_t sm_id;
2562
2563         printf("%s packet forwarding%s - ports=%d - cores=%d - streams=%d - "
2564                 "NUMA support %s, MP allocation mode: %s\n",
2565                 cfg->fwd_eng->fwd_mode_name,
2566                 retry_enabled == 0 ? "" : " with retry",
2567                 cfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams,
2568                 numa_support == 1 ? "enabled" : "disabled",
2569                 mp_alloc_to_str(mp_alloc_type));
2570
2571         if (retry_enabled)
2572                 printf("TX retry num: %u, delay between TX retries: %uus\n",
2573                         burst_tx_retry_num, burst_tx_delay_time);
2574         for (lc_id = 0; lc_id < cfg->nb_fwd_lcores; lc_id++) {
2575                 printf("Logical Core %u (socket %u) forwards packets on "
2576                        "%d streams:",
2577                        fwd_lcores_cpuids[lc_id],
2578                        rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]),
2579                        fwd_lcores[lc_id]->stream_nb);
2580                 for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) {
2581                         fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id];
2582                         printf("\n  RX P=%d/Q=%d (socket %u) -> TX "
2583                                "P=%d/Q=%d (socket %u) ",
2584                                fs->rx_port, fs->rx_queue,
2585                                ports[fs->rx_port].socket_id,
2586                                fs->tx_port, fs->tx_queue,
2587                                ports[fs->tx_port].socket_id);
2588                         print_ethaddr("peer=",
2589                                       &peer_eth_addrs[fs->peer_addr]);
2590                 }
2591                 printf("\n");
2592         }
2593         printf("\n");
2594 }
2595
2596 void
2597 set_fwd_eth_peer(portid_t port_id, char *peer_addr)
2598 {
2599         struct rte_ether_addr new_peer_addr;
2600         if (!rte_eth_dev_is_valid_port(port_id)) {
2601                 printf("Error: Invalid port number %i\n", port_id);
2602                 return;
2603         }
2604         if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
2605                 printf("Error: Invalid ethernet address: %s\n", peer_addr);
2606                 return;
2607         }
2608         peer_eth_addrs[port_id] = new_peer_addr;
2609 }
2610
2611 int
2612 set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc)
2613 {
2614         unsigned int i;
2615         unsigned int lcore_cpuid;
2616         int record_now;
2617
2618         record_now = 0;
2619  again:
2620         for (i = 0; i < nb_lc; i++) {
2621                 lcore_cpuid = lcorelist[i];
2622                 if (! rte_lcore_is_enabled(lcore_cpuid)) {
2623                         printf("lcore %u not enabled\n", lcore_cpuid);
2624                         return -1;
2625                 }
2626                 if (lcore_cpuid == rte_get_master_lcore()) {
2627                         printf("lcore %u cannot be masked on for running "
2628                                "packet forwarding, which is the master lcore "
2629                                "and reserved for command line parsing only\n",
2630                                lcore_cpuid);
2631                         return -1;
2632                 }
2633                 if (record_now)
2634                         fwd_lcores_cpuids[i] = lcore_cpuid;
2635         }
2636         if (record_now == 0) {
2637                 record_now = 1;
2638                 goto again;
2639         }
2640         nb_cfg_lcores = (lcoreid_t) nb_lc;
2641         if (nb_fwd_lcores != (lcoreid_t) nb_lc) {
2642                 printf("previous number of forwarding cores %u - changed to "
2643                        "number of configured cores %u\n",
2644                        (unsigned int) nb_fwd_lcores, nb_lc);
2645                 nb_fwd_lcores = (lcoreid_t) nb_lc;
2646         }
2647
2648         return 0;
2649 }
2650
2651 int
2652 set_fwd_lcores_mask(uint64_t lcoremask)
2653 {
2654         unsigned int lcorelist[64];
2655         unsigned int nb_lc;
2656         unsigned int i;
2657
2658         if (lcoremask == 0) {
2659                 printf("Invalid NULL mask of cores\n");
2660                 return -1;
2661         }
2662         nb_lc = 0;
2663         for (i = 0; i < 64; i++) {
2664                 if (! ((uint64_t)(1ULL << i) & lcoremask))
2665                         continue;
2666                 lcorelist[nb_lc++] = i;
2667         }
2668         return set_fwd_lcores_list(lcorelist, nb_lc);
2669 }
2670
2671 void
2672 set_fwd_lcores_number(uint16_t nb_lc)
2673 {
2674         if (nb_lc > nb_cfg_lcores) {
2675                 printf("nb fwd cores %u > %u (max. number of configured "
2676                        "lcores) - ignored\n",
2677                        (unsigned int) nb_lc, (unsigned int) nb_cfg_lcores);
2678                 return;
2679         }
2680         nb_fwd_lcores = (lcoreid_t) nb_lc;
2681         printf("Number of forwarding cores set to %u\n",
2682                (unsigned int) nb_fwd_lcores);
2683 }
2684
2685 void
2686 set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt)
2687 {
2688         unsigned int i;
2689         portid_t port_id;
2690         int record_now;
2691
2692         record_now = 0;
2693  again:
2694         for (i = 0; i < nb_pt; i++) {
2695                 port_id = (portid_t) portlist[i];
2696                 if (port_id_is_invalid(port_id, ENABLED_WARN))
2697                         return;
2698                 if (record_now)
2699                         fwd_ports_ids[i] = port_id;
2700         }
2701         if (record_now == 0) {
2702                 record_now = 1;
2703                 goto again;
2704         }
2705         nb_cfg_ports = (portid_t) nb_pt;
2706         if (nb_fwd_ports != (portid_t) nb_pt) {
2707                 printf("previous number of forwarding ports %u - changed to "
2708                        "number of configured ports %u\n",
2709                        (unsigned int) nb_fwd_ports, nb_pt);
2710                 nb_fwd_ports = (portid_t) nb_pt;
2711         }
2712 }
2713
2714 /**
2715  * Parse the user input and obtain the list of forwarding ports
2716  *
2717  * @param[in] list
2718  *   String containing the user input. User can specify
2719  *   in these formats 1,3,5 or 1-3 or 1-2,5 or 3,5-6.
2720  *   For example, if the user wants to use all the available
2721  *   4 ports in his system, then the input can be 0-3 or 0,1,2,3.
2722  *   If the user wants to use only the ports 1,2 then the input
2723  *   is 1,2.
2724  *   valid characters are '-' and ','
2725  * @param[out] values
2726  *   This array will be filled with a list of port IDs
2727  *   based on the user input
2728  *   Note that duplicate entries are discarded and only the first
2729  *   count entries in this array are port IDs and all the rest
2730  *   will contain default values
2731  * @param[in] maxsize
2732  *   This parameter denotes 2 things
2733  *   1) Number of elements in the values array
2734  *   2) Maximum value of each element in the values array
2735  * @return
2736  *   On success, returns total count of parsed port IDs
2737  *   On failure, returns 0
2738  */
2739 static unsigned int
2740 parse_port_list(const char *list, unsigned int *values, unsigned int maxsize)
2741 {
2742         unsigned int count = 0;
2743         char *end = NULL;
2744         int min, max;
2745         int value, i;
2746         unsigned int marked[maxsize];
2747
2748         if (list == NULL || values == NULL)
2749                 return 0;
2750
2751         for (i = 0; i < (int)maxsize; i++)
2752                 marked[i] = 0;
2753
2754         min = INT_MAX;
2755
2756         do {
2757                 /*Remove the blank spaces if any*/
2758                 while (isblank(*list))
2759                         list++;
2760                 if (*list == '\0')
2761                         break;
2762                 errno = 0;
2763                 value = strtol(list, &end, 10);
2764                 if (errno || end == NULL)
2765                         return 0;
2766                 if (value < 0 || value >= (int)maxsize)
2767                         return 0;
2768                 while (isblank(*end))
2769                         end++;
2770                 if (*end == '-' && min == INT_MAX) {
2771                         min = value;
2772                 } else if ((*end == ',') || (*end == '\0')) {
2773                         max = value;
2774                         if (min == INT_MAX)
2775                                 min = value;
2776                         for (i = min; i <= max; i++) {
2777                                 if (count < maxsize) {
2778                                         if (marked[i])
2779                                                 continue;
2780                                         values[count] = i;
2781                                         marked[i] = 1;
2782                                         count++;
2783                                 }
2784                         }
2785                         min = INT_MAX;
2786                 } else
2787                         return 0;
2788                 list = end + 1;
2789         } while (*end != '\0');
2790
2791         return count;
2792 }
2793
2794 void
2795 parse_fwd_portlist(const char *portlist)
2796 {
2797         unsigned int portcount;
2798         unsigned int portindex[RTE_MAX_ETHPORTS];
2799         unsigned int i, valid_port_count = 0;
2800
2801         portcount = parse_port_list(portlist, portindex, RTE_MAX_ETHPORTS);
2802         if (!portcount)
2803                 rte_exit(EXIT_FAILURE, "Invalid fwd port list\n");
2804
2805         /*
2806          * Here we verify the validity of the ports
2807          * and thereby calculate the total number of
2808          * valid ports
2809          */
2810         for (i = 0; i < portcount && i < RTE_DIM(portindex); i++) {
2811                 if (rte_eth_dev_is_valid_port(portindex[i])) {
2812                         portindex[valid_port_count] = portindex[i];
2813                         valid_port_count++;
2814                 }
2815         }
2816
2817         set_fwd_ports_list(portindex, valid_port_count);
2818 }
2819
2820 void
2821 set_fwd_ports_mask(uint64_t portmask)
2822 {
2823         unsigned int portlist[64];
2824         unsigned int nb_pt;
2825         unsigned int i;
2826
2827         if (portmask == 0) {
2828                 printf("Invalid NULL mask of ports\n");
2829                 return;
2830         }
2831         nb_pt = 0;
2832         RTE_ETH_FOREACH_DEV(i) {
2833                 if (! ((uint64_t)(1ULL << i) & portmask))
2834                         continue;
2835                 portlist[nb_pt++] = i;
2836         }
2837         set_fwd_ports_list(portlist, nb_pt);
2838 }
2839
2840 void
2841 set_fwd_ports_number(uint16_t nb_pt)
2842 {
2843         if (nb_pt > nb_cfg_ports) {
2844                 printf("nb fwd ports %u > %u (number of configured "
2845                        "ports) - ignored\n",
2846                        (unsigned int) nb_pt, (unsigned int) nb_cfg_ports);
2847                 return;
2848         }
2849         nb_fwd_ports = (portid_t) nb_pt;
2850         printf("Number of forwarding ports set to %u\n",
2851                (unsigned int) nb_fwd_ports);
2852 }
2853
2854 int
2855 port_is_forwarding(portid_t port_id)
2856 {
2857         unsigned int i;
2858
2859         if (port_id_is_invalid(port_id, ENABLED_WARN))
2860                 return -1;
2861
2862         for (i = 0; i < nb_fwd_ports; i++) {
2863                 if (fwd_ports_ids[i] == port_id)
2864                         return 1;
2865         }
2866
2867         return 0;
2868 }
2869
2870 void
2871 set_nb_pkt_per_burst(uint16_t nb)
2872 {
2873         if (nb > MAX_PKT_BURST) {
2874                 printf("nb pkt per burst: %u > %u (maximum packet per burst) "
2875                        " ignored\n",
2876                        (unsigned int) nb, (unsigned int) MAX_PKT_BURST);
2877                 return;
2878         }
2879         nb_pkt_per_burst = nb;
2880         printf("Number of packets per burst set to %u\n",
2881                (unsigned int) nb_pkt_per_burst);
2882 }
2883
2884 static const char *
2885 tx_split_get_name(enum tx_pkt_split split)
2886 {
2887         uint32_t i;
2888
2889         for (i = 0; i != RTE_DIM(tx_split_name); i++) {
2890                 if (tx_split_name[i].split == split)
2891                         return tx_split_name[i].name;
2892         }
2893         return NULL;
2894 }
2895
2896 void
2897 set_tx_pkt_split(const char *name)
2898 {
2899         uint32_t i;
2900
2901         for (i = 0; i != RTE_DIM(tx_split_name); i++) {
2902                 if (strcmp(tx_split_name[i].name, name) == 0) {
2903                         tx_pkt_split = tx_split_name[i].split;
2904                         return;
2905                 }
2906         }
2907         printf("unknown value: \"%s\"\n", name);
2908 }
2909
2910 void
2911 show_tx_pkt_segments(void)
2912 {
2913         uint32_t i, n;
2914         const char *split;
2915
2916         n = tx_pkt_nb_segs;
2917         split = tx_split_get_name(tx_pkt_split);
2918
2919         printf("Number of segments: %u\n", n);
2920         printf("Segment sizes: ");
2921         for (i = 0; i != n - 1; i++)
2922                 printf("%hu,", tx_pkt_seg_lengths[i]);
2923         printf("%hu\n", tx_pkt_seg_lengths[i]);
2924         printf("Split packet: %s\n", split);
2925 }
2926
2927 void
2928 set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs)
2929 {
2930         uint16_t tx_pkt_len;
2931         unsigned i;
2932
2933         if (nb_segs >= (unsigned) nb_txd) {
2934                 printf("nb segments per TX packets=%u >= nb_txd=%u - ignored\n",
2935                        nb_segs, (unsigned int) nb_txd);
2936                 return;
2937         }
2938
2939         /*
2940          * Check that each segment length is greater or equal than
2941          * the mbuf data sise.
2942          * Check also that the total packet length is greater or equal than the
2943          * size of an empty UDP/IP packet (sizeof(struct rte_ether_hdr) +
2944          * 20 + 8).
2945          */
2946         tx_pkt_len = 0;
2947         for (i = 0; i < nb_segs; i++) {
2948                 if (seg_lengths[i] > (unsigned) mbuf_data_size) {
2949                         printf("length[%u]=%u > mbuf_data_size=%u - give up\n",
2950                                i, seg_lengths[i], (unsigned) mbuf_data_size);
2951                         return;
2952                 }
2953                 tx_pkt_len = (uint16_t)(tx_pkt_len + seg_lengths[i]);
2954         }
2955         if (tx_pkt_len < (sizeof(struct rte_ether_hdr) + 20 + 8)) {
2956                 printf("total packet length=%u < %d - give up\n",
2957                                 (unsigned) tx_pkt_len,
2958                                 (int)(sizeof(struct rte_ether_hdr) + 20 + 8));
2959                 return;
2960         }
2961
2962         for (i = 0; i < nb_segs; i++)
2963                 tx_pkt_seg_lengths[i] = (uint16_t) seg_lengths[i];
2964
2965         tx_pkt_length  = tx_pkt_len;
2966         tx_pkt_nb_segs = (uint8_t) nb_segs;
2967 }
2968
2969 void
2970 setup_gro(const char *onoff, portid_t port_id)
2971 {
2972         if (!rte_eth_dev_is_valid_port(port_id)) {
2973                 printf("invalid port id %u\n", port_id);
2974                 return;
2975         }
2976         if (test_done == 0) {
2977                 printf("Before enable/disable GRO,"
2978                                 " please stop forwarding first\n");
2979                 return;
2980         }
2981         if (strcmp(onoff, "on") == 0) {
2982                 if (gro_ports[port_id].enable != 0) {
2983                         printf("Port %u has enabled GRO. Please"
2984                                         " disable GRO first\n", port_id);
2985                         return;
2986                 }
2987                 if (gro_flush_cycles == GRO_DEFAULT_FLUSH_CYCLES) {
2988                         gro_ports[port_id].param.gro_types = RTE_GRO_TCP_IPV4;
2989                         gro_ports[port_id].param.max_flow_num =
2990                                 GRO_DEFAULT_FLOW_NUM;
2991                         gro_ports[port_id].param.max_item_per_flow =
2992                                 GRO_DEFAULT_ITEM_NUM_PER_FLOW;
2993                 }
2994                 gro_ports[port_id].enable = 1;
2995         } else {
2996                 if (gro_ports[port_id].enable == 0) {
2997                         printf("Port %u has disabled GRO\n", port_id);
2998                         return;
2999                 }
3000                 gro_ports[port_id].enable = 0;
3001         }
3002 }
3003
3004 void
3005 setup_gro_flush_cycles(uint8_t cycles)
3006 {
3007         if (test_done == 0) {
3008                 printf("Before change flush interval for GRO,"
3009                                 " please stop forwarding first.\n");
3010                 return;
3011         }
3012
3013         if (cycles > GRO_MAX_FLUSH_CYCLES || cycles <
3014                         GRO_DEFAULT_FLUSH_CYCLES) {
3015                 printf("The flushing cycle be in the range"
3016                                 " of 1 to %u. Revert to the default"
3017                                 " value %u.\n",
3018                                 GRO_MAX_FLUSH_CYCLES,
3019                                 GRO_DEFAULT_FLUSH_CYCLES);
3020                 cycles = GRO_DEFAULT_FLUSH_CYCLES;
3021         }
3022
3023         gro_flush_cycles = cycles;
3024 }
3025
3026 void
3027 show_gro(portid_t port_id)
3028 {
3029         struct rte_gro_param *param;
3030         uint32_t max_pkts_num;
3031
3032         param = &gro_ports[port_id].param;
3033
3034         if (!rte_eth_dev_is_valid_port(port_id)) {
3035                 printf("Invalid port id %u.\n", port_id);
3036                 return;
3037         }
3038         if (gro_ports[port_id].enable) {
3039                 printf("GRO type: TCP/IPv4\n");
3040                 if (gro_flush_cycles == GRO_DEFAULT_FLUSH_CYCLES) {
3041                         max_pkts_num = param->max_flow_num *
3042                                 param->max_item_per_flow;
3043                 } else
3044                         max_pkts_num = MAX_PKT_BURST * GRO_MAX_FLUSH_CYCLES;
3045                 printf("Max number of packets to perform GRO: %u\n",
3046                                 max_pkts_num);
3047                 printf("Flushing cycles: %u\n", gro_flush_cycles);
3048         } else
3049                 printf("Port %u doesn't enable GRO.\n", port_id);
3050 }
3051
3052 void
3053 setup_gso(const char *mode, portid_t port_id)
3054 {
3055         if (!rte_eth_dev_is_valid_port(port_id)) {
3056                 printf("invalid port id %u\n", port_id);
3057                 return;
3058         }
3059         if (strcmp(mode, "on") == 0) {
3060                 if (test_done == 0) {
3061                         printf("before enabling GSO,"
3062                                         " please stop forwarding first\n");
3063                         return;
3064                 }
3065                 gso_ports[port_id].enable = 1;
3066         } else if (strcmp(mode, "off") == 0) {
3067                 if (test_done == 0) {
3068                         printf("before disabling GSO,"
3069                                         " please stop forwarding first\n");
3070                         return;
3071                 }
3072                 gso_ports[port_id].enable = 0;
3073         }
3074 }
3075
3076 char*
3077 list_pkt_forwarding_modes(void)
3078 {
3079         static char fwd_modes[128] = "";
3080         const char *separator = "|";
3081         struct fwd_engine *fwd_eng;
3082         unsigned i = 0;
3083
3084         if (strlen (fwd_modes) == 0) {
3085                 while ((fwd_eng = fwd_engines[i++]) != NULL) {
3086                         strncat(fwd_modes, fwd_eng->fwd_mode_name,
3087                                         sizeof(fwd_modes) - strlen(fwd_modes) - 1);
3088                         strncat(fwd_modes, separator,
3089                                         sizeof(fwd_modes) - strlen(fwd_modes) - 1);
3090                 }
3091                 fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0';
3092         }
3093
3094         return fwd_modes;
3095 }
3096
3097 char*
3098 list_pkt_forwarding_retry_modes(void)
3099 {
3100         static char fwd_modes[128] = "";
3101         const char *separator = "|";
3102         struct fwd_engine *fwd_eng;
3103         unsigned i = 0;
3104
3105         if (strlen(fwd_modes) == 0) {
3106                 while ((fwd_eng = fwd_engines[i++]) != NULL) {
3107                         if (fwd_eng == &rx_only_engine)
3108                                 continue;
3109                         strncat(fwd_modes, fwd_eng->fwd_mode_name,
3110                                         sizeof(fwd_modes) -
3111                                         strlen(fwd_modes) - 1);
3112                         strncat(fwd_modes, separator,
3113                                         sizeof(fwd_modes) -
3114                                         strlen(fwd_modes) - 1);
3115                 }
3116                 fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0';
3117         }
3118
3119         return fwd_modes;
3120 }
3121
3122 void
3123 set_pkt_forwarding_mode(const char *fwd_mode_name)
3124 {
3125         struct fwd_engine *fwd_eng;
3126         unsigned i;
3127
3128         i = 0;
3129         while ((fwd_eng = fwd_engines[i]) != NULL) {
3130                 if (! strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) {
3131                         printf("Set %s packet forwarding mode%s\n",
3132                                fwd_mode_name,
3133                                retry_enabled == 0 ? "" : " with retry");
3134                         cur_fwd_eng = fwd_eng;
3135                         return;
3136                 }
3137                 i++;
3138         }
3139         printf("Invalid %s packet forwarding mode\n", fwd_mode_name);
3140 }
3141
3142 void
3143 add_rx_dump_callbacks(portid_t portid)
3144 {
3145         struct rte_eth_dev_info dev_info;
3146         uint16_t queue;
3147         int ret;
3148
3149         if (port_id_is_invalid(portid, ENABLED_WARN))
3150                 return;
3151
3152         ret = eth_dev_info_get_print_err(portid, &dev_info);
3153         if (ret != 0)
3154                 return;
3155
3156         for (queue = 0; queue < dev_info.nb_rx_queues; queue++)
3157                 if (!ports[portid].rx_dump_cb[queue])
3158                         ports[portid].rx_dump_cb[queue] =
3159                                 rte_eth_add_rx_callback(portid, queue,
3160                                         dump_rx_pkts, NULL);
3161 }
3162
3163 void
3164 add_tx_dump_callbacks(portid_t portid)
3165 {
3166         struct rte_eth_dev_info dev_info;
3167         uint16_t queue;
3168         int ret;
3169
3170         if (port_id_is_invalid(portid, ENABLED_WARN))
3171                 return;
3172
3173         ret = eth_dev_info_get_print_err(portid, &dev_info);
3174         if (ret != 0)
3175                 return;
3176
3177         for (queue = 0; queue < dev_info.nb_tx_queues; queue++)
3178                 if (!ports[portid].tx_dump_cb[queue])
3179                         ports[portid].tx_dump_cb[queue] =
3180                                 rte_eth_add_tx_callback(portid, queue,
3181                                                         dump_tx_pkts, NULL);
3182 }
3183
3184 void
3185 remove_rx_dump_callbacks(portid_t portid)
3186 {
3187         struct rte_eth_dev_info dev_info;
3188         uint16_t queue;
3189         int ret;
3190
3191         if (port_id_is_invalid(portid, ENABLED_WARN))
3192                 return;
3193
3194         ret = eth_dev_info_get_print_err(portid, &dev_info);
3195         if (ret != 0)
3196                 return;
3197
3198         for (queue = 0; queue < dev_info.nb_rx_queues; queue++)
3199                 if (ports[portid].rx_dump_cb[queue]) {
3200                         rte_eth_remove_rx_callback(portid, queue,
3201                                 ports[portid].rx_dump_cb[queue]);
3202                         ports[portid].rx_dump_cb[queue] = NULL;
3203                 }
3204 }
3205
3206 void
3207 remove_tx_dump_callbacks(portid_t portid)
3208 {
3209         struct rte_eth_dev_info dev_info;
3210         uint16_t queue;
3211         int ret;
3212
3213         if (port_id_is_invalid(portid, ENABLED_WARN))
3214                 return;
3215
3216         ret = eth_dev_info_get_print_err(portid, &dev_info);
3217         if (ret != 0)
3218                 return;
3219
3220         for (queue = 0; queue < dev_info.nb_tx_queues; queue++)
3221                 if (ports[portid].tx_dump_cb[queue]) {
3222                         rte_eth_remove_tx_callback(portid, queue,
3223                                 ports[portid].tx_dump_cb[queue]);
3224                         ports[portid].tx_dump_cb[queue] = NULL;
3225                 }
3226 }
3227
3228 void
3229 configure_rxtx_dump_callbacks(uint16_t verbose)
3230 {
3231         portid_t portid;
3232
3233 #ifndef RTE_ETHDEV_RXTX_CALLBACKS
3234                 TESTPMD_LOG(ERR, "setting rxtx callbacks is not enabled\n");
3235                 return;
3236 #endif
3237
3238         RTE_ETH_FOREACH_DEV(portid)
3239         {
3240                 if (verbose == 1 || verbose > 2)
3241                         add_rx_dump_callbacks(portid);
3242                 else
3243                         remove_rx_dump_callbacks(portid);
3244                 if (verbose >= 2)
3245                         add_tx_dump_callbacks(portid);
3246                 else
3247                         remove_tx_dump_callbacks(portid);
3248         }
3249 }
3250
3251 void
3252 set_verbose_level(uint16_t vb_level)
3253 {
3254         printf("Change verbose level from %u to %u\n",
3255                (unsigned int) verbose_level, (unsigned int) vb_level);
3256         verbose_level = vb_level;
3257         configure_rxtx_dump_callbacks(verbose_level);
3258 }
3259
3260 void
3261 vlan_extend_set(portid_t port_id, int on)
3262 {
3263         int diag;
3264         int vlan_offload;
3265         uint64_t port_rx_offloads = ports[port_id].dev_conf.rxmode.offloads;
3266
3267         if (port_id_is_invalid(port_id, ENABLED_WARN))
3268                 return;
3269
3270         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
3271
3272         if (on) {
3273                 vlan_offload |= ETH_VLAN_EXTEND_OFFLOAD;
3274                 port_rx_offloads |= DEV_RX_OFFLOAD_VLAN_EXTEND;
3275         } else {
3276                 vlan_offload &= ~ETH_VLAN_EXTEND_OFFLOAD;
3277                 port_rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_EXTEND;
3278         }
3279
3280         diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
3281         if (diag < 0)
3282                 printf("rx_vlan_extend_set(port_pi=%d, on=%d) failed "
3283                "diag=%d\n", port_id, on, diag);
3284         ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads;
3285 }
3286
3287 void
3288 rx_vlan_strip_set(portid_t port_id, int on)
3289 {
3290         int diag;
3291         int vlan_offload;
3292         uint64_t port_rx_offloads = ports[port_id].dev_conf.rxmode.offloads;
3293
3294         if (port_id_is_invalid(port_id, ENABLED_WARN))
3295                 return;
3296
3297         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
3298
3299         if (on) {
3300                 vlan_offload |= ETH_VLAN_STRIP_OFFLOAD;
3301                 port_rx_offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
3302         } else {
3303                 vlan_offload &= ~ETH_VLAN_STRIP_OFFLOAD;
3304                 port_rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
3305         }
3306
3307         diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
3308         if (diag < 0)
3309                 printf("rx_vlan_strip_set(port_pi=%d, on=%d) failed "
3310                "diag=%d\n", port_id, on, diag);
3311         ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads;
3312 }
3313
3314 void
3315 rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on)
3316 {
3317         int diag;
3318
3319         if (port_id_is_invalid(port_id, ENABLED_WARN))
3320                 return;
3321
3322         diag = rte_eth_dev_set_vlan_strip_on_queue(port_id, queue_id, on);
3323         if (diag < 0)
3324                 printf("rx_vlan_strip_set_on_queue(port_pi=%d, queue_id=%d, on=%d) failed "
3325                "diag=%d\n", port_id, queue_id, on, diag);
3326 }
3327
3328 void
3329 rx_vlan_filter_set(portid_t port_id, int on)
3330 {
3331         int diag;
3332         int vlan_offload;
3333         uint64_t port_rx_offloads = ports[port_id].dev_conf.rxmode.offloads;
3334
3335         if (port_id_is_invalid(port_id, ENABLED_WARN))
3336                 return;
3337
3338         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
3339
3340         if (on) {
3341                 vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
3342                 port_rx_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
3343         } else {
3344                 vlan_offload &= ~ETH_VLAN_FILTER_OFFLOAD;
3345                 port_rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
3346         }
3347
3348         diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
3349         if (diag < 0)
3350                 printf("rx_vlan_filter_set(port_pi=%d, on=%d) failed "
3351                "diag=%d\n", port_id, on, diag);
3352         ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads;
3353 }
3354
3355 void
3356 rx_vlan_qinq_strip_set(portid_t port_id, int on)
3357 {
3358         int diag;
3359         int vlan_offload;
3360         uint64_t port_rx_offloads = ports[port_id].dev_conf.rxmode.offloads;
3361
3362         if (port_id_is_invalid(port_id, ENABLED_WARN))
3363                 return;
3364
3365         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
3366
3367         if (on) {
3368                 vlan_offload |= ETH_QINQ_STRIP_OFFLOAD;
3369                 port_rx_offloads |= DEV_RX_OFFLOAD_QINQ_STRIP;
3370         } else {
3371                 vlan_offload &= ~ETH_QINQ_STRIP_OFFLOAD;
3372                 port_rx_offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
3373         }
3374
3375         diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
3376         if (diag < 0)
3377                 printf("%s(port_pi=%d, on=%d) failed "
3378                "diag=%d\n", __func__, port_id, on, diag);
3379         ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads;
3380 }
3381
3382 int
3383 rx_vft_set(portid_t port_id, uint16_t vlan_id, int on)
3384 {
3385         int diag;
3386
3387         if (port_id_is_invalid(port_id, ENABLED_WARN))
3388                 return 1;
3389         if (vlan_id_is_invalid(vlan_id))
3390                 return 1;
3391         diag = rte_eth_dev_vlan_filter(port_id, vlan_id, on);
3392         if (diag == 0)
3393                 return 0;
3394         printf("rte_eth_dev_vlan_filter(port_pi=%d, vlan_id=%d, on=%d) failed "
3395                "diag=%d\n",
3396                port_id, vlan_id, on, diag);
3397         return -1;
3398 }
3399
3400 void
3401 rx_vlan_all_filter_set(portid_t port_id, int on)
3402 {
3403         uint16_t vlan_id;
3404
3405         if (port_id_is_invalid(port_id, ENABLED_WARN))
3406                 return;
3407         for (vlan_id = 0; vlan_id < 4096; vlan_id++) {
3408                 if (rx_vft_set(port_id, vlan_id, on))
3409                         break;
3410         }
3411 }
3412
3413 void
3414 vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type, uint16_t tp_id)
3415 {
3416         int diag;
3417
3418         if (port_id_is_invalid(port_id, ENABLED_WARN))
3419                 return;
3420
3421         diag = rte_eth_dev_set_vlan_ether_type(port_id, vlan_type, tp_id);
3422         if (diag == 0)
3423                 return;
3424
3425         printf("tx_vlan_tpid_set(port_pi=%d, vlan_type=%d, tpid=%d) failed "
3426                "diag=%d\n",
3427                port_id, vlan_type, tp_id, diag);
3428 }
3429
3430 void
3431 tx_vlan_set(portid_t port_id, uint16_t vlan_id)
3432 {
3433         struct rte_eth_dev_info dev_info;
3434         int ret;
3435
3436         if (port_id_is_invalid(port_id, ENABLED_WARN))
3437                 return;
3438         if (vlan_id_is_invalid(vlan_id))
3439                 return;
3440
3441         if (ports[port_id].dev_conf.txmode.offloads &
3442             DEV_TX_OFFLOAD_QINQ_INSERT) {
3443                 printf("Error, as QinQ has been enabled.\n");
3444                 return;
3445         }
3446
3447         ret = eth_dev_info_get_print_err(port_id, &dev_info);
3448         if (ret != 0)
3449                 return;
3450
3451         if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT) == 0) {
3452                 printf("Error: vlan insert is not supported by port %d\n",
3453                         port_id);
3454                 return;
3455         }
3456
3457         tx_vlan_reset(port_id);
3458         ports[port_id].dev_conf.txmode.offloads |= DEV_TX_OFFLOAD_VLAN_INSERT;
3459         ports[port_id].tx_vlan_id = vlan_id;
3460 }
3461
3462 void
3463 tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer)
3464 {
3465         struct rte_eth_dev_info dev_info;
3466         int ret;
3467
3468         if (port_id_is_invalid(port_id, ENABLED_WARN))
3469                 return;
3470         if (vlan_id_is_invalid(vlan_id))
3471                 return;
3472         if (vlan_id_is_invalid(vlan_id_outer))
3473                 return;
3474
3475         ret = eth_dev_info_get_print_err(port_id, &dev_info);
3476         if (ret != 0)
3477                 return;
3478
3479         if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_QINQ_INSERT) == 0) {
3480                 printf("Error: qinq insert not supported by port %d\n",
3481                         port_id);
3482                 return;
3483         }
3484
3485         tx_vlan_reset(port_id);
3486         ports[port_id].dev_conf.txmode.offloads |= (DEV_TX_OFFLOAD_VLAN_INSERT |
3487                                                     DEV_TX_OFFLOAD_QINQ_INSERT);
3488         ports[port_id].tx_vlan_id = vlan_id;
3489         ports[port_id].tx_vlan_id_outer = vlan_id_outer;
3490 }
3491
3492 void
3493 tx_vlan_reset(portid_t port_id)
3494 {
3495         if (port_id_is_invalid(port_id, ENABLED_WARN))
3496                 return;
3497         ports[port_id].dev_conf.txmode.offloads &=
3498                                 ~(DEV_TX_OFFLOAD_VLAN_INSERT |
3499                                   DEV_TX_OFFLOAD_QINQ_INSERT);
3500         ports[port_id].tx_vlan_id = 0;
3501         ports[port_id].tx_vlan_id_outer = 0;
3502 }
3503
3504 void
3505 tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on)
3506 {
3507         if (port_id_is_invalid(port_id, ENABLED_WARN))
3508                 return;
3509
3510         rte_eth_dev_set_vlan_pvid(port_id, vlan_id, on);
3511 }
3512
3513 void
3514 set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value)
3515 {
3516         uint16_t i;
3517         uint8_t existing_mapping_found = 0;
3518
3519         if (port_id_is_invalid(port_id, ENABLED_WARN))
3520                 return;
3521
3522         if (is_rx ? (rx_queue_id_is_invalid(queue_id)) : (tx_queue_id_is_invalid(queue_id)))
3523                 return;
3524
3525         if (map_value >= RTE_ETHDEV_QUEUE_STAT_CNTRS) {
3526                 printf("map_value not in required range 0..%d\n",
3527                                 RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
3528                 return;
3529         }
3530
3531         if (!is_rx) { /*then tx*/
3532                 for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
3533                         if ((tx_queue_stats_mappings[i].port_id == port_id) &&
3534                             (tx_queue_stats_mappings[i].queue_id == queue_id)) {
3535                                 tx_queue_stats_mappings[i].stats_counter_id = map_value;
3536                                 existing_mapping_found = 1;
3537                                 break;
3538                         }
3539                 }
3540                 if (!existing_mapping_found) { /* A new additional mapping... */
3541                         tx_queue_stats_mappings[nb_tx_queue_stats_mappings].port_id = port_id;
3542                         tx_queue_stats_mappings[nb_tx_queue_stats_mappings].queue_id = queue_id;
3543                         tx_queue_stats_mappings[nb_tx_queue_stats_mappings].stats_counter_id = map_value;
3544                         nb_tx_queue_stats_mappings++;
3545                 }
3546         }
3547         else { /*rx*/
3548                 for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
3549                         if ((rx_queue_stats_mappings[i].port_id == port_id) &&
3550                             (rx_queue_stats_mappings[i].queue_id == queue_id)) {
3551                                 rx_queue_stats_mappings[i].stats_counter_id = map_value;
3552                                 existing_mapping_found = 1;
3553                                 break;
3554                         }
3555                 }
3556                 if (!existing_mapping_found) { /* A new additional mapping... */
3557                         rx_queue_stats_mappings[nb_rx_queue_stats_mappings].port_id = port_id;
3558                         rx_queue_stats_mappings[nb_rx_queue_stats_mappings].queue_id = queue_id;
3559                         rx_queue_stats_mappings[nb_rx_queue_stats_mappings].stats_counter_id = map_value;
3560                         nb_rx_queue_stats_mappings++;
3561                 }
3562         }
3563 }
3564
3565 void
3566 set_xstats_hide_zero(uint8_t on_off)
3567 {
3568         xstats_hide_zero = on_off;
3569 }
3570
3571 static inline void
3572 print_fdir_mask(struct rte_eth_fdir_masks *mask)
3573 {
3574         printf("\n    vlan_tci: 0x%04x", rte_be_to_cpu_16(mask->vlan_tci_mask));
3575
3576         if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
3577                 printf(", mac_addr: 0x%02x, tunnel_type: 0x%01x,"
3578                         " tunnel_id: 0x%08x",
3579                         mask->mac_addr_byte_mask, mask->tunnel_type_mask,
3580                         rte_be_to_cpu_32(mask->tunnel_id_mask));
3581         else if (fdir_conf.mode != RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
3582                 printf(", src_ipv4: 0x%08x, dst_ipv4: 0x%08x",
3583                         rte_be_to_cpu_32(mask->ipv4_mask.src_ip),
3584                         rte_be_to_cpu_32(mask->ipv4_mask.dst_ip));
3585
3586                 printf("\n    src_port: 0x%04x, dst_port: 0x%04x",
3587                         rte_be_to_cpu_16(mask->src_port_mask),
3588                         rte_be_to_cpu_16(mask->dst_port_mask));
3589
3590                 printf("\n    src_ipv6: 0x%08x,0x%08x,0x%08x,0x%08x",
3591                         rte_be_to_cpu_32(mask->ipv6_mask.src_ip[0]),
3592                         rte_be_to_cpu_32(mask->ipv6_mask.src_ip[1]),
3593                         rte_be_to_cpu_32(mask->ipv6_mask.src_ip[2]),
3594                         rte_be_to_cpu_32(mask->ipv6_mask.src_ip[3]));
3595
3596                 printf("\n    dst_ipv6: 0x%08x,0x%08x,0x%08x,0x%08x",
3597                         rte_be_to_cpu_32(mask->ipv6_mask.dst_ip[0]),
3598                         rte_be_to_cpu_32(mask->ipv6_mask.dst_ip[1]),
3599                         rte_be_to_cpu_32(mask->ipv6_mask.dst_ip[2]),
3600                         rte_be_to_cpu_32(mask->ipv6_mask.dst_ip[3]));
3601         }
3602
3603         printf("\n");
3604 }
3605
3606 static inline void
3607 print_fdir_flex_payload(struct rte_eth_fdir_flex_conf *flex_conf, uint32_t num)
3608 {
3609         struct rte_eth_flex_payload_cfg *cfg;
3610         uint32_t i, j;
3611
3612         for (i = 0; i < flex_conf->nb_payloads; i++) {
3613                 cfg = &flex_conf->flex_set[i];
3614                 if (cfg->type == RTE_ETH_RAW_PAYLOAD)
3615                         printf("\n    RAW:  ");
3616                 else if (cfg->type == RTE_ETH_L2_PAYLOAD)
3617                         printf("\n    L2_PAYLOAD:  ");
3618                 else if (cfg->type == RTE_ETH_L3_PAYLOAD)
3619                         printf("\n    L3_PAYLOAD:  ");
3620                 else if (cfg->type == RTE_ETH_L4_PAYLOAD)
3621                         printf("\n    L4_PAYLOAD:  ");
3622                 else
3623                         printf("\n    UNKNOWN PAYLOAD(%u):  ", cfg->type);
3624                 for (j = 0; j < num; j++)
3625                         printf("  %-5u", cfg->src_offset[j]);
3626         }
3627         printf("\n");
3628 }
3629
3630 static char *
3631 flowtype_to_str(uint16_t flow_type)
3632 {
3633         struct flow_type_info {
3634                 char str[32];
3635                 uint16_t ftype;
3636         };
3637
3638         uint8_t i;
3639         static struct flow_type_info flowtype_str_table[] = {
3640                 {"raw", RTE_ETH_FLOW_RAW},
3641                 {"ipv4", RTE_ETH_FLOW_IPV4},
3642                 {"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
3643                 {"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
3644                 {"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
3645                 {"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
3646                 {"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
3647                 {"ipv6", RTE_ETH_FLOW_IPV6},
3648                 {"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
3649                 {"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
3650                 {"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
3651                 {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
3652                 {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
3653                 {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
3654                 {"port", RTE_ETH_FLOW_PORT},
3655                 {"vxlan", RTE_ETH_FLOW_VXLAN},
3656                 {"geneve", RTE_ETH_FLOW_GENEVE},
3657                 {"nvgre", RTE_ETH_FLOW_NVGRE},
3658                 {"vxlan-gpe", RTE_ETH_FLOW_VXLAN_GPE},
3659         };
3660
3661         for (i = 0; i < RTE_DIM(flowtype_str_table); i++) {
3662                 if (flowtype_str_table[i].ftype == flow_type)
3663                         return flowtype_str_table[i].str;
3664         }
3665
3666         return NULL;
3667 }
3668
3669 static inline void
3670 print_fdir_flex_mask(struct rte_eth_fdir_flex_conf *flex_conf, uint32_t num)
3671 {
3672         struct rte_eth_fdir_flex_mask *mask;
3673         uint32_t i, j;
3674         char *p;
3675
3676         for (i = 0; i < flex_conf->nb_flexmasks; i++) {
3677                 mask = &flex_conf->flex_mask[i];
3678                 p = flowtype_to_str(mask->flow_type);
3679                 printf("\n    %s:\t", p ? p : "unknown");
3680                 for (j = 0; j < num; j++)
3681                         printf(" %02x", mask->mask[j]);
3682         }
3683         printf("\n");
3684 }
3685
3686 static inline void
3687 print_fdir_flow_type(uint32_t flow_types_mask)
3688 {
3689         int i;
3690         char *p;
3691
3692         for (i = RTE_ETH_FLOW_UNKNOWN; i < RTE_ETH_FLOW_MAX; i++) {
3693                 if (!(flow_types_mask & (1 << i)))
3694                         continue;
3695                 p = flowtype_to_str(i);
3696                 if (p)
3697                         printf(" %s", p);
3698                 else
3699                         printf(" unknown");
3700         }
3701         printf("\n");
3702 }
3703
3704 void
3705 fdir_get_infos(portid_t port_id)
3706 {
3707         struct rte_eth_fdir_stats fdir_stat;
3708         struct rte_eth_fdir_info fdir_info;
3709         int ret;
3710
3711         static const char *fdir_stats_border = "########################";
3712
3713         if (port_id_is_invalid(port_id, ENABLED_WARN))
3714                 return;
3715         ret = rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_FDIR);
3716         if (ret < 0) {
3717                 printf("\n FDIR is not supported on port %-2d\n",
3718                         port_id);
3719                 return;
3720         }
3721
3722         memset(&fdir_info, 0, sizeof(fdir_info));
3723         rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR,
3724                                RTE_ETH_FILTER_INFO, &fdir_info);
3725         memset(&fdir_stat, 0, sizeof(fdir_stat));
3726         rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR,
3727                                RTE_ETH_FILTER_STATS, &fdir_stat);
3728         printf("\n  %s FDIR infos for port %-2d     %s\n",
3729                fdir_stats_border, port_id, fdir_stats_border);
3730         printf("  MODE: ");
3731         if (fdir_info.mode == RTE_FDIR_MODE_PERFECT)
3732                 printf("  PERFECT\n");
3733         else if (fdir_info.mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN)
3734                 printf("  PERFECT-MAC-VLAN\n");
3735         else if (fdir_info.mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
3736                 printf("  PERFECT-TUNNEL\n");
3737         else if (fdir_info.mode == RTE_FDIR_MODE_SIGNATURE)
3738                 printf("  SIGNATURE\n");
3739         else
3740                 printf("  DISABLE\n");
3741         if (fdir_info.mode != RTE_FDIR_MODE_PERFECT_MAC_VLAN
3742                 && fdir_info.mode != RTE_FDIR_MODE_PERFECT_TUNNEL) {
3743                 printf("  SUPPORTED FLOW TYPE: ");
3744                 print_fdir_flow_type(fdir_info.flow_types_mask[0]);
3745         }
3746         printf("  FLEX PAYLOAD INFO:\n");
3747         printf("  max_len:       %-10"PRIu32"  payload_limit: %-10"PRIu32"\n"
3748                "  payload_unit:  %-10"PRIu32"  payload_seg:   %-10"PRIu32"\n"
3749                "  bitmask_unit:  %-10"PRIu32"  bitmask_num:   %-10"PRIu32"\n",
3750                 fdir_info.max_flexpayload, fdir_info.flex_payload_limit,
3751                 fdir_info.flex_payload_unit,
3752                 fdir_info.max_flex_payload_segment_num,
3753                 fdir_info.flex_bitmask_unit, fdir_info.max_flex_bitmask_num);
3754         printf("  MASK: ");
3755         print_fdir_mask(&fdir_info.mask);
3756         if (fdir_info.flex_conf.nb_payloads > 0) {
3757                 printf("  FLEX PAYLOAD SRC OFFSET:");
3758                 print_fdir_flex_payload(&fdir_info.flex_conf, fdir_info.max_flexpayload);
3759         }
3760         if (fdir_info.flex_conf.nb_flexmasks > 0) {
3761                 printf("  FLEX MASK CFG:");
3762                 print_fdir_flex_mask(&fdir_info.flex_conf, fdir_info.max_flexpayload);
3763         }
3764         printf("  guarant_count: %-10"PRIu32"  best_count:    %"PRIu32"\n",
3765                fdir_stat.guarant_cnt, fdir_stat.best_cnt);
3766         printf("  guarant_space: %-10"PRIu32"  best_space:    %"PRIu32"\n",
3767                fdir_info.guarant_spc, fdir_info.best_spc);
3768         printf("  collision:     %-10"PRIu32"  free:          %"PRIu32"\n"
3769                "  maxhash:       %-10"PRIu32"  maxlen:        %"PRIu32"\n"
3770                "  add:           %-10"PRIu64"  remove:        %"PRIu64"\n"
3771                "  f_add:         %-10"PRIu64"  f_remove:      %"PRIu64"\n",
3772                fdir_stat.collision, fdir_stat.free,
3773                fdir_stat.maxhash, fdir_stat.maxlen,
3774                fdir_stat.add, fdir_stat.remove,
3775                fdir_stat.f_add, fdir_stat.f_remove);
3776         printf("  %s############################%s\n",
3777                fdir_stats_border, fdir_stats_border);
3778 }
3779
3780 void
3781 fdir_set_flex_mask(portid_t port_id, struct rte_eth_fdir_flex_mask *cfg)
3782 {
3783         struct rte_port *port;
3784         struct rte_eth_fdir_flex_conf *flex_conf;
3785         int i, idx = 0;
3786
3787         port = &ports[port_id];
3788         flex_conf = &port->dev_conf.fdir_conf.flex_conf;
3789         for (i = 0; i < RTE_ETH_FLOW_MAX; i++) {
3790                 if (cfg->flow_type == flex_conf->flex_mask[i].flow_type) {
3791                         idx = i;
3792                         break;
3793                 }
3794         }
3795         if (i >= RTE_ETH_FLOW_MAX) {
3796                 if (flex_conf->nb_flexmasks < RTE_DIM(flex_conf->flex_mask)) {
3797                         idx = flex_conf->nb_flexmasks;
3798                         flex_conf->nb_flexmasks++;
3799                 } else {
3800                         printf("The flex mask table is full. Can not set flex"
3801                                 " mask for flow_type(%u).", cfg->flow_type);
3802                         return;
3803                 }
3804         }
3805         rte_memcpy(&flex_conf->flex_mask[idx],
3806                          cfg,
3807                          sizeof(struct rte_eth_fdir_flex_mask));
3808 }
3809
3810 void
3811 fdir_set_flex_payload(portid_t port_id, struct rte_eth_flex_payload_cfg *cfg)
3812 {
3813         struct rte_port *port;
3814         struct rte_eth_fdir_flex_conf *flex_conf;
3815         int i, idx = 0;
3816
3817         port = &ports[port_id];
3818         flex_conf = &port->dev_conf.fdir_conf.flex_conf;
3819         for (i = 0; i < RTE_ETH_PAYLOAD_MAX; i++) {
3820                 if (cfg->type == flex_conf->flex_set[i].type) {
3821                         idx = i;
3822                         break;
3823                 }
3824         }
3825         if (i >= RTE_ETH_PAYLOAD_MAX) {
3826                 if (flex_conf->nb_payloads < RTE_DIM(flex_conf->flex_set)) {
3827                         idx = flex_conf->nb_payloads;
3828                         flex_conf->nb_payloads++;
3829                 } else {
3830                         printf("The flex payload table is full. Can not set"
3831                                 " flex payload for type(%u).", cfg->type);
3832                         return;
3833                 }
3834         }
3835         rte_memcpy(&flex_conf->flex_set[idx],
3836                          cfg,
3837                          sizeof(struct rte_eth_flex_payload_cfg));
3838
3839 }
3840
3841 void
3842 set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on)
3843 {
3844 #ifdef RTE_LIBRTE_IXGBE_PMD
3845         int diag;
3846
3847         if (is_rx)
3848                 diag = rte_pmd_ixgbe_set_vf_rx(port_id, vf, on);
3849         else
3850                 diag = rte_pmd_ixgbe_set_vf_tx(port_id, vf, on);
3851
3852         if (diag == 0)
3853                 return;
3854         printf("rte_pmd_ixgbe_set_vf_%s for port_id=%d failed diag=%d\n",
3855                         is_rx ? "rx" : "tx", port_id, diag);
3856         return;
3857 #endif
3858         printf("VF %s setting not supported for port %d\n",
3859                         is_rx ? "Rx" : "Tx", port_id);
3860         RTE_SET_USED(vf);
3861         RTE_SET_USED(on);
3862 }
3863
3864 int
3865 set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
3866 {
3867         int diag;
3868         struct rte_eth_link link;
3869         int ret;
3870
3871         if (port_id_is_invalid(port_id, ENABLED_WARN))
3872                 return 1;
3873         ret = eth_link_get_nowait_print_err(port_id, &link);
3874         if (ret < 0)
3875                 return 1;
3876         if (rate > link.link_speed) {
3877                 printf("Invalid rate value:%u bigger than link speed: %u\n",
3878                         rate, link.link_speed);
3879                 return 1;
3880         }
3881         diag = rte_eth_set_queue_rate_limit(port_id, queue_idx, rate);
3882         if (diag == 0)
3883                 return diag;
3884         printf("rte_eth_set_queue_rate_limit for port_id=%d failed diag=%d\n",
3885                 port_id, diag);
3886         return diag;
3887 }
3888
3889 int
3890 set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
3891 {
3892         int diag = -ENOTSUP;
3893
3894         RTE_SET_USED(vf);
3895         RTE_SET_USED(rate);
3896         RTE_SET_USED(q_msk);
3897
3898 #ifdef RTE_LIBRTE_IXGBE_PMD
3899         if (diag == -ENOTSUP)
3900                 diag = rte_pmd_ixgbe_set_vf_rate_limit(port_id, vf, rate,
3901                                                        q_msk);
3902 #endif
3903 #ifdef RTE_LIBRTE_BNXT_PMD
3904         if (diag == -ENOTSUP)
3905                 diag = rte_pmd_bnxt_set_vf_rate_limit(port_id, vf, rate, q_msk);
3906 #endif
3907         if (diag == 0)
3908                 return diag;
3909
3910         printf("set_vf_rate_limit for port_id=%d failed diag=%d\n",
3911                 port_id, diag);
3912         return diag;
3913 }
3914
3915 /*
3916  * Functions to manage the set of filtered Multicast MAC addresses.
3917  *
3918  * A pool of filtered multicast MAC addresses is associated with each port.
3919  * The pool is allocated in chunks of MCAST_POOL_INC multicast addresses.
3920  * The address of the pool and the number of valid multicast MAC addresses
3921  * recorded in the pool are stored in the fields "mc_addr_pool" and
3922  * "mc_addr_nb" of the "rte_port" data structure.
3923  *
3924  * The function "rte_eth_dev_set_mc_addr_list" of the PMDs API imposes
3925  * to be supplied a contiguous array of multicast MAC addresses.
3926  * To comply with this constraint, the set of multicast addresses recorded
3927  * into the pool are systematically compacted at the beginning of the pool.
3928  * Hence, when a multicast address is removed from the pool, all following
3929  * addresses, if any, are copied back to keep the set contiguous.
3930  */
3931 #define MCAST_POOL_INC 32
3932
3933 static int
3934 mcast_addr_pool_extend(struct rte_port *port)
3935 {
3936         struct rte_ether_addr *mc_pool;
3937         size_t mc_pool_size;
3938
3939         /*
3940          * If a free entry is available at the end of the pool, just
3941          * increment the number of recorded multicast addresses.
3942          */
3943         if ((port->mc_addr_nb % MCAST_POOL_INC) != 0) {
3944                 port->mc_addr_nb++;
3945                 return 0;
3946         }
3947
3948         /*
3949          * [re]allocate a pool with MCAST_POOL_INC more entries.
3950          * The previous test guarantees that port->mc_addr_nb is a multiple
3951          * of MCAST_POOL_INC.
3952          */
3953         mc_pool_size = sizeof(struct rte_ether_addr) * (port->mc_addr_nb +
3954                                                     MCAST_POOL_INC);
3955         mc_pool = (struct rte_ether_addr *) realloc(port->mc_addr_pool,
3956                                                 mc_pool_size);
3957         if (mc_pool == NULL) {
3958                 printf("allocation of pool of %u multicast addresses failed\n",
3959                        port->mc_addr_nb + MCAST_POOL_INC);
3960                 return -ENOMEM;
3961         }
3962
3963         port->mc_addr_pool = mc_pool;
3964         port->mc_addr_nb++;
3965         return 0;
3966
3967 }
3968
3969 static void
3970 mcast_addr_pool_append(struct rte_port *port, struct rte_ether_addr *mc_addr)
3971 {
3972         if (mcast_addr_pool_extend(port) != 0)
3973                 return;
3974         rte_ether_addr_copy(mc_addr, &port->mc_addr_pool[port->mc_addr_nb - 1]);
3975 }
3976
3977 static void
3978 mcast_addr_pool_remove(struct rte_port *port, uint32_t addr_idx)
3979 {
3980         port->mc_addr_nb--;
3981         if (addr_idx == port->mc_addr_nb) {
3982                 /* No need to recompact the set of multicast addressses. */
3983                 if (port->mc_addr_nb == 0) {
3984                         /* free the pool of multicast addresses. */
3985                         free(port->mc_addr_pool);
3986                         port->mc_addr_pool = NULL;
3987                 }
3988                 return;
3989         }
3990         memmove(&port->mc_addr_pool[addr_idx],
3991                 &port->mc_addr_pool[addr_idx + 1],
3992                 sizeof(struct rte_ether_addr) * (port->mc_addr_nb - addr_idx));
3993 }
3994
3995 static int
3996 eth_port_multicast_addr_list_set(portid_t port_id)
3997 {
3998         struct rte_port *port;
3999         int diag;
4000
4001         port = &ports[port_id];
4002         diag = rte_eth_dev_set_mc_addr_list(port_id, port->mc_addr_pool,
4003                                             port->mc_addr_nb);
4004         if (diag < 0)
4005                 printf("rte_eth_dev_set_mc_addr_list(port=%d, nb=%u) failed. diag=%d\n",
4006                         port_id, port->mc_addr_nb, diag);
4007
4008         return diag;
4009 }
4010
4011 void
4012 mcast_addr_add(portid_t port_id, struct rte_ether_addr *mc_addr)
4013 {
4014         struct rte_port *port;
4015         uint32_t i;
4016
4017         if (port_id_is_invalid(port_id, ENABLED_WARN))
4018                 return;
4019
4020         port = &ports[port_id];
4021
4022         /*
4023          * Check that the added multicast MAC address is not already recorded
4024          * in the pool of multicast addresses.
4025          */
4026         for (i = 0; i < port->mc_addr_nb; i++) {
4027                 if (rte_is_same_ether_addr(mc_addr, &port->mc_addr_pool[i])) {
4028                         printf("multicast address already filtered by port\n");
4029                         return;
4030                 }
4031         }
4032
4033         mcast_addr_pool_append(port, mc_addr);
4034         if (eth_port_multicast_addr_list_set(port_id) < 0)
4035                 /* Rollback on failure, remove the address from the pool */
4036                 mcast_addr_pool_remove(port, i);
4037 }
4038
4039 void
4040 mcast_addr_remove(portid_t port_id, struct rte_ether_addr *mc_addr)
4041 {
4042         struct rte_port *port;
4043         uint32_t i;
4044
4045         if (port_id_is_invalid(port_id, ENABLED_WARN))
4046                 return;
4047
4048         port = &ports[port_id];
4049
4050         /*
4051          * Search the pool of multicast MAC addresses for the removed address.
4052          */
4053         for (i = 0; i < port->mc_addr_nb; i++) {
4054                 if (rte_is_same_ether_addr(mc_addr, &port->mc_addr_pool[i]))
4055                         break;
4056         }
4057         if (i == port->mc_addr_nb) {
4058                 printf("multicast address not filtered by port %d\n", port_id);
4059                 return;
4060         }
4061
4062         mcast_addr_pool_remove(port, i);
4063         if (eth_port_multicast_addr_list_set(port_id) < 0)
4064                 /* Rollback on failure, add the address back into the pool */
4065                 mcast_addr_pool_append(port, mc_addr);
4066 }
4067
4068 void
4069 port_dcb_info_display(portid_t port_id)
4070 {
4071         struct rte_eth_dcb_info dcb_info;
4072         uint16_t i;
4073         int ret;
4074         static const char *border = "================";
4075
4076         if (port_id_is_invalid(port_id, ENABLED_WARN))
4077                 return;
4078
4079         ret = rte_eth_dev_get_dcb_info(port_id, &dcb_info);
4080         if (ret) {
4081                 printf("\n Failed to get dcb infos on port %-2d\n",
4082                         port_id);
4083                 return;
4084         }
4085         printf("\n  %s DCB infos for port %-2d  %s\n", border, port_id, border);
4086         printf("  TC NUMBER: %d\n", dcb_info.nb_tcs);
4087         printf("\n  TC :        ");
4088         for (i = 0; i < dcb_info.nb_tcs; i++)
4089                 printf("\t%4d", i);
4090         printf("\n  Priority :  ");
4091         for (i = 0; i < dcb_info.nb_tcs; i++)
4092                 printf("\t%4d", dcb_info.prio_tc[i]);
4093         printf("\n  BW percent :");
4094         for (i = 0; i < dcb_info.nb_tcs; i++)
4095                 printf("\t%4d%%", dcb_info.tc_bws[i]);
4096         printf("\n  RXQ base :  ");
4097         for (i = 0; i < dcb_info.nb_tcs; i++)
4098                 printf("\t%4d", dcb_info.tc_queue.tc_rxq[0][i].base);
4099         printf("\n  RXQ number :");
4100         for (i = 0; i < dcb_info.nb_tcs; i++)
4101                 printf("\t%4d", dcb_info.tc_queue.tc_rxq[0][i].nb_queue);
4102         printf("\n  TXQ base :  ");
4103         for (i = 0; i < dcb_info.nb_tcs; i++)
4104                 printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].base);
4105         printf("\n  TXQ number :");
4106         for (i = 0; i < dcb_info.nb_tcs; i++)
4107                 printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
4108         printf("\n");
4109 }
4110
4111 uint8_t *
4112 open_file(const char *file_path, uint32_t *size)
4113 {
4114         int fd = open(file_path, O_RDONLY);
4115         off_t pkg_size;
4116         uint8_t *buf = NULL;
4117         int ret = 0;
4118         struct stat st_buf;
4119
4120         if (size)
4121                 *size = 0;
4122
4123         if (fd == -1) {
4124                 printf("%s: Failed to open %s\n", __func__, file_path);
4125                 return buf;
4126         }
4127
4128         if ((fstat(fd, &st_buf) != 0) || (!S_ISREG(st_buf.st_mode))) {
4129                 close(fd);
4130                 printf("%s: File operations failed\n", __func__);
4131                 return buf;
4132         }
4133
4134         pkg_size = st_buf.st_size;
4135         if (pkg_size < 0) {
4136                 close(fd);
4137                 printf("%s: File operations failed\n", __func__);
4138                 return buf;
4139         }
4140
4141         buf = (uint8_t *)malloc(pkg_size);
4142         if (!buf) {
4143                 close(fd);
4144                 printf("%s: Failed to malloc memory\n", __func__);
4145                 return buf;
4146         }
4147
4148         ret = read(fd, buf, pkg_size);
4149         if (ret < 0) {
4150                 close(fd);
4151                 printf("%s: File read operation failed\n", __func__);
4152                 close_file(buf);
4153                 return NULL;
4154         }
4155
4156         if (size)
4157                 *size = pkg_size;
4158
4159         close(fd);
4160
4161         return buf;
4162 }
4163
4164 int
4165 save_file(const char *file_path, uint8_t *buf, uint32_t size)
4166 {
4167         FILE *fh = fopen(file_path, "wb");
4168
4169         if (fh == NULL) {
4170                 printf("%s: Failed to open %s\n", __func__, file_path);
4171                 return -1;
4172         }
4173
4174         if (fwrite(buf, 1, size, fh) != size) {
4175                 fclose(fh);
4176                 printf("%s: File write operation failed\n", __func__);
4177                 return -1;
4178         }
4179
4180         fclose(fh);
4181
4182         return 0;
4183 }
4184
4185 int
4186 close_file(uint8_t *buf)
4187 {
4188         if (buf) {
4189                 free((void *)buf);
4190                 return 0;
4191         }
4192
4193         return -1;
4194 }
4195
4196 void
4197 port_queue_region_info_display(portid_t port_id, void *buf)
4198 {
4199 #ifdef RTE_LIBRTE_I40E_PMD
4200         uint16_t i, j;
4201         struct rte_pmd_i40e_queue_regions *info =
4202                 (struct rte_pmd_i40e_queue_regions *)buf;
4203         static const char *queue_region_info_stats_border = "-------";
4204
4205         if (!info->queue_region_number)
4206                 printf("there is no region has been set before");
4207
4208         printf("\n      %s All queue region info for port=%2d %s",
4209                         queue_region_info_stats_border, port_id,
4210                         queue_region_info_stats_border);
4211         printf("\n      queue_region_number: %-14u \n",
4212                         info->queue_region_number);
4213
4214         for (i = 0; i < info->queue_region_number; i++) {
4215                 printf("\n      region_id: %-14u queue_number: %-14u "
4216                         "queue_start_index: %-14u \n",
4217                         info->region[i].region_id,
4218                         info->region[i].queue_num,
4219                         info->region[i].queue_start_index);
4220
4221                 printf("  user_priority_num is  %-14u :",
4222                                         info->region[i].user_priority_num);
4223                 for (j = 0; j < info->region[i].user_priority_num; j++)
4224                         printf(" %-14u ", info->region[i].user_priority[j]);
4225
4226                 printf("\n      flowtype_num is  %-14u :",
4227                                 info->region[i].flowtype_num);
4228                 for (j = 0; j < info->region[i].flowtype_num; j++)
4229                         printf(" %-14u ", info->region[i].hw_flowtype[j]);
4230         }
4231 #else
4232         RTE_SET_USED(port_id);
4233         RTE_SET_USED(buf);
4234 #endif
4235
4236         printf("\n\n");
4237 }
4238
4239 void
4240 show_macs(portid_t port_id)
4241 {
4242         char buf[RTE_ETHER_ADDR_FMT_SIZE];
4243         struct rte_eth_dev_info dev_info;
4244         struct rte_ether_addr *addr;
4245         uint32_t i, num_macs = 0;
4246         struct rte_eth_dev *dev;
4247
4248         dev = &rte_eth_devices[port_id];
4249
4250         rte_eth_dev_info_get(port_id, &dev_info);
4251
4252         for (i = 0; i < dev_info.max_mac_addrs; i++) {
4253                 addr = &dev->data->mac_addrs[i];
4254
4255                 /* skip zero address */
4256                 if (rte_is_zero_ether_addr(addr))
4257                         continue;
4258
4259                 num_macs++;
4260         }
4261
4262         printf("Number of MAC address added: %d\n", num_macs);
4263
4264         for (i = 0; i < dev_info.max_mac_addrs; i++) {
4265                 addr = &dev->data->mac_addrs[i];
4266
4267                 /* skip zero address */
4268                 if (rte_is_zero_ether_addr(addr))
4269                         continue;
4270
4271                 rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, addr);
4272                 printf("  %s\n", buf);
4273         }
4274 }
4275
4276 void
4277 show_mcast_macs(portid_t port_id)
4278 {
4279         char buf[RTE_ETHER_ADDR_FMT_SIZE];
4280         struct rte_ether_addr *addr;
4281         struct rte_port *port;
4282         uint32_t i;
4283
4284         port = &ports[port_id];
4285
4286         printf("Number of Multicast MAC address added: %d\n", port->mc_addr_nb);
4287
4288         for (i = 0; i < port->mc_addr_nb; i++) {
4289                 addr = &port->mc_addr_pool[i];
4290
4291                 rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, addr);
4292                 printf("  %s\n", buf);
4293         }
4294 }