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