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