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