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