ethdev: remove flexbytes offset from flow director
[dpdk.git] / app / test-pmd / testpmd.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
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <signal.h>
38 #include <string.h>
39 #include <time.h>
40 #include <fcntl.h>
41 #include <sys/types.h>
42 #include <errno.h>
43
44 #include <sys/queue.h>
45 #include <sys/stat.h>
46
47 #include <stdint.h>
48 #include <unistd.h>
49 #include <inttypes.h>
50
51 #include <rte_common.h>
52 #include <rte_byteorder.h>
53 #include <rte_log.h>
54 #include <rte_debug.h>
55 #include <rte_cycles.h>
56 #include <rte_memory.h>
57 #include <rte_memcpy.h>
58 #include <rte_memzone.h>
59 #include <rte_launch.h>
60 #include <rte_tailq.h>
61 #include <rte_eal.h>
62 #include <rte_per_lcore.h>
63 #include <rte_lcore.h>
64 #include <rte_atomic.h>
65 #include <rte_branch_prediction.h>
66 #include <rte_ring.h>
67 #include <rte_mempool.h>
68 #include <rte_malloc.h>
69 #include <rte_mbuf.h>
70 #include <rte_interrupts.h>
71 #include <rte_pci.h>
72 #include <rte_ether.h>
73 #include <rte_ethdev.h>
74 #include <rte_string_fns.h>
75 #ifdef RTE_LIBRTE_PMD_XENVIRT
76 #include <rte_eth_xenvirt.h>
77 #endif
78
79 #include "testpmd.h"
80 #include "mempool_osdep.h"
81
82 uint16_t verbose_level = 0; /**< Silent by default. */
83
84 /* use master core for command line ? */
85 uint8_t interactive = 0;
86 uint8_t auto_start = 0;
87
88 /*
89  * NUMA support configuration.
90  * When set, the NUMA support attempts to dispatch the allocation of the
91  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
92  * probed ports among the CPU sockets 0 and 1.
93  * Otherwise, all memory is allocated from CPU socket 0.
94  */
95 uint8_t numa_support = 0; /**< No numa support by default */
96
97 /*
98  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
99  * not configured.
100  */
101 uint8_t socket_num = UMA_NO_CONFIG;
102
103 /*
104  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
105  */
106 uint8_t mp_anon = 0;
107
108 /*
109  * Record the Ethernet address of peer target ports to which packets are
110  * forwarded.
111  * Must be instanciated with the ethernet addresses of peer traffic generator
112  * ports.
113  */
114 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
115 portid_t nb_peer_eth_addrs = 0;
116
117 /*
118  * Probed Target Environment.
119  */
120 struct rte_port *ports;        /**< For all probed ethernet ports. */
121 portid_t nb_ports;             /**< Number of probed ethernet ports. */
122 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
123 lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
124
125 /*
126  * Test Forwarding Configuration.
127  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
128  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
129  */
130 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
131 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
132 portid_t  nb_cfg_ports;  /**< Number of configured ports. */
133 portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
134
135 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
136 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
137
138 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
139 streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
140
141 /*
142  * Forwarding engines.
143  */
144 struct fwd_engine * fwd_engines[] = {
145         &io_fwd_engine,
146         &mac_fwd_engine,
147         &mac_retry_fwd_engine,
148         &mac_swap_engine,
149         &flow_gen_engine,
150         &rx_only_engine,
151         &tx_only_engine,
152         &csum_fwd_engine,
153         &icmp_echo_engine,
154 #ifdef RTE_LIBRTE_IEEE1588
155         &ieee1588_fwd_engine,
156 #endif
157         NULL,
158 };
159
160 struct fwd_config cur_fwd_config;
161 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
162
163 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
164 uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
165                                       * specified on command-line. */
166
167 /*
168  * Configuration of packet segments used by the "txonly" processing engine.
169  */
170 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
171 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
172         TXONLY_DEF_PACKET_LEN,
173 };
174 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
175
176 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
177 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
178
179 /* current configuration is in DCB or not,0 means it is not in DCB mode */
180 uint8_t dcb_config = 0;
181
182 /* Whether the dcb is in testing status */
183 uint8_t dcb_test = 0;
184
185 /* DCB on and VT on mapping is default */
186 enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING;
187
188 /*
189  * Configurable number of RX/TX queues.
190  */
191 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
192 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
193
194 /*
195  * Configurable number of RX/TX ring descriptors.
196  */
197 #define RTE_TEST_RX_DESC_DEFAULT 128
198 #define RTE_TEST_TX_DESC_DEFAULT 512
199 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
200 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
201
202 #define RTE_PMD_PARAM_UNSET -1
203 /*
204  * Configurable values of RX and TX ring threshold registers.
205  */
206
207 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
208 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
209 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
210
211 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
212 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
213 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
214
215 /*
216  * Configurable value of RX free threshold.
217  */
218 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
219
220 /*
221  * Configurable value of RX drop enable.
222  */
223 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
224
225 /*
226  * Configurable value of TX free threshold.
227  */
228 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
229
230 /*
231  * Configurable value of TX RS bit threshold.
232  */
233 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
234
235 /*
236  * Configurable value of TX queue flags.
237  */
238 int32_t txq_flags = RTE_PMD_PARAM_UNSET;
239
240 /*
241  * Receive Side Scaling (RSS) configuration.
242  */
243 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
244
245 /*
246  * Port topology configuration
247  */
248 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
249
250 /*
251  * Avoids to flush all the RX streams before starts forwarding.
252  */
253 uint8_t no_flush_rx = 0; /* flush by default */
254
255 /*
256  * Avoids to check link status when starting/stopping a port.
257  */
258 uint8_t no_link_check = 0; /* check by default */
259
260 /*
261  * NIC bypass mode configuration options.
262  */
263 #ifdef RTE_NIC_BYPASS
264
265 /* The NIC bypass watchdog timeout. */
266 uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
267
268 #endif
269
270 /*
271  * Ethernet device configuration.
272  */
273 struct rte_eth_rxmode rx_mode = {
274         .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
275         .split_hdr_size = 0,
276         .header_split   = 0, /**< Header Split disabled. */
277         .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
278         .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
279         .hw_vlan_strip  = 1, /**< VLAN strip enabled. */
280         .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
281         .jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
282         .hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
283 };
284
285 struct rte_fdir_conf fdir_conf = {
286         .mode = RTE_FDIR_MODE_NONE,
287         .pballoc = RTE_FDIR_PBALLOC_64K,
288         .status = RTE_FDIR_REPORT_STATUS,
289         .drop_queue = 127,
290 };
291
292 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
293
294 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
295 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
296
297 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
298 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
299
300 uint16_t nb_tx_queue_stats_mappings = 0;
301 uint16_t nb_rx_queue_stats_mappings = 0;
302
303 /* Forward function declarations */
304 static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
305 static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask);
306
307 /*
308  * Check if all the ports are started.
309  * If yes, return positive value. If not, return zero.
310  */
311 static int all_ports_started(void);
312
313 /*
314  * Setup default configuration.
315  */
316 static void
317 set_default_fwd_lcores_config(void)
318 {
319         unsigned int i;
320         unsigned int nb_lc;
321
322         nb_lc = 0;
323         for (i = 0; i < RTE_MAX_LCORE; i++) {
324                 if (! rte_lcore_is_enabled(i))
325                         continue;
326                 if (i == rte_get_master_lcore())
327                         continue;
328                 fwd_lcores_cpuids[nb_lc++] = i;
329         }
330         nb_lcores = (lcoreid_t) nb_lc;
331         nb_cfg_lcores = nb_lcores;
332         nb_fwd_lcores = 1;
333 }
334
335 static void
336 set_def_peer_eth_addrs(void)
337 {
338         portid_t i;
339
340         for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
341                 peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
342                 peer_eth_addrs[i].addr_bytes[5] = i;
343         }
344 }
345
346 static void
347 set_default_fwd_ports_config(void)
348 {
349         portid_t pt_id;
350
351         for (pt_id = 0; pt_id < nb_ports; pt_id++)
352                 fwd_ports_ids[pt_id] = pt_id;
353
354         nb_cfg_ports = nb_ports;
355         nb_fwd_ports = nb_ports;
356 }
357
358 void
359 set_def_fwd_config(void)
360 {
361         set_default_fwd_lcores_config();
362         set_def_peer_eth_addrs();
363         set_default_fwd_ports_config();
364 }
365
366 /*
367  * Configuration initialisation done once at init time.
368  */
369 struct mbuf_ctor_arg {
370         uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */
371         uint16_t seg_buf_size;   /**< size of data segment in mbuf. */
372 };
373
374 struct mbuf_pool_ctor_arg {
375         uint16_t seg_buf_size; /**< size of data segment in mbuf. */
376 };
377
378 static void
379 testpmd_mbuf_ctor(struct rte_mempool *mp,
380                   void *opaque_arg,
381                   void *raw_mbuf,
382                   __attribute__((unused)) unsigned i)
383 {
384         struct mbuf_ctor_arg *mb_ctor_arg;
385         struct rte_mbuf    *mb;
386
387         mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg;
388         mb = (struct rte_mbuf *) raw_mbuf;
389
390         mb->pool         = mp;
391         mb->buf_addr     = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset);
392         mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) +
393                         mb_ctor_arg->seg_buf_offset);
394         mb->buf_len      = mb_ctor_arg->seg_buf_size;
395         mb->ol_flags     = 0;
396         mb->data_off     = RTE_PKTMBUF_HEADROOM;
397         mb->nb_segs      = 1;
398         mb->tx_offload   = 0;
399         mb->vlan_tci     = 0;
400         mb->hash.rss     = 0;
401 }
402
403 static void
404 testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
405                        void *opaque_arg)
406 {
407         struct mbuf_pool_ctor_arg      *mbp_ctor_arg;
408         struct rte_pktmbuf_pool_private *mbp_priv;
409
410         if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
411                 printf("%s(%s) private_data_size %d < %d\n",
412                        __func__, mp->name, (int) mp->private_data_size,
413                        (int) sizeof(struct rte_pktmbuf_pool_private));
414                 return;
415         }
416         mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
417         mbp_priv = rte_mempool_get_priv(mp);
418         mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
419 }
420
421 static void
422 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
423                  unsigned int socket_id)
424 {
425         char pool_name[RTE_MEMPOOL_NAMESIZE];
426         struct rte_mempool *rte_mp;
427         struct mbuf_pool_ctor_arg mbp_ctor_arg;
428         struct mbuf_ctor_arg mb_ctor_arg;
429         uint32_t mb_size;
430
431         mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM +
432                                                 mbuf_seg_size);
433         mb_ctor_arg.seg_buf_offset =
434                 (uint16_t) RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf));
435         mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
436         mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
437         mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
438
439 #ifdef RTE_LIBRTE_PMD_XENVIRT
440         rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
441                                    (unsigned) mb_mempool_cache,
442                                    sizeof(struct rte_pktmbuf_pool_private),
443                                    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
444                                    testpmd_mbuf_ctor, &mb_ctor_arg,
445                                    socket_id, 0);
446
447
448
449 #else
450         if (mp_anon != 0)
451                 rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
452                                     (unsigned) mb_mempool_cache,
453                                     sizeof(struct rte_pktmbuf_pool_private),
454                                     testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
455                                     testpmd_mbuf_ctor, &mb_ctor_arg,
456                                     socket_id, 0);
457         else
458                 rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
459                                     (unsigned) mb_mempool_cache,
460                                     sizeof(struct rte_pktmbuf_pool_private),
461                                     testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
462                                     testpmd_mbuf_ctor, &mb_ctor_arg,
463                                     socket_id, 0);
464
465 #endif
466
467         if (rte_mp == NULL) {
468                 rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u "
469                                                 "failed\n", socket_id);
470         } else if (verbose_level > 0) {
471                 rte_mempool_dump(stdout, rte_mp);
472         }
473 }
474
475 /*
476  * Check given socket id is valid or not with NUMA mode,
477  * if valid, return 0, else return -1
478  */
479 static int
480 check_socket_id(const unsigned int socket_id)
481 {
482         static int warning_once = 0;
483
484         if (socket_id >= MAX_SOCKET) {
485                 if (!warning_once && numa_support)
486                         printf("Warning: NUMA should be configured manually by"
487                                " using --port-numa-config and"
488                                " --ring-numa-config parameters along with"
489                                " --numa.\n");
490                 warning_once = 1;
491                 return -1;
492         }
493         return 0;
494 }
495
496 static void
497 init_config(void)
498 {
499         portid_t pid;
500         struct rte_port *port;
501         struct rte_mempool *mbp;
502         unsigned int nb_mbuf_per_pool;
503         lcoreid_t  lc_id;
504         uint8_t port_per_socket[MAX_SOCKET];
505
506         memset(port_per_socket,0,MAX_SOCKET);
507         /* Configuration of logical cores. */
508         fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
509                                 sizeof(struct fwd_lcore *) * nb_lcores,
510                                 RTE_CACHE_LINE_SIZE);
511         if (fwd_lcores == NULL) {
512                 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
513                                                         "failed\n", nb_lcores);
514         }
515         for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
516                 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
517                                                sizeof(struct fwd_lcore),
518                                                RTE_CACHE_LINE_SIZE);
519                 if (fwd_lcores[lc_id] == NULL) {
520                         rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
521                                                                 "failed\n");
522                 }
523                 fwd_lcores[lc_id]->cpuid_idx = lc_id;
524         }
525
526         /*
527          * Create pools of mbuf.
528          * If NUMA support is disabled, create a single pool of mbuf in
529          * socket 0 memory by default.
530          * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
531          *
532          * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
533          * nb_txd can be configured at run time.
534          */
535         if (param_total_num_mbufs)
536                 nb_mbuf_per_pool = param_total_num_mbufs;
537         else {
538                 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
539                                 + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
540
541                 if (!numa_support)
542                         nb_mbuf_per_pool = (nb_mbuf_per_pool * nb_ports);
543         }
544
545         if (!numa_support) {
546                 if (socket_num == UMA_NO_CONFIG)
547                         mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
548                 else
549                         mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
550                                                  socket_num);
551         }
552
553         /* Configuration of Ethernet ports. */
554         ports = rte_zmalloc("testpmd: ports",
555                             sizeof(struct rte_port) * nb_ports,
556                             RTE_CACHE_LINE_SIZE);
557         if (ports == NULL) {
558                 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d struct rte_port) "
559                                                         "failed\n", nb_ports);
560         }
561
562         for (pid = 0; pid < nb_ports; pid++) {
563                 port = &ports[pid];
564                 rte_eth_dev_info_get(pid, &port->dev_info);
565
566                 if (numa_support) {
567                         if (port_numa[pid] != NUMA_NO_CONFIG)
568                                 port_per_socket[port_numa[pid]]++;
569                         else {
570                                 uint32_t socket_id = rte_eth_dev_socket_id(pid);
571
572                                 /* if socket_id is invalid, set to 0 */
573                                 if (check_socket_id(socket_id) < 0)
574                                         socket_id = 0;
575                                 port_per_socket[socket_id]++;
576                         }
577                 }
578
579                 /* set flag to initialize port/queue */
580                 port->need_reconfig = 1;
581                 port->need_reconfig_queues = 1;
582         }
583
584         if (numa_support) {
585                 uint8_t i;
586                 unsigned int nb_mbuf;
587
588                 if (param_total_num_mbufs)
589                         nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
590
591                 for (i = 0; i < MAX_SOCKET; i++) {
592                         nb_mbuf = (nb_mbuf_per_pool *
593                                                 port_per_socket[i]);
594                         if (nb_mbuf)
595                                 mbuf_pool_create(mbuf_data_size,
596                                                 nb_mbuf,i);
597                 }
598         }
599         init_port_config();
600
601         /*
602          * Records which Mbuf pool to use by each logical core, if needed.
603          */
604         for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
605                 mbp = mbuf_pool_find(
606                         rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
607
608                 if (mbp == NULL)
609                         mbp = mbuf_pool_find(0);
610                 fwd_lcores[lc_id]->mbp = mbp;
611         }
612
613         /* Configuration of packet forwarding streams. */
614         if (init_fwd_streams() < 0)
615                 rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
616 }
617
618
619 void
620 reconfig(portid_t new_port_id, unsigned socket_id)
621 {
622         struct rte_port *port;
623
624         /* Reconfiguration of Ethernet ports. */
625         ports = rte_realloc(ports,
626                             sizeof(struct rte_port) * nb_ports,
627                             RTE_CACHE_LINE_SIZE);
628         if (ports == NULL) {
629                 rte_exit(EXIT_FAILURE, "rte_realloc(%d struct rte_port) failed\n",
630                                 nb_ports);
631         }
632
633         port = &ports[new_port_id];
634         rte_eth_dev_info_get(new_port_id, &port->dev_info);
635
636         /* set flag to initialize port/queue */
637         port->need_reconfig = 1;
638         port->need_reconfig_queues = 1;
639         port->socket_id = socket_id;
640
641         init_port_config();
642 }
643
644
645 int
646 init_fwd_streams(void)
647 {
648         portid_t pid;
649         struct rte_port *port;
650         streamid_t sm_id, nb_fwd_streams_new;
651
652         /* set socket id according to numa or not */
653         for (pid = 0; pid < nb_ports; pid++) {
654                 port = &ports[pid];
655                 if (nb_rxq > port->dev_info.max_rx_queues) {
656                         printf("Fail: nb_rxq(%d) is greater than "
657                                 "max_rx_queues(%d)\n", nb_rxq,
658                                 port->dev_info.max_rx_queues);
659                         return -1;
660                 }
661                 if (nb_txq > port->dev_info.max_tx_queues) {
662                         printf("Fail: nb_txq(%d) is greater than "
663                                 "max_tx_queues(%d)\n", nb_txq,
664                                 port->dev_info.max_tx_queues);
665                         return -1;
666                 }
667                 if (numa_support) {
668                         if (port_numa[pid] != NUMA_NO_CONFIG)
669                                 port->socket_id = port_numa[pid];
670                         else {
671                                 port->socket_id = rte_eth_dev_socket_id(pid);
672
673                                 /* if socket_id is invalid, set to 0 */
674                                 if (check_socket_id(port->socket_id) < 0)
675                                         port->socket_id = 0;
676                         }
677                 }
678                 else {
679                         if (socket_num == UMA_NO_CONFIG)
680                                 port->socket_id = 0;
681                         else
682                                 port->socket_id = socket_num;
683                 }
684         }
685
686         nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq);
687         if (nb_fwd_streams_new == nb_fwd_streams)
688                 return 0;
689         /* clear the old */
690         if (fwd_streams != NULL) {
691                 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
692                         if (fwd_streams[sm_id] == NULL)
693                                 continue;
694                         rte_free(fwd_streams[sm_id]);
695                         fwd_streams[sm_id] = NULL;
696                 }
697                 rte_free(fwd_streams);
698                 fwd_streams = NULL;
699         }
700
701         /* init new */
702         nb_fwd_streams = nb_fwd_streams_new;
703         fwd_streams = rte_zmalloc("testpmd: fwd_streams",
704                 sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
705         if (fwd_streams == NULL)
706                 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
707                                                 "failed\n", nb_fwd_streams);
708
709         for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
710                 fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
711                                 sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
712                 if (fwd_streams[sm_id] == NULL)
713                         rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
714                                                                 " failed\n");
715         }
716
717         return 0;
718 }
719
720 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
721 static void
722 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
723 {
724         unsigned int total_burst;
725         unsigned int nb_burst;
726         unsigned int burst_stats[3];
727         uint16_t pktnb_stats[3];
728         uint16_t nb_pkt;
729         int burst_percent[3];
730
731         /*
732          * First compute the total number of packet bursts and the
733          * two highest numbers of bursts of the same number of packets.
734          */
735         total_burst = 0;
736         burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
737         pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
738         for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
739                 nb_burst = pbs->pkt_burst_spread[nb_pkt];
740                 if (nb_burst == 0)
741                         continue;
742                 total_burst += nb_burst;
743                 if (nb_burst > burst_stats[0]) {
744                         burst_stats[1] = burst_stats[0];
745                         pktnb_stats[1] = pktnb_stats[0];
746                         burst_stats[0] = nb_burst;
747                         pktnb_stats[0] = nb_pkt;
748                 }
749         }
750         if (total_burst == 0)
751                 return;
752         burst_percent[0] = (burst_stats[0] * 100) / total_burst;
753         printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
754                burst_percent[0], (int) pktnb_stats[0]);
755         if (burst_stats[0] == total_burst) {
756                 printf("]\n");
757                 return;
758         }
759         if (burst_stats[0] + burst_stats[1] == total_burst) {
760                 printf(" + %d%% of %d pkts]\n",
761                        100 - burst_percent[0], pktnb_stats[1]);
762                 return;
763         }
764         burst_percent[1] = (burst_stats[1] * 100) / total_burst;
765         burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
766         if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
767                 printf(" + %d%% of others]\n", 100 - burst_percent[0]);
768                 return;
769         }
770         printf(" + %d%% of %d pkts + %d%% of others]\n",
771                burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
772 }
773 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
774
775 static void
776 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
777 {
778         struct rte_port *port;
779         uint8_t i;
780
781         static const char *fwd_stats_border = "----------------------";
782
783         port = &ports[port_id];
784         printf("\n  %s Forward statistics for port %-2d %s\n",
785                fwd_stats_border, port_id, fwd_stats_border);
786
787         if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
788                 printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
789                        "%-"PRIu64"\n",
790                        stats->ipackets, stats->imissed,
791                        (uint64_t) (stats->ipackets + stats->imissed));
792
793                 if (cur_fwd_eng == &csum_fwd_engine)
794                         printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
795                                port->rx_bad_ip_csum, port->rx_bad_l4_csum);
796                 if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
797                         printf("  RX-badcrc:  %-14"PRIu64" RX-badlen:  %-14"PRIu64
798                                "RX-error: %-"PRIu64"\n",
799                                stats->ibadcrc, stats->ibadlen, stats->ierrors);
800                         printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
801                 }
802
803                 printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
804                        "%-"PRIu64"\n",
805                        stats->opackets, port->tx_dropped,
806                        (uint64_t) (stats->opackets + port->tx_dropped));
807         }
808         else {
809                 printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
810                        "%14"PRIu64"\n",
811                        stats->ipackets, stats->imissed,
812                        (uint64_t) (stats->ipackets + stats->imissed));
813
814                 if (cur_fwd_eng == &csum_fwd_engine)
815                         printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
816                                port->rx_bad_ip_csum, port->rx_bad_l4_csum);
817                 if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
818                         printf("  RX-badcrc:              %14"PRIu64"    RX-badlen: %14"PRIu64
819                                "    RX-error:%"PRIu64"\n",
820                                stats->ibadcrc, stats->ibadlen, stats->ierrors);
821                         printf("  RX-nombufs:             %14"PRIu64"\n",
822                                stats->rx_nombuf);
823                 }
824
825                 printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
826                        "%14"PRIu64"\n",
827                        stats->opackets, port->tx_dropped,
828                        (uint64_t) (stats->opackets + port->tx_dropped));
829         }
830
831         /* Display statistics of XON/XOFF pause frames, if any. */
832         if ((stats->tx_pause_xon  | stats->rx_pause_xon |
833              stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
834                 printf("  RX-XOFF:    %-14"PRIu64" RX-XON:     %-14"PRIu64"\n",
835                        stats->rx_pause_xoff, stats->rx_pause_xon);
836                 printf("  TX-XOFF:    %-14"PRIu64" TX-XON:     %-14"PRIu64"\n",
837                        stats->tx_pause_xoff, stats->tx_pause_xon);
838         }
839
840 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
841         if (port->rx_stream)
842                 pkt_burst_stats_display("RX",
843                         &port->rx_stream->rx_burst_stats);
844         if (port->tx_stream)
845                 pkt_burst_stats_display("TX",
846                         &port->tx_stream->tx_burst_stats);
847 #endif
848         /* stats fdir */
849         if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
850                 printf("  Fdirmiss:%14"PRIu64"    Fdirmatch:%14"PRIu64"\n",
851                        stats->fdirmiss,
852                        stats->fdirmatch);
853
854         if (port->rx_queue_stats_mapping_enabled) {
855                 printf("\n");
856                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
857                         printf("  Stats reg %2d RX-packets:%14"PRIu64
858                                "     RX-errors:%14"PRIu64
859                                "    RX-bytes:%14"PRIu64"\n",
860                                i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
861                 }
862                 printf("\n");
863         }
864         if (port->tx_queue_stats_mapping_enabled) {
865                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
866                         printf("  Stats reg %2d TX-packets:%14"PRIu64
867                                "                                 TX-bytes:%14"PRIu64"\n",
868                                i, stats->q_opackets[i], stats->q_obytes[i]);
869                 }
870         }
871
872         printf("  %s--------------------------------%s\n",
873                fwd_stats_border, fwd_stats_border);
874 }
875
876 static void
877 fwd_stream_stats_display(streamid_t stream_id)
878 {
879         struct fwd_stream *fs;
880         static const char *fwd_top_stats_border = "-------";
881
882         fs = fwd_streams[stream_id];
883         if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
884             (fs->fwd_dropped == 0))
885                 return;
886         printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
887                "TX Port=%2d/Queue=%2d %s\n",
888                fwd_top_stats_border, fs->rx_port, fs->rx_queue,
889                fs->tx_port, fs->tx_queue, fwd_top_stats_border);
890         printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
891                fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
892
893         /* if checksum mode */
894         if (cur_fwd_eng == &csum_fwd_engine) {
895                printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
896                         "%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
897         }
898
899 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
900         pkt_burst_stats_display("RX", &fs->rx_burst_stats);
901         pkt_burst_stats_display("TX", &fs->tx_burst_stats);
902 #endif
903 }
904
905 static void
906 flush_fwd_rx_queues(void)
907 {
908         struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
909         portid_t  rxp;
910         portid_t port_id;
911         queueid_t rxq;
912         uint16_t  nb_rx;
913         uint16_t  i;
914         uint8_t   j;
915
916         for (j = 0; j < 2; j++) {
917                 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
918                         for (rxq = 0; rxq < nb_rxq; rxq++) {
919                                 port_id = fwd_ports_ids[rxp];
920                                 do {
921                                         nb_rx = rte_eth_rx_burst(port_id, rxq,
922                                                 pkts_burst, MAX_PKT_BURST);
923                                         for (i = 0; i < nb_rx; i++)
924                                                 rte_pktmbuf_free(pkts_burst[i]);
925                                 } while (nb_rx > 0);
926                         }
927                 }
928                 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
929         }
930 }
931
932 static void
933 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
934 {
935         struct fwd_stream **fsm;
936         streamid_t nb_fs;
937         streamid_t sm_id;
938
939         fsm = &fwd_streams[fc->stream_idx];
940         nb_fs = fc->stream_nb;
941         do {
942                 for (sm_id = 0; sm_id < nb_fs; sm_id++)
943                         (*pkt_fwd)(fsm[sm_id]);
944         } while (! fc->stopped);
945 }
946
947 static int
948 start_pkt_forward_on_core(void *fwd_arg)
949 {
950         run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
951                              cur_fwd_config.fwd_eng->packet_fwd);
952         return 0;
953 }
954
955 /*
956  * Run the TXONLY packet forwarding engine to send a single burst of packets.
957  * Used to start communication flows in network loopback test configurations.
958  */
959 static int
960 run_one_txonly_burst_on_core(void *fwd_arg)
961 {
962         struct fwd_lcore *fwd_lc;
963         struct fwd_lcore tmp_lcore;
964
965         fwd_lc = (struct fwd_lcore *) fwd_arg;
966         tmp_lcore = *fwd_lc;
967         tmp_lcore.stopped = 1;
968         run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
969         return 0;
970 }
971
972 /*
973  * Launch packet forwarding:
974  *     - Setup per-port forwarding context.
975  *     - launch logical cores with their forwarding configuration.
976  */
977 static void
978 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
979 {
980         port_fwd_begin_t port_fwd_begin;
981         unsigned int i;
982         unsigned int lc_id;
983         int diag;
984
985         port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
986         if (port_fwd_begin != NULL) {
987                 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
988                         (*port_fwd_begin)(fwd_ports_ids[i]);
989         }
990         for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
991                 lc_id = fwd_lcores_cpuids[i];
992                 if ((interactive == 0) || (lc_id != rte_lcore_id())) {
993                         fwd_lcores[i]->stopped = 0;
994                         diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
995                                                      fwd_lcores[i], lc_id);
996                         if (diag != 0)
997                                 printf("launch lcore %u failed - diag=%d\n",
998                                        lc_id, diag);
999                 }
1000         }
1001 }
1002
1003 /*
1004  * Launch packet forwarding configuration.
1005  */
1006 void
1007 start_packet_forwarding(int with_tx_first)
1008 {
1009         port_fwd_begin_t port_fwd_begin;
1010         port_fwd_end_t  port_fwd_end;
1011         struct rte_port *port;
1012         unsigned int i;
1013         portid_t   pt_id;
1014         streamid_t sm_id;
1015
1016         if (all_ports_started() == 0) {
1017                 printf("Not all ports were started\n");
1018                 return;
1019         }
1020         if (test_done == 0) {
1021                 printf("Packet forwarding already started\n");
1022                 return;
1023         }
1024         if(dcb_test) {
1025                 for (i = 0; i < nb_fwd_ports; i++) {
1026                         pt_id = fwd_ports_ids[i];
1027                         port = &ports[pt_id];
1028                         if (!port->dcb_flag) {
1029                                 printf("In DCB mode, all forwarding ports must "
1030                                        "be configured in this mode.\n");
1031                                 return;
1032                         }
1033                 }
1034                 if (nb_fwd_lcores == 1) {
1035                         printf("In DCB mode,the nb forwarding cores "
1036                                "should be larger than 1.\n");
1037                         return;
1038                 }
1039         }
1040         test_done = 0;
1041
1042         if(!no_flush_rx)
1043                 flush_fwd_rx_queues();
1044
1045         fwd_config_setup();
1046         rxtx_config_display();
1047
1048         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1049                 pt_id = fwd_ports_ids[i];
1050                 port = &ports[pt_id];
1051                 rte_eth_stats_get(pt_id, &port->stats);
1052                 port->tx_dropped = 0;
1053
1054                 map_port_queue_stats_mapping_registers(pt_id, port);
1055         }
1056         for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1057                 fwd_streams[sm_id]->rx_packets = 0;
1058                 fwd_streams[sm_id]->tx_packets = 0;
1059                 fwd_streams[sm_id]->fwd_dropped = 0;
1060                 fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1061                 fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1062
1063 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1064                 memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1065                        sizeof(fwd_streams[sm_id]->rx_burst_stats));
1066                 memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1067                        sizeof(fwd_streams[sm_id]->tx_burst_stats));
1068 #endif
1069 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1070                 fwd_streams[sm_id]->core_cycles = 0;
1071 #endif
1072         }
1073         if (with_tx_first) {
1074                 port_fwd_begin = tx_only_engine.port_fwd_begin;
1075                 if (port_fwd_begin != NULL) {
1076                         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1077                                 (*port_fwd_begin)(fwd_ports_ids[i]);
1078                 }
1079                 launch_packet_forwarding(run_one_txonly_burst_on_core);
1080                 rte_eal_mp_wait_lcore();
1081                 port_fwd_end = tx_only_engine.port_fwd_end;
1082                 if (port_fwd_end != NULL) {
1083                         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1084                                 (*port_fwd_end)(fwd_ports_ids[i]);
1085                 }
1086         }
1087         launch_packet_forwarding(start_pkt_forward_on_core);
1088 }
1089
1090 void
1091 stop_packet_forwarding(void)
1092 {
1093         struct rte_eth_stats stats;
1094         struct rte_port *port;
1095         port_fwd_end_t  port_fwd_end;
1096         int i;
1097         portid_t   pt_id;
1098         streamid_t sm_id;
1099         lcoreid_t  lc_id;
1100         uint64_t total_recv;
1101         uint64_t total_xmit;
1102         uint64_t total_rx_dropped;
1103         uint64_t total_tx_dropped;
1104         uint64_t total_rx_nombuf;
1105         uint64_t tx_dropped;
1106         uint64_t rx_bad_ip_csum;
1107         uint64_t rx_bad_l4_csum;
1108 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1109         uint64_t fwd_cycles;
1110 #endif
1111         static const char *acc_stats_border = "+++++++++++++++";
1112
1113         if (all_ports_started() == 0) {
1114                 printf("Not all ports were started\n");
1115                 return;
1116         }
1117         if (test_done) {
1118                 printf("Packet forwarding not started\n");
1119                 return;
1120         }
1121         printf("Telling cores to stop...");
1122         for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1123                 fwd_lcores[lc_id]->stopped = 1;
1124         printf("\nWaiting for lcores to finish...\n");
1125         rte_eal_mp_wait_lcore();
1126         port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1127         if (port_fwd_end != NULL) {
1128                 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1129                         pt_id = fwd_ports_ids[i];
1130                         (*port_fwd_end)(pt_id);
1131                 }
1132         }
1133 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1134         fwd_cycles = 0;
1135 #endif
1136         for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1137                 if (cur_fwd_config.nb_fwd_streams >
1138                     cur_fwd_config.nb_fwd_ports) {
1139                         fwd_stream_stats_display(sm_id);
1140                         ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1141                         ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1142                 } else {
1143                         ports[fwd_streams[sm_id]->tx_port].tx_stream =
1144                                 fwd_streams[sm_id];
1145                         ports[fwd_streams[sm_id]->rx_port].rx_stream =
1146                                 fwd_streams[sm_id];
1147                 }
1148                 tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1149                 tx_dropped = (uint64_t) (tx_dropped +
1150                                          fwd_streams[sm_id]->fwd_dropped);
1151                 ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1152
1153                 rx_bad_ip_csum =
1154                         ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1155                 rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1156                                          fwd_streams[sm_id]->rx_bad_ip_csum);
1157                 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1158                                                         rx_bad_ip_csum;
1159
1160                 rx_bad_l4_csum =
1161                         ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1162                 rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1163                                          fwd_streams[sm_id]->rx_bad_l4_csum);
1164                 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1165                                                         rx_bad_l4_csum;
1166
1167 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1168                 fwd_cycles = (uint64_t) (fwd_cycles +
1169                                          fwd_streams[sm_id]->core_cycles);
1170 #endif
1171         }
1172         total_recv = 0;
1173         total_xmit = 0;
1174         total_rx_dropped = 0;
1175         total_tx_dropped = 0;
1176         total_rx_nombuf  = 0;
1177         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1178                 pt_id = fwd_ports_ids[i];
1179
1180                 port = &ports[pt_id];
1181                 rte_eth_stats_get(pt_id, &stats);
1182                 stats.ipackets -= port->stats.ipackets;
1183                 port->stats.ipackets = 0;
1184                 stats.opackets -= port->stats.opackets;
1185                 port->stats.opackets = 0;
1186                 stats.ibytes   -= port->stats.ibytes;
1187                 port->stats.ibytes = 0;
1188                 stats.obytes   -= port->stats.obytes;
1189                 port->stats.obytes = 0;
1190                 stats.imissed  -= port->stats.imissed;
1191                 port->stats.imissed = 0;
1192                 stats.oerrors  -= port->stats.oerrors;
1193                 port->stats.oerrors = 0;
1194                 stats.rx_nombuf -= port->stats.rx_nombuf;
1195                 port->stats.rx_nombuf = 0;
1196                 stats.fdirmatch -= port->stats.fdirmatch;
1197                 port->stats.rx_nombuf = 0;
1198                 stats.fdirmiss -= port->stats.fdirmiss;
1199                 port->stats.rx_nombuf = 0;
1200
1201                 total_recv += stats.ipackets;
1202                 total_xmit += stats.opackets;
1203                 total_rx_dropped += stats.imissed;
1204                 total_tx_dropped += port->tx_dropped;
1205                 total_rx_nombuf  += stats.rx_nombuf;
1206
1207                 fwd_port_stats_display(pt_id, &stats);
1208         }
1209         printf("\n  %s Accumulated forward statistics for all ports"
1210                "%s\n",
1211                acc_stats_border, acc_stats_border);
1212         printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1213                "%-"PRIu64"\n"
1214                "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1215                "%-"PRIu64"\n",
1216                total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1217                total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1218         if (total_rx_nombuf > 0)
1219                 printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1220         printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1221                "%s\n",
1222                acc_stats_border, acc_stats_border);
1223 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1224         if (total_recv > 0)
1225                 printf("\n  CPU cycles/packet=%u (total cycles="
1226                        "%"PRIu64" / total RX packets=%"PRIu64")\n",
1227                        (unsigned int)(fwd_cycles / total_recv),
1228                        fwd_cycles, total_recv);
1229 #endif
1230         printf("\nDone.\n");
1231         test_done = 1;
1232 }
1233
1234 void
1235 dev_set_link_up(portid_t pid)
1236 {
1237         if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1238                 printf("\nSet link up fail.\n");
1239 }
1240
1241 void
1242 dev_set_link_down(portid_t pid)
1243 {
1244         if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1245                 printf("\nSet link down fail.\n");
1246 }
1247
1248 static int
1249 all_ports_started(void)
1250 {
1251         portid_t pi;
1252         struct rte_port *port;
1253
1254         for (pi = 0; pi < nb_ports; pi++) {
1255                 port = &ports[pi];
1256                 /* Check if there is a port which is not started */
1257                 if (port->port_status != RTE_PORT_STARTED)
1258                         return 0;
1259         }
1260
1261         /* No port is not started */
1262         return 1;
1263 }
1264
1265 int
1266 start_port(portid_t pid)
1267 {
1268         int diag, need_check_link_status = 0;
1269         portid_t pi;
1270         queueid_t qi;
1271         struct rte_port *port;
1272         struct ether_addr mac_addr;
1273
1274         if (test_done == 0) {
1275                 printf("Please stop forwarding first\n");
1276                 return -1;
1277         }
1278
1279         if (init_fwd_streams() < 0) {
1280                 printf("Fail from init_fwd_streams()\n");
1281                 return -1;
1282         }
1283
1284         if(dcb_config)
1285                 dcb_test = 1;
1286         for (pi = 0; pi < nb_ports; pi++) {
1287                 if (pid < nb_ports && pid != pi)
1288                         continue;
1289
1290                 port = &ports[pi];
1291                 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1292                                                  RTE_PORT_HANDLING) == 0) {
1293                         printf("Port %d is now not stopped\n", pi);
1294                         continue;
1295                 }
1296
1297                 if (port->need_reconfig > 0) {
1298                         port->need_reconfig = 0;
1299
1300                         printf("Configuring Port %d (socket %u)\n", pi,
1301                                         port->socket_id);
1302                         /* configure port */
1303                         diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1304                                                 &(port->dev_conf));
1305                         if (diag != 0) {
1306                                 if (rte_atomic16_cmpset(&(port->port_status),
1307                                 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1308                                         printf("Port %d can not be set back "
1309                                                         "to stopped\n", pi);
1310                                 printf("Fail to configure port %d\n", pi);
1311                                 /* try to reconfigure port next time */
1312                                 port->need_reconfig = 1;
1313                                 return -1;
1314                         }
1315                 }
1316                 if (port->need_reconfig_queues > 0) {
1317                         port->need_reconfig_queues = 0;
1318                         /* setup tx queues */
1319                         for (qi = 0; qi < nb_txq; qi++) {
1320                                 if ((numa_support) &&
1321                                         (txring_numa[pi] != NUMA_NO_CONFIG))
1322                                         diag = rte_eth_tx_queue_setup(pi, qi,
1323                                                 nb_txd,txring_numa[pi],
1324                                                 &(port->tx_conf));
1325                                 else
1326                                         diag = rte_eth_tx_queue_setup(pi, qi,
1327                                                 nb_txd,port->socket_id,
1328                                                 &(port->tx_conf));
1329
1330                                 if (diag == 0)
1331                                         continue;
1332
1333                                 /* Fail to setup tx queue, return */
1334                                 if (rte_atomic16_cmpset(&(port->port_status),
1335                                                         RTE_PORT_HANDLING,
1336                                                         RTE_PORT_STOPPED) == 0)
1337                                         printf("Port %d can not be set back "
1338                                                         "to stopped\n", pi);
1339                                 printf("Fail to configure port %d tx queues\n", pi);
1340                                 /* try to reconfigure queues next time */
1341                                 port->need_reconfig_queues = 1;
1342                                 return -1;
1343                         }
1344                         /* setup rx queues */
1345                         for (qi = 0; qi < nb_rxq; qi++) {
1346                                 if ((numa_support) &&
1347                                         (rxring_numa[pi] != NUMA_NO_CONFIG)) {
1348                                         struct rte_mempool * mp =
1349                                                 mbuf_pool_find(rxring_numa[pi]);
1350                                         if (mp == NULL) {
1351                                                 printf("Failed to setup RX queue:"
1352                                                         "No mempool allocation"
1353                                                         "on the socket %d\n",
1354                                                         rxring_numa[pi]);
1355                                                 return -1;
1356                                         }
1357
1358                                         diag = rte_eth_rx_queue_setup(pi, qi,
1359                                              nb_rxd,rxring_numa[pi],
1360                                              &(port->rx_conf),mp);
1361                                 }
1362                                 else
1363                                         diag = rte_eth_rx_queue_setup(pi, qi,
1364                                              nb_rxd,port->socket_id,
1365                                              &(port->rx_conf),
1366                                              mbuf_pool_find(port->socket_id));
1367
1368                                 if (diag == 0)
1369                                         continue;
1370
1371
1372                                 /* Fail to setup rx queue, return */
1373                                 if (rte_atomic16_cmpset(&(port->port_status),
1374                                                         RTE_PORT_HANDLING,
1375                                                         RTE_PORT_STOPPED) == 0)
1376                                         printf("Port %d can not be set back "
1377                                                         "to stopped\n", pi);
1378                                 printf("Fail to configure port %d rx queues\n", pi);
1379                                 /* try to reconfigure queues next time */
1380                                 port->need_reconfig_queues = 1;
1381                                 return -1;
1382                         }
1383                 }
1384                 /* start port */
1385                 if (rte_eth_dev_start(pi) < 0) {
1386                         printf("Fail to start port %d\n", pi);
1387
1388                         /* Fail to setup rx queue, return */
1389                         if (rte_atomic16_cmpset(&(port->port_status),
1390                                 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1391                                 printf("Port %d can not be set back to "
1392                                                         "stopped\n", pi);
1393                         continue;
1394                 }
1395
1396                 if (rte_atomic16_cmpset(&(port->port_status),
1397                         RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1398                         printf("Port %d can not be set into started\n", pi);
1399
1400                 rte_eth_macaddr_get(pi, &mac_addr);
1401                 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1402                                 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
1403                                 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
1404                                 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1405
1406                 /* at least one port started, need checking link status */
1407                 need_check_link_status = 1;
1408         }
1409
1410         if (need_check_link_status && !no_link_check)
1411                 check_all_ports_link_status(nb_ports, RTE_PORT_ALL);
1412         else
1413                 printf("Please stop the ports first\n");
1414
1415         printf("Done\n");
1416         return 0;
1417 }
1418
1419 void
1420 stop_port(portid_t pid)
1421 {
1422         portid_t pi;
1423         struct rte_port *port;
1424         int need_check_link_status = 0;
1425
1426         if (test_done == 0) {
1427                 printf("Please stop forwarding first\n");
1428                 return;
1429         }
1430         if (dcb_test) {
1431                 dcb_test = 0;
1432                 dcb_config = 0;
1433         }
1434         printf("Stopping ports...\n");
1435
1436         for (pi = 0; pi < nb_ports; pi++) {
1437                 if (pid < nb_ports && pid != pi)
1438                         continue;
1439
1440                 port = &ports[pi];
1441                 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1442                                                 RTE_PORT_HANDLING) == 0)
1443                         continue;
1444
1445                 rte_eth_dev_stop(pi);
1446
1447                 if (rte_atomic16_cmpset(&(port->port_status),
1448                         RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1449                         printf("Port %d can not be set into stopped\n", pi);
1450                 need_check_link_status = 1;
1451         }
1452         if (need_check_link_status && !no_link_check)
1453                 check_all_ports_link_status(nb_ports, RTE_PORT_ALL);
1454
1455         printf("Done\n");
1456 }
1457
1458 void
1459 close_port(portid_t pid)
1460 {
1461         portid_t pi;
1462         struct rte_port *port;
1463
1464         if (test_done == 0) {
1465                 printf("Please stop forwarding first\n");
1466                 return;
1467         }
1468
1469         printf("Closing ports...\n");
1470
1471         for (pi = 0; pi < nb_ports; pi++) {
1472                 if (pid < nb_ports && pid != pi)
1473                         continue;
1474
1475                 port = &ports[pi];
1476                 if (rte_atomic16_cmpset(&(port->port_status),
1477                         RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1478                         printf("Port %d is now not stopped\n", pi);
1479                         continue;
1480                 }
1481
1482                 rte_eth_dev_close(pi);
1483
1484                 if (rte_atomic16_cmpset(&(port->port_status),
1485                         RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1486                         printf("Port %d can not be set into stopped\n", pi);
1487         }
1488
1489         printf("Done\n");
1490 }
1491
1492 int
1493 all_ports_stopped(void)
1494 {
1495         portid_t pi;
1496         struct rte_port *port;
1497
1498         for (pi = 0; pi < nb_ports; pi++) {
1499                 port = &ports[pi];
1500                 if (port->port_status != RTE_PORT_STOPPED)
1501                         return 0;
1502         }
1503
1504         return 1;
1505 }
1506
1507 int
1508 port_is_started(portid_t port_id)
1509 {
1510         if (port_id_is_invalid(port_id))
1511                 return -1;
1512
1513         if (ports[port_id].port_status != RTE_PORT_STARTED)
1514                 return 0;
1515
1516         return 1;
1517 }
1518
1519 void
1520 pmd_test_exit(void)
1521 {
1522         portid_t pt_id;
1523
1524         for (pt_id = 0; pt_id < nb_ports; pt_id++) {
1525                 printf("Stopping port %d...", pt_id);
1526                 fflush(stdout);
1527                 rte_eth_dev_close(pt_id);
1528                 printf("done\n");
1529         }
1530         printf("bye...\n");
1531 }
1532
1533 typedef void (*cmd_func_t)(void);
1534 struct pmd_test_command {
1535         const char *cmd_name;
1536         cmd_func_t cmd_func;
1537 };
1538
1539 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1540
1541 /* Check the link status of all ports in up to 9s, and print them finally */
1542 static void
1543 check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
1544 {
1545 #define CHECK_INTERVAL 100 /* 100ms */
1546 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1547         uint8_t portid, count, all_ports_up, print_flag = 0;
1548         struct rte_eth_link link;
1549
1550         printf("Checking link statuses...\n");
1551         fflush(stdout);
1552         for (count = 0; count <= MAX_CHECK_TIME; count++) {
1553                 all_ports_up = 1;
1554                 for (portid = 0; portid < port_num; portid++) {
1555                         if ((port_mask & (1 << portid)) == 0)
1556                                 continue;
1557                         memset(&link, 0, sizeof(link));
1558                         rte_eth_link_get_nowait(portid, &link);
1559                         /* print link status if flag set */
1560                         if (print_flag == 1) {
1561                                 if (link.link_status)
1562                                         printf("Port %d Link Up - speed %u "
1563                                                 "Mbps - %s\n", (uint8_t)portid,
1564                                                 (unsigned)link.link_speed,
1565                                 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1566                                         ("full-duplex") : ("half-duplex\n"));
1567                                 else
1568                                         printf("Port %d Link Down\n",
1569                                                 (uint8_t)portid);
1570                                 continue;
1571                         }
1572                         /* clear all_ports_up flag if any link down */
1573                         if (link.link_status == 0) {
1574                                 all_ports_up = 0;
1575                                 break;
1576                         }
1577                 }
1578                 /* after finally printing all link status, get out */
1579                 if (print_flag == 1)
1580                         break;
1581
1582                 if (all_ports_up == 0) {
1583                         fflush(stdout);
1584                         rte_delay_ms(CHECK_INTERVAL);
1585                 }
1586
1587                 /* set the print_flag if all ports up or timeout */
1588                 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1589                         print_flag = 1;
1590                 }
1591         }
1592 }
1593
1594 static int
1595 set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1596 {
1597         uint16_t i;
1598         int diag;
1599         uint8_t mapping_found = 0;
1600
1601         for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1602                 if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1603                                 (tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1604                         diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1605                                         tx_queue_stats_mappings[i].queue_id,
1606                                         tx_queue_stats_mappings[i].stats_counter_id);
1607                         if (diag != 0)
1608                                 return diag;
1609                         mapping_found = 1;
1610                 }
1611         }
1612         if (mapping_found)
1613                 port->tx_queue_stats_mapping_enabled = 1;
1614         return 0;
1615 }
1616
1617 static int
1618 set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1619 {
1620         uint16_t i;
1621         int diag;
1622         uint8_t mapping_found = 0;
1623
1624         for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1625                 if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1626                                 (rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1627                         diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1628                                         rx_queue_stats_mappings[i].queue_id,
1629                                         rx_queue_stats_mappings[i].stats_counter_id);
1630                         if (diag != 0)
1631                                 return diag;
1632                         mapping_found = 1;
1633                 }
1634         }
1635         if (mapping_found)
1636                 port->rx_queue_stats_mapping_enabled = 1;
1637         return 0;
1638 }
1639
1640 static void
1641 map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1642 {
1643         int diag = 0;
1644
1645         diag = set_tx_queue_stats_mapping_registers(pi, port);
1646         if (diag != 0) {
1647                 if (diag == -ENOTSUP) {
1648                         port->tx_queue_stats_mapping_enabled = 0;
1649                         printf("TX queue stats mapping not supported port id=%d\n", pi);
1650                 }
1651                 else
1652                         rte_exit(EXIT_FAILURE,
1653                                         "set_tx_queue_stats_mapping_registers "
1654                                         "failed for port id=%d diag=%d\n",
1655                                         pi, diag);
1656         }
1657
1658         diag = set_rx_queue_stats_mapping_registers(pi, port);
1659         if (diag != 0) {
1660                 if (diag == -ENOTSUP) {
1661                         port->rx_queue_stats_mapping_enabled = 0;
1662                         printf("RX queue stats mapping not supported port id=%d\n", pi);
1663                 }
1664                 else
1665                         rte_exit(EXIT_FAILURE,
1666                                         "set_rx_queue_stats_mapping_registers "
1667                                         "failed for port id=%d diag=%d\n",
1668                                         pi, diag);
1669         }
1670 }
1671
1672 static void
1673 rxtx_port_config(struct rte_port *port)
1674 {
1675         port->rx_conf = port->dev_info.default_rxconf;
1676         port->tx_conf = port->dev_info.default_txconf;
1677
1678         /* Check if any RX/TX parameters have been passed */
1679         if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1680                 port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1681
1682         if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1683                 port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1684
1685         if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1686                 port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1687
1688         if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1689                 port->rx_conf.rx_free_thresh = rx_free_thresh;
1690
1691         if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1692                 port->rx_conf.rx_drop_en = rx_drop_en;
1693
1694         if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1695                 port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1696
1697         if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1698                 port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1699
1700         if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1701                 port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1702
1703         if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1704                 port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1705
1706         if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1707                 port->tx_conf.tx_free_thresh = tx_free_thresh;
1708
1709         if (txq_flags != RTE_PMD_PARAM_UNSET)
1710                 port->tx_conf.txq_flags = txq_flags;
1711 }
1712
1713 void
1714 init_port_config(void)
1715 {
1716         portid_t pid;
1717         struct rte_port *port;
1718
1719         for (pid = 0; pid < nb_ports; pid++) {
1720                 port = &ports[pid];
1721                 port->dev_conf.rxmode = rx_mode;
1722                 port->dev_conf.fdir_conf = fdir_conf;
1723                 if (nb_rxq > 1) {
1724                         port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1725                         port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1726                 } else {
1727                         port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1728                         port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1729                 }
1730
1731                 if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
1732                         if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1733                                 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
1734                         else
1735                                 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
1736                 }
1737
1738                 if (port->dev_info.max_vfs != 0) {
1739                         if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1740                                 port->dev_conf.rxmode.mq_mode =
1741                                         ETH_MQ_RX_VMDQ_RSS;
1742                         else
1743                                 port->dev_conf.rxmode.mq_mode =
1744                                         ETH_MQ_RX_NONE;
1745
1746                         port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1747                 }
1748
1749                 rxtx_port_config(port);
1750
1751                 rte_eth_macaddr_get(pid, &port->eth_addr);
1752
1753                 map_port_queue_stats_mapping_registers(pid, port);
1754 #ifdef RTE_NIC_BYPASS
1755                 rte_eth_dev_bypass_init(pid);
1756 #endif
1757         }
1758 }
1759
1760 const uint16_t vlan_tags[] = {
1761                 0,  1,  2,  3,  4,  5,  6,  7,
1762                 8,  9, 10, 11,  12, 13, 14, 15,
1763                 16, 17, 18, 19, 20, 21, 22, 23,
1764                 24, 25, 26, 27, 28, 29, 30, 31
1765 };
1766
1767 static  int
1768 get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf)
1769 {
1770         uint8_t i;
1771
1772         /*
1773          * Builds up the correct configuration for dcb+vt based on the vlan tags array
1774          * given above, and the number of traffic classes available for use.
1775          */
1776         if (dcb_conf->dcb_mode == DCB_VT_ENABLED) {
1777                 struct rte_eth_vmdq_dcb_conf vmdq_rx_conf;
1778                 struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf;
1779
1780                 /* VMDQ+DCB RX and TX configrations */
1781                 vmdq_rx_conf.enable_default_pool = 0;
1782                 vmdq_rx_conf.default_pool = 0;
1783                 vmdq_rx_conf.nb_queue_pools =
1784                         (dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1785                 vmdq_tx_conf.nb_queue_pools =
1786                         (dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1787
1788                 vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1789                 for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) {
1790                         vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ];
1791                         vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools);
1792                 }
1793                 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1794                         vmdq_rx_conf.dcb_queue[i] = i;
1795                         vmdq_tx_conf.dcb_queue[i] = i;
1796                 }
1797
1798                 /*set DCB mode of RX and TX of multiple queues*/
1799                 eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
1800                 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
1801                 if (dcb_conf->pfc_en)
1802                         eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1803                 else
1804                         eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1805
1806                 (void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf,
1807                                 sizeof(struct rte_eth_vmdq_dcb_conf)));
1808                 (void)(rte_memcpy(&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf,
1809                                 sizeof(struct rte_eth_vmdq_dcb_tx_conf)));
1810         }
1811         else {
1812                 struct rte_eth_dcb_rx_conf rx_conf;
1813                 struct rte_eth_dcb_tx_conf tx_conf;
1814
1815                 /* queue mapping configuration of DCB RX and TX */
1816                 if (dcb_conf->num_tcs == ETH_4_TCS)
1817                         dcb_q_mapping = DCB_4_TCS_Q_MAPPING;
1818                 else
1819                         dcb_q_mapping = DCB_8_TCS_Q_MAPPING;
1820
1821                 rx_conf.nb_tcs = dcb_conf->num_tcs;
1822                 tx_conf.nb_tcs = dcb_conf->num_tcs;
1823
1824                 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){
1825                         rx_conf.dcb_queue[i] = i;
1826                         tx_conf.dcb_queue[i] = i;
1827                 }
1828                 eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB;
1829                 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
1830                 if (dcb_conf->pfc_en)
1831                         eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1832                 else
1833                         eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1834
1835                 (void)(rte_memcpy(&eth_conf->rx_adv_conf.dcb_rx_conf, &rx_conf,
1836                                 sizeof(struct rte_eth_dcb_rx_conf)));
1837                 (void)(rte_memcpy(&eth_conf->tx_adv_conf.dcb_tx_conf, &tx_conf,
1838                                 sizeof(struct rte_eth_dcb_tx_conf)));
1839         }
1840
1841         return 0;
1842 }
1843
1844 int
1845 init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
1846 {
1847         struct rte_eth_conf port_conf;
1848         struct rte_port *rte_port;
1849         int retval;
1850         uint16_t nb_vlan;
1851         uint16_t i;
1852
1853         /* rxq and txq configuration in dcb mode */
1854         nb_rxq = 128;
1855         nb_txq = 128;
1856         rx_free_thresh = 64;
1857
1858         memset(&port_conf,0,sizeof(struct rte_eth_conf));
1859         /* Enter DCB configuration status */
1860         dcb_config = 1;
1861
1862         nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1863         /*set configuration of DCB in vt mode and DCB in non-vt mode*/
1864         retval = get_eth_dcb_conf(&port_conf, dcb_conf);
1865         if (retval < 0)
1866                 return retval;
1867
1868         rte_port = &ports[pid];
1869         memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf));
1870
1871         rxtx_port_config(rte_port);
1872         /* VLAN filter */
1873         rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
1874         for (i = 0; i < nb_vlan; i++){
1875                 rx_vft_set(pid, vlan_tags[i], 1);
1876         }
1877
1878         rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1879         map_port_queue_stats_mapping_registers(pid, rte_port);
1880
1881         rte_port->dcb_flag = 1;
1882
1883         return 0;
1884 }
1885
1886 int
1887 main(int argc, char** argv)
1888 {
1889         int  diag;
1890         uint8_t port_id;
1891
1892         diag = rte_eal_init(argc, argv);
1893         if (diag < 0)
1894                 rte_panic("Cannot init EAL\n");
1895
1896         nb_ports = (portid_t) rte_eth_dev_count();
1897         if (nb_ports == 0)
1898                 rte_exit(EXIT_FAILURE, "No probed ethernet device\n");
1899
1900         set_def_fwd_config();
1901         if (nb_lcores == 0)
1902                 rte_panic("Empty set of forwarding logical cores - check the "
1903                           "core mask supplied in the command parameters\n");
1904
1905         argc -= diag;
1906         argv += diag;
1907         if (argc > 1)
1908                 launch_args_parse(argc, argv);
1909
1910         if (nb_rxq > nb_txq)
1911                 printf("Warning: nb_rxq=%d enables RSS configuration, "
1912                        "but nb_txq=%d will prevent to fully test it.\n",
1913                        nb_rxq, nb_txq);
1914
1915         init_config();
1916         if (start_port(RTE_PORT_ALL) != 0)
1917                 rte_exit(EXIT_FAILURE, "Start ports failed\n");
1918
1919         /* set all ports to promiscuous mode by default */
1920         for (port_id = 0; port_id < nb_ports; port_id++)
1921                 rte_eth_promiscuous_enable(port_id);
1922
1923 #ifdef RTE_LIBRTE_CMDLINE
1924         if (interactive == 1) {
1925                 if (auto_start) {
1926                         printf("Start automatic packet forwarding\n");
1927                         start_packet_forwarding(0);
1928                 }
1929                 prompt();
1930         } else
1931 #endif
1932         {
1933                 char c;
1934                 int rc;
1935
1936                 printf("No commandline core given, start packet forwarding\n");
1937                 start_packet_forwarding(0);
1938                 printf("Press enter to exit\n");
1939                 rc = read(0, &c, 1);
1940                 if (rc < 0)
1941                         return 1;
1942         }
1943
1944         return 0;
1945 }