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