app/testpmd: new commands for flex filter
[dpdk.git] / app / test-pmd / config.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 /*   BSD LICENSE
34  *
35  *   Copyright 2013-2014 6WIND S.A.
36  *
37  *   Redistribution and use in source and binary forms, with or without
38  *   modification, are permitted provided that the following conditions
39  *   are met:
40  *
41  *     * Redistributions of source code must retain the above copyright
42  *       notice, this list of conditions and the following disclaimer.
43  *     * Redistributions in binary form must reproduce the above copyright
44  *       notice, this list of conditions and the following disclaimer in
45  *       the documentation and/or other materials provided with the
46  *       distribution.
47  *     * Neither the name of 6WIND S.A. nor the names of its
48  *       contributors may be used to endorse or promote products derived
49  *       from this software without specific prior written permission.
50  *
51  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
52  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
53  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
54  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
55  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
56  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
57  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
61  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63
64 #include <stdarg.h>
65 #include <errno.h>
66 #include <stdio.h>
67 #include <string.h>
68 #include <stdarg.h>
69 #include <stdint.h>
70 #include <inttypes.h>
71
72 #include <sys/queue.h>
73
74 #include <rte_common.h>
75 #include <rte_byteorder.h>
76 #include <rte_debug.h>
77 #include <rte_log.h>
78 #include <rte_memory.h>
79 #include <rte_memcpy.h>
80 #include <rte_memzone.h>
81 #include <rte_launch.h>
82 #include <rte_tailq.h>
83 #include <rte_eal.h>
84 #include <rte_per_lcore.h>
85 #include <rte_lcore.h>
86 #include <rte_atomic.h>
87 #include <rte_branch_prediction.h>
88 #include <rte_ring.h>
89 #include <rte_mempool.h>
90 #include <rte_mbuf.h>
91 #include <rte_interrupts.h>
92 #include <rte_pci.h>
93 #include <rte_ether.h>
94 #include <rte_ethdev.h>
95 #include <rte_string_fns.h>
96
97 #include "testpmd.h"
98
99 static const char *flowtype_str[RTE_ETH_FLOW_TYPE_MAX] = {
100         NULL,
101         "raw",
102         "udp4",
103         "tcp4",
104         "sctp4",
105         "ip4",
106         "ip4-frag",
107         "udp6",
108         "tcp6",
109         "sctp6",
110         "ip6",
111         "ip6-frag",
112 };
113
114 static void
115 print_ethaddr(const char *name, struct ether_addr *eth_addr)
116 {
117         char buf[ETHER_ADDR_FMT_SIZE];
118         ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr);
119         printf("%s%s", name, buf);
120 }
121
122 void
123 nic_stats_display(portid_t port_id)
124 {
125         struct rte_eth_stats stats;
126         struct rte_port *port = &ports[port_id];
127         uint8_t i;
128
129         static const char *nic_stats_border = "########################";
130
131         if (port_id >= nb_ports) {
132                 printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
133                 return;
134         }
135         rte_eth_stats_get(port_id, &stats);
136         printf("\n  %s NIC statistics for port %-2d %s\n",
137                nic_stats_border, port_id, nic_stats_border);
138
139         if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
140                 printf("  RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes:  "
141                        "%-"PRIu64"\n",
142                        stats.ipackets, stats.imissed, stats.ibytes);
143                 printf("  RX-badcrc:  %-10"PRIu64" RX-badlen: %-10"PRIu64" RX-errors: "
144                        "%-"PRIu64"\n",
145                        stats.ibadcrc, stats.ibadlen, stats.ierrors);
146                 printf("  RX-nombuf:  %-10"PRIu64"\n",
147                        stats.rx_nombuf);
148                 printf("  TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes:  "
149                        "%-"PRIu64"\n",
150                        stats.opackets, stats.oerrors, stats.obytes);
151         }
152         else {
153                 printf("  RX-packets:              %10"PRIu64"    RX-errors: %10"PRIu64
154                        "    RX-bytes: %10"PRIu64"\n",
155                        stats.ipackets, stats.ierrors, stats.ibytes);
156                 printf("  RX-badcrc:               %10"PRIu64"    RX-badlen: %10"PRIu64
157                        "  RX-errors:  %10"PRIu64"\n",
158                        stats.ibadcrc, stats.ibadlen, stats.ierrors);
159                 printf("  RX-nombuf:               %10"PRIu64"\n",
160                        stats.rx_nombuf);
161                 printf("  TX-packets:              %10"PRIu64"    TX-errors: %10"PRIu64
162                        "    TX-bytes: %10"PRIu64"\n",
163                        stats.opackets, stats.oerrors, stats.obytes);
164         }
165
166         /* stats fdir */
167         if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
168                 printf("  Fdirmiss:   %-10"PRIu64" Fdirmatch: %-10"PRIu64"\n",
169                        stats.fdirmiss,
170                        stats.fdirmatch);
171
172         if (port->rx_queue_stats_mapping_enabled) {
173                 printf("\n");
174                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
175                         printf("  Stats reg %2d RX-packets: %10"PRIu64
176                                "    RX-errors: %10"PRIu64
177                                "    RX-bytes: %10"PRIu64"\n",
178                                i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]);
179                 }
180         }
181         if (port->tx_queue_stats_mapping_enabled) {
182                 printf("\n");
183                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
184                         printf("  Stats reg %2d TX-packets: %10"PRIu64
185                                "                             TX-bytes: %10"PRIu64"\n",
186                                i, stats.q_opackets[i], stats.q_obytes[i]);
187                 }
188         }
189
190         /* Display statistics of XON/XOFF pause frames, if any. */
191         if ((stats.tx_pause_xon  | stats.rx_pause_xon |
192              stats.tx_pause_xoff | stats.rx_pause_xoff) > 0) {
193                 printf("  RX-XOFF:    %-10"PRIu64" RX-XON:    %-10"PRIu64"\n",
194                        stats.rx_pause_xoff, stats.rx_pause_xon);
195                 printf("  TX-XOFF:    %-10"PRIu64" TX-XON:    %-10"PRIu64"\n",
196                        stats.tx_pause_xoff, stats.tx_pause_xon);
197         }
198         printf("  %s############################%s\n",
199                nic_stats_border, nic_stats_border);
200 }
201
202 void
203 nic_stats_clear(portid_t port_id)
204 {
205         if (port_id >= nb_ports) {
206                 printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
207                 return;
208         }
209         rte_eth_stats_reset(port_id);
210         printf("\n  NIC statistics for port %d cleared\n", port_id);
211 }
212
213 void
214 nic_xstats_display(portid_t port_id)
215 {
216         struct rte_eth_xstats *xstats;
217         int len, ret, i;
218
219         printf("###### NIC extended statistics for port %-2d\n", port_id);
220
221         len = rte_eth_xstats_get(port_id, NULL, 0);
222         if (len < 0) {
223                 printf("Cannot get xstats count\n");
224                 return;
225         }
226         xstats = malloc(sizeof(xstats[0]) * len);
227         if (xstats == NULL) {
228                 printf("Cannot allocate memory for xstats\n");
229                 return;
230         }
231         ret = rte_eth_xstats_get(port_id, xstats, len);
232         if (ret < 0 || ret > len) {
233                 printf("Cannot get xstats\n");
234                 free(xstats);
235                 return;
236         }
237         for (i = 0; i < len; i++)
238                 printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value);
239         free(xstats);
240 }
241
242 void
243 nic_xstats_clear(portid_t port_id)
244 {
245         rte_eth_xstats_reset(port_id);
246 }
247
248 void
249 nic_stats_mapping_display(portid_t port_id)
250 {
251         struct rte_port *port = &ports[port_id];
252         uint16_t i;
253
254         static const char *nic_stats_mapping_border = "########################";
255
256         if (port_id >= nb_ports) {
257                 printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
258                 return;
259         }
260
261         if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
262                 printf("Port id %d - either does not support queue statistic mapping or"
263                        " no queue statistic mapping set\n", port_id);
264                 return;
265         }
266
267         printf("\n  %s NIC statistics mapping for port %-2d %s\n",
268                nic_stats_mapping_border, port_id, nic_stats_mapping_border);
269
270         if (port->rx_queue_stats_mapping_enabled) {
271                 for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
272                         if (rx_queue_stats_mappings[i].port_id == port_id) {
273                                 printf("  RX-queue %2d mapped to Stats Reg %2d\n",
274                                        rx_queue_stats_mappings[i].queue_id,
275                                        rx_queue_stats_mappings[i].stats_counter_id);
276                         }
277                 }
278                 printf("\n");
279         }
280
281
282         if (port->tx_queue_stats_mapping_enabled) {
283                 for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
284                         if (tx_queue_stats_mappings[i].port_id == port_id) {
285                                 printf("  TX-queue %2d mapped to Stats Reg %2d\n",
286                                        tx_queue_stats_mappings[i].queue_id,
287                                        tx_queue_stats_mappings[i].stats_counter_id);
288                         }
289                 }
290         }
291
292         printf("  %s####################################%s\n",
293                nic_stats_mapping_border, nic_stats_mapping_border);
294 }
295
296 void
297 port_infos_display(portid_t port_id)
298 {
299         struct rte_port *port;
300         struct ether_addr mac_addr;
301         struct rte_eth_link link;
302         struct rte_eth_dev_info dev_info;
303         int vlan_offload;
304         struct rte_mempool * mp;
305         static const char *info_border = "*********************";
306
307         if (port_id >= nb_ports) {
308                 printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
309                 return;
310         }
311         port = &ports[port_id];
312         rte_eth_link_get_nowait(port_id, &link);
313         printf("\n%s Infos for port %-2d %s\n",
314                info_border, port_id, info_border);
315         rte_eth_macaddr_get(port_id, &mac_addr);
316         print_ethaddr("MAC address: ", &mac_addr);
317         printf("\nConnect to socket: %u", port->socket_id);
318
319         if (port_numa[port_id] != NUMA_NO_CONFIG) {
320                 mp = mbuf_pool_find(port_numa[port_id]);
321                 if (mp)
322                         printf("\nmemory allocation on the socket: %d",
323                                                         port_numa[port_id]);
324         } else
325                 printf("\nmemory allocation on the socket: %u",port->socket_id);
326
327         printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
328         printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
329         printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
330                ("full-duplex") : ("half-duplex"));
331         printf("Promiscuous mode: %s\n",
332                rte_eth_promiscuous_get(port_id) ? "enabled" : "disabled");
333         printf("Allmulticast mode: %s\n",
334                rte_eth_allmulticast_get(port_id) ? "enabled" : "disabled");
335         printf("Maximum number of MAC addresses: %u\n",
336                (unsigned int)(port->dev_info.max_mac_addrs));
337         printf("Maximum number of MAC addresses of hash filtering: %u\n",
338                (unsigned int)(port->dev_info.max_hash_mac_addrs));
339
340         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
341         if (vlan_offload >= 0){
342                 printf("VLAN offload: \n");
343                 if (vlan_offload & ETH_VLAN_STRIP_OFFLOAD)
344                         printf("  strip on \n");
345                 else
346                         printf("  strip off \n");
347
348                 if (vlan_offload & ETH_VLAN_FILTER_OFFLOAD)
349                         printf("  filter on \n");
350                 else
351                         printf("  filter off \n");
352
353                 if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)
354                         printf("  qinq(extend) on \n");
355                 else
356                         printf("  qinq(extend) off \n");
357         }
358
359         memset(&dev_info, 0, sizeof(dev_info));
360         rte_eth_dev_info_get(port_id, &dev_info);
361         if (dev_info.reta_size > 0)
362                 printf("Redirection table size: %u\n", dev_info.reta_size);
363 }
364
365 int
366 port_id_is_invalid(portid_t port_id)
367 {
368         if (port_id < nb_ports)
369                 return 0;
370         printf("Invalid port %d (must be < nb_ports=%d)\n", port_id, nb_ports);
371         return 1;
372 }
373
374 static int
375 vlan_id_is_invalid(uint16_t vlan_id)
376 {
377         if (vlan_id < 4096)
378                 return 0;
379         printf("Invalid vlan_id %d (must be < 4096)\n", vlan_id);
380         return 1;
381 }
382
383 static int
384 port_reg_off_is_invalid(portid_t port_id, uint32_t reg_off)
385 {
386         uint64_t pci_len;
387
388         if (reg_off & 0x3) {
389                 printf("Port register offset 0x%X not aligned on a 4-byte "
390                        "boundary\n",
391                        (unsigned)reg_off);
392                 return 1;
393         }
394         pci_len = ports[port_id].dev_info.pci_dev->mem_resource[0].len;
395         if (reg_off >= pci_len) {
396                 printf("Port %d: register offset %u (0x%X) out of port PCI "
397                        "resource (length=%"PRIu64")\n",
398                        port_id, (unsigned)reg_off, (unsigned)reg_off,  pci_len);
399                 return 1;
400         }
401         return 0;
402 }
403
404 static int
405 reg_bit_pos_is_invalid(uint8_t bit_pos)
406 {
407         if (bit_pos <= 31)
408                 return 0;
409         printf("Invalid bit position %d (must be <= 31)\n", bit_pos);
410         return 1;
411 }
412
413 #define display_port_and_reg_off(port_id, reg_off) \
414         printf("port %d PCI register at offset 0x%X: ", (port_id), (reg_off))
415
416 static inline void
417 display_port_reg_value(portid_t port_id, uint32_t reg_off, uint32_t reg_v)
418 {
419         display_port_and_reg_off(port_id, (unsigned)reg_off);
420         printf("0x%08X (%u)\n", (unsigned)reg_v, (unsigned)reg_v);
421 }
422
423 void
424 port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_x)
425 {
426         uint32_t reg_v;
427
428
429         if (port_id_is_invalid(port_id))
430                 return;
431         if (port_reg_off_is_invalid(port_id, reg_off))
432                 return;
433         if (reg_bit_pos_is_invalid(bit_x))
434                 return;
435         reg_v = port_id_pci_reg_read(port_id, reg_off);
436         display_port_and_reg_off(port_id, (unsigned)reg_off);
437         printf("bit %d=%d\n", bit_x, (int) ((reg_v & (1 << bit_x)) >> bit_x));
438 }
439
440 void
441 port_reg_bit_field_display(portid_t port_id, uint32_t reg_off,
442                            uint8_t bit1_pos, uint8_t bit2_pos)
443 {
444         uint32_t reg_v;
445         uint8_t  l_bit;
446         uint8_t  h_bit;
447
448         if (port_id_is_invalid(port_id))
449                 return;
450         if (port_reg_off_is_invalid(port_id, reg_off))
451                 return;
452         if (reg_bit_pos_is_invalid(bit1_pos))
453                 return;
454         if (reg_bit_pos_is_invalid(bit2_pos))
455                 return;
456         if (bit1_pos > bit2_pos)
457                 l_bit = bit2_pos, h_bit = bit1_pos;
458         else
459                 l_bit = bit1_pos, h_bit = bit2_pos;
460
461         reg_v = port_id_pci_reg_read(port_id, reg_off);
462         reg_v >>= l_bit;
463         if (h_bit < 31)
464                 reg_v &= ((1 << (h_bit - l_bit + 1)) - 1);
465         display_port_and_reg_off(port_id, (unsigned)reg_off);
466         printf("bits[%d, %d]=0x%0*X (%u)\n", l_bit, h_bit,
467                ((h_bit - l_bit) / 4) + 1, (unsigned)reg_v, (unsigned)reg_v);
468 }
469
470 void
471 port_reg_display(portid_t port_id, uint32_t reg_off)
472 {
473         uint32_t reg_v;
474
475         if (port_id_is_invalid(port_id))
476                 return;
477         if (port_reg_off_is_invalid(port_id, reg_off))
478                 return;
479         reg_v = port_id_pci_reg_read(port_id, reg_off);
480         display_port_reg_value(port_id, reg_off, reg_v);
481 }
482
483 void
484 port_reg_bit_set(portid_t port_id, uint32_t reg_off, uint8_t bit_pos,
485                  uint8_t bit_v)
486 {
487         uint32_t reg_v;
488
489         if (port_id_is_invalid(port_id))
490                 return;
491         if (port_reg_off_is_invalid(port_id, reg_off))
492                 return;
493         if (reg_bit_pos_is_invalid(bit_pos))
494                 return;
495         if (bit_v > 1) {
496                 printf("Invalid bit value %d (must be 0 or 1)\n", (int) bit_v);
497                 return;
498         }
499         reg_v = port_id_pci_reg_read(port_id, reg_off);
500         if (bit_v == 0)
501                 reg_v &= ~(1 << bit_pos);
502         else
503                 reg_v |= (1 << bit_pos);
504         port_id_pci_reg_write(port_id, reg_off, reg_v);
505         display_port_reg_value(port_id, reg_off, reg_v);
506 }
507
508 void
509 port_reg_bit_field_set(portid_t port_id, uint32_t reg_off,
510                        uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value)
511 {
512         uint32_t max_v;
513         uint32_t reg_v;
514         uint8_t  l_bit;
515         uint8_t  h_bit;
516
517         if (port_id_is_invalid(port_id))
518                 return;
519         if (port_reg_off_is_invalid(port_id, reg_off))
520                 return;
521         if (reg_bit_pos_is_invalid(bit1_pos))
522                 return;
523         if (reg_bit_pos_is_invalid(bit2_pos))
524                 return;
525         if (bit1_pos > bit2_pos)
526                 l_bit = bit2_pos, h_bit = bit1_pos;
527         else
528                 l_bit = bit1_pos, h_bit = bit2_pos;
529
530         if ((h_bit - l_bit) < 31)
531                 max_v = (1 << (h_bit - l_bit + 1)) - 1;
532         else
533                 max_v = 0xFFFFFFFF;
534
535         if (value > max_v) {
536                 printf("Invalid value %u (0x%x) must be < %u (0x%x)\n",
537                                 (unsigned)value, (unsigned)value,
538                                 (unsigned)max_v, (unsigned)max_v);
539                 return;
540         }
541         reg_v = port_id_pci_reg_read(port_id, reg_off);
542         reg_v &= ~(max_v << l_bit); /* Keep unchanged bits */
543         reg_v |= (value << l_bit); /* Set changed bits */
544         port_id_pci_reg_write(port_id, reg_off, reg_v);
545         display_port_reg_value(port_id, reg_off, reg_v);
546 }
547
548 void
549 port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t reg_v)
550 {
551         if (port_id_is_invalid(port_id))
552                 return;
553         if (port_reg_off_is_invalid(port_id, reg_off))
554                 return;
555         port_id_pci_reg_write(port_id, reg_off, reg_v);
556         display_port_reg_value(port_id, reg_off, reg_v);
557 }
558
559 void
560 port_mtu_set(portid_t port_id, uint16_t mtu)
561 {
562         int diag;
563
564         if (port_id_is_invalid(port_id))
565                 return;
566         diag = rte_eth_dev_set_mtu(port_id, mtu);
567         if (diag == 0)
568                 return;
569         printf("Set MTU failed. diag=%d\n", diag);
570 }
571
572 /*
573  * RX/TX ring descriptors display functions.
574  */
575 int
576 rx_queue_id_is_invalid(queueid_t rxq_id)
577 {
578         if (rxq_id < nb_rxq)
579                 return 0;
580         printf("Invalid RX queue %d (must be < nb_rxq=%d)\n", rxq_id, nb_rxq);
581         return 1;
582 }
583
584 int
585 tx_queue_id_is_invalid(queueid_t txq_id)
586 {
587         if (txq_id < nb_txq)
588                 return 0;
589         printf("Invalid TX queue %d (must be < nb_rxq=%d)\n", txq_id, nb_txq);
590         return 1;
591 }
592
593 static int
594 rx_desc_id_is_invalid(uint16_t rxdesc_id)
595 {
596         if (rxdesc_id < nb_rxd)
597                 return 0;
598         printf("Invalid RX descriptor %d (must be < nb_rxd=%d)\n",
599                rxdesc_id, nb_rxd);
600         return 1;
601 }
602
603 static int
604 tx_desc_id_is_invalid(uint16_t txdesc_id)
605 {
606         if (txdesc_id < nb_txd)
607                 return 0;
608         printf("Invalid TX descriptor %d (must be < nb_txd=%d)\n",
609                txdesc_id, nb_txd);
610         return 1;
611 }
612
613 static const struct rte_memzone *
614 ring_dma_zone_lookup(const char *ring_name, uint8_t port_id, uint16_t q_id)
615 {
616         char mz_name[RTE_MEMZONE_NAMESIZE];
617         const struct rte_memzone *mz;
618
619         snprintf(mz_name, sizeof(mz_name), "%s_%s_%d_%d",
620                  ports[port_id].dev_info.driver_name, ring_name, port_id, q_id);
621         mz = rte_memzone_lookup(mz_name);
622         if (mz == NULL)
623                 printf("%s ring memory zoneof (port %d, queue %d) not"
624                        "found (zone name = %s\n",
625                        ring_name, port_id, q_id, mz_name);
626         return (mz);
627 }
628
629 union igb_ring_dword {
630         uint64_t dword;
631         struct {
632 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
633                 uint32_t lo;
634                 uint32_t hi;
635 #else
636                 uint32_t hi;
637                 uint32_t lo;
638 #endif
639         } words;
640 };
641
642 struct igb_ring_desc_32_bytes {
643         union igb_ring_dword lo_dword;
644         union igb_ring_dword hi_dword;
645         union igb_ring_dword resv1;
646         union igb_ring_dword resv2;
647 };
648
649 struct igb_ring_desc_16_bytes {
650         union igb_ring_dword lo_dword;
651         union igb_ring_dword hi_dword;
652 };
653
654 static void
655 ring_rxd_display_dword(union igb_ring_dword dword)
656 {
657         printf("    0x%08X - 0x%08X\n", (unsigned)dword.words.lo,
658                                         (unsigned)dword.words.hi);
659 }
660
661 static void
662 ring_rx_descriptor_display(const struct rte_memzone *ring_mz,
663 #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
664                            uint8_t port_id,
665 #else
666                            __rte_unused uint8_t port_id,
667 #endif
668                            uint16_t desc_id)
669 {
670         struct igb_ring_desc_16_bytes *ring =
671                 (struct igb_ring_desc_16_bytes *)ring_mz->addr;
672 #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
673         struct rte_eth_dev_info dev_info;
674
675         memset(&dev_info, 0, sizeof(dev_info));
676         rte_eth_dev_info_get(port_id, &dev_info);
677         if (strstr(dev_info.driver_name, "i40e") != NULL) {
678                 /* 32 bytes RX descriptor, i40e only */
679                 struct igb_ring_desc_32_bytes *ring =
680                         (struct igb_ring_desc_32_bytes *)ring_mz->addr;
681                 ring[desc_id].lo_dword.dword =
682                         rte_le_to_cpu_64(ring[desc_id].lo_dword.dword);
683                 ring_rxd_display_dword(ring[desc_id].lo_dword);
684                 ring[desc_id].hi_dword.dword =
685                         rte_le_to_cpu_64(ring[desc_id].hi_dword.dword);
686                 ring_rxd_display_dword(ring[desc_id].hi_dword);
687                 ring[desc_id].resv1.dword =
688                         rte_le_to_cpu_64(ring[desc_id].resv1.dword);
689                 ring_rxd_display_dword(ring[desc_id].resv1);
690                 ring[desc_id].resv2.dword =
691                         rte_le_to_cpu_64(ring[desc_id].resv2.dword);
692                 ring_rxd_display_dword(ring[desc_id].resv2);
693
694                 return;
695         }
696 #endif
697         /* 16 bytes RX descriptor */
698         ring[desc_id].lo_dword.dword =
699                 rte_le_to_cpu_64(ring[desc_id].lo_dword.dword);
700         ring_rxd_display_dword(ring[desc_id].lo_dword);
701         ring[desc_id].hi_dword.dword =
702                 rte_le_to_cpu_64(ring[desc_id].hi_dword.dword);
703         ring_rxd_display_dword(ring[desc_id].hi_dword);
704 }
705
706 static void
707 ring_tx_descriptor_display(const struct rte_memzone *ring_mz, uint16_t desc_id)
708 {
709         struct igb_ring_desc_16_bytes *ring;
710         struct igb_ring_desc_16_bytes txd;
711
712         ring = (struct igb_ring_desc_16_bytes *)ring_mz->addr;
713         txd.lo_dword.dword = rte_le_to_cpu_64(ring[desc_id].lo_dword.dword);
714         txd.hi_dword.dword = rte_le_to_cpu_64(ring[desc_id].hi_dword.dword);
715         printf("    0x%08X - 0x%08X / 0x%08X - 0x%08X\n",
716                         (unsigned)txd.lo_dword.words.lo,
717                         (unsigned)txd.lo_dword.words.hi,
718                         (unsigned)txd.hi_dword.words.lo,
719                         (unsigned)txd.hi_dword.words.hi);
720 }
721
722 void
723 rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id)
724 {
725         const struct rte_memzone *rx_mz;
726
727         if (port_id_is_invalid(port_id))
728                 return;
729         if (rx_queue_id_is_invalid(rxq_id))
730                 return;
731         if (rx_desc_id_is_invalid(rxd_id))
732                 return;
733         rx_mz = ring_dma_zone_lookup("rx_ring", port_id, rxq_id);
734         if (rx_mz == NULL)
735                 return;
736         ring_rx_descriptor_display(rx_mz, port_id, rxd_id);
737 }
738
739 void
740 tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id)
741 {
742         const struct rte_memzone *tx_mz;
743
744         if (port_id_is_invalid(port_id))
745                 return;
746         if (tx_queue_id_is_invalid(txq_id))
747                 return;
748         if (tx_desc_id_is_invalid(txd_id))
749                 return;
750         tx_mz = ring_dma_zone_lookup("tx_ring", port_id, txq_id);
751         if (tx_mz == NULL)
752                 return;
753         ring_tx_descriptor_display(tx_mz, txd_id);
754 }
755
756 void
757 fwd_lcores_config_display(void)
758 {
759         lcoreid_t lc_id;
760
761         printf("List of forwarding lcores:");
762         for (lc_id = 0; lc_id < nb_cfg_lcores; lc_id++)
763                 printf(" %2u", fwd_lcores_cpuids[lc_id]);
764         printf("\n");
765 }
766 void
767 rxtx_config_display(void)
768 {
769         printf("  %s packet forwarding - CRC stripping %s - "
770                "packets/burst=%d\n", cur_fwd_eng->fwd_mode_name,
771                rx_mode.hw_strip_crc ? "enabled" : "disabled",
772                nb_pkt_per_burst);
773
774         if (cur_fwd_eng == &tx_only_engine)
775                 printf("  packet len=%u - nb packet segments=%d\n",
776                                 (unsigned)tx_pkt_length, (int) tx_pkt_nb_segs);
777
778         struct rte_eth_rxconf *rx_conf = &ports[0].rx_conf;
779         struct rte_eth_txconf *tx_conf = &ports[0].tx_conf;
780
781         printf("  nb forwarding cores=%d - nb forwarding ports=%d\n",
782                nb_fwd_lcores, nb_fwd_ports);
783         printf("  RX queues=%d - RX desc=%d - RX free threshold=%d\n",
784                nb_rxq, nb_rxd, rx_conf->rx_free_thresh);
785         printf("  RX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n",
786                rx_conf->rx_thresh.pthresh, rx_conf->rx_thresh.hthresh,
787                rx_conf->rx_thresh.wthresh);
788         printf("  TX queues=%d - TX desc=%d - TX free threshold=%d\n",
789                nb_txq, nb_txd, tx_conf->tx_free_thresh);
790         printf("  TX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n",
791                tx_conf->tx_thresh.pthresh, tx_conf->tx_thresh.hthresh,
792                tx_conf->tx_thresh.wthresh);
793         printf("  TX RS bit threshold=%d - TXQ flags=0x%"PRIx32"\n",
794                tx_conf->tx_rs_thresh, tx_conf->txq_flags);
795 }
796
797 void
798 port_rss_reta_info(portid_t port_id,
799                    struct rte_eth_rss_reta_entry64 *reta_conf,
800                    uint16_t nb_entries)
801 {
802         uint16_t i, idx, shift;
803         int ret;
804
805         if (port_id_is_invalid(port_id))
806                 return;
807
808         ret = rte_eth_dev_rss_reta_query(port_id, reta_conf, nb_entries);
809         if (ret != 0) {
810                 printf("Failed to get RSS RETA info, return code = %d\n", ret);
811                 return;
812         }
813
814         for (i = 0; i < nb_entries; i++) {
815                 idx = i / RTE_RETA_GROUP_SIZE;
816                 shift = i % RTE_RETA_GROUP_SIZE;
817                 if (!(reta_conf[idx].mask & (1ULL << shift)))
818                         continue;
819                 printf("RSS RETA configuration: hash index=%u, queue=%u\n",
820                                         i, reta_conf[idx].reta[shift]);
821         }
822 }
823
824 /*
825  * Displays the RSS hash functions of a port, and, optionaly, the RSS hash
826  * key of the port.
827  */
828 void
829 port_rss_hash_conf_show(portid_t port_id, int show_rss_key)
830 {
831         struct rte_eth_rss_conf rss_conf;
832         uint8_t rss_key[10 * 4];
833         uint64_t rss_hf;
834         uint8_t i;
835         int diag;
836
837         if (port_id_is_invalid(port_id))
838                 return;
839         /* Get RSS hash key if asked to display it */
840         rss_conf.rss_key = (show_rss_key) ? rss_key : NULL;
841         diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
842         if (diag != 0) {
843                 switch (diag) {
844                 case -ENODEV:
845                         printf("port index %d invalid\n", port_id);
846                         break;
847                 case -ENOTSUP:
848                         printf("operation not supported by device\n");
849                         break;
850                 default:
851                         printf("operation failed - diag=%d\n", diag);
852                         break;
853                 }
854                 return;
855         }
856         rss_hf = rss_conf.rss_hf;
857         if (rss_hf == 0) {
858                 printf("RSS disabled\n");
859                 return;
860         }
861         printf("RSS functions:\n ");
862         if (rss_hf & ETH_RSS_IPV4)
863                 printf("ip4");
864         if (rss_hf & ETH_RSS_IPV4_TCP)
865                 printf(" tcp4");
866         if (rss_hf & ETH_RSS_IPV4_UDP)
867                 printf(" udp4");
868         if (rss_hf & ETH_RSS_IPV6)
869                 printf(" ip6");
870         if (rss_hf & ETH_RSS_IPV6_EX)
871                 printf(" ip6-ex");
872         if (rss_hf & ETH_RSS_IPV6_TCP)
873                 printf(" tcp6");
874         if (rss_hf & ETH_RSS_IPV6_TCP_EX)
875                 printf(" tcp6-ex");
876         if (rss_hf & ETH_RSS_IPV6_UDP)
877                 printf(" udp6");
878         if (rss_hf & ETH_RSS_IPV6_UDP_EX)
879                 printf(" udp6-ex");
880         printf("\n");
881         if (!show_rss_key)
882                 return;
883         printf("RSS key:\n");
884         for (i = 0; i < sizeof(rss_key); i++)
885                 printf("%02X", rss_key[i]);
886         printf("\n");
887 }
888
889 void
890 port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key)
891 {
892         struct rte_eth_rss_conf rss_conf;
893         int diag;
894
895         rss_conf.rss_key = NULL;
896         diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
897         if (diag == 0) {
898                 rss_conf.rss_key = hash_key;
899                 diag = rte_eth_dev_rss_hash_update(port_id, &rss_conf);
900         }
901         if (diag == 0)
902                 return;
903
904         switch (diag) {
905         case -ENODEV:
906                 printf("port index %d invalid\n", port_id);
907                 break;
908         case -ENOTSUP:
909                 printf("operation not supported by device\n");
910                 break;
911         default:
912                 printf("operation failed - diag=%d\n", diag);
913                 break;
914         }
915 }
916
917 /*
918  * Setup forwarding configuration for each logical core.
919  */
920 static void
921 setup_fwd_config_of_each_lcore(struct fwd_config *cfg)
922 {
923         streamid_t nb_fs_per_lcore;
924         streamid_t nb_fs;
925         streamid_t sm_id;
926         lcoreid_t  nb_extra;
927         lcoreid_t  nb_fc;
928         lcoreid_t  nb_lc;
929         lcoreid_t  lc_id;
930
931         nb_fs = cfg->nb_fwd_streams;
932         nb_fc = cfg->nb_fwd_lcores;
933         if (nb_fs <= nb_fc) {
934                 nb_fs_per_lcore = 1;
935                 nb_extra = 0;
936         } else {
937                 nb_fs_per_lcore = (streamid_t) (nb_fs / nb_fc);
938                 nb_extra = (lcoreid_t) (nb_fs % nb_fc);
939         }
940
941         nb_lc = (lcoreid_t) (nb_fc - nb_extra);
942         sm_id = 0;
943         for (lc_id = 0; lc_id < nb_lc; lc_id++) {
944                 fwd_lcores[lc_id]->stream_idx = sm_id;
945                 fwd_lcores[lc_id]->stream_nb = nb_fs_per_lcore;
946                 sm_id = (streamid_t) (sm_id + nb_fs_per_lcore);
947         }
948
949         /*
950          * Assign extra remaining streams, if any.
951          */
952         nb_fs_per_lcore = (streamid_t) (nb_fs_per_lcore + 1);
953         for (lc_id = 0; lc_id < nb_extra; lc_id++) {
954                 fwd_lcores[nb_lc + lc_id]->stream_idx = sm_id;
955                 fwd_lcores[nb_lc + lc_id]->stream_nb = nb_fs_per_lcore;
956                 sm_id = (streamid_t) (sm_id + nb_fs_per_lcore);
957         }
958 }
959
960 static void
961 simple_fwd_config_setup(void)
962 {
963         portid_t i;
964         portid_t j;
965         portid_t inc = 2;
966
967         if (port_topology == PORT_TOPOLOGY_CHAINED ||
968             port_topology == PORT_TOPOLOGY_LOOP) {
969                 inc = 1;
970         } else if (nb_fwd_ports % 2) {
971                 printf("\nWarning! Cannot handle an odd number of ports "
972                        "with the current port topology. Configuration "
973                        "must be changed to have an even number of ports, "
974                        "or relaunch application with "
975                        "--port-topology=chained\n\n");
976         }
977
978         cur_fwd_config.nb_fwd_ports = (portid_t) nb_fwd_ports;
979         cur_fwd_config.nb_fwd_streams =
980                 (streamid_t) cur_fwd_config.nb_fwd_ports;
981
982         /* reinitialize forwarding streams */
983         init_fwd_streams();
984
985         /*
986          * In the simple forwarding test, the number of forwarding cores
987          * must be lower or equal to the number of forwarding ports.
988          */
989         cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
990         if (cur_fwd_config.nb_fwd_lcores > cur_fwd_config.nb_fwd_ports)
991                 cur_fwd_config.nb_fwd_lcores =
992                         (lcoreid_t) cur_fwd_config.nb_fwd_ports;
993         setup_fwd_config_of_each_lcore(&cur_fwd_config);
994
995         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i = (portid_t) (i + inc)) {
996                 if (port_topology != PORT_TOPOLOGY_LOOP)
997                         j = (portid_t) ((i + 1) % cur_fwd_config.nb_fwd_ports);
998                 else
999                         j = i;
1000                 fwd_streams[i]->rx_port   = fwd_ports_ids[i];
1001                 fwd_streams[i]->rx_queue  = 0;
1002                 fwd_streams[i]->tx_port   = fwd_ports_ids[j];
1003                 fwd_streams[i]->tx_queue  = 0;
1004                 fwd_streams[i]->peer_addr = j;
1005
1006                 if (port_topology == PORT_TOPOLOGY_PAIRED) {
1007                         fwd_streams[j]->rx_port   = fwd_ports_ids[j];
1008                         fwd_streams[j]->rx_queue  = 0;
1009                         fwd_streams[j]->tx_port   = fwd_ports_ids[i];
1010                         fwd_streams[j]->tx_queue  = 0;
1011                         fwd_streams[j]->peer_addr = i;
1012                 }
1013         }
1014 }
1015
1016 /**
1017  * For the RSS forwarding test, each core is assigned on every port a transmit
1018  * queue whose index is the index of the core itself. This approach limits the
1019  * maximumm number of processing cores of the RSS test to the maximum number of
1020  * TX queues supported by the devices.
1021  *
1022  * Each core is assigned a single stream, each stream being composed of
1023  * a RX queue to poll on a RX port for input messages, associated with
1024  * a TX queue of a TX port where to send forwarded packets.
1025  * All packets received on the RX queue of index "RxQj" of the RX port "RxPi"
1026  * are sent on the TX queue "TxQl" of the TX port "TxPk" according to the two
1027  * following rules:
1028  *    - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd
1029  *    - TxQl = RxQj
1030  */
1031 static void
1032 rss_fwd_config_setup(void)
1033 {
1034         portid_t   rxp;
1035         portid_t   txp;
1036         queueid_t  rxq;
1037         queueid_t  nb_q;
1038         lcoreid_t  lc_id;
1039
1040         nb_q = nb_rxq;
1041         if (nb_q > nb_txq)
1042                 nb_q = nb_txq;
1043         cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
1044         cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
1045         cur_fwd_config.nb_fwd_streams =
1046                 (streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports);
1047         if (cur_fwd_config.nb_fwd_streams > cur_fwd_config.nb_fwd_lcores)
1048                 cur_fwd_config.nb_fwd_streams =
1049                         (streamid_t)cur_fwd_config.nb_fwd_lcores;
1050         else
1051                 cur_fwd_config.nb_fwd_lcores =
1052                         (lcoreid_t)cur_fwd_config.nb_fwd_streams;
1053
1054         /* reinitialize forwarding streams */
1055         init_fwd_streams();
1056
1057         setup_fwd_config_of_each_lcore(&cur_fwd_config);
1058         rxp = 0; rxq = 0;
1059         for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
1060                 struct fwd_stream *fs;
1061
1062                 fs = fwd_streams[lc_id];
1063
1064                 if ((rxp & 0x1) == 0)
1065                         txp = (portid_t) (rxp + 1);
1066                 else
1067                         txp = (portid_t) (rxp - 1);
1068                 /*
1069                  * if we are in loopback, simply send stuff out through the
1070                  * ingress port
1071                  */
1072                 if (port_topology == PORT_TOPOLOGY_LOOP)
1073                         txp = rxp;
1074
1075                 fs->rx_port = fwd_ports_ids[rxp];
1076                 fs->rx_queue = rxq;
1077                 fs->tx_port = fwd_ports_ids[txp];
1078                 fs->tx_queue = rxq;
1079                 fs->peer_addr = fs->tx_port;
1080                 rxq = (queueid_t) (rxq + 1);
1081                 if (rxq < nb_q)
1082                         continue;
1083                 /*
1084                  * rxq == nb_q
1085                  * Restart from RX queue 0 on next RX port
1086                  */
1087                 rxq = 0;
1088                 if (numa_support && (nb_fwd_ports <= (nb_ports >> 1)))
1089                         rxp = (portid_t)
1090                                 (rxp + ((nb_ports >> 1) / nb_fwd_ports));
1091                 else
1092                         rxp = (portid_t) (rxp + 1);
1093         }
1094 }
1095
1096 /*
1097  * In DCB and VT on,the mapping of 128 receive queues to 128 transmit queues.
1098  */
1099 static void
1100 dcb_rxq_2_txq_mapping(queueid_t rxq, queueid_t *txq)
1101 {
1102         if(dcb_q_mapping == DCB_4_TCS_Q_MAPPING) {
1103
1104                 if (rxq < 32)
1105                         /* tc0: 0-31 */
1106                         *txq = rxq;
1107                 else if (rxq < 64) {
1108                         /* tc1: 64-95 */
1109                         *txq =  (uint16_t)(rxq + 32);
1110                 }
1111                 else {
1112                         /* tc2: 96-111;tc3:112-127 */
1113                         *txq =  (uint16_t)(rxq/2 + 64);
1114                 }
1115         }
1116         else {
1117                 if (rxq < 16)
1118                         /* tc0 mapping*/
1119                         *txq = rxq;
1120                 else if (rxq < 32) {
1121                         /* tc1 mapping*/
1122                          *txq = (uint16_t)(rxq + 16);
1123                 }
1124                 else if (rxq < 64) {
1125                         /*tc2,tc3 mapping */
1126                         *txq =  (uint16_t)(rxq + 32);
1127                 }
1128                 else {
1129                         /* tc4,tc5,tc6 and tc7 mapping */
1130                         *txq =  (uint16_t)(rxq/2 + 64);
1131                 }
1132         }
1133 }
1134
1135 /**
1136  * For the DCB forwarding test, each core is assigned on every port multi-transmit
1137  * queue.
1138  *
1139  * Each core is assigned a multi-stream, each stream being composed of
1140  * a RX queue to poll on a RX port for input messages, associated with
1141  * a TX queue of a TX port where to send forwarded packets.
1142  * All packets received on the RX queue of index "RxQj" of the RX port "RxPi"
1143  * are sent on the TX queue "TxQl" of the TX port "TxPk" according to the two
1144  * following rules:
1145  * In VT mode,
1146  *    - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd
1147  *    - TxQl = RxQj
1148  * In non-VT mode,
1149  *    - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd
1150  *    There is a mapping of RxQj to TxQl to be required,and the mapping was implemented
1151  *    in dcb_rxq_2_txq_mapping function.
1152  */
1153 static void
1154 dcb_fwd_config_setup(void)
1155 {
1156         portid_t   rxp;
1157         portid_t   txp;
1158         queueid_t  rxq;
1159         queueid_t  nb_q;
1160         lcoreid_t  lc_id;
1161         uint16_t sm_id;
1162
1163         nb_q = nb_rxq;
1164
1165         cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
1166         cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
1167         cur_fwd_config.nb_fwd_streams =
1168                 (streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports);
1169
1170         /* reinitialize forwarding streams */
1171         init_fwd_streams();
1172
1173         setup_fwd_config_of_each_lcore(&cur_fwd_config);
1174         rxp = 0; rxq = 0;
1175         for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
1176                 /* a fwd core can run multi-streams */
1177                 for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++)
1178                 {
1179                         struct fwd_stream *fs;
1180                         fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id];
1181                         if ((rxp & 0x1) == 0)
1182                                 txp = (portid_t) (rxp + 1);
1183                         else
1184                                 txp = (portid_t) (rxp - 1);
1185                         fs->rx_port = fwd_ports_ids[rxp];
1186                         fs->rx_queue = rxq;
1187                         fs->tx_port = fwd_ports_ids[txp];
1188                         if (dcb_q_mapping == DCB_VT_Q_MAPPING)
1189                                 fs->tx_queue = rxq;
1190                         else
1191                                 dcb_rxq_2_txq_mapping(rxq, &fs->tx_queue);
1192                         fs->peer_addr = fs->tx_port;
1193                         rxq = (queueid_t) (rxq + 1);
1194                         if (rxq < nb_q)
1195                                 continue;
1196                         rxq = 0;
1197                         if (numa_support && (nb_fwd_ports <= (nb_ports >> 1)))
1198                                 rxp = (portid_t)
1199                                         (rxp + ((nb_ports >> 1) / nb_fwd_ports));
1200                         else
1201                                 rxp = (portid_t) (rxp + 1);
1202                 }
1203         }
1204 }
1205
1206 static void
1207 icmp_echo_config_setup(void)
1208 {
1209         portid_t  rxp;
1210         queueid_t rxq;
1211         lcoreid_t lc_id;
1212         uint16_t  sm_id;
1213
1214         if ((nb_txq * nb_fwd_ports) < nb_fwd_lcores)
1215                 cur_fwd_config.nb_fwd_lcores = (lcoreid_t)
1216                         (nb_txq * nb_fwd_ports);
1217         else
1218                 cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
1219         cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
1220         cur_fwd_config.nb_fwd_streams =
1221                 (streamid_t) (nb_rxq * cur_fwd_config.nb_fwd_ports);
1222         if (cur_fwd_config.nb_fwd_streams < cur_fwd_config.nb_fwd_lcores)
1223                 cur_fwd_config.nb_fwd_lcores =
1224                         (lcoreid_t)cur_fwd_config.nb_fwd_streams;
1225         if (verbose_level > 0) {
1226                 printf("%s fwd_cores=%d fwd_ports=%d fwd_streams=%d\n",
1227                        __FUNCTION__,
1228                        cur_fwd_config.nb_fwd_lcores,
1229                        cur_fwd_config.nb_fwd_ports,
1230                        cur_fwd_config.nb_fwd_streams);
1231         }
1232
1233         /* reinitialize forwarding streams */
1234         init_fwd_streams();
1235         setup_fwd_config_of_each_lcore(&cur_fwd_config);
1236         rxp = 0; rxq = 0;
1237         for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
1238                 if (verbose_level > 0)
1239                         printf("  core=%d: \n", lc_id);
1240                 for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) {
1241                         struct fwd_stream *fs;
1242                         fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id];
1243                         fs->rx_port = fwd_ports_ids[rxp];
1244                         fs->rx_queue = rxq;
1245                         fs->tx_port = fs->rx_port;
1246                         fs->tx_queue = lc_id;
1247                         fs->peer_addr = fs->tx_port;
1248                         if (verbose_level > 0)
1249                                 printf("  stream=%d port=%d rxq=%d txq=%d\n",
1250                                        sm_id, fs->rx_port, fs->rx_queue,
1251                                        fs->tx_queue);
1252                         rxq = (queueid_t) (rxq + 1);
1253                         if (rxq == nb_rxq) {
1254                                 rxq = 0;
1255                                 rxp = (portid_t) (rxp + 1);
1256                         }
1257                 }
1258         }
1259 }
1260
1261 void
1262 fwd_config_setup(void)
1263 {
1264         cur_fwd_config.fwd_eng = cur_fwd_eng;
1265         if (strcmp(cur_fwd_eng->fwd_mode_name, "icmpecho") == 0) {
1266                 icmp_echo_config_setup();
1267                 return;
1268         }
1269         if ((nb_rxq > 1) && (nb_txq > 1)){
1270                 if (dcb_config)
1271                         dcb_fwd_config_setup();
1272                 else
1273                         rss_fwd_config_setup();
1274         }
1275         else
1276                 simple_fwd_config_setup();
1277 }
1278
1279 static void
1280 pkt_fwd_config_display(struct fwd_config *cfg)
1281 {
1282         struct fwd_stream *fs;
1283         lcoreid_t  lc_id;
1284         streamid_t sm_id;
1285
1286         printf("%s packet forwarding - ports=%d - cores=%d - streams=%d - "
1287                 "NUMA support %s, MP over anonymous pages %s\n",
1288                 cfg->fwd_eng->fwd_mode_name,
1289                 cfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams,
1290                 numa_support == 1 ? "enabled" : "disabled",
1291                 mp_anon != 0 ? "enabled" : "disabled");
1292
1293         if (strcmp(cfg->fwd_eng->fwd_mode_name, "mac_retry") == 0)
1294                 printf("TX retry num: %u, delay between TX retries: %uus\n",
1295                         burst_tx_retry_num, burst_tx_delay_time);
1296         for (lc_id = 0; lc_id < cfg->nb_fwd_lcores; lc_id++) {
1297                 printf("Logical Core %u (socket %u) forwards packets on "
1298                        "%d streams:",
1299                        fwd_lcores_cpuids[lc_id],
1300                        rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]),
1301                        fwd_lcores[lc_id]->stream_nb);
1302                 for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) {
1303                         fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id];
1304                         printf("\n  RX P=%d/Q=%d (socket %u) -> TX "
1305                                "P=%d/Q=%d (socket %u) ",
1306                                fs->rx_port, fs->rx_queue,
1307                                ports[fs->rx_port].socket_id,
1308                                fs->tx_port, fs->tx_queue,
1309                                ports[fs->tx_port].socket_id);
1310                         print_ethaddr("peer=",
1311                                       &peer_eth_addrs[fs->peer_addr]);
1312                 }
1313                 printf("\n");
1314         }
1315         printf("\n");
1316 }
1317
1318
1319 void
1320 fwd_config_display(void)
1321 {
1322         if((dcb_config) && (nb_fwd_lcores == 1)) {
1323                 printf("In DCB mode,the nb forwarding cores should be larger than 1\n");
1324                 return;
1325         }
1326         fwd_config_setup();
1327         pkt_fwd_config_display(&cur_fwd_config);
1328 }
1329
1330 int
1331 set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc)
1332 {
1333         unsigned int i;
1334         unsigned int lcore_cpuid;
1335         int record_now;
1336
1337         record_now = 0;
1338  again:
1339         for (i = 0; i < nb_lc; i++) {
1340                 lcore_cpuid = lcorelist[i];
1341                 if (! rte_lcore_is_enabled(lcore_cpuid)) {
1342                         printf("lcore %u not enabled\n", lcore_cpuid);
1343                         return -1;
1344                 }
1345                 if (lcore_cpuid == rte_get_master_lcore()) {
1346                         printf("lcore %u cannot be masked on for running "
1347                                "packet forwarding, which is the master lcore "
1348                                "and reserved for command line parsing only\n",
1349                                lcore_cpuid);
1350                         return -1;
1351                 }
1352                 if (record_now)
1353                         fwd_lcores_cpuids[i] = lcore_cpuid;
1354         }
1355         if (record_now == 0) {
1356                 record_now = 1;
1357                 goto again;
1358         }
1359         nb_cfg_lcores = (lcoreid_t) nb_lc;
1360         if (nb_fwd_lcores != (lcoreid_t) nb_lc) {
1361                 printf("previous number of forwarding cores %u - changed to "
1362                        "number of configured cores %u\n",
1363                        (unsigned int) nb_fwd_lcores, nb_lc);
1364                 nb_fwd_lcores = (lcoreid_t) nb_lc;
1365         }
1366
1367         return 0;
1368 }
1369
1370 int
1371 set_fwd_lcores_mask(uint64_t lcoremask)
1372 {
1373         unsigned int lcorelist[64];
1374         unsigned int nb_lc;
1375         unsigned int i;
1376
1377         if (lcoremask == 0) {
1378                 printf("Invalid NULL mask of cores\n");
1379                 return -1;
1380         }
1381         nb_lc = 0;
1382         for (i = 0; i < 64; i++) {
1383                 if (! ((uint64_t)(1ULL << i) & lcoremask))
1384                         continue;
1385                 lcorelist[nb_lc++] = i;
1386         }
1387         return set_fwd_lcores_list(lcorelist, nb_lc);
1388 }
1389
1390 void
1391 set_fwd_lcores_number(uint16_t nb_lc)
1392 {
1393         if (nb_lc > nb_cfg_lcores) {
1394                 printf("nb fwd cores %u > %u (max. number of configured "
1395                        "lcores) - ignored\n",
1396                        (unsigned int) nb_lc, (unsigned int) nb_cfg_lcores);
1397                 return;
1398         }
1399         nb_fwd_lcores = (lcoreid_t) nb_lc;
1400         printf("Number of forwarding cores set to %u\n",
1401                (unsigned int) nb_fwd_lcores);
1402 }
1403
1404 void
1405 set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt)
1406 {
1407         unsigned int i;
1408         portid_t port_id;
1409         int record_now;
1410
1411         record_now = 0;
1412  again:
1413         for (i = 0; i < nb_pt; i++) {
1414                 port_id = (portid_t) portlist[i];
1415                 if (port_id >= nb_ports) {
1416                         printf("Invalid port id %u >= %u\n",
1417                                (unsigned int) port_id,
1418                                (unsigned int) nb_ports);
1419                         return;
1420                 }
1421                 if (record_now)
1422                         fwd_ports_ids[i] = port_id;
1423         }
1424         if (record_now == 0) {
1425                 record_now = 1;
1426                 goto again;
1427         }
1428         nb_cfg_ports = (portid_t) nb_pt;
1429         if (nb_fwd_ports != (portid_t) nb_pt) {
1430                 printf("previous number of forwarding ports %u - changed to "
1431                        "number of configured ports %u\n",
1432                        (unsigned int) nb_fwd_ports, nb_pt);
1433                 nb_fwd_ports = (portid_t) nb_pt;
1434         }
1435 }
1436
1437 void
1438 set_fwd_ports_mask(uint64_t portmask)
1439 {
1440         unsigned int portlist[64];
1441         unsigned int nb_pt;
1442         unsigned int i;
1443
1444         if (portmask == 0) {
1445                 printf("Invalid NULL mask of ports\n");
1446                 return;
1447         }
1448         nb_pt = 0;
1449         for (i = 0; i < (unsigned)RTE_MIN(64, RTE_MAX_ETHPORTS); i++) {
1450                 if (! ((uint64_t)(1ULL << i) & portmask))
1451                         continue;
1452                 portlist[nb_pt++] = i;
1453         }
1454         set_fwd_ports_list(portlist, nb_pt);
1455 }
1456
1457 void
1458 set_fwd_ports_number(uint16_t nb_pt)
1459 {
1460         if (nb_pt > nb_cfg_ports) {
1461                 printf("nb fwd ports %u > %u (number of configured "
1462                        "ports) - ignored\n",
1463                        (unsigned int) nb_pt, (unsigned int) nb_cfg_ports);
1464                 return;
1465         }
1466         nb_fwd_ports = (portid_t) nb_pt;
1467         printf("Number of forwarding ports set to %u\n",
1468                (unsigned int) nb_fwd_ports);
1469 }
1470
1471 void
1472 set_nb_pkt_per_burst(uint16_t nb)
1473 {
1474         if (nb > MAX_PKT_BURST) {
1475                 printf("nb pkt per burst: %u > %u (maximum packet per burst) "
1476                        " ignored\n",
1477                        (unsigned int) nb, (unsigned int) MAX_PKT_BURST);
1478                 return;
1479         }
1480         nb_pkt_per_burst = nb;
1481         printf("Number of packets per burst set to %u\n",
1482                (unsigned int) nb_pkt_per_burst);
1483 }
1484
1485 void
1486 set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs)
1487 {
1488         uint16_t tx_pkt_len;
1489         unsigned i;
1490
1491         if (nb_segs >= (unsigned) nb_txd) {
1492                 printf("nb segments per TX packets=%u >= nb_txd=%u - ignored\n",
1493                        nb_segs, (unsigned int) nb_txd);
1494                 return;
1495         }
1496
1497         /*
1498          * Check that each segment length is greater or equal than
1499          * the mbuf data sise.
1500          * Check also that the total packet length is greater or equal than the
1501          * size of an empty UDP/IP packet (sizeof(struct ether_hdr) + 20 + 8).
1502          */
1503         tx_pkt_len = 0;
1504         for (i = 0; i < nb_segs; i++) {
1505                 if (seg_lengths[i] > (unsigned) mbuf_data_size) {
1506                         printf("length[%u]=%u > mbuf_data_size=%u - give up\n",
1507                                i, seg_lengths[i], (unsigned) mbuf_data_size);
1508                         return;
1509                 }
1510                 tx_pkt_len = (uint16_t)(tx_pkt_len + seg_lengths[i]);
1511         }
1512         if (tx_pkt_len < (sizeof(struct ether_hdr) + 20 + 8)) {
1513                 printf("total packet length=%u < %d - give up\n",
1514                                 (unsigned) tx_pkt_len,
1515                                 (int)(sizeof(struct ether_hdr) + 20 + 8));
1516                 return;
1517         }
1518
1519         for (i = 0; i < nb_segs; i++)
1520                 tx_pkt_seg_lengths[i] = (uint16_t) seg_lengths[i];
1521
1522         tx_pkt_length  = tx_pkt_len;
1523         tx_pkt_nb_segs = (uint8_t) nb_segs;
1524 }
1525
1526 char*
1527 list_pkt_forwarding_modes(void)
1528 {
1529         static char fwd_modes[128] = "";
1530         const char *separator = "|";
1531         struct fwd_engine *fwd_eng;
1532         unsigned i = 0;
1533
1534         if (strlen (fwd_modes) == 0) {
1535                 while ((fwd_eng = fwd_engines[i++]) != NULL) {
1536                         strcat(fwd_modes, fwd_eng->fwd_mode_name);
1537                         strcat(fwd_modes, separator);
1538                 }
1539                 fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0';
1540         }
1541
1542         return fwd_modes;
1543 }
1544
1545 void
1546 set_pkt_forwarding_mode(const char *fwd_mode_name)
1547 {
1548         struct fwd_engine *fwd_eng;
1549         unsigned i;
1550
1551         i = 0;
1552         while ((fwd_eng = fwd_engines[i]) != NULL) {
1553                 if (! strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) {
1554                         printf("Set %s packet forwarding mode\n",
1555                                fwd_mode_name);
1556                         cur_fwd_eng = fwd_eng;
1557                         return;
1558                 }
1559                 i++;
1560         }
1561         printf("Invalid %s packet forwarding mode\n", fwd_mode_name);
1562 }
1563
1564 void
1565 set_verbose_level(uint16_t vb_level)
1566 {
1567         printf("Change verbose level from %u to %u\n",
1568                (unsigned int) verbose_level, (unsigned int) vb_level);
1569         verbose_level = vb_level;
1570 }
1571
1572 void
1573 vlan_extend_set(portid_t port_id, int on)
1574 {
1575         int diag;
1576         int vlan_offload;
1577
1578         if (port_id_is_invalid(port_id))
1579                 return;
1580
1581         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
1582
1583         if (on)
1584                 vlan_offload |= ETH_VLAN_EXTEND_OFFLOAD;
1585         else
1586                 vlan_offload &= ~ETH_VLAN_EXTEND_OFFLOAD;
1587
1588         diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
1589         if (diag < 0)
1590                 printf("rx_vlan_extend_set(port_pi=%d, on=%d) failed "
1591                "diag=%d\n", port_id, on, diag);
1592 }
1593
1594 void
1595 rx_vlan_strip_set(portid_t port_id, int on)
1596 {
1597         int diag;
1598         int vlan_offload;
1599
1600         if (port_id_is_invalid(port_id))
1601                 return;
1602
1603         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
1604
1605         if (on)
1606                 vlan_offload |= ETH_VLAN_STRIP_OFFLOAD;
1607         else
1608                 vlan_offload &= ~ETH_VLAN_STRIP_OFFLOAD;
1609
1610         diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
1611         if (diag < 0)
1612                 printf("rx_vlan_strip_set(port_pi=%d, on=%d) failed "
1613                "diag=%d\n", port_id, on, diag);
1614 }
1615
1616 void
1617 rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on)
1618 {
1619         int diag;
1620
1621         if (port_id_is_invalid(port_id))
1622                 return;
1623
1624         diag = rte_eth_dev_set_vlan_strip_on_queue(port_id, queue_id, on);
1625         if (diag < 0)
1626                 printf("rx_vlan_strip_set_on_queue(port_pi=%d, queue_id=%d, on=%d) failed "
1627                "diag=%d\n", port_id, queue_id, on, diag);
1628 }
1629
1630 void
1631 rx_vlan_filter_set(portid_t port_id, int on)
1632 {
1633         int diag;
1634         int vlan_offload;
1635
1636         if (port_id_is_invalid(port_id))
1637                 return;
1638
1639         vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
1640
1641         if (on)
1642                 vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
1643         else
1644                 vlan_offload &= ~ETH_VLAN_FILTER_OFFLOAD;
1645
1646         diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
1647         if (diag < 0)
1648                 printf("rx_vlan_filter_set(port_pi=%d, on=%d) failed "
1649                "diag=%d\n", port_id, on, diag);
1650 }
1651
1652 void
1653 rx_vft_set(portid_t port_id, uint16_t vlan_id, int on)
1654 {
1655         int diag;
1656
1657         if (port_id_is_invalid(port_id))
1658                 return;
1659         if (vlan_id_is_invalid(vlan_id))
1660                 return;
1661         diag = rte_eth_dev_vlan_filter(port_id, vlan_id, on);
1662         if (diag == 0)
1663                 return;
1664         printf("rte_eth_dev_vlan_filter(port_pi=%d, vlan_id=%d, on=%d) failed "
1665                "diag=%d\n",
1666                port_id, vlan_id, on, diag);
1667 }
1668
1669 void
1670 rx_vlan_all_filter_set(portid_t port_id, int on)
1671 {
1672         uint16_t vlan_id;
1673
1674         if (port_id_is_invalid(port_id))
1675                 return;
1676         for (vlan_id = 0; vlan_id < 4096; vlan_id++)
1677                 rx_vft_set(port_id, vlan_id, on);
1678 }
1679
1680 void
1681 vlan_tpid_set(portid_t port_id, uint16_t tp_id)
1682 {
1683         int diag;
1684         if (port_id_is_invalid(port_id))
1685                 return;
1686
1687         diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id);
1688         if (diag == 0)
1689                 return;
1690
1691         printf("tx_vlan_tpid_set(port_pi=%d, tpid=%d) failed "
1692                "diag=%d\n",
1693                port_id, tp_id, diag);
1694 }
1695
1696 void
1697 tx_vlan_set(portid_t port_id, uint16_t vlan_id)
1698 {
1699         if (port_id_is_invalid(port_id))
1700                 return;
1701         if (vlan_id_is_invalid(vlan_id))
1702                 return;
1703         ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_VLAN;
1704         ports[port_id].tx_vlan_id = vlan_id;
1705 }
1706
1707 void
1708 tx_vlan_reset(portid_t port_id)
1709 {
1710         if (port_id_is_invalid(port_id))
1711                 return;
1712         ports[port_id].tx_ol_flags &= ~TESTPMD_TX_OFFLOAD_INSERT_VLAN;
1713 }
1714
1715 void
1716 tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on)
1717 {
1718         if (port_id_is_invalid(port_id))
1719                 return;
1720
1721         rte_eth_dev_set_vlan_pvid(port_id, vlan_id, on);
1722 }
1723
1724 void
1725 set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value)
1726 {
1727         uint16_t i;
1728         uint8_t existing_mapping_found = 0;
1729
1730         if (port_id_is_invalid(port_id))
1731                 return;
1732
1733         if (is_rx ? (rx_queue_id_is_invalid(queue_id)) : (tx_queue_id_is_invalid(queue_id)))
1734                 return;
1735
1736         if (map_value >= RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1737                 printf("map_value not in required range 0..%d\n",
1738                                 RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
1739                 return;
1740         }
1741
1742         if (!is_rx) { /*then tx*/
1743                 for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1744                         if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1745                             (tx_queue_stats_mappings[i].queue_id == queue_id)) {
1746                                 tx_queue_stats_mappings[i].stats_counter_id = map_value;
1747                                 existing_mapping_found = 1;
1748                                 break;
1749                         }
1750                 }
1751                 if (!existing_mapping_found) { /* A new additional mapping... */
1752                         tx_queue_stats_mappings[nb_tx_queue_stats_mappings].port_id = port_id;
1753                         tx_queue_stats_mappings[nb_tx_queue_stats_mappings].queue_id = queue_id;
1754                         tx_queue_stats_mappings[nb_tx_queue_stats_mappings].stats_counter_id = map_value;
1755                         nb_tx_queue_stats_mappings++;
1756                 }
1757         }
1758         else { /*rx*/
1759                 for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1760                         if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1761                             (rx_queue_stats_mappings[i].queue_id == queue_id)) {
1762                                 rx_queue_stats_mappings[i].stats_counter_id = map_value;
1763                                 existing_mapping_found = 1;
1764                                 break;
1765                         }
1766                 }
1767                 if (!existing_mapping_found) { /* A new additional mapping... */
1768                         rx_queue_stats_mappings[nb_rx_queue_stats_mappings].port_id = port_id;
1769                         rx_queue_stats_mappings[nb_rx_queue_stats_mappings].queue_id = queue_id;
1770                         rx_queue_stats_mappings[nb_rx_queue_stats_mappings].stats_counter_id = map_value;
1771                         nb_rx_queue_stats_mappings++;
1772                 }
1773         }
1774 }
1775
1776 static inline void
1777 print_fdir_mask(struct rte_eth_fdir_masks *mask)
1778 {
1779         printf("\n    vlan_tci: 0x%04x, src_ipv4: 0x%08x, dst_ipv4: 0x%08x,"
1780                       " src_port: 0x%04x, dst_port: 0x%04x",
1781                 mask->vlan_tci_mask, mask->ipv4_mask.src_ip,
1782                 mask->ipv4_mask.dst_ip,
1783                 mask->src_port_mask, mask->dst_port_mask);
1784
1785         printf("\n    src_ipv6: 0x%08x,0x%08x,0x%08x,0x%08x,"
1786                      " dst_ipv6: 0x%08x,0x%08x,0x%08x,0x%08x",
1787                 mask->ipv6_mask.src_ip[0], mask->ipv6_mask.src_ip[1],
1788                 mask->ipv6_mask.src_ip[2], mask->ipv6_mask.src_ip[3],
1789                 mask->ipv6_mask.dst_ip[0], mask->ipv6_mask.dst_ip[1],
1790                 mask->ipv6_mask.dst_ip[2], mask->ipv6_mask.dst_ip[3]);
1791         printf("\n");
1792 }
1793
1794 static inline void
1795 print_fdir_flex_payload(struct rte_eth_fdir_flex_conf *flex_conf, uint32_t num)
1796 {
1797         struct rte_eth_flex_payload_cfg *cfg;
1798         uint32_t i, j;
1799
1800         for (i = 0; i < flex_conf->nb_payloads; i++) {
1801                 cfg = &flex_conf->flex_set[i];
1802                 if (cfg->type == RTE_ETH_RAW_PAYLOAD)
1803                         printf("\n    RAW:  ");
1804                 else if (cfg->type == RTE_ETH_L2_PAYLOAD)
1805                         printf("\n    L2_PAYLOAD:  ");
1806                 else if (cfg->type == RTE_ETH_L3_PAYLOAD)
1807                         printf("\n    L3_PAYLOAD:  ");
1808                 else if (cfg->type == RTE_ETH_L4_PAYLOAD)
1809                         printf("\n    L4_PAYLOAD:  ");
1810                 else
1811                         printf("\n    UNKNOWN PAYLOAD(%u):  ", cfg->type);
1812                 for (j = 0; j < num; j++)
1813                         printf("  %-5u", cfg->src_offset[j]);
1814         }
1815         printf("\n");
1816 }
1817
1818 static inline void
1819 print_fdir_flex_mask(struct rte_eth_fdir_flex_conf *flex_conf, uint32_t num)
1820 {
1821         struct rte_eth_fdir_flex_mask *mask;
1822         uint32_t i, j;
1823
1824         for (i = 0; i < flex_conf->nb_flexmasks; i++) {
1825                 mask = &flex_conf->flex_mask[i];
1826                 printf("\n    %s:\t", flowtype_str[mask->flow_type]);
1827                 for (j = 0; j < num; j++)
1828                         printf(" %02x", mask->mask[j]);
1829         }
1830         printf("\n");
1831 }
1832
1833 static inline void
1834 print_fdir_flow_type(uint32_t flow_types_mask)
1835 {
1836         int i = 0;
1837
1838         for (i = RTE_ETH_FLOW_TYPE_UDPV4;
1839              i <= RTE_ETH_FLOW_TYPE_FRAG_IPV6;
1840              i++) {
1841                 if (flow_types_mask & (1 << i))
1842                         printf(" %s", flowtype_str[i]);
1843         }
1844         printf("\n");
1845 }
1846
1847 void
1848 fdir_get_infos(portid_t port_id)
1849 {
1850         struct rte_eth_fdir_stats fdir_stat;
1851         struct rte_eth_fdir_info fdir_info;
1852         int ret;
1853
1854         static const char *fdir_stats_border = "########################";
1855
1856         if (port_id_is_invalid(port_id))
1857                 return;
1858         ret = rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_FDIR);
1859         if (ret < 0) {
1860                 printf("\n FDIR is not supported on port %-2d\n",
1861                         port_id);
1862                 return;
1863         }
1864
1865         memset(&fdir_info, 0, sizeof(fdir_info));
1866         rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR,
1867                                RTE_ETH_FILTER_INFO, &fdir_info);
1868         memset(&fdir_stat, 0, sizeof(fdir_stat));
1869         rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR,
1870                                RTE_ETH_FILTER_STATS, &fdir_stat);
1871         printf("\n  %s FDIR infos for port %-2d     %s\n",
1872                fdir_stats_border, port_id, fdir_stats_border);
1873         printf("  MODE: ");
1874         if (fdir_info.mode == RTE_FDIR_MODE_PERFECT)
1875                         printf("  PERFECT\n");
1876         else if (fdir_info.mode == RTE_FDIR_MODE_SIGNATURE)
1877                         printf("  SIGNATURE\n");
1878         else
1879                         printf("  DISABLE\n");
1880         printf("  SUPPORTED FLOW TYPE: ");
1881         print_fdir_flow_type(fdir_info.flow_types_mask[0]);
1882         printf("  FLEX PAYLOAD INFO:\n");
1883         printf("  max_len:       %-10"PRIu32"  payload_limit: %-10"PRIu32"\n"
1884                "  payload_unit:  %-10"PRIu32"  payload_seg:   %-10"PRIu32"\n"
1885                "  bitmask_unit:  %-10"PRIu32"  bitmask_num:   %-10"PRIu32"\n",
1886                 fdir_info.max_flexpayload, fdir_info.flex_payload_limit,
1887                 fdir_info.flex_payload_unit,
1888                 fdir_info.max_flex_payload_segment_num,
1889                 fdir_info.flex_bitmask_unit, fdir_info.max_flex_bitmask_num);
1890         printf("  MASK: ");
1891         print_fdir_mask(&fdir_info.mask);
1892         if (fdir_info.flex_conf.nb_payloads > 0) {
1893                 printf("  FLEX PAYLOAD SRC OFFSET:");
1894                 print_fdir_flex_payload(&fdir_info.flex_conf, fdir_info.max_flexpayload);
1895         }
1896         if (fdir_info.flex_conf.nb_flexmasks > 0) {
1897                 printf("  FLEX MASK CFG:");
1898                 print_fdir_flex_mask(&fdir_info.flex_conf, fdir_info.max_flexpayload);
1899         }
1900         printf("  guarant_count: %-10"PRIu32"  best_count:    %"PRIu32"\n",
1901                fdir_stat.guarant_cnt, fdir_stat.best_cnt);
1902         printf("  guarant_space: %-10"PRIu32"  best_space:    %"PRIu32"\n",
1903                fdir_info.guarant_spc, fdir_info.best_spc);
1904         printf("  collision:     %-10"PRIu32"  free:          %"PRIu32"\n"
1905                "  maxhash:       %-10"PRIu32"  maxlen:        %"PRIu32"\n"
1906                "  add:           %-10"PRIu64"  remove:        %"PRIu64"\n"
1907                "  f_add:         %-10"PRIu64"  f_remove:      %"PRIu64"\n",
1908                fdir_stat.collision, fdir_stat.free,
1909                fdir_stat.maxhash, fdir_stat.maxlen,
1910                fdir_stat.add, fdir_stat.remove,
1911                fdir_stat.f_add, fdir_stat.f_remove);
1912         printf("  %s############################%s\n",
1913                fdir_stats_border, fdir_stats_border);
1914 }
1915
1916 void
1917 fdir_set_flex_mask(portid_t port_id, struct rte_eth_fdir_flex_mask *cfg)
1918 {
1919         struct rte_port *port;
1920         struct rte_eth_fdir_flex_conf *flex_conf;
1921         int i, idx = 0;
1922
1923         port = &ports[port_id];
1924         flex_conf = &port->dev_conf.fdir_conf.flex_conf;
1925         for (i = 0; i < RTE_ETH_FLOW_TYPE_MAX; i++) {
1926                 if (cfg->flow_type == flex_conf->flex_mask[i].flow_type) {
1927                         idx = i;
1928                         break;
1929                 }
1930         }
1931         if (i >= RTE_ETH_FLOW_TYPE_MAX) {
1932                 if (flex_conf->nb_flexmasks < RTE_DIM(flex_conf->flex_mask)) {
1933                         idx = flex_conf->nb_flexmasks;
1934                         flex_conf->nb_flexmasks++;
1935                 } else {
1936                         printf("The flex mask table is full. Can not set flex"
1937                                 " mask for flow_type(%u).", cfg->flow_type);
1938                         return;
1939                 }
1940         }
1941         (void)rte_memcpy(&flex_conf->flex_mask[idx],
1942                          cfg,
1943                          sizeof(struct rte_eth_fdir_flex_mask));
1944 }
1945
1946 void
1947 fdir_set_flex_payload(portid_t port_id, struct rte_eth_flex_payload_cfg *cfg)
1948 {
1949         struct rte_port *port;
1950         struct rte_eth_fdir_flex_conf *flex_conf;
1951         int i, idx = 0;
1952
1953         port = &ports[port_id];
1954         flex_conf = &port->dev_conf.fdir_conf.flex_conf;
1955         for (i = 0; i < RTE_ETH_PAYLOAD_MAX; i++) {
1956                 if (cfg->type == flex_conf->flex_set[i].type) {
1957                         idx = i;
1958                         break;
1959                 }
1960         }
1961         if (i >= RTE_ETH_PAYLOAD_MAX) {
1962                 if (flex_conf->nb_payloads < RTE_DIM(flex_conf->flex_set)) {
1963                         idx = flex_conf->nb_payloads;
1964                         flex_conf->nb_payloads++;
1965                 } else {
1966                         printf("The flex payload table is full. Can not set"
1967                                 " flex payload for type(%u).", cfg->type);
1968                         return;
1969                 }
1970         }
1971         (void)rte_memcpy(&flex_conf->flex_set[idx],
1972                          cfg,
1973                          sizeof(struct rte_eth_flex_payload_cfg));
1974
1975 }
1976
1977 void
1978 set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on)
1979 {
1980         int diag;
1981
1982         if (port_id_is_invalid(port_id))
1983                 return;
1984         if (is_rx)
1985                 diag = rte_eth_dev_set_vf_rx(port_id,vf,on);
1986         else
1987                 diag = rte_eth_dev_set_vf_tx(port_id,vf,on);
1988         if (diag == 0)
1989                 return;
1990         if(is_rx)
1991                 printf("rte_eth_dev_set_vf_rx for port_id=%d failed "
1992                         "diag=%d\n", port_id, diag);
1993         else
1994                 printf("rte_eth_dev_set_vf_tx for port_id=%d failed "
1995                         "diag=%d\n", port_id, diag);
1996
1997 }
1998
1999 void
2000 set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on)
2001 {
2002         int diag;
2003
2004         if (port_id_is_invalid(port_id))
2005                 return;
2006         if (vlan_id_is_invalid(vlan_id))
2007                 return;
2008         diag = rte_eth_dev_set_vf_vlan_filter(port_id, vlan_id, vf_mask, on);
2009         if (diag == 0)
2010                 return;
2011         printf("rte_eth_dev_set_vf_vlan_filter for port_id=%d failed "
2012                "diag=%d\n", port_id, diag);
2013 }
2014
2015 int
2016 set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
2017 {
2018         int diag;
2019         struct rte_eth_link link;
2020
2021         if (port_id_is_invalid(port_id))
2022                 return 1;
2023         rte_eth_link_get_nowait(port_id, &link);
2024         if (rate > link.link_speed) {
2025                 printf("Invalid rate value:%u bigger than link speed: %u\n",
2026                         rate, link.link_speed);
2027                 return 1;
2028         }
2029         diag = rte_eth_set_queue_rate_limit(port_id, queue_idx, rate);
2030         if (diag == 0)
2031                 return diag;
2032         printf("rte_eth_set_queue_rate_limit for port_id=%d failed diag=%d\n",
2033                 port_id, diag);
2034         return diag;
2035 }
2036
2037 int
2038 set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
2039 {
2040         int diag;
2041         struct rte_eth_link link;
2042
2043         if (q_msk == 0)
2044                 return 0;
2045
2046         if (port_id_is_invalid(port_id))
2047                 return 1;
2048         rte_eth_link_get_nowait(port_id, &link);
2049         if (rate > link.link_speed) {
2050                 printf("Invalid rate value:%u bigger than link speed: %u\n",
2051                         rate, link.link_speed);
2052                 return 1;
2053         }
2054         diag = rte_eth_set_vf_rate_limit(port_id, vf, rate, q_msk);
2055         if (diag == 0)
2056                 return diag;
2057         printf("rte_eth_set_vf_rate_limit for port_id=%d failed diag=%d\n",
2058                 port_id, diag);
2059         return diag;
2060 }
2061
2062 void
2063 get_syn_filter(uint8_t port_id)
2064 {
2065         struct rte_syn_filter filter;
2066         int ret = 0;
2067         uint16_t rx_queue;
2068
2069         memset(&filter, 0, sizeof(filter));
2070         ret = rte_eth_dev_get_syn_filter(port_id, &filter, &rx_queue);
2071
2072         if (ret < 0) {
2073                 if (ret == (-ENOENT))
2074                         printf("syn filter is not enabled\n");
2075                 else
2076                         printf("get syn filter fails(%s)\n", strerror(-ret));
2077                 return;
2078         }
2079         printf("syn filter: priority: %s, queue: %d\n",
2080                 filter.hig_pri ? "high" : "low",
2081                 rx_queue);
2082 }
2083 void
2084 get_2tuple_filter(uint8_t port_id, uint16_t index)
2085 {
2086         struct rte_2tuple_filter filter;
2087         int ret = 0;
2088         uint16_t rx_queue;
2089
2090         memset(&filter, 0, sizeof(filter));
2091         ret = rte_eth_dev_get_2tuple_filter(port_id, index,
2092                                 &filter, &rx_queue);
2093         if (ret < 0) {
2094                 if (ret == (-ENOENT))
2095                         printf("filter[%d] is not enabled\n", index);
2096                 else
2097                         printf("get 2tuple filter fails(%s)\n", strerror(-ret));
2098                 return;
2099         } else {
2100                 printf("filter[%d]:\n", index);
2101                 printf("    Destination Port:     0x%04x    mask: %d\n",
2102                         rte_be_to_cpu_16(filter.dst_port),
2103                         filter.dst_port_mask ? 0 : 1);
2104                 printf("    protocol:  0x%02x     mask:%d     tcp_flags: 0x%02x\n",
2105                         filter.protocol, filter.protocol_mask ? 0 : 1,
2106                         filter.tcp_flags);
2107                 printf("    priority: %d    queue: %d\n",
2108                         filter.priority, rx_queue);
2109         }
2110 }
2111
2112 void
2113 get_5tuple_filter(uint8_t port_id, uint16_t index)
2114 {
2115         struct rte_5tuple_filter filter;
2116         int ret = 0;
2117         uint16_t rx_queue;
2118
2119         memset(&filter, 0, sizeof(filter));
2120         ret = rte_eth_dev_get_5tuple_filter(port_id, index,
2121                                 &filter, &rx_queue);
2122         if (ret < 0) {
2123                 if (ret == (-ENOENT))
2124                         printf("filter[%d] is not enabled\n", index);
2125                 else
2126                         printf("get 5tuple filter fails(%s)\n", strerror(-ret));
2127                 return;
2128         } else {
2129                 printf("filter[%d]:\n", index);
2130                 printf("    Destination IP:  0x%08x    mask: %d\n",
2131                         (unsigned)rte_be_to_cpu_32(filter.dst_ip),
2132                         filter.dst_ip_mask ? 0 : 1);
2133                 printf("    Source IP:       0x%08x    mask: %d\n",
2134                         (unsigned)rte_be_to_cpu_32(filter.src_ip),
2135                         filter.src_ip_mask ? 0 : 1);
2136                 printf("    Destination Port:       0x%04x    mask: %d\n",
2137                         rte_be_to_cpu_16(filter.dst_port),
2138                         filter.dst_port_mask ? 0 : 1);
2139                 printf("    Source Port:       0x%04x    mask: %d\n",
2140                         rte_be_to_cpu_16(filter.src_port),
2141                         filter.src_port_mask ? 0 : 1);
2142                 printf("    protocol:           0x%02x    mask: %d\n",
2143                         filter.protocol,
2144                         filter.protocol_mask ? 0 : 1);
2145                 printf("    priority: %d    flags: 0x%02x    queue: %d\n",
2146                         filter.priority, filter.tcp_flags, rx_queue);
2147         }
2148 }