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