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