e8718f73ab9ff414ef3f0738f70d9f119aa7a8c3
[vpp.git] / src / plugins / dpdk / device / init.c
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vnet/vnet.h>
16 #include <vppinfra/vec.h>
17 #include <vppinfra/error.h>
18 #include <vppinfra/format.h>
19 #include <vppinfra/bitmap.h>
20 #include <vppinfra/linux/sysfs.h>
21 #include <vlib/unix/unix.h>
22 #include <vlib/log.h>
23
24 #include <vnet/ethernet/ethernet.h>
25 #include <dpdk/device/dpdk.h>
26 #include <vlib/pci/pci.h>
27
28 #include <rte_ring.h>
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/stat.h>
34 #include <sys/mount.h>
35 #include <string.h>
36 #include <fcntl.h>
37
38 #include <dpdk/device/dpdk_priv.h>
39
40 #define ETHER_MAX_LEN   1518  /**< Maximum frame len, including CRC. */
41
42 dpdk_main_t dpdk_main;
43 dpdk_config_main_t dpdk_config_main;
44
45 #define LINK_STATE_ELOGS        0
46
47 /* Port configuration, mildly modified Intel app values */
48
49 static dpdk_port_type_t
50 port_type_from_speed_capa (struct rte_eth_dev_info *dev_info)
51 {
52
53   if (dev_info->speed_capa & ETH_LINK_SPEED_100G)
54     return VNET_DPDK_PORT_TYPE_ETH_100G;
55   else if (dev_info->speed_capa & ETH_LINK_SPEED_56G)
56     return VNET_DPDK_PORT_TYPE_ETH_56G;
57   else if (dev_info->speed_capa & ETH_LINK_SPEED_50G)
58     return VNET_DPDK_PORT_TYPE_ETH_50G;
59   else if (dev_info->speed_capa & ETH_LINK_SPEED_40G)
60     return VNET_DPDK_PORT_TYPE_ETH_40G;
61   else if (dev_info->speed_capa & ETH_LINK_SPEED_25G)
62     return VNET_DPDK_PORT_TYPE_ETH_25G;
63   else if (dev_info->speed_capa & ETH_LINK_SPEED_20G)
64     return VNET_DPDK_PORT_TYPE_ETH_20G;
65   else if (dev_info->speed_capa & ETH_LINK_SPEED_10G)
66     return VNET_DPDK_PORT_TYPE_ETH_10G;
67   else if (dev_info->speed_capa & ETH_LINK_SPEED_5G)
68     return VNET_DPDK_PORT_TYPE_ETH_5G;
69   else if (dev_info->speed_capa & ETH_LINK_SPEED_2_5G)
70     return VNET_DPDK_PORT_TYPE_ETH_2_5G;
71   else if (dev_info->speed_capa & ETH_LINK_SPEED_1G)
72     return VNET_DPDK_PORT_TYPE_ETH_1G;
73
74   return VNET_DPDK_PORT_TYPE_UNKNOWN;
75 }
76
77 static dpdk_port_type_t
78 port_type_from_link_speed (u32 link_speed)
79 {
80   switch (link_speed)
81     {
82     case ETH_SPEED_NUM_1G:
83       return VNET_DPDK_PORT_TYPE_ETH_1G;
84     case ETH_SPEED_NUM_2_5G:
85       return VNET_DPDK_PORT_TYPE_ETH_2_5G;
86     case ETH_SPEED_NUM_5G:
87       return VNET_DPDK_PORT_TYPE_ETH_5G;
88     case ETH_SPEED_NUM_10G:
89       return VNET_DPDK_PORT_TYPE_ETH_10G;
90     case ETH_SPEED_NUM_20G:
91       return VNET_DPDK_PORT_TYPE_ETH_20G;
92     case ETH_SPEED_NUM_25G:
93       return VNET_DPDK_PORT_TYPE_ETH_25G;
94     case ETH_SPEED_NUM_40G:
95       return VNET_DPDK_PORT_TYPE_ETH_40G;
96     case ETH_SPEED_NUM_50G:
97       return VNET_DPDK_PORT_TYPE_ETH_50G;
98     case ETH_SPEED_NUM_56G:
99       return VNET_DPDK_PORT_TYPE_ETH_56G;
100     case ETH_SPEED_NUM_100G:
101       return VNET_DPDK_PORT_TYPE_ETH_100G;
102     default:
103       return VNET_DPDK_PORT_TYPE_UNKNOWN;
104     }
105 }
106
107 static u32
108 dpdk_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags)
109 {
110   dpdk_main_t *dm = &dpdk_main;
111   dpdk_device_t *xd = vec_elt_at_index (dm->devices, hi->dev_instance);
112   u32 old = 0;
113
114   if (ETHERNET_INTERFACE_FLAG_CONFIG_PROMISC (flags))
115     {
116       old = (xd->flags & DPDK_DEVICE_FLAG_PROMISC) != 0;
117
118       if (flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL)
119         xd->flags |= DPDK_DEVICE_FLAG_PROMISC;
120       else
121         xd->flags &= ~DPDK_DEVICE_FLAG_PROMISC;
122
123       if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
124         {
125           if (xd->flags & DPDK_DEVICE_FLAG_PROMISC)
126             rte_eth_promiscuous_enable (xd->port_id);
127           else
128             rte_eth_promiscuous_disable (xd->port_id);
129         }
130     }
131   else if (ETHERNET_INTERFACE_FLAG_CONFIG_MTU (flags))
132     {
133       xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes;
134       dpdk_device_setup (xd);
135     }
136   return old;
137 }
138
139 static void
140 dpdk_device_lock_init (dpdk_device_t * xd)
141 {
142   int q;
143   vec_validate (xd->lockp, xd->tx_q_used - 1);
144   for (q = 0; q < xd->tx_q_used; q++)
145     {
146       xd->lockp[q] = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
147                                              CLIB_CACHE_LINE_BYTES);
148       clib_memset ((void *) xd->lockp[q], 0, CLIB_CACHE_LINE_BYTES);
149     }
150 }
151
152 static struct rte_mempool_ops *
153 get_ops_by_name (char *ops_name)
154 {
155   u32 i;
156
157   for (i = 0; i < rte_mempool_ops_table.num_ops; i++)
158     {
159       if (!strcmp (ops_name, rte_mempool_ops_table.ops[i].name))
160         return &rte_mempool_ops_table.ops[i];
161     }
162
163   return 0;
164 }
165
166 static int
167 dpdk_ring_alloc (struct rte_mempool *mp)
168 {
169   u32 rg_flags = 0, count;
170   i32 ret;
171   char rg_name[RTE_RING_NAMESIZE];
172   struct rte_ring *r;
173
174   ret = snprintf (rg_name, sizeof (rg_name), RTE_MEMPOOL_MZ_FORMAT, mp->name);
175   if (ret < 0 || ret >= (i32) sizeof (rg_name))
176     return -ENAMETOOLONG;
177
178   /* ring flags */
179   if (mp->flags & MEMPOOL_F_SP_PUT)
180     rg_flags |= RING_F_SP_ENQ;
181   if (mp->flags & MEMPOOL_F_SC_GET)
182     rg_flags |= RING_F_SC_DEQ;
183
184   count = rte_align32pow2 (mp->size + 1);
185   /*
186    * Allocate the ring that will be used to store objects.
187    * Ring functions will return appropriate errors if we are
188    * running as a secondary process etc., so no checks made
189    * in this function for that condition.
190    */
191   /* XXX can we get memory from the right socket? */
192   r = clib_mem_alloc_aligned (rte_ring_get_memsize (count),
193                               CLIB_CACHE_LINE_BYTES);
194
195   /* XXX rte_ring_lookup will not work */
196
197   ret = rte_ring_init (r, rg_name, count, rg_flags);
198   if (ret)
199     return ret;
200
201   mp->pool_data = r;
202
203   return 0;
204 }
205
206 static int
207 dpdk_port_crc_strip_enabled (dpdk_device_t * xd)
208 {
209 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
210   return ! !(xd->port_conf.rxmode.hw_strip_crc);
211 #elif RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
212   return ! !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_CRC_STRIP);
213 #else
214   return !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC);
215 #endif
216 }
217
218 static clib_error_t *
219 dpdk_lib_init (dpdk_main_t * dm)
220 {
221   u32 nports;
222   u32 mtu, max_rx_frame;
223   u32 nb_desc = 0;
224   int i;
225   clib_error_t *error;
226   vlib_main_t *vm = vlib_get_main ();
227   vlib_thread_main_t *tm = vlib_get_thread_main ();
228   vnet_device_main_t *vdm = &vnet_device_main;
229   vnet_sw_interface_t *sw;
230   vnet_hw_interface_t *hi;
231   dpdk_device_t *xd;
232   vlib_pci_addr_t last_pci_addr;
233   u32 last_pci_addr_port = 0;
234   vlib_thread_registration_t *tr_hqos;
235   uword *p_hqos;
236
237   u32 next_hqos_cpu = 0;
238   u8 af_packet_instance_num = 0;
239   u8 bond_ether_instance_num = 0;
240   last_pci_addr.as_u32 = ~0;
241
242   dm->hqos_cpu_first_index = 0;
243   dm->hqos_cpu_count = 0;
244
245   /* find out which cpus will be used for I/O TX */
246   p_hqos = hash_get_mem (tm->thread_registrations_by_name, "hqos-threads");
247   tr_hqos = p_hqos ? (vlib_thread_registration_t *) p_hqos[0] : 0;
248
249   if (tr_hqos && tr_hqos->count > 0)
250     {
251       dm->hqos_cpu_first_index = tr_hqos->first_index;
252       dm->hqos_cpu_count = tr_hqos->count;
253     }
254
255   vec_validate_aligned (dm->devices_by_hqos_cpu, tm->n_vlib_mains - 1,
256                         CLIB_CACHE_LINE_BYTES);
257
258   nports = rte_eth_dev_count_avail ();
259
260   if (nports < 1)
261     {
262       dpdk_log_notice ("DPDK drivers found no ports...");
263     }
264
265   if (CLIB_DEBUG > 0)
266     dpdk_log_notice ("DPDK drivers found %d ports...", nports);
267
268   if (dm->conf->enable_tcp_udp_checksum)
269     dm->buffer_flags_template &= ~(VNET_BUFFER_F_L4_CHECKSUM_CORRECT
270                                    | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED);
271
272   /* vlib_buffer_t template */
273   vec_validate_aligned (dm->per_thread_data, tm->n_vlib_mains - 1,
274                         CLIB_CACHE_LINE_BYTES);
275   for (i = 0; i < tm->n_vlib_mains; i++)
276     {
277       vlib_buffer_free_list_t *fl;
278       dpdk_per_thread_data_t *ptd = vec_elt_at_index (dm->per_thread_data, i);
279       fl = vlib_buffer_get_free_list (vm,
280                                       VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
281       vlib_buffer_init_for_free_list (&ptd->buffer_template, fl);
282       ptd->buffer_template.flags = dm->buffer_flags_template;
283       vnet_buffer (&ptd->buffer_template)->sw_if_index[VLIB_TX] = (u32) ~ 0;
284     }
285
286   /* *INDENT-OFF* */
287   RTE_ETH_FOREACH_DEV(i)
288     {
289       u8 addr[6];
290       u8 vlan_strip = 0;
291       struct rte_eth_dev_info dev_info;
292       struct rte_pci_device *pci_dev;
293       struct rte_eth_link l;
294       dpdk_device_config_t *devconf = 0;
295       vlib_pci_addr_t pci_addr;
296       uword *p = 0;
297
298       if (!rte_eth_dev_is_valid_port(i))
299         continue;
300
301       rte_eth_link_get_nowait (i, &l);
302       rte_eth_dev_info_get (i, &dev_info);
303
304       if (dev_info.device == 0)
305         {
306           clib_warning ("DPDK bug: missing device info. Skipping %s device",
307                         dev_info.driver_name);
308           continue;
309         }
310
311       pci_dev = dpdk_get_pci_device (&dev_info);
312
313       if (pci_dev)      /* bonded interface has no pci info */
314         {
315           pci_addr.domain = pci_dev->addr.domain;
316           pci_addr.bus = pci_dev->addr.bus;
317           pci_addr.slot = pci_dev->addr.devid;
318           pci_addr.function = pci_dev->addr.function;
319           p = hash_get (dm->conf->device_config_index_by_pci_addr,
320                         pci_addr.as_u32);
321         }
322
323       if (p)
324         devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
325       else
326         devconf = &dm->conf->default_devconf;
327
328       /* Create vnet interface */
329       vec_add2_aligned (dm->devices, xd, 1, CLIB_CACHE_LINE_BYTES);
330       xd->nb_rx_desc = DPDK_NB_RX_DESC_DEFAULT;
331       xd->nb_tx_desc = DPDK_NB_TX_DESC_DEFAULT;
332       xd->cpu_socket = (i8) rte_eth_dev_socket_id (i);
333
334       /* Handle interface naming for devices with multiple ports sharing same PCI ID */
335       if (pci_dev)
336         {
337           struct rte_eth_dev_info di = { 0 };
338           struct rte_pci_device *next_pci_dev;
339           rte_eth_dev_info_get (i + 1, &di);
340           next_pci_dev = di.device ? RTE_DEV_TO_PCI (di.device) : 0;
341           if (pci_dev && next_pci_dev &&
342               pci_addr.as_u32 != last_pci_addr.as_u32 &&
343               memcmp (&pci_dev->addr, &next_pci_dev->addr,
344                       sizeof (struct rte_pci_addr)) == 0)
345             {
346               xd->interface_name_suffix = format (0, "0");
347               last_pci_addr.as_u32 = pci_addr.as_u32;
348               last_pci_addr_port = i;
349             }
350           else if (pci_addr.as_u32 == last_pci_addr.as_u32)
351             {
352               xd->interface_name_suffix =
353                 format (0, "%u", i - last_pci_addr_port);
354             }
355           else
356             {
357               last_pci_addr.as_u32 = ~0;
358             }
359         }
360       else
361         last_pci_addr.as_u32 = ~0;
362
363       clib_memcpy (&xd->tx_conf, &dev_info.default_txconf,
364                    sizeof (struct rte_eth_txconf));
365
366       if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM)
367         {
368           xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_IPV4_CKSUM;
369           xd->flags |= DPDK_DEVICE_FLAG_RX_IP4_CKSUM;
370         }
371
372       if (dm->conf->no_multi_seg)
373         {
374 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
375           xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
376           xd->port_conf.rxmode.jumbo_frame = 0;
377           xd->port_conf.rxmode.enable_scatter = 0;
378 #else
379           xd->port_conf.txmode.offloads &= ~DEV_TX_OFFLOAD_MULTI_SEGS;
380           xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
381           xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_SCATTER;
382 #endif
383         }
384       else
385         {
386 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
387           xd->tx_conf.txq_flags &= ~ETH_TXQ_FLAGS_NOMULTSEGS;
388           xd->port_conf.rxmode.jumbo_frame = 1;
389           xd->port_conf.rxmode.enable_scatter = 1;
390 #else
391           xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
392           xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
393           xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_SCATTER;
394 #endif
395           xd->flags |= DPDK_DEVICE_FLAG_MAYBE_MULTISEG;
396         }
397
398       xd->tx_q_used = clib_min (dev_info.max_tx_queues, tm->n_vlib_mains);
399
400       if (devconf->num_tx_queues > 0
401           && devconf->num_tx_queues < xd->tx_q_used)
402         xd->tx_q_used = clib_min (xd->tx_q_used, devconf->num_tx_queues);
403
404       if (devconf->num_rx_queues > 1
405           && dev_info.max_rx_queues >= devconf->num_rx_queues)
406         {
407           xd->rx_q_used = devconf->num_rx_queues;
408           xd->port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
409           if (devconf->rss_fn == 0)
410             xd->port_conf.rx_adv_conf.rss_conf.rss_hf =
411               ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP;
412           else
413             {
414               u64 unsupported_bits;
415               xd->port_conf.rx_adv_conf.rss_conf.rss_hf = devconf->rss_fn;
416               unsupported_bits = xd->port_conf.rx_adv_conf.rss_conf.rss_hf;
417               unsupported_bits &= ~dev_info.flow_type_rss_offloads;
418               if (unsupported_bits)
419                 dpdk_log_warn ("Unsupported RSS hash functions: %U",
420                                format_dpdk_rss_hf_name, unsupported_bits);
421             }
422           xd->port_conf.rx_adv_conf.rss_conf.rss_hf &=
423             dev_info.flow_type_rss_offloads;
424         }
425       else
426         xd->rx_q_used = 1;
427
428       xd->flags |= DPDK_DEVICE_FLAG_PMD;
429
430       /* workaround for drivers not setting driver_name */
431       if ((!dev_info.driver_name) && (pci_dev))
432         dev_info.driver_name = pci_dev->driver->driver.name;
433
434       ASSERT (dev_info.driver_name);
435
436       if (!xd->pmd)
437         {
438
439
440 #define _(s,f) else if (dev_info.driver_name &&                 \
441                         !strcmp(dev_info.driver_name, s))       \
442                  xd->pmd = VNET_DPDK_PMD_##f;
443           if (0)
444             ;
445           foreach_dpdk_pmd
446 #undef _
447             else
448             xd->pmd = VNET_DPDK_PMD_UNKNOWN;
449
450           xd->port_type = VNET_DPDK_PORT_TYPE_UNKNOWN;
451           xd->nb_rx_desc = DPDK_NB_RX_DESC_DEFAULT;
452           xd->nb_tx_desc = DPDK_NB_TX_DESC_DEFAULT;
453
454           switch (xd->pmd)
455             {
456               /* Drivers with valid speed_capa set */
457             case VNET_DPDK_PMD_E1000EM:
458             case VNET_DPDK_PMD_IGB:
459             case VNET_DPDK_PMD_IXGBE:
460             case VNET_DPDK_PMD_I40E:
461               xd->port_type = port_type_from_speed_capa (&dev_info);
462               xd->supported_flow_actions = VNET_FLOW_ACTION_MARK |
463                 VNET_FLOW_ACTION_REDIRECT_TO_NODE |
464                 VNET_FLOW_ACTION_BUFFER_ADVANCE |
465                 VNET_FLOW_ACTION_COUNT | VNET_FLOW_ACTION_DROP;
466
467               if (dm->conf->no_tx_checksum_offload == 0)
468                 {
469 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
470                   xd->tx_conf.txq_flags &= ~(ETH_TXQ_FLAGS_NOXSUMUDP |
471                                                      ETH_TXQ_FLAGS_NOXSUMTCP);
472 #else
473                   xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
474                   xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
475 #endif
476                   xd->flags |=
477                     DPDK_DEVICE_FLAG_TX_OFFLOAD |
478                     DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
479                 }
480
481
482               break;
483             case VNET_DPDK_PMD_CXGBE:
484             case VNET_DPDK_PMD_MLX4:
485             case VNET_DPDK_PMD_MLX5:
486             case VNET_DPDK_PMD_QEDE:
487               xd->port_type = port_type_from_speed_capa (&dev_info);
488               break;
489
490               /* SR-IOV VFs */
491             case VNET_DPDK_PMD_IGBVF:
492             case VNET_DPDK_PMD_IXGBEVF:
493             case VNET_DPDK_PMD_I40EVF:
494               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
495 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
496               xd->port_conf.rxmode.hw_strip_crc = 1;
497 #elif RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
498               xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
499 #endif
500               break;
501
502             case VNET_DPDK_PMD_THUNDERX:
503               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
504 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
505               xd->port_conf.rxmode.hw_strip_crc = 1;
506 #elif RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
507               xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
508 #endif
509
510               if (dm->conf->no_tx_checksum_offload == 0)
511                 {
512 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
513                   xd->tx_conf.txq_flags &= ~(ETH_TXQ_FLAGS_NOXSUMUDP |
514                                                      ETH_TXQ_FLAGS_NOXSUMTCP);
515 #else
516                   xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
517                   xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
518 #endif
519                   xd->flags |=
520                     DPDK_DEVICE_FLAG_TX_OFFLOAD;
521                 }
522               break;
523
524             case VNET_DPDK_PMD_ENA:
525               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
526 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
527               xd->port_conf.rxmode.enable_scatter = 0;
528 #else
529               xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_SCATTER;
530 #endif
531               break;
532
533             case VNET_DPDK_PMD_DPAA2:
534               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
535               break;
536
537               /* Cisco VIC */
538             case VNET_DPDK_PMD_ENIC:
539               if (l.link_speed == 40000)
540                 xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
541               else
542                 xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
543               break;
544
545               /* Intel Red Rock Canyon */
546             case VNET_DPDK_PMD_FM10K:
547               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_SWITCH;
548 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
549               xd->port_conf.rxmode.hw_strip_crc = 1;
550 #elif RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
551               xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
552 #endif
553               break;
554
555               /* virtio */
556             case VNET_DPDK_PMD_VIRTIO:
557               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_1G;
558               xd->nb_rx_desc = DPDK_NB_RX_DESC_VIRTIO;
559               xd->nb_tx_desc = DPDK_NB_TX_DESC_VIRTIO;
560               break;
561
562               /* vmxnet3 */
563             case VNET_DPDK_PMD_VMXNET3:
564               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_1G;
565 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
566               xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
567 #else
568               xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
569 #endif
570               break;
571
572             case VNET_DPDK_PMD_AF_PACKET:
573               xd->port_type = VNET_DPDK_PORT_TYPE_AF_PACKET;
574               xd->af_packet_instance_num = af_packet_instance_num++;
575               break;
576
577             case VNET_DPDK_PMD_BOND:
578               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_BOND;
579               xd->bond_instance_num = bond_ether_instance_num++;
580               break;
581
582             case VNET_DPDK_PMD_VIRTIO_USER:
583               xd->port_type = VNET_DPDK_PORT_TYPE_VIRTIO_USER;
584               break;
585
586             case VNET_DPDK_PMD_VHOST_ETHER:
587               xd->port_type = VNET_DPDK_PORT_TYPE_VHOST_ETHER;
588               break;
589
590             case VNET_DPDK_PMD_LIOVF_ETHER:
591               xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
592               break;
593
594             case VNET_DPDK_PMD_FAILSAFE:
595               xd->port_type = VNET_DPDK_PORT_TYPE_FAILSAFE;
596               xd->port_conf.intr_conf.lsc = 1;
597               break;
598
599             case VNET_DPDK_PMD_NETVSC:
600               xd->port_type = port_type_from_link_speed (l.link_speed);
601               break;
602
603             default:
604               xd->port_type = VNET_DPDK_PORT_TYPE_UNKNOWN;
605             }
606
607           if (devconf->num_rx_desc)
608             xd->nb_rx_desc = devconf->num_rx_desc;
609
610           if (devconf->num_tx_desc)
611             xd->nb_tx_desc = devconf->num_tx_desc;
612         }
613
614       if (xd->pmd == VNET_DPDK_PMD_AF_PACKET)
615         {
616           f64 now = vlib_time_now (vm);
617           u32 rnd;
618           rnd = (u32) (now * 1e6);
619           rnd = random_u32 (&rnd);
620           clib_memcpy (addr + 2, &rnd, sizeof (rnd));
621           addr[0] = 2;
622           addr[1] = 0xfe;
623         }
624       else
625         rte_eth_macaddr_get (i, (struct ether_addr *) addr);
626
627       if (xd->tx_q_used < tm->n_vlib_mains)
628         dpdk_device_lock_init (xd);
629
630       xd->port_id = i;
631       xd->device_index = xd - dm->devices;
632       xd->per_interface_next_index = ~0;
633
634       /* assign interface to input thread */
635       int q;
636
637       if (devconf->hqos_enabled)
638         {
639           xd->flags |= DPDK_DEVICE_FLAG_HQOS;
640
641           int cpu;
642           if (devconf->hqos.hqos_thread_valid)
643             {
644               if (devconf->hqos.hqos_thread >= dm->hqos_cpu_count)
645                 return clib_error_return (0, "invalid HQoS thread index");
646
647               cpu = dm->hqos_cpu_first_index + devconf->hqos.hqos_thread;
648             }
649           else
650             {
651               if (dm->hqos_cpu_count == 0)
652                 return clib_error_return (0, "no HQoS threads available");
653
654               cpu = dm->hqos_cpu_first_index + next_hqos_cpu;
655
656               next_hqos_cpu++;
657               if (next_hqos_cpu == dm->hqos_cpu_count)
658                 next_hqos_cpu = 0;
659
660               devconf->hqos.hqos_thread_valid = 1;
661               devconf->hqos.hqos_thread = cpu;
662             }
663
664           dpdk_device_and_queue_t *dq;
665           vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
666           dq->device = xd->device_index;
667           dq->queue_id = 0;
668         }
669
670       /* count the number of descriptors used for this device */
671       nb_desc += xd->nb_rx_desc + xd->nb_tx_desc * xd->tx_q_used;
672
673       error = ethernet_register_interface
674         (dm->vnet_main, dpdk_device_class.index, xd->device_index,
675          /* ethernet address */ addr,
676          &xd->hw_if_index, dpdk_flag_change);
677       if (error)
678         return error;
679
680       /*
681        * Ensure default mtu is not > the mtu read from the hardware.
682        * Otherwise rte_eth_dev_configure() will fail and the port will
683        * not be available.
684        * Calculate max_frame_size and mtu supported by NIC
685        */
686       if (ETHERNET_MAX_PACKET_BYTES > dev_info.max_rx_pktlen)
687         {
688           /*
689            * This device does not support the platforms's max frame
690            * size. Use it's advertised mru instead.
691            */
692           max_rx_frame = dev_info.max_rx_pktlen;
693           mtu = dev_info.max_rx_pktlen - sizeof (ethernet_header_t);
694         }
695       else
696         {
697           /* VPP treats MTU and max_rx_pktlen both equal to
698            * ETHERNET_MAX_PACKET_BYTES, if dev_info.max_rx_pktlen >=
699            * ETHERNET_MAX_PACKET_BYTES + sizeof(ethernet_header_t)
700            */
701           if (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES +
702                                          sizeof (ethernet_header_t)))
703             {
704               mtu = ETHERNET_MAX_PACKET_BYTES;
705               max_rx_frame = ETHERNET_MAX_PACKET_BYTES;
706
707               /*
708                * Some platforms do not account for Ethernet FCS (4 bytes) in
709                * MTU calculations. To interop with them increase mru but only
710                * if the device's settings can support it.
711                */
712               if (dpdk_port_crc_strip_enabled (xd) &&
713                   (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES +
714                                               sizeof (ethernet_header_t) +
715                                               4)))
716                 {
717                   max_rx_frame += 4;
718                 }
719             }
720           else
721             {
722               max_rx_frame = ETHERNET_MAX_PACKET_BYTES;
723               mtu = ETHERNET_MAX_PACKET_BYTES - sizeof (ethernet_header_t);
724
725               if (dpdk_port_crc_strip_enabled (xd) &&
726                   (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + 4)))
727                 {
728                   max_rx_frame += 4;
729                 }
730             }
731         }
732
733       if (xd->pmd == VNET_DPDK_PMD_FAILSAFE)
734         {
735           /* failsafe device numerables are reported with active device only,
736            * need to query the mtu for current device setup to overwrite
737            * reported value.
738            */
739           uint16_t dev_mtu;
740           if (!rte_eth_dev_get_mtu (i, &dev_mtu))
741             {
742               mtu = dev_mtu;
743               max_rx_frame = mtu + sizeof (ethernet_header_t);
744
745               if (dpdk_port_crc_strip_enabled (xd))
746                 {
747                   max_rx_frame += 4;
748                 }
749             }
750         }
751
752       /*Set port rxmode config */
753       xd->port_conf.rxmode.max_rx_pkt_len = max_rx_frame;
754
755       sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->hw_if_index);
756       xd->sw_if_index = sw->sw_if_index;
757       vnet_hw_interface_set_input_node (dm->vnet_main, xd->hw_if_index,
758                                         dpdk_input_node.index);
759
760       if (devconf->workers)
761         {
762           int i;
763           q = 0;
764           clib_bitmap_foreach (i, devconf->workers, ({
765             vnet_hw_interface_assign_rx_thread (dm->vnet_main, xd->hw_if_index, q++,
766                                              vdm->first_worker_thread_index + i);
767           }));
768         }
769       else
770         for (q = 0; q < xd->rx_q_used; q++)
771           {
772             vnet_hw_interface_assign_rx_thread (dm->vnet_main, xd->hw_if_index, q,      /* any */
773                                                 ~1);
774           }
775
776       /*Get vnet hardware interface */
777       hi = vnet_get_hw_interface (dm->vnet_main, xd->hw_if_index);
778
779       /*Override default max_packet_bytes and max_supported_bytes set in
780        * ethernet_register_interface() above*/
781       if (hi)
782         {
783           hi->max_packet_bytes = mtu;
784           hi->max_supported_packet_bytes = max_rx_frame;
785         }
786
787       if (dm->conf->no_tx_checksum_offload == 0)
788         if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD && hi != NULL)
789           hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD;
790
791       dpdk_device_setup (xd);
792
793       if (vec_len (xd->errors))
794         dpdk_log_err ("setup failed for device %U. Errors:\n  %U",
795                       format_dpdk_device_name, i,
796                       format_dpdk_device_errors, xd);
797
798       if (devconf->hqos_enabled)
799         {
800           clib_error_t *rv;
801           rv = dpdk_port_setup_hqos (xd, &devconf->hqos);
802           if (rv)
803             return rv;
804         }
805
806       /*
807        * For cisco VIC vNIC, set default to VLAN strip enabled, unless
808        * specified otherwise in the startup config.
809        * For other NICs default to VLAN strip disabled, unless specified
810        * otherwise in the startup config.
811        */
812       if (xd->pmd == VNET_DPDK_PMD_ENIC)
813         {
814           if (devconf->vlan_strip_offload != DPDK_DEVICE_VLAN_STRIP_OFF)
815             vlan_strip = 1;     /* remove vlan tag from VIC port by default */
816           else
817             dpdk_log_warn ("VLAN strip disabled for interface\n");
818         }
819       else if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
820         vlan_strip = 1;
821
822       if (vlan_strip)
823         {
824           int vlan_off;
825           vlan_off = rte_eth_dev_get_vlan_offload (xd->port_id);
826           vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
827 #if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
828           xd->port_conf.rxmode.hw_vlan_strip = vlan_off;
829 #else
830           if (vlan_off)
831             xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
832           else
833             xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
834 #endif
835           if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) == 0)
836             dpdk_log_info ("VLAN strip enabled for interface\n");
837           else
838             dpdk_log_warn ("VLAN strip cannot be supported by interface\n");
839         }
840
841       if (hi)
842         hi->max_packet_bytes = xd->port_conf.rxmode.max_rx_pkt_len
843           - sizeof (ethernet_header_t);
844       else
845         clib_warning ("hi NULL");
846
847       if (dm->conf->no_multi_seg)
848         mtu = mtu > ETHER_MAX_LEN ? ETHER_MAX_LEN : mtu;
849
850       rte_eth_dev_set_mtu (xd->port_id, mtu);
851     }
852   /* *INDENT-ON* */
853
854   if (nb_desc > dm->conf->num_mbufs)
855     dpdk_log_err ("%d mbufs allocated but total rx/tx ring size is %d\n",
856                   dm->conf->num_mbufs, nb_desc);
857
858   return 0;
859 }
860
861 static void
862 dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
863 {
864   vlib_main_t *vm = vlib_get_main ();
865   clib_error_t *error;
866   u8 *pci_addr = 0;
867   int num_whitelisted = vec_len (conf->dev_confs);
868   vlib_pci_device_info_t *d = 0;
869   vlib_pci_addr_t *addr = 0, *addrs;
870
871   addrs = vlib_pci_get_all_dev_addrs ();
872   /* *INDENT-OFF* */
873   vec_foreach (addr, addrs)
874     {
875     dpdk_device_config_t * devconf = 0;
876     vec_reset_length (pci_addr);
877     pci_addr = format (pci_addr, "%U%c", format_vlib_pci_addr, addr, 0);
878     if (d)
879     {
880       vlib_pci_free_device_info (d);
881       d = 0;
882       }
883     d = vlib_pci_get_device_info (vm, addr, &error);
884     if (error)
885     {
886       clib_error_report (error);
887       continue;
888     }
889
890     if (d->device_class != PCI_CLASS_NETWORK_ETHERNET && d->device_class != PCI_CLASS_PROCESSOR_CO)
891       continue;
892
893     if (num_whitelisted)
894       {
895         uword * p = hash_get (conf->device_config_index_by_pci_addr, addr->as_u32);
896
897         if (!p)
898           continue;
899
900         devconf = pool_elt_at_index (conf->dev_confs, p[0]);
901       }
902
903     /* virtio */
904     if (d->vendor_id == 0x1af4 &&
905             (d->device_id == VIRTIO_PCI_LEGACY_DEVICEID_NET ||
906              d->device_id == VIRTIO_PCI_MODERN_DEVICEID_NET))
907       ;
908     /* vmxnet3 */
909     else if (d->vendor_id == 0x15ad && d->device_id == 0x07b0)
910       {
911         /*
912          * For vmxnet3 PCI, unless it is explicitly specified in the whitelist,
913          * the default is to put it in the blacklist.
914          */
915         if (devconf == 0)
916           {
917             pool_get (conf->dev_confs, devconf);
918             hash_set (conf->device_config_index_by_pci_addr, addr->as_u32,
919                       devconf - conf->dev_confs);
920             devconf->pci_addr.as_u32 = addr->as_u32;
921             devconf->is_blacklisted = 1;
922           }
923       }
924     /* all Intel network devices */
925     else if (d->vendor_id == 0x8086 && d->device_class == PCI_CLASS_NETWORK_ETHERNET)
926       ;
927     /* all Intel QAT devices VFs */
928     else if (d->vendor_id == 0x8086 && d->device_class == PCI_CLASS_PROCESSOR_CO &&
929         (d->device_id == 0x0443 || d->device_id == 0x37c9 || d->device_id == 0x19e3))
930       ;
931     /* Cisco VIC */
932     else if (d->vendor_id == 0x1137 && d->device_id == 0x0043)
933       ;
934     /* Chelsio T4/T5 */
935     else if (d->vendor_id == 0x1425 && (d->device_id & 0xe000) == 0x4000)
936       ;
937     /* Amazen Elastic Network Adapter */
938     else if (d->vendor_id == 0x1d0f && d->device_id >= 0xec20 && d->device_id <= 0xec21)
939       ;
940     /* Cavium Network Adapter */
941     else if (d->vendor_id == 0x177d && d->device_id == 0x9712)
942       ;
943     /* Cavium FastlinQ QL41000 Series */
944     else if (d->vendor_id == 0x1077 && d->device_id >= 0x8070 && d->device_id <= 0x8090)
945       ;
946     /* Mellanox mlx4 */
947     else if (d->vendor_id == 0x15b3 && d->device_id >= 0x1003 && d->device_id <= 0x1004)
948       {
949         continue;
950       }
951     /* Mellanox mlx5 */
952     else if (d->vendor_id == 0x15b3 && d->device_id >= 0x1013 && d->device_id <= 0x101a)
953       {
954         continue;
955       }
956     else
957       {
958         dpdk_log_warn ("Unsupported PCI device 0x%04x:0x%04x found "
959                       "at PCI address %s\n", (u16) d->vendor_id, (u16) d->device_id,
960                       pci_addr);
961         continue;
962       }
963
964     error = vlib_pci_bind_to_uio (vm, addr, (char *) conf->uio_driver_name);
965
966     if (error)
967       {
968         if (devconf == 0)
969           {
970             pool_get (conf->dev_confs, devconf);
971             hash_set (conf->device_config_index_by_pci_addr, addr->as_u32,
972                       devconf - conf->dev_confs);
973             devconf->pci_addr.as_u32 = addr->as_u32;
974           }
975         devconf->is_blacklisted = 1;
976         clib_error_report (error);
977       }
978   }
979   /* *INDENT-ON* */
980   vec_free (pci_addr);
981   vlib_pci_free_device_info (d);
982 }
983
984 static clib_error_t *
985 dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr,
986                     unformat_input_t * input, u8 is_default)
987 {
988   clib_error_t *error = 0;
989   uword *p;
990   dpdk_device_config_t *devconf;
991   unformat_input_t sub_input;
992
993   if (is_default)
994     {
995       devconf = &conf->default_devconf;
996     }
997   else
998     {
999       p = hash_get (conf->device_config_index_by_pci_addr, pci_addr.as_u32);
1000
1001       if (!p)
1002         {
1003           pool_get (conf->dev_confs, devconf);
1004           hash_set (conf->device_config_index_by_pci_addr, pci_addr.as_u32,
1005                     devconf - conf->dev_confs);
1006         }
1007       else
1008         return clib_error_return (0,
1009                                   "duplicate configuration for PCI address %U",
1010                                   format_vlib_pci_addr, &pci_addr);
1011     }
1012
1013   devconf->pci_addr.as_u32 = pci_addr.as_u32;
1014   devconf->hqos_enabled = 0;
1015   dpdk_device_config_hqos_default (&devconf->hqos);
1016
1017   if (!input)
1018     return 0;
1019
1020   unformat_skip_white_space (input);
1021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1022     {
1023       if (unformat (input, "num-rx-queues %u", &devconf->num_rx_queues))
1024         ;
1025       else if (unformat (input, "num-tx-queues %u", &devconf->num_tx_queues))
1026         ;
1027       else if (unformat (input, "num-rx-desc %u", &devconf->num_rx_desc))
1028         ;
1029       else if (unformat (input, "num-tx-desc %u", &devconf->num_tx_desc))
1030         ;
1031       else if (unformat (input, "workers %U", unformat_bitmap_list,
1032                          &devconf->workers))
1033         ;
1034       else
1035         if (unformat
1036             (input, "rss %U", unformat_vlib_cli_sub_input, &sub_input))
1037         {
1038           error = unformat_rss_fn (&sub_input, &devconf->rss_fn);
1039           if (error)
1040             break;
1041         }
1042       else if (unformat (input, "vlan-strip-offload off"))
1043         devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_OFF;
1044       else if (unformat (input, "vlan-strip-offload on"))
1045         devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_ON;
1046       else
1047         if (unformat
1048             (input, "hqos %U", unformat_vlib_cli_sub_input, &sub_input))
1049         {
1050           devconf->hqos_enabled = 1;
1051           error = unformat_hqos (&sub_input, &devconf->hqos);
1052           if (error)
1053             break;
1054         }
1055       else if (unformat (input, "hqos"))
1056         {
1057           devconf->hqos_enabled = 1;
1058         }
1059       else
1060         {
1061           error = clib_error_return (0, "unknown input `%U'",
1062                                      format_unformat_error, input);
1063           break;
1064         }
1065     }
1066
1067   if (error)
1068     return error;
1069
1070   if (devconf->workers && devconf->num_rx_queues == 0)
1071     devconf->num_rx_queues = clib_bitmap_count_set_bits (devconf->workers);
1072   else if (devconf->workers &&
1073            clib_bitmap_count_set_bits (devconf->workers) !=
1074            devconf->num_rx_queues)
1075     error =
1076       clib_error_return (0,
1077                          "%U: number of worker threads must be "
1078                          "equal to number of rx queues", format_vlib_pci_addr,
1079                          &pci_addr);
1080
1081   return error;
1082 }
1083
1084 static clib_error_t *
1085 dpdk_log_read_ready (clib_file_t * uf)
1086 {
1087   unformat_input_t input;
1088   u8 *line, *s = 0;
1089   int n, n_try;
1090
1091   n = n_try = 4096;
1092   while (n == n_try)
1093     {
1094       uword len = vec_len (s);
1095       vec_resize (s, len + n_try);
1096
1097       n = read (uf->file_descriptor, s + len, n_try);
1098       if (n < 0 && errno != EAGAIN)
1099         return clib_error_return_unix (0, "read");
1100       _vec_len (s) = len + (n < 0 ? 0 : n);
1101     }
1102
1103   unformat_init_vector (&input, s);
1104
1105   while (unformat_user (&input, unformat_line, &line))
1106     {
1107       dpdk_log_notice ("%v", line);
1108       vec_free (line);
1109     }
1110
1111   unformat_free (&input);
1112   return 0;
1113 }
1114
1115 static clib_error_t *
1116 dpdk_config (vlib_main_t * vm, unformat_input_t * input)
1117 {
1118   clib_error_t *error = 0;
1119   dpdk_config_main_t *conf = &dpdk_config_main;
1120   vlib_thread_main_t *tm = vlib_get_thread_main ();
1121   dpdk_device_config_t *devconf;
1122   vlib_pci_addr_t pci_addr;
1123   unformat_input_t sub_input;
1124   uword x;
1125   u8 *s, *tmp = 0;
1126   u32 log_level;
1127   int ret, i;
1128   int num_whitelisted = 0;
1129   u8 no_pci = 0;
1130   u8 no_huge = 0;
1131   u8 huge_dir = 0;
1132   u8 file_prefix = 0;
1133   u8 *socket_mem = 0;
1134   u8 *huge_dir_path = 0;
1135
1136   huge_dir_path =
1137     format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0);
1138
1139   conf->device_config_index_by_pci_addr = hash_create (0, sizeof (uword));
1140   log_level = RTE_LOG_NOTICE;
1141
1142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1143     {
1144       /* Prime the pump */
1145       if (unformat (input, "no-hugetlb"))
1146         {
1147           vec_add1 (conf->eal_init_args, (u8 *) "--no-huge");
1148           no_huge = 1;
1149         }
1150
1151       else if (unformat (input, "enable-tcp-udp-checksum"))
1152         conf->enable_tcp_udp_checksum = 1;
1153
1154       else if (unformat (input, "no-tx-checksum-offload"))
1155         conf->no_tx_checksum_offload = 1;
1156
1157       else if (unformat (input, "decimal-interface-names"))
1158         conf->interface_name_format_decimal = 1;
1159
1160       else if (unformat (input, "log-level %U", unformat_dpdk_log_level, &x))
1161         log_level = x;
1162
1163       else if (unformat (input, "no-multi-seg"))
1164         conf->no_multi_seg = 1;
1165
1166       else if (unformat (input, "dev default %U", unformat_vlib_cli_sub_input,
1167                          &sub_input))
1168         {
1169           error =
1170             dpdk_device_config (conf, (vlib_pci_addr_t) (u32) ~ 1, &sub_input,
1171                                 1);
1172
1173           if (error)
1174             return error;
1175         }
1176       else
1177         if (unformat
1178             (input, "dev %U %U", unformat_vlib_pci_addr, &pci_addr,
1179              unformat_vlib_cli_sub_input, &sub_input))
1180         {
1181           error = dpdk_device_config (conf, pci_addr, &sub_input, 0);
1182
1183           if (error)
1184             return error;
1185
1186           num_whitelisted++;
1187         }
1188       else if (unformat (input, "dev %U", unformat_vlib_pci_addr, &pci_addr))
1189         {
1190           error = dpdk_device_config (conf, pci_addr, 0, 0);
1191
1192           if (error)
1193             return error;
1194
1195           num_whitelisted++;
1196         }
1197       else if (unformat (input, "num-mem-channels %d", &conf->nchannels))
1198         conf->nchannels_set_manually = 0;
1199       else if (unformat (input, "num-mbufs %d", &conf->num_mbufs))
1200         ;
1201       else if (unformat (input, "uio-driver %s", &conf->uio_driver_name))
1202         ;
1203       else if (unformat (input, "socket-mem %s", &socket_mem))
1204         ;
1205       else if (unformat (input, "no-pci"))
1206         {
1207           no_pci = 1;
1208           tmp = format (0, "--no-pci%c", 0);
1209           vec_add1 (conf->eal_init_args, tmp);
1210         }
1211
1212 #define _(a)                                    \
1213       else if (unformat(input, #a))             \
1214         {                                       \
1215           tmp = format (0, "--%s%c", #a, 0);    \
1216           vec_add1 (conf->eal_init_args, tmp);    \
1217         }
1218       foreach_eal_double_hyphen_predicate_arg
1219 #undef _
1220 #define _(a)                                          \
1221         else if (unformat(input, #a " %s", &s))       \
1222           {                                           \
1223             if (!strncmp(#a, "huge-dir", 8))          \
1224               huge_dir = 1;                           \
1225             else if (!strncmp(#a, "file-prefix", 11)) \
1226               file_prefix = 1;                        \
1227             tmp = format (0, "--%s%c", #a, 0);        \
1228             vec_add1 (conf->eal_init_args, tmp);      \
1229             vec_add1 (s, 0);                          \
1230             if (!strncmp(#a, "vdev", 4))              \
1231               if (strstr((char*)s, "af_packet"))      \
1232                 clib_warning ("af_packet obsoleted. Use CLI 'create host-interface'."); \
1233             vec_add1 (conf->eal_init_args, s);        \
1234           }
1235         foreach_eal_double_hyphen_arg
1236 #undef _
1237 #define _(a,b)                                          \
1238           else if (unformat(input, #a " %s", &s))       \
1239             {                                           \
1240               tmp = format (0, "-%s%c", #b, 0);         \
1241               vec_add1 (conf->eal_init_args, tmp);      \
1242               vec_add1 (s, 0);                          \
1243               vec_add1 (conf->eal_init_args, s);        \
1244             }
1245         foreach_eal_single_hyphen_arg
1246 #undef _
1247 #define _(a,b)                                          \
1248             else if (unformat(input, #a " %s", &s))     \
1249               {                                         \
1250                 tmp = format (0, "-%s%c", #b, 0);       \
1251                 vec_add1 (conf->eal_init_args, tmp);    \
1252                 vec_add1 (s, 0);                        \
1253                 vec_add1 (conf->eal_init_args, s);      \
1254                 conf->a##_set_manually = 1;             \
1255               }
1256         foreach_eal_single_hyphen_mandatory_arg
1257 #undef _
1258         else if (unformat (input, "default"))
1259         ;
1260
1261       else if (unformat_skip_white_space (input))
1262         ;
1263       else
1264         {
1265           error = clib_error_return (0, "unknown input `%U'",
1266                                      format_unformat_error, input);
1267           goto done;
1268         }
1269     }
1270
1271   if (!conf->uio_driver_name)
1272     conf->uio_driver_name = format (0, "auto%c", 0);
1273
1274   /*
1275    * Use 1G huge pages if available.
1276    */
1277   if (!no_huge && !huge_dir)
1278     {
1279       u32 x, *mem_by_socket = 0;
1280       uword c = 0;
1281       int rv;
1282
1283       umount ((char *) huge_dir_path);
1284
1285       /* Process "socket-mem" parameter value */
1286       if (vec_len (socket_mem))
1287         {
1288           unformat_input_t in;
1289           unformat_init_vector (&in, socket_mem);
1290           while (unformat_check_input (&in) != UNFORMAT_END_OF_INPUT)
1291             {
1292               if (unformat (&in, "%u,", &x))
1293                 ;
1294               else if (unformat (&in, "%u", &x))
1295                 ;
1296               else if (unformat (&in, ","))
1297                 x = 0;
1298               else
1299                 break;
1300
1301               vec_add1 (mem_by_socket, x);
1302             }
1303           /* Note: unformat_free vec_frees(in.buffer), aka socket_mem... */
1304           unformat_free (&in);
1305           socket_mem = 0;
1306         }
1307       else
1308         {
1309           /* *INDENT-OFF* */
1310           clib_bitmap_foreach (c, tm->cpu_socket_bitmap, (
1311             {
1312               vec_validate(mem_by_socket, c);
1313               mem_by_socket[c] = 64; /* default per-socket mem */
1314             }
1315           ));
1316           /* *INDENT-ON* */
1317         }
1318
1319       uword default_hugepage_sz = clib_mem_get_default_hugepage_size ();
1320       /* *INDENT-OFF* */
1321       clib_bitmap_foreach (c, tm->cpu_socket_bitmap, (
1322         {
1323           clib_error_t *e;
1324           uword n_pages;
1325           vec_validate(mem_by_socket, c);
1326           n_pages = round_pow2 ((uword) mem_by_socket[c]<<20,
1327                                 default_hugepage_sz);
1328           n_pages /= default_hugepage_sz;
1329
1330           if ((e = clib_sysfs_prealloc_hugepages(c, 0, n_pages)))
1331             clib_error_report (e);
1332       }));
1333       /* *INDENT-ON* */
1334
1335       if (mem_by_socket == 0)
1336         {
1337           error = clib_error_return (0, "mem_by_socket NULL");
1338           goto done;
1339         }
1340       _vec_len (mem_by_socket) = c + 1;
1341
1342       /* regenerate socket_mem string */
1343       vec_foreach_index (x, mem_by_socket)
1344         socket_mem = format (socket_mem, "%s%u",
1345                              socket_mem ? "," : "", mem_by_socket[x]);
1346       socket_mem = format (socket_mem, "%c", 0);
1347
1348       vec_free (mem_by_socket);
1349
1350       error = vlib_unix_recursive_mkdir ((char *) huge_dir_path);
1351       if (error)
1352         {
1353           goto done;
1354         }
1355
1356       rv = mount ("none", (char *) huge_dir_path, "hugetlbfs", 0, NULL);
1357
1358       if (rv)
1359         {
1360           error = clib_error_return (0, "mount failed %d", errno);
1361           goto done;
1362         }
1363
1364       tmp = format (0, "--huge-dir%c", 0);
1365       vec_add1 (conf->eal_init_args, tmp);
1366       tmp = format (0, "%s%c", huge_dir_path, 0);
1367       vec_add1 (conf->eal_init_args, tmp);
1368       if (!file_prefix)
1369         {
1370           tmp = format (0, "--file-prefix%c", 0);
1371           vec_add1 (conf->eal_init_args, tmp);
1372           tmp = format (0, "vpp%c", 0);
1373           vec_add1 (conf->eal_init_args, tmp);
1374         }
1375     }
1376
1377   if (error)
1378     return error;
1379
1380   /* I'll bet that -c and -n must be the first and second args... */
1381   if (!conf->coremask_set_manually)
1382     {
1383       vlib_thread_registration_t *tr;
1384       uword *coremask = 0;
1385       int i;
1386
1387       /* main thread core */
1388       coremask = clib_bitmap_set (coremask, tm->main_lcore, 1);
1389
1390       for (i = 0; i < vec_len (tm->registrations); i++)
1391         {
1392           tr = tm->registrations[i];
1393           coremask = clib_bitmap_or (coremask, tr->coremask);
1394         }
1395
1396       vec_insert (conf->eal_init_args, 2, 1);
1397       conf->eal_init_args[1] = (u8 *) "-c";
1398       tmp = format (0, "%U%c", format_bitmap_hex, coremask, 0);
1399       conf->eal_init_args[2] = tmp;
1400       clib_bitmap_free (coremask);
1401     }
1402
1403   if (!conf->nchannels_set_manually)
1404     {
1405       vec_insert (conf->eal_init_args, 2, 3);
1406       conf->eal_init_args[3] = (u8 *) "-n";
1407       tmp = format (0, "%d", conf->nchannels);
1408       conf->eal_init_args[4] = tmp;
1409     }
1410
1411   if (no_pci == 0 && geteuid () == 0)
1412     dpdk_bind_devices_to_uio (conf);
1413
1414 #define _(x) \
1415     if (devconf->x == 0 && conf->default_devconf.x > 0) \
1416       devconf->x = conf->default_devconf.x ;
1417
1418   /* *INDENT-OFF* */
1419   pool_foreach (devconf, conf->dev_confs, ({
1420
1421     /* default per-device config items */
1422     foreach_dpdk_device_config_item
1423
1424     /* add DPDK EAL whitelist/blacklist entry */
1425     if (num_whitelisted > 0 && devconf->is_blacklisted == 0)
1426       {
1427         tmp = format (0, "-w%c", 0);
1428         vec_add1 (conf->eal_init_args, tmp);
1429         tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
1430         vec_add1 (conf->eal_init_args, tmp);
1431       }
1432     else if (num_whitelisted == 0 && devconf->is_blacklisted != 0)
1433       {
1434         tmp = format (0, "-b%c", 0);
1435         vec_add1 (conf->eal_init_args, tmp);
1436         tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
1437         vec_add1 (conf->eal_init_args, tmp);
1438       }
1439   }));
1440   /* *INDENT-ON* */
1441
1442 #undef _
1443
1444   /* set master-lcore */
1445   tmp = format (0, "--master-lcore%c", 0);
1446   vec_add1 (conf->eal_init_args, tmp);
1447   tmp = format (0, "%u%c", tm->main_lcore, 0);
1448   vec_add1 (conf->eal_init_args, tmp);
1449
1450   /* set socket-mem */
1451   if (!no_huge)
1452     {
1453       tmp = format (0, "--socket-mem%c", 0);
1454       vec_add1 (conf->eal_init_args, tmp);
1455       tmp = format (0, "%s%c", socket_mem, 0);
1456       vec_add1 (conf->eal_init_args, tmp);
1457     }
1458
1459   /* NULL terminate the "argv" vector, in case of stupidity */
1460   vec_add1 (conf->eal_init_args, 0);
1461   _vec_len (conf->eal_init_args) -= 1;
1462
1463   /* Set up DPDK eal and packet mbuf pool early. */
1464
1465   rte_log_set_global_level (log_level);
1466   int log_fds[2] = { 0 };
1467   if (pipe (log_fds) == 0)
1468     {
1469       if (fcntl (log_fds[1], F_SETFL, O_NONBLOCK) == 0)
1470         {
1471           FILE *f = fdopen (log_fds[1], "a");
1472           if (f && rte_openlog_stream (f) == 0)
1473             {
1474               clib_file_t t = { 0 };
1475               t.read_function = dpdk_log_read_ready;
1476               t.file_descriptor = log_fds[0];
1477               t.description = format (0, "DPDK logging pipe");
1478               clib_file_add (&file_main, &t);
1479             }
1480         }
1481       else
1482         {
1483           close (log_fds[0]);
1484           close (log_fds[1]);
1485         }
1486     }
1487
1488   vm = vlib_get_main ();
1489
1490   /* make copy of args as rte_eal_init tends to mess up with arg array */
1491   for (i = 1; i < vec_len (conf->eal_init_args); i++)
1492     conf->eal_init_args_str = format (conf->eal_init_args_str, "%s ",
1493                                       conf->eal_init_args[i]);
1494
1495   dpdk_log_warn ("EAL init args: %s", conf->eal_init_args_str);
1496   ret = rte_eal_init (vec_len (conf->eal_init_args),
1497                       (char **) conf->eal_init_args);
1498
1499   /* lazy umount hugepages */
1500   umount2 ((char *) huge_dir_path, MNT_DETACH);
1501   rmdir ((char *) huge_dir_path);
1502   vec_free (huge_dir_path);
1503
1504   if (ret < 0)
1505     return clib_error_return (0, "rte_eal_init returned %d", ret);
1506
1507   /* set custom ring memory allocator */
1508   {
1509     struct rte_mempool_ops *ops = NULL;
1510
1511     ops = get_ops_by_name ("ring_sp_sc");
1512     ops->alloc = dpdk_ring_alloc;
1513
1514     ops = get_ops_by_name ("ring_mp_sc");
1515     ops->alloc = dpdk_ring_alloc;
1516
1517     ops = get_ops_by_name ("ring_sp_mc");
1518     ops->alloc = dpdk_ring_alloc;
1519
1520     ops = get_ops_by_name ("ring_mp_mc");
1521     ops->alloc = dpdk_ring_alloc;
1522   }
1523
1524   /* main thread 1st */
1525   error = dpdk_buffer_pool_create (vm, conf->num_mbufs, rte_socket_id ());
1526   if (error)
1527     return error;
1528
1529   for (i = 0; i < RTE_MAX_LCORE; i++)
1530     {
1531       error = dpdk_buffer_pool_create (vm, conf->num_mbufs,
1532                                        rte_lcore_to_socket_id (i));
1533       if (error)
1534         return error;
1535     }
1536
1537 done:
1538   return error;
1539 }
1540
1541 VLIB_CONFIG_FUNCTION (dpdk_config, "dpdk");
1542
1543 void
1544 dpdk_update_link_state (dpdk_device_t * xd, f64 now)
1545 {
1546   vnet_main_t *vnm = vnet_get_main ();
1547   struct rte_eth_link prev_link = xd->link;
1548   u32 hw_flags = 0;
1549   u8 hw_flags_chg = 0;
1550
1551   /* only update link state for PMD interfaces */
1552   if ((xd->flags & DPDK_DEVICE_FLAG_PMD) == 0)
1553     return;
1554
1555   xd->time_last_link_update = now ? now : xd->time_last_link_update;
1556   clib_memset (&xd->link, 0, sizeof (xd->link));
1557   rte_eth_link_get_nowait (xd->port_id, &xd->link);
1558
1559   if (LINK_STATE_ELOGS)
1560     {
1561       vlib_main_t *vm = vlib_get_main ();
1562       ELOG_TYPE_DECLARE (e) =
1563       {
1564       .format =
1565           "update-link-state: sw_if_index %d, admin_up %d,"
1566           "old link_state %d new link_state %d",.format_args = "i4i1i1i1",};
1567
1568       struct
1569       {
1570         u32 sw_if_index;
1571         u8 admin_up;
1572         u8 old_link_state;
1573         u8 new_link_state;
1574       } *ed;
1575       ed = ELOG_DATA (&vm->elog_main, e);
1576       ed->sw_if_index = xd->sw_if_index;
1577       ed->admin_up = (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) != 0;
1578       ed->old_link_state = (u8)
1579         vnet_hw_interface_is_link_up (vnm, xd->hw_if_index);
1580       ed->new_link_state = (u8) xd->link.link_status;
1581     }
1582
1583   if ((xd->flags & (DPDK_DEVICE_FLAG_ADMIN_UP | DPDK_DEVICE_FLAG_BOND_SLAVE))
1584       && ((xd->link.link_status != 0) ^
1585           vnet_hw_interface_is_link_up (vnm, xd->hw_if_index)))
1586     {
1587       hw_flags_chg = 1;
1588       hw_flags |= (xd->link.link_status ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
1589     }
1590
1591   if (hw_flags_chg || (xd->link.link_duplex != prev_link.link_duplex))
1592     {
1593       hw_flags_chg = 1;
1594       switch (xd->link.link_duplex)
1595         {
1596         case ETH_LINK_HALF_DUPLEX:
1597           hw_flags |= VNET_HW_INTERFACE_FLAG_HALF_DUPLEX;
1598           break;
1599         case ETH_LINK_FULL_DUPLEX:
1600           hw_flags |= VNET_HW_INTERFACE_FLAG_FULL_DUPLEX;
1601           break;
1602         default:
1603           break;
1604         }
1605     }
1606   if (xd->link.link_speed != prev_link.link_speed)
1607     vnet_hw_interface_set_link_speed (vnm, xd->hw_if_index,
1608                                       xd->link.link_speed * 1000);
1609
1610   if (hw_flags_chg)
1611     {
1612       if (LINK_STATE_ELOGS)
1613         {
1614           vlib_main_t *vm = vlib_get_main ();
1615
1616           ELOG_TYPE_DECLARE (e) =
1617           {
1618           .format =
1619               "update-link-state: sw_if_index %d, new flags %d",.format_args
1620               = "i4i4",};
1621
1622           struct
1623           {
1624             u32 sw_if_index;
1625             u32 flags;
1626           } *ed;
1627           ed = ELOG_DATA (&vm->elog_main, e);
1628           ed->sw_if_index = xd->sw_if_index;
1629           ed->flags = hw_flags;
1630         }
1631       vnet_hw_interface_set_flags (vnm, xd->hw_if_index, hw_flags);
1632     }
1633 }
1634
1635 static uword
1636 dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
1637 {
1638   clib_error_t *error;
1639   vnet_main_t *vnm = vnet_get_main ();
1640   dpdk_main_t *dm = &dpdk_main;
1641   ethernet_main_t *em = &ethernet_main;
1642   dpdk_device_t *xd;
1643   vlib_thread_main_t *tm = vlib_get_thread_main ();
1644   int i;
1645   int j;
1646
1647   error = dpdk_lib_init (dm);
1648
1649   if (error)
1650     clib_error_report (error);
1651
1652   tm->worker_thread_release = 1;
1653
1654   f64 now = vlib_time_now (vm);
1655   vec_foreach (xd, dm->devices)
1656   {
1657     dpdk_update_link_state (xd, now);
1658   }
1659
1660   {
1661     /*
1662      * Extra set up for bond interfaces:
1663      *  1. Setup MACs for bond interfaces and their slave links which was set
1664      *     in dpdk_device_setup() but needs to be done again here to take
1665      *     effect.
1666      *  2. Set up info and register slave link state change callback handling.
1667      *  3. Set up info for bond interface related CLI support.
1668      */
1669     int nports = rte_eth_dev_count_avail ();
1670     if (nports > 0)
1671       {
1672         /* *INDENT-OFF* */
1673         RTE_ETH_FOREACH_DEV(i)
1674           {
1675             xd = NULL;
1676             for (j = 0; j < nports; j++)
1677               {
1678                 if (dm->devices[j].port_id == i)
1679                   {
1680                     xd = &dm->devices[j];
1681                   }
1682               }
1683             if (xd != NULL && xd->pmd == VNET_DPDK_PMD_BOND)
1684               {
1685                 u8 addr[6];
1686                 dpdk_portid_t slink[16];
1687                 int nlink = rte_eth_bond_slaves_get (i, slink, 16);
1688                 if (nlink > 0)
1689                   {
1690                     vnet_hw_interface_t *bhi;
1691                     ethernet_interface_t *bei;
1692                     int rv;
1693
1694                     /* Get MAC of 1st slave link */
1695                     rte_eth_macaddr_get
1696                       (slink[0], (struct ether_addr *) addr);
1697
1698                     /* Set MAC of bounded interface to that of 1st slave link */
1699                     dpdk_log_info ("Set MAC for bond port %d BondEthernet%d",
1700                                    i, xd->bond_instance_num);
1701                     rv = rte_eth_bond_mac_address_set
1702                       (i, (struct ether_addr *) addr);
1703                     if (rv)
1704                       dpdk_log_warn ("Set MAC addr failure rv=%d", rv);
1705
1706                     /* Populate MAC of bonded interface in VPP hw tables */
1707                     bhi = vnet_get_hw_interface
1708                       (vnm, dm->devices[i].hw_if_index);
1709                     bei = pool_elt_at_index
1710                       (em->interfaces, bhi->hw_instance);
1711                     clib_memcpy (bhi->hw_address, addr, 6);
1712                     clib_memcpy (bei->address, addr, 6);
1713
1714                     /* Init l3 packet size allowed on bonded interface */
1715                     bhi->max_packet_bytes = ETHERNET_MAX_PACKET_BYTES;
1716                     while (nlink >= 1)
1717                       {         /* for all slave links */
1718                         int slave = slink[--nlink];
1719                         dpdk_device_t *sdev = &dm->devices[slave];
1720                         vnet_hw_interface_t *shi;
1721                         vnet_sw_interface_t *ssi;
1722                         ethernet_interface_t *sei;
1723                         /* Add MAC to all slave links except the first one */
1724                         if (nlink)
1725                           {
1726                             dpdk_log_info ("Add MAC for slave port %d",
1727                                            slave);
1728                             rv = rte_eth_dev_mac_addr_add
1729                               (slave, (struct ether_addr *) addr, 0);
1730                             if (rv)
1731                               dpdk_log_warn ("Add MAC addr failure rv=%d",
1732                                              rv);
1733                           }
1734                         /* Setup slave link state change callback handling */
1735                         rte_eth_dev_callback_register
1736                           (slave, RTE_ETH_EVENT_INTR_LSC,
1737                            dpdk_port_state_callback, NULL);
1738                         dpdk_device_t *sxd = &dm->devices[slave];
1739                         sxd->flags |= DPDK_DEVICE_FLAG_BOND_SLAVE;
1740                         sxd->bond_port = i;
1741                         /* Set slaves bitmap for bonded interface */
1742                         bhi->bond_info = clib_bitmap_set
1743                           (bhi->bond_info, sdev->hw_if_index, 1);
1744                         /* Set MACs and slave link flags on slave interface */
1745                         shi = vnet_get_hw_interface (vnm, sdev->hw_if_index);
1746                         ssi = vnet_get_sw_interface (vnm, sdev->sw_if_index);
1747                         sei = pool_elt_at_index
1748                           (em->interfaces, shi->hw_instance);
1749                         shi->bond_info = VNET_HW_INTERFACE_BOND_INFO_SLAVE;
1750                         ssi->flags |= VNET_SW_INTERFACE_FLAG_BOND_SLAVE;
1751                         clib_memcpy (shi->hw_address, addr, 6);
1752                         clib_memcpy (sei->address, addr, 6);
1753                         /* Set l3 packet size allowed as the lowest of slave */
1754                         if (bhi->max_packet_bytes > shi->max_packet_bytes)
1755                           bhi->max_packet_bytes = shi->max_packet_bytes;
1756                       }
1757                   }
1758               }
1759           }
1760         /* *INDENT-ON* */
1761       }
1762   }
1763
1764   while (1)
1765     {
1766       /*
1767        * check each time through the loop in case intervals are changed
1768        */
1769       f64 min_wait = dm->link_state_poll_interval < dm->stat_poll_interval ?
1770         dm->link_state_poll_interval : dm->stat_poll_interval;
1771
1772       vlib_process_wait_for_event_or_clock (vm, min_wait);
1773
1774       if (dm->admin_up_down_in_progress)
1775         /* skip the poll if an admin up down is in progress (on any interface) */
1776         continue;
1777
1778       vec_foreach (xd, dm->devices)
1779       {
1780         f64 now = vlib_time_now (vm);
1781         if ((now - xd->time_last_stats_update) >= dm->stat_poll_interval)
1782           dpdk_update_counters (xd, now);
1783         if ((now - xd->time_last_link_update) >= dm->link_state_poll_interval)
1784           dpdk_update_link_state (xd, now);
1785
1786       }
1787     }
1788
1789   return 0;
1790 }
1791
1792 /* *INDENT-OFF* */
1793 VLIB_REGISTER_NODE (dpdk_process_node,static) = {
1794     .function = dpdk_process,
1795     .type = VLIB_NODE_TYPE_PROCESS,
1796     .name = "dpdk-process",
1797     .process_log2_n_stack_bytes = 17,
1798 };
1799 /* *INDENT-ON* */
1800
1801 static clib_error_t *
1802 dpdk_init (vlib_main_t * vm)
1803 {
1804   dpdk_main_t *dm = &dpdk_main;
1805   clib_error_t *error = 0;
1806
1807   /* verify that structs are cacheline aligned */
1808   STATIC_ASSERT (offsetof (dpdk_device_t, cacheline0) == 0,
1809                  "Cache line marker must be 1st element in dpdk_device_t");
1810   STATIC_ASSERT (offsetof (dpdk_device_t, cacheline1) ==
1811                  CLIB_CACHE_LINE_BYTES,
1812                  "Data in cache line 0 is bigger than cache line size");
1813   STATIC_ASSERT (offsetof (frame_queue_trace_t, cacheline0) == 0,
1814                  "Cache line marker must be 1st element in frame_queue_trace_t");
1815   STATIC_ASSERT (RTE_CACHE_LINE_SIZE == 1 << CLIB_LOG2_CACHE_LINE_BYTES,
1816                  "DPDK RTE CACHE LINE SIZE does not match with 1<<CLIB_LOG2_CACHE_LINE_BYTES");
1817
1818   dm->vlib_main = vm;
1819   dm->vnet_main = vnet_get_main ();
1820   dm->conf = &dpdk_config_main;
1821
1822   dm->conf->nchannels = 4;
1823   dm->conf->num_mbufs = dm->conf->num_mbufs ? dm->conf->num_mbufs : NB_MBUF;
1824   vec_add1 (dm->conf->eal_init_args, (u8 *) "vnet");
1825
1826   /* Default vlib_buffer_t flags, DISABLES tcp/udp checksumming... */
1827   dm->buffer_flags_template =
1828     (VLIB_BUFFER_TOTAL_LENGTH_VALID | VLIB_BUFFER_EXT_HDR_VALID
1829      | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED |
1830      VNET_BUFFER_F_L4_CHECKSUM_CORRECT | VNET_BUFFER_F_L2_HDR_OFFSET_VALID);
1831
1832   dm->stat_poll_interval = DPDK_STATS_POLL_INTERVAL;
1833   dm->link_state_poll_interval = DPDK_LINK_POLL_INTERVAL;
1834
1835   /* init CLI */
1836   if ((error = vlib_call_init_function (vm, dpdk_cli_init)))
1837     return error;
1838
1839   dm->log_default = vlib_log_register_class ("dpdk", 0);
1840
1841   return error;
1842 }
1843
1844 VLIB_INIT_FUNCTION (dpdk_init);
1845
1846
1847 /*
1848  * fd.io coding-style-patch-verification: ON
1849  *
1850  * Local Variables:
1851  * eval: (c-set-style "gnu")
1852  * End:
1853  */