FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
pci.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 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 
16 #include <fcntl.h>
17 #include <sys/ioctl.h>
18 
19 #include <vppinfra/types.h>
20 #include <vlib/vlib.h>
21 #include <vlib/pci/pci.h>
22 #include <vnet/ethernet/ethernet.h>
23 #include <vnet/ip/ip4_packet.h>
24 #include <vnet/ip/ip6_packet.h>
27 
28 #define PCI_VENDOR_ID_VIRTIO 0x1af4
29 #define PCI_DEVICE_ID_VIRTIO_NIC 0x1000
30 /* Doesn't support modern device */
31 #define PCI_DEVICE_ID_VIRTIO_NIC_MODERN 0x1041
32 
33 #define PCI_CAPABILITY_LIST 0x34
34 #define PCI_CAP_ID_VNDR 0x09
35 #define PCI_CAP_ID_MSIX 0x11
36 
37 #define PCI_MSIX_ENABLE 0x8000
38 
39 #define PCI_CONFIG_SIZE(vif) ((vif->msix_enabled == VIRTIO_MSIX_ENABLED) ? \
40  24 : 20)
41 
42 static pci_device_id_t virtio_pci_device_ids[] = {
43  {
45  .device_id = PCI_DEVICE_ID_VIRTIO_NIC},
46  {
47  .vendor_id = PCI_VENDOR_ID_VIRTIO,
48  .device_id = PCI_DEVICE_ID_VIRTIO_NIC_MODERN},
49  {0},
50 };
51 
52 static void
54  int len, u32 addr)
55 {
56  u32 size = 0;
58 
59  while (len > 0)
60  {
61  if (len >= 4)
62  {
63  size = 4;
64  vlib_pci_read_io_u32 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst);
65  }
66  else if (len >= 2)
67  {
68  size = 2;
69  vlib_pci_read_io_u16 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst);
70  }
71  else
72  {
73  size = 1;
74  vlib_pci_read_io_u8 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst);
75  }
76  dst = (u8 *) dst + size;
77  addr += size;
78  len -= size;
79  }
80 }
81 
82 static void
84  void *src, int len, u32 addr)
85 {
86  u32 size = 0;
88 
89  while (len > 0)
90  {
91  if (len >= 4)
92  {
93  size = 4;
94  vlib_pci_write_io_u32 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src);
95  }
96  else if (len >= 2)
97  {
98  size = 2;
99  vlib_pci_write_io_u16 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src);
100  }
101  else
102  {
103  size = 1;
104  vlib_pci_write_io_u8 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src);
105  }
106  src = (u8 *) src + size;
107  addr += size;
108  len -= size;
109  }
110 }
111 
112 static u64
114 {
115  u32 features;
116  vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_HOST_FEATURES,
117  &features);
118  return features;
119 }
120 
121 static u32
123 {
124  u32 feature = 0;
125  vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES,
126  &feature);
127  vif->features = feature;
128  return feature;
129 }
130 
131 static u32
133  u64 features)
134 {
135  if ((features >> 32) != 0)
136  {
137  clib_warning ("only 32 bit features are allowed for legacy virtio!");
138  }
139  u32 feature = 0, guest_features = (u32) features;
140  vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES,
141  &guest_features);
142  vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES,
143  &feature);
144  return feature;
145 }
146 
147 static u8
149 {
150  u8 status = 0;
151  vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &status);
152  return status;
153 }
154 
155 static void
157 {
158  if (status != VIRTIO_CONFIG_STATUS_RESET)
159  status |= virtio_pci_legacy_get_status (vm, vif);
160  vlib_pci_write_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &status);
161 }
162 
163 static u8
165 {
166  virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_RESET);
167  return virtio_pci_legacy_get_status (vm, vif);
168 }
169 
170 static u8
172 {
173  u8 isr = 0;
174  vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_ISR, &isr);
175  return isr;
176 }
177 
178 static u16
180  u16 queue_id)
181 {
182  u16 queue_num = 0;
183  vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
184  &queue_id);
185  vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NUM,
186  &queue_num);
187  return queue_num;
188 }
189 
190 static int
192  u16 queue_id, void *p)
193 {
195  u32 addr2 = 0;
196  vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
197  &queue_id);
198  vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN,
199  (u32 *) & addr);
200  vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN,
201  &addr2);
202  if ((u32) addr == addr2)
203  return 0;
204  return 1;
205 }
206 
207 static void
209  u16 queue_id)
210 {
211  u32 src = 0;
212  vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
213  &queue_id);
214  vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, &src);
215 }
216 
217 inline void
219  u16 queue_id)
220 {
221  vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY,
222  &queue_id);
223 }
224 
225 /* Enable one vector (0) for Link State Intrerrupt */
226 static u16
228  u16 vec)
229 {
230  vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR,
231  &vec);
232  vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR,
233  &vec);
234  return vec;
235 }
236 
237 static u16
239  u16 queue_id)
240 {
241  vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
242  &queue_id);
243  vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR,
244  &vec);
245  vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR,
246  &vec);
247  return vec;
248 }
249 
250 static u32
252  u32 flags)
253 {
254  return 0;
255 }
256 
257 static clib_error_t *
259 {
260  virtio_net_config_t config;
261  clib_error_t *error = 0;
262  u16 max_queue_pairs = 1;
263 
264  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ))
265  {
267  sizeof (config.max_virtqueue_pairs),
269  max_virtqueue_pairs));
270  max_queue_pairs = config.max_virtqueue_pairs;
271  }
272 
273  virtio_log_debug (vif, "max queue pair is %x", max_queue_pairs);
274  if (max_queue_pairs < 1 || max_queue_pairs > 0x8000)
275  return clib_error_return (error, "max queue pair is %x", max_queue_pairs);
276 
277  vif->max_queue_pairs = max_queue_pairs;
278  return error;
279 }
280 
281 static void
283 {
285  sizeof (vif->mac_addr), 0);
286 }
287 
288 static u32
290 {
291  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MAC))
292  {
294  sizeof (vif->mac_addr), 0);
295  return 0;
296  }
297  return 1;
298 }
299 
300 static u16
302 {
303  /*
304  * Minimal driver: assumes link is up
305  */
306  u16 status = 1;
307  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_STATUS))
308  virtio_pci_legacy_read_config (vm, vif, &status, sizeof (status), /* mac */
310  status));
311  return status;
312 }
313 
314 static void
316 {
317  vnet_main_t *vnm = vnet_get_main ();
318  virtio_main_t *vim = &virtio_main;
319  uword pd = vlib_pci_get_private_data (vm, h);
320  virtio_if_t *vif = pool_elt_at_index (vim->interfaces, pd);
321  u16 qid = line;
322 
324 }
325 
326 static void
328 {
329  vnet_main_t *vnm = vnet_get_main ();
330  virtio_main_t *vim = &virtio_main;
331  uword pd = vlib_pci_get_private_data (vm, h);
332  virtio_if_t *vif = pool_elt_at_index (vim->interfaces, pd);
333 
334  if (virtio_pci_is_link_up (vm, vif) & VIRTIO_NET_S_LINK_UP)
335  {
336  vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
339  }
340  else
341  {
342  vif->flags &= ~VIRTIO_IF_FLAG_ADMIN_UP;
344  }
345 }
346 
347 static void
349 {
350  virtio_main_t *vim = &virtio_main;
351  uword pd = vlib_pci_get_private_data (vm, h);
352  virtio_if_t *vif = pool_elt_at_index (vim->interfaces, pd);
353  u8 isr = 0;
354  u16 line = 0;
355 
356  isr = virtio_pci_legacy_get_isr (vm, vif);
357 
358  /*
359  * If the lower bit is set: look through the used rings of
360  * all virtqueues for the device, to see if any progress has
361  * been made by the device which requires servicing.
362  */
363  if (isr & VIRTIO_PCI_ISR_INTR)
364  virtio_pci_irq_0_handler (vm, h, line);
365 
366  if (isr & VIRTIO_PCI_ISR_CONFIG)
367  virtio_pci_irq_1_handler (vm, h, line);
368 }
369 
370 inline void
372 {
373  struct status_struct
374  {
375  u8 bit;
376  char *str;
377  };
378  struct status_struct *status_entry;
379  static struct status_struct status_array[] = {
380 #define _(s,b) { .str = #s, .bit = b, },
382 #undef _
383  {.str = NULL}
384  };
385 
386  vlib_cli_output (vm, " status 0x%x", vif->status);
387 
388  status_entry = (struct status_struct *) &status_array;
389  while (status_entry->str)
390  {
391  if (vif->status & status_entry->bit)
392  vlib_cli_output (vm, " %s (%x)", status_entry->str,
393  status_entry->bit);
394  status_entry++;
395  }
396 }
397 
398 inline void
400 {
401  u32 data_u32;
402  u16 data_u16;
403  u8 data_u8;
404  vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_HOST_FEATURES,
405  &data_u32);
406  vlib_cli_output (vm, "remote features 0x%lx", data_u32);
407  vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES,
408  &data_u32);
409  vlib_cli_output (vm, "guest features 0x%lx", data_u32);
410  vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN,
411  &data_u32);
412  vlib_cli_output (vm, "queue address 0x%lx", data_u32);
413  vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NUM,
414  &data_u16);
415  vlib_cli_output (vm, "queue size 0x%x", data_u16);
416  vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
417  &data_u16);
418  vlib_cli_output (vm, "queue select 0x%x", data_u16);
419  vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY,
420  &data_u16);
421  vlib_cli_output (vm, "queue notify 0x%x", data_u16);
422  vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &data_u8);
423  vlib_cli_output (vm, "status 0x%x", data_u8);
424  vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_ISR, &data_u8);
425  vlib_cli_output (vm, "isr 0x%x", data_u8);
426 
427  if (vif->msix_enabled == VIRTIO_MSIX_ENABLED)
428  {
429  vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR,
430  &data_u16);
431  vlib_cli_output (vm, "config vector 0x%x", data_u16);
432  u16 queue_id = 0;
433  vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
434  &queue_id);
435  vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR,
436  &data_u16);
437  vlib_cli_output (vm, "queue vector for queue (0) 0x%x", data_u16);
438  }
439 
440  u8 mac[6];
441  virtio_pci_legacy_read_config (vm, vif, mac, sizeof (mac), 0);
442  vlib_cli_output (vm, "mac %U", format_ethernet_address, mac);
443  virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16), /* offset to status */
444  6);
445  vlib_cli_output (vm, "link up/down status 0x%x", data_u16);
446  virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16),
447  /* offset to max_virtqueue */ 8);
448  vlib_cli_output (vm, "num of virtqueue 0x%x", data_u16);
449  virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16), /* offset to mtu */
450  10);
451  vlib_cli_output (vm, "mtu 0x%x", data_u16);
452 
453  u32 i = PCI_CONFIG_SIZE (vif) + 12, a = 4;
454  i += a;
455  i &= ~a;
456  for (; i < 64; i += 4)
457  {
458  u32 data = 0;
459  vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, i, &data);
460  vlib_cli_output (vm, "0x%lx", data);
461  }
462 }
463 
465 {
466  struct virtio_net_ctrl_hdr ctrl;
467  virtio_net_ctrl_ack status;
468  u8 data[1024];
469 };
470 
471 static int
473  struct virtio_ctrl_msg *data, u32 len)
474 {
475  virtio_vring_t *vring = vif->cxq_vring;
476  virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
477  struct virtio_ctrl_msg result;
478  u32 buffer_index;
479  vlib_buffer_t *b;
480  u16 used, next, avail;
481  u16 sz = vring->size;
482  u16 mask = sz - 1;
483 
484  used = vring->desc_in_use;
485  next = vring->desc_next;
486  avail = vring->avail->idx;
487  struct vring_desc *d = &vring->desc[next];
488 
489  if (vlib_buffer_alloc (vm, &buffer_index, 1))
490  b = vlib_get_buffer (vm, buffer_index);
491  else
492  return VIRTIO_NET_ERR;
493  /*
494  * current_data may not be initialized with 0 and may contain
495  * previous offset.
496  */
497  b->current_data = 0;
499  sizeof (struct virtio_ctrl_msg));
500  d->flags = VRING_DESC_F_NEXT;
501  d->addr = vlib_buffer_get_current_pa (vm, b);
502  d->len = sizeof (struct virtio_net_ctrl_hdr);
503  vring->avail->ring[avail & mask] = next;
504  avail++;
505  next = (next + 1) & mask;
506  d->next = next;
507  used++;
508 
509  d = &vring->desc[next];
510  d->flags = VRING_DESC_F_NEXT;
511  d->addr = vlib_buffer_get_current_pa (vm, b) +
512  STRUCT_OFFSET_OF (struct virtio_ctrl_msg, data);
513  d->len = len;
514  next = (next + 1) & mask;
515  d->next = next;
516  used++;
517 
518  d = &vring->desc[next];
519  d->flags = VRING_DESC_F_WRITE;
520  d->addr = vlib_buffer_get_current_pa (vm, b) +
521  STRUCT_OFFSET_OF (struct virtio_ctrl_msg, status);
522  d->len = sizeof (data->status);
523  next = (next + 1) & mask;
524  used++;
525 
527  vring->avail->idx = avail;
528  vring->desc_next = next;
529  vring->desc_in_use = used;
530 
531  if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0)
532  {
533  virtio_kick (vm, vring, vif);
534  }
535 
536  u16 last = vring->last_used_idx, n_left = 0;
537  n_left = vring->used->idx - last;
538 
539  while (n_left)
540  {
541  struct vring_used_elem *e = &vring->used->ring[last & mask];
542  u16 slot = e->id;
543 
544  d = &vring->desc[slot];
545  while (d->flags & VRING_DESC_F_NEXT)
546  {
547  used--;
548  slot = d->next;
549  d = &vring->desc[slot];
550  }
551  used--;
552  last++;
553  n_left--;
554  }
555  vring->desc_in_use = used;
556  vring->last_used_idx = last;
557 
559  clib_memcpy (&result, vlib_buffer_get_current (b),
560  sizeof (struct virtio_ctrl_msg));
561  virtio_log_debug (vif, "ctrl-queue: status %u", result.status);
562  status = result.status;
563  vlib_buffer_free (vm, &buffer_index, 1);
564  return status;
565 }
566 
567 static int
569 {
570  struct virtio_ctrl_msg offload_hdr;
571  virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
572 
573  offload_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
574  offload_hdr.ctrl.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
575  offload_hdr.status = VIRTIO_NET_ERR;
576  u64 offloads = 0ULL;
577  clib_memcpy (offload_hdr.data, &offloads, sizeof (offloads));
578 
579  status =
580  virtio_pci_send_ctrl_msg (vm, vif, &offload_hdr, sizeof (offloads));
581  virtio_log_debug (vif, "disable offloads");
584  return status;
585 }
586 
587 static int
589 {
590  struct virtio_ctrl_msg csum_offload_hdr;
591  virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
592 
593  csum_offload_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
594  csum_offload_hdr.ctrl.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
595  csum_offload_hdr.status = VIRTIO_NET_ERR;
596  u64 offloads = 0ULL;
597  offloads |= VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM);
598  clib_memcpy (csum_offload_hdr.data, &offloads, sizeof (offloads));
599 
600  status =
601  virtio_pci_send_ctrl_msg (vm, vif, &csum_offload_hdr, sizeof (offloads));
602  virtio_log_debug (vif, "enable checksum offload");
605  return status;
606 }
607 
608 static int
610 {
611  struct virtio_ctrl_msg gso_hdr;
612  virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
613 
614  gso_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
616  gso_hdr.status = VIRTIO_NET_ERR;
617  u64 offloads = VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
618  | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
619  | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6);
620  clib_memcpy (gso_hdr.data, &offloads, sizeof (offloads));
621 
622  status = virtio_pci_send_ctrl_msg (vm, vif, &gso_hdr, sizeof (offloads));
623  virtio_log_debug (vif, "enable gso");
626  return status;
627 }
628 
629 static int
630 virtio_pci_offloads (vlib_main_t * vm, virtio_if_t * vif, int gso_enabled,
631  int csum_offload_enabled)
632 {
633  vnet_main_t *vnm = vnet_get_main ();
635 
636  if ((vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) &&
638  {
639  if (gso_enabled
640  && (vif->features & (VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO4) |
641  VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO6))))
642  {
643  if (virtio_pci_enable_gso (vm, vif))
644  {
645  virtio_log_warning (vif, "gso is not enabled");
646  }
647  else
648  {
649  vif->gso_enabled = 1;
650  vif->csum_offload_enabled = 0;
653  }
654  }
655  else if (csum_offload_enabled
656  && (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CSUM)))
657  {
659  {
660  virtio_log_warning (vif, "checksum offload is not enabled");
661  }
662  else
663  {
664  vif->csum_offload_enabled = 1;
665  vif->gso_enabled = 0;
667  hw->flags |=
669  }
670  }
671  else
672  {
673  if (virtio_pci_disable_offload (vm, vif))
674  {
675  virtio_log_warning (vif, "offloads are not disabled");
676  }
677  else
678  {
679  vif->csum_offload_enabled = 0;
680  vif->gso_enabled = 0;
683  }
684  }
685  }
686 
687  return 0;
688 }
689 
690 static int
692  u16 num_queues)
693 {
694  struct virtio_ctrl_msg mq_hdr;
695  virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
696 
697  mq_hdr.ctrl.class = VIRTIO_NET_CTRL_MQ;
699  mq_hdr.status = VIRTIO_NET_ERR;
700  clib_memcpy (mq_hdr.data, &num_queues, sizeof (num_queues));
701 
702  status = virtio_pci_send_ctrl_msg (vm, vif, &mq_hdr, sizeof (num_queues));
703  virtio_log_debug (vif, "multi-queue enable %u queues", num_queues);
704  return status;
705 }
706 
707 static u8
709 {
710  if (qsz < 64 || qsz > 4096)
711  return 0;
712  if ((qsz % 64) != 0)
713  return 0;
714  return 1;
715 }
716 
717 clib_error_t *
719  u16 queue_num)
720 {
721  clib_error_t *error = 0;
722  u16 queue_size = 0;
723  virtio_vring_t *vring;
724  struct vring vr;
725  u32 i = 0;
726  void *ptr = NULL;
727 
728  queue_size = virtio_pci_legacy_get_queue_num (vm, vif, queue_num);
729  if (!virtio_pci_queue_size_valid (queue_size))
730  clib_warning ("queue size is not valid");
731 
732  if (!is_pow2 (queue_size))
733  return clib_error_return (0, "ring size must be power of 2");
734 
735  if (queue_size > 32768)
736  return clib_error_return (0, "ring size must be 32768 or lower");
737 
738  if (queue_size == 0)
739  queue_size = 256;
740 
742  vring = vec_elt_at_index (vif->cxq_vring, 0);
743  i = vring_size (queue_size, VIRTIO_PCI_VRING_ALIGN);
745  ptr =
747  vif->numa_node);
748  if (!ptr)
749  return vlib_physmem_last_error (vm);
750  clib_memset (ptr, 0, i);
751  vring_init (&vr, queue_size, ptr, VIRTIO_PCI_VRING_ALIGN);
752  vring->desc = vr.desc;
753  vring->avail = vr.avail;
754  vring->used = vr.used;
755  vring->queue_id = queue_num;
756  vring->avail->flags = VIRTIO_RING_FLAG_MASK_INT;
757 
758  ASSERT (vring->buffers == 0);
759 
760  vring->size = queue_size;
761  virtio_log_debug (vif, "control-queue: number %u, size %u", queue_num,
762  queue_size);
763  virtio_pci_legacy_setup_queue (vm, vif, queue_num, ptr);
764  vring->kick_fd = -1;
765 
766  return error;
767 }
768 
769 clib_error_t *
771 {
772  clib_error_t *error = 0;
773  u16 queue_size = 0;
774  virtio_vring_t *vring;
775  struct vring vr;
776  u32 i = 0;
777  void *ptr = NULL;
778 
779  queue_size = virtio_pci_legacy_get_queue_num (vm, vif, queue_num);
780  if (!virtio_pci_queue_size_valid (queue_size))
781  clib_warning ("queue size is not valid");
782 
783  if (!is_pow2 (queue_size))
784  return clib_error_return (0, "ring size must be power of 2");
785 
786  if (queue_size > 32768)
787  return clib_error_return (0, "ring size must be 32768 or lower");
788 
789  if (queue_size == 0)
790  queue_size = 256;
791 
792  if (queue_num % 2)
793  {
796  vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num));
797  clib_spinlock_init (&vring->lockp);
798  }
799  else
800  {
803  vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS (queue_num));
804  }
805  i = vring_size (queue_size, VIRTIO_PCI_VRING_ALIGN);
807  ptr =
809  vif->numa_node);
810  if (!ptr)
811  return vlib_physmem_last_error (vm);
812  clib_memset (ptr, 0, i);
813  vring_init (&vr, queue_size, ptr, VIRTIO_PCI_VRING_ALIGN);
814  vring->desc = vr.desc;
815  vring->avail = vr.avail;
816  vring->used = vr.used;
817  vring->queue_id = queue_num;
818  vring->avail->flags = VIRTIO_RING_FLAG_MASK_INT;
819 
820  ASSERT (vring->buffers == 0);
821  vec_validate_aligned (vring->buffers, queue_size, CLIB_CACHE_LINE_BYTES);
822  if (queue_num % 2)
823  {
824  virtio_log_debug (vif, "tx-queue: number %u, size %u", queue_num,
825  queue_size);
826  clib_memset_u32 (vring->buffers, ~0, queue_size);
827  }
828  else
829  {
830  virtio_log_debug (vif, "rx-queue: number %u, size %u", queue_num,
831  queue_size);
832  }
833  vring->size = queue_size;
834  if (virtio_pci_legacy_setup_queue (vm, vif, queue_num, ptr))
835  return clib_error_return (0, "error in queue address setup");
836 
837  vring->kick_fd = -1;
838  return error;
839 }
840 
841 static void
843  u64 req_features)
844 {
845  /*
846  * if features are not requested
847  * default: all supported features
848  */
849  u64 supported_features = VIRTIO_FEATURE (VIRTIO_NET_F_CSUM)
850  | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
853  | VIRTIO_FEATURE (VIRTIO_NET_F_MAC)
854  | VIRTIO_FEATURE (VIRTIO_NET_F_GSO)
855  | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
856  | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6)
857  | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO)
858  | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO4)
859  | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO6)
860  | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_UFO)
861  | VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)
862  | VIRTIO_FEATURE (VIRTIO_NET_F_STATUS)
863  | VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)
864  | VIRTIO_FEATURE (VIRTIO_NET_F_MQ)
865  | VIRTIO_FEATURE (VIRTIO_F_NOTIFY_ON_EMPTY)
866  | VIRTIO_FEATURE (VIRTIO_F_ANY_LAYOUT)
867  | VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC);
868 
869  if (req_features == 0)
870  {
871  req_features = supported_features;
872  }
873 
874  vif->features = req_features & vif->remote_features & supported_features;
875 
877  {
878  virtio_net_config_t config;
879  virtio_pci_legacy_read_config (vm, vif, &config.mtu,
880  sizeof (config.mtu),
882  mtu));
883  if (config.mtu < 64)
885  }
886 
887  vif->features =
889 }
890 
891 void
893 {
895 }
896 
897 int
899 {
900  u8 status = 0;
901 
902  /*
903  * Reset the device
904  */
905  status = virtio_pci_legacy_reset (vm, vif);
906 
907  /*
908  * Set the Acknowledge status bit
909  */
910  virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_ACK);
911 
912  /*
913  * Set the Driver status bit
914  */
915  virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_DRIVER);
916 
917  /*
918  * Read the status and verify it
919  */
920  status = virtio_pci_legacy_get_status (vm, vif);
921  if (!
922  ((status & VIRTIO_CONFIG_STATUS_ACK)
923  && (status & VIRTIO_CONFIG_STATUS_DRIVER)))
924  return -1;
925  vif->status = status;
926 
927  return 0;
928 }
929 
930 clib_error_t *
932 {
933  clib_error_t *error = 0;
934  struct virtio_pci_cap cap;
935  u8 pos, common_cfg = 0, notify_base = 0, dev_cfg = 0, isr = 0, pci_cfg = 0;
937 
938  if ((error = vlib_pci_read_config_u8 (vm, h, PCI_CAPABILITY_LIST, &pos)))
939  {
940  virtio_log_error (vif, "error in reading capabilty list position");
941  clib_error_return (error, "error in reading capabilty list position");
942  }
943  while (pos)
944  {
945  if ((error =
946  vlib_pci_read_write_config (vm, h, VLIB_READ, pos, &cap,
947  sizeof (cap))))
948  {
949  virtio_log_error (vif, "%s [%2x]",
950  "error in reading the capability at", pos);
951  clib_error_return (error,
952  "error in reading the capability at [%2x]", pos);
953  }
954 
955  if (cap.cap_vndr == PCI_CAP_ID_MSIX)
956  {
957  u16 flags, table_size, table_size_mask = 0x07FF;
958 
959  if ((error =
960  vlib_pci_read_write_config (vm, h, VLIB_READ, pos + 2, &flags,
961  sizeof (flags))))
962  clib_error_return (error,
963  "error in reading the capability at [%2x]",
964  pos + 2);
965 
966  table_size = flags & table_size_mask;
967  virtio_log_debug (vif, "flags:0x%x %s 0x%x", flags,
968  "msix interrupt vector table-size", table_size);
969 
970  if (flags & PCI_MSIX_ENABLE)
971  {
972  virtio_log_debug (vif, "msix interrupt enabled");
974  }
975  else
976  {
977  virtio_log_debug (vif, "msix interrupt disabled");
979  }
980  }
981 
982  if (cap.cap_vndr != PCI_CAP_ID_VNDR)
983  {
984  virtio_log_debug (vif, "[%2x] %s %2x ", pos,
985  "skipping non VNDR cap id:", cap.cap_vndr);
986  goto next;
987  }
988 
989  virtio_log_debug (vif,
990  "[%4x] cfg type: %u, bar: %u, offset: %04x, len: %u",
991  pos, cap.cfg_type, cap.bar, cap.offset, cap.length);
992  switch (cap.cfg_type)
993  {
995  common_cfg = 1;
996  break;
998  notify_base = 1;
999  break;
1001  dev_cfg = 1;
1002  break;
1004  isr = 1;
1005  break;
1007  if (cap.bar == 0)
1008  pci_cfg = 1;
1009  break;
1010  }
1011  next:
1012  pos = cap.cap_next;
1013  }
1014 
1015  if (common_cfg == 0 || notify_base == 0 || dev_cfg == 0 || isr == 0)
1016  {
1017  virtio_log_debug (vif, "legacy virtio pci device found");
1018  return error;
1019  }
1020 
1021  if (!pci_cfg)
1022  clib_error_return (error, "modern virtio pci device found");
1023 
1024  virtio_log_debug (vif, "transitional virtio pci device found");
1025  return error;
1026 }
1027 
1028 static clib_error_t *
1031 {
1032  clib_error_t *error = 0;
1034  u8 status = 0;
1035 
1036  if ((error = virtio_pci_read_caps (vm, vif)))
1037  clib_error_return (error, "Device is not supported");
1038 
1039  if (virtio_pci_reset_device (vm, vif) < 0)
1040  {
1041  virtio_log_error (vif, "Failed to reset the device");
1042  clib_error_return (error, "Failed to reset the device");
1043  }
1044  /*
1045  * read device features and negotiate (user) requested features
1046  */
1048  virtio_negotiate_features (vm, vif, args->features);
1049 
1050  /*
1051  * After FEATURE_OK, driver should not accept new feature bits
1052  */
1053  virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_FEATURES_OK);
1054  status = virtio_pci_legacy_get_status (vm, vif);
1055  if (!(status & VIRTIO_CONFIG_STATUS_FEATURES_OK))
1056  {
1057  virtio_log_error (vif,
1058  "error encountered: Device doesn't support requested features");
1059  clib_error_return (error, "Device doesn't support requested features");
1060  }
1061  vif->status = status;
1062 
1063  /*
1064  * get or set the mac address
1065  */
1066  if (virtio_pci_get_mac (vm, vif))
1067  {
1068  f64 now = vlib_time_now (vm);
1069  u32 rnd;
1070  rnd = (u32) (now * 1e6);
1071  rnd = random_u32 (&rnd);
1072 
1073  memcpy (vif->mac_addr + 2, &rnd, sizeof (rnd));
1074  vif->mac_addr[0] = 2;
1075  vif->mac_addr[1] = 0xfe;
1076  virtio_pci_set_mac (vm, vif);
1077  }
1078 
1080 
1081  /*
1082  * Initialize the virtqueues
1083  */
1084  if ((error = virtio_pci_get_max_virtqueue_pairs (vm, vif)))
1085  goto err;
1086 
1087  for (int i = 0; i < vif->max_queue_pairs; i++)
1088  {
1089  if ((error = virtio_pci_vring_init (vm, vif, RX_QUEUE (i))))
1090  {
1091  virtio_log_warning (vif, "%s (%u) %s", "error in rxq-queue",
1092  RX_QUEUE (i), "initialization");
1093  }
1094  else
1095  {
1096  vif->num_rxqs++;
1097  }
1098 
1099  if (i >= vtm->n_vlib_mains)
1100  {
1101  /*
1102  * There is 1:1 mapping between tx queue and vpp worker thread.
1103  * tx queue 0 is bind with thread index 0, tx queue 1 on thread
1104  * index 1 and so on.
1105  * Multiple worker threads can poll same tx queue when number of
1106  * workers are more than tx queues. In this case, 1:N mapping
1107  * between tx queue and vpp worker thread.
1108  */
1109  virtio_log_debug (vif, "%s %u, %s", "tx-queue: number",
1110  TX_QUEUE (i),
1111  "no VPP worker thread is available");
1112  continue;
1113  }
1114 
1115  if ((error = virtio_pci_vring_init (vm, vif, TX_QUEUE (i))))
1116  {
1117  virtio_log_warning (vif, "%s (%u) %s", "error in txq-queue",
1118  TX_QUEUE (i), "initialization");
1119  }
1120  else
1121  {
1122  vif->num_txqs++;
1123  }
1124  }
1125 
1126  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
1127  {
1128  if ((error =
1129  virtio_pci_control_vring_init (vm, vif, vif->max_queue_pairs * 2)))
1130  {
1131  virtio_log_warning (vif, "%s (%u) %s", "error in control-queue",
1132  vif->max_queue_pairs * 2, "initialization");
1133  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ))
1134  vif->features &= ~VIRTIO_FEATURE (VIRTIO_NET_F_MQ);
1135  }
1136  }
1137  else
1138  {
1139  virtio_log_debug (vif, "control queue is not available");
1140  vif->cxq_vring = NULL;
1141  }
1142 
1143  /*
1144  * set the msix interrupts
1145  */
1146  if (vif->msix_enabled == VIRTIO_MSIX_ENABLED)
1147  {
1148  if (virtio_pci_legacy_set_config_irq (vm, vif, 1) ==
1149  VIRTIO_MSI_NO_VECTOR)
1150  virtio_log_warning (vif, "config vector 1 is not set");
1151  if (virtio_pci_legacy_set_queue_irq (vm, vif, 0, 0) ==
1152  VIRTIO_MSI_NO_VECTOR)
1153  virtio_log_warning (vif, "queue vector 0 is not set");
1154  }
1155 
1156  /*
1157  * set the driver status OK
1158  */
1159  virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_DRIVER_OK);
1160  vif->status = virtio_pci_legacy_get_status (vm, vif);
1161 err:
1162  return error;
1163 }
1164 
1165 void
1167 {
1168  vnet_main_t *vnm = vnet_get_main ();
1169  virtio_main_t *vim = &virtio_main;
1170  virtio_if_t *vif;
1172  clib_error_t *error = 0;
1173 
1174  /* *INDENT-OFF* */
1175  pool_foreach (vif, vim->interfaces, ({
1176  if (vif->pci_addr.as_u32 == args->addr)
1177  {
1178  args->rv = VNET_API_ERROR_INVALID_VALUE;
1179  args->error =
1180  clib_error_return (error, "PCI address in use");
1181  vlib_log (VLIB_LOG_LEVEL_ERR, vim->log_default, "%U: %s",
1182  format_vlib_pci_addr, &args->addr,
1183  " PCI address in use");
1184  return;
1185  }
1186  }));
1187  /* *INDENT-ON* */
1188 
1189  pool_get (vim->interfaces, vif);
1190  vif->dev_instance = vif - vim->interfaces;
1191  vif->per_interface_next_index = ~0;
1192  vif->pci_addr.as_u32 = args->addr;
1193 
1194  if ((error =
1195  vlib_pci_device_open (vm, (vlib_pci_addr_t *) & vif->pci_addr,
1196  virtio_pci_device_ids, &h)))
1197  {
1198  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
1199  args->error =
1200  clib_error_return (error, "pci-addr %U", format_vlib_pci_addr,
1201  &vif->pci_addr);
1202  vlib_log (VLIB_LOG_LEVEL_ERR, vim->log_default, "%U: %s",
1203  format_vlib_pci_addr, &vif->pci_addr,
1204  "error encountered on pci device open");
1205  pool_put (vim->interfaces, vif);
1206  return;
1207  }
1208  vif->pci_dev_handle = h;
1209  vlib_pci_set_private_data (vm, h, vif->dev_instance);
1210  vif->numa_node = vlib_pci_get_numa_node (vm, h);
1211  vif->type = VIRTIO_IF_TYPE_PCI;
1212 
1213  if ((error = vlib_pci_bus_master_enable (vm, h)))
1214  {
1215  virtio_log_error (vif, "error encountered on pci bus master enable");
1216  goto error;
1217  }
1218 
1219  if ((error = vlib_pci_io_region (vm, h, 0)))
1220  {
1221  virtio_log_error (vif, "error encountered on pci io region");
1222  goto error;
1223  }
1224 
1226  {
1227  if ((error = vlib_pci_register_msix_handler (vm, h, 0, 1,
1229  {
1230  virtio_log_error (vif,
1231  "error encountered on pci register msix handler 0");
1232  goto error;
1233  }
1234  if ((error = vlib_pci_register_msix_handler (vm, h, 1, 1,
1236  {
1237  virtio_log_error (vif,
1238  "error encountered on pci register msix handler 1");
1239  goto error;
1240  }
1241 
1242  if ((error = vlib_pci_enable_msix_irq (vm, h, 0, 2)))
1243  {
1244  virtio_log_error (vif, "error encountered on pci enable msix irq");
1245  goto error;
1246  }
1247  vif->support_int_mode = 1;
1248  virtio_log_debug (vif, "device supports msix interrupts");
1249  }
1250  else if (vlib_pci_get_num_msix_interrupts (vm, h) == 1)
1251  {
1252  /*
1253  * if msix table-size is 1, fall back to intX.
1254  */
1255  if ((error =
1257  {
1258  virtio_log_error (vif,
1259  "error encountered on pci register interrupt handler");
1260  goto error;
1261  }
1262  vif->support_int_mode = 1;
1263  virtio_log_debug (vif, "pci register interrupt handler");
1264  }
1265  else
1266  {
1267  /*
1268  * WARN: intX is showing some weird behaviour.
1269  * Please don't use interrupt mode with UIO driver.
1270  */
1271  vif->support_int_mode = 0;
1272  virtio_log_debug (vif, "driver is configured in poll mode only");
1273  }
1274 
1275  if ((error = vlib_pci_intr_enable (vm, h)))
1276  {
1277  virtio_log_error (vif, "error encountered on pci interrupt enable");
1278  goto error;
1279  }
1280 
1281  if ((error = virtio_pci_device_init (vm, vif, args)))
1282  {
1283  virtio_log_error (vif, "error encountered on device init");
1284  goto error;
1285  }
1286 
1287  /* create interface */
1289  vif->dev_instance, vif->mac_addr,
1290  &vif->hw_if_index,
1292 
1293  if (error)
1294  {
1295  virtio_log_error (vif,
1296  "error encountered on ethernet register interface");
1297  goto error;
1298  }
1299 
1300  vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vif->hw_if_index);
1301  vif->sw_if_index = sw->sw_if_index;
1302  args->sw_if_index = sw->sw_if_index;
1303 
1304  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vif->hw_if_index);
1306  vnet_hw_interface_set_input_node (vnm, vif->hw_if_index,
1307  virtio_input_node.index);
1308  u32 i = 0;
1309  vec_foreach_index (i, vif->rxq_vrings)
1310  {
1311  vnet_hw_interface_assign_rx_thread (vnm, vif->hw_if_index, i, ~0);
1313  /* Set default rx mode to POLLING */
1314  vnet_hw_interface_set_rx_mode (vnm, vif->hw_if_index, i,
1316  }
1317  if (virtio_pci_is_link_up (vm, vif) & VIRTIO_NET_S_LINK_UP)
1318  {
1319  vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
1320  vnet_hw_interface_set_flags (vnm, vif->hw_if_index,
1322  }
1323  else
1324  vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
1325 
1326  virtio_pci_offloads (vm, vif, args->gso_enabled,
1327  args->checksum_offload_enabled);
1328 
1329  if ((vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) &&
1330  (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ)))
1331  {
1332  if (virtio_pci_enable_multiqueue (vm, vif, vif->max_queue_pairs))
1333  virtio_log_warning (vif, "multiqueue is not set");
1334  }
1335  return;
1336 
1337 error:
1338  virtio_pci_delete_if (vm, vif);
1339  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
1340  args->error = error;
1341 }
1342 
1343 int
1345 {
1346  vnet_main_t *vnm = vnet_get_main ();
1347  virtio_main_t *vim = &virtio_main;
1348  u32 i = 0;
1349 
1350  if (vif->type != VIRTIO_IF_TYPE_PCI)
1351  return VNET_API_ERROR_INVALID_INTERFACE;
1352 
1354 
1355  for (i = 0; i < vif->max_queue_pairs; i++)
1356  {
1357  virtio_pci_legacy_del_queue (vm, vif, RX_QUEUE (i));
1358  virtio_pci_legacy_del_queue (vm, vif, TX_QUEUE (i));
1359  }
1360 
1361  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
1362  virtio_pci_legacy_del_queue (vm, vif, vif->max_queue_pairs * 2);
1363 
1364  virtio_pci_legacy_reset (vm, vif);
1365 
1366  if (vif->hw_if_index)
1367  {
1369  vec_foreach_index (i, vif->rxq_vrings)
1370  {
1372  }
1374  }
1375 
1377 
1378  vec_foreach_index (i, vif->rxq_vrings)
1379  {
1380  virtio_vring_t *vring = vec_elt_at_index (vif->rxq_vrings, i);
1381  if (vring->kick_fd != -1)
1382  close (vring->kick_fd);
1383  if (vring->used)
1384  {
1385  virtio_free_rx_buffers (vm, vring);
1386  }
1387  vec_free (vring->buffers);
1388  vlib_physmem_free (vm, vring->desc);
1389  }
1390 
1391  vec_foreach_index (i, vif->txq_vrings)
1392  {
1393  virtio_vring_t *vring = vec_elt_at_index (vif->txq_vrings, i);
1394  if (vring->kick_fd != -1)
1395  close (vring->kick_fd);
1396  if (vring->used)
1397  {
1398  virtio_free_used_desc (vm, vring);
1399  }
1400  vec_free (vring->buffers);
1401  clib_spinlock_free (&vring->lockp);
1402  vlib_physmem_free (vm, vring->desc);
1403  }
1404 
1405  if (vif->cxq_vring != NULL)
1406  {
1407  u16 last = vif->cxq_vring->last_used_idx;
1408  u16 n_left = vif->cxq_vring->used->idx - last;
1409  while (n_left)
1410  {
1411  last++;
1412  n_left--;
1413  }
1414 
1415  vif->cxq_vring->last_used_idx = last;
1416  vlib_physmem_free (vm, vif->cxq_vring->desc);
1417  }
1418 
1419  vec_free (vif->rxq_vrings);
1420  vec_free (vif->txq_vrings);
1421  vec_free (vif->cxq_vring);
1422 
1423  clib_error_free (vif->error);
1424  memset (vif, 0, sizeof (*vif));
1425  pool_put (vim->interfaces, vif);
1426 
1427  return 0;
1428 }
1429 
1430 int
1432  int gso_enabled,
1433  int checksum_offload_enabled,
1434  int offloads_disabled)
1435 {
1436  if (vif->type != VIRTIO_IF_TYPE_PCI)
1437  return VNET_API_ERROR_INVALID_INTERFACE;
1438 
1439  if (gso_enabled)
1440  virtio_pci_offloads (vm, vif, 1, 0);
1441  else if (checksum_offload_enabled)
1442  virtio_pci_offloads (vm, vif, 0, 1);
1443  else if (offloads_disabled)
1444  virtio_pci_offloads (vm, vif, 0, 0);
1445 
1446  return 0;
1447 }
1448 
1449 /*
1450  * fd.io coding-style-patch-verification: ON
1451  *
1452  * Local Variables:
1453  * eval: (c-set-style "gnu")
1454  * End:
1455  */
static u8 virtio_pci_legacy_get_isr(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:171
struct vring_used * used
Definition: virtio.h:105
static uword vlib_buffer_get_current_pa(vlib_main_t *vm, vlib_buffer_t *b)
Definition: buffer_funcs.h:427
#define vec_foreach_index(var, v)
Iterate over vector indices.
static int virtio_pci_disable_offload(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:568
static clib_error_t * vlib_pci_intr_enable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.h:239
vlib_node_registration_t virtio_input_node
(constructor) VLIB_REGISTER_NODE (virtio_input_node)
Definition: node.c:414
void virtio_set_net_hdr_size(virtio_if_t *vif)
Definition: virtio.c:240
virtio_if_t * interfaces
Definition: virtio.h:188
clib_error_t * virtio_pci_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 queue_num)
Definition: pci.c:770
static int virtio_pci_legacy_setup_queue(vlib_main_t *vm, virtio_if_t *vif, u16 queue_id, void *p)
Definition: pci.c:191
static u32 virtio_pci_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 flags)
Definition: pci.c:251
static void virtio_pci_legacy_del_queue(vlib_main_t *vm, virtio_if_t *vif, u16 queue_id)
Definition: pci.c:208
static clib_error_t * vlib_pci_bus_master_enable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.h:271
static void * vlib_physmem_alloc_aligned_on_numa(vlib_main_t *vm, uword n_bytes, uword alignment, u32 numa_node)
Definition: physmem_funcs.h:63
#define VIRTIO_PCI_CAP_ISR_CFG
Definition: pci.h:125
vl_api_mac_address_t mac
Definition: l2.api:491
a
Definition: bitmap.h:538
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:890
u16 max_virtqueue_pairs
Definition: virtio.h:95
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:378
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static u16 virtio_pci_legacy_get_queue_num(vlib_main_t *vm, virtio_if_t *vif, u16 queue_id)
Definition: pci.c:179
#define VIRTIO_MSI_QUEUE_VECTOR
Definition: pci.h:36
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:110
unsigned long u64
Definition: types.h:89
int gso_enabled
Definition: virtio.h:177
void vlib_pci_device_close(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:1274
#define VIRTIO_PCI_STATUS
Definition: pci.h:31
#define CLIB_MEMORY_STORE_BARRIER()
Definition: clib.h:118
#define VIRTIO_PCI_QUEUE_PFN
Definition: pci.h:27
#define NULL
Definition: clib.h:58
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static u8 virtio_pci_legacy_get_status(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:148
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:279
u32 vlib_pci_get_num_msix_interrupts(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:177
static clib_error_t * vlib_physmem_last_error(struct vlib_main_t *vm)
static clib_error_t * vlib_pci_intr_disable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.h:255
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_device_class_t virtio_device_class
static clib_error_t * virtio_pci_device_init(vlib_main_t *vm, virtio_if_t *vif, virtio_pci_create_if_args_t *args)
Definition: pci.c:1029
vl_api_address_t src
Definition: gre.api:60
static heap_elt_t * last(heap_header_t *h)
Definition: heap.c:53
void virtio_vring_set_numa_node(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:224
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:65
clib_error_t * vlib_pci_enable_msix_irq(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 start, u16 count)
Definition: pci.c:882
#define VIRTIO_MSI_CONFIG_VECTOR
Definition: pci.h:35
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:451
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:237
vhost_vring_addr_t addr
Definition: vhost_user.h:147
#define VIRTIO_PCI_HOST_FEATURES
Definition: pci.h:25
static int virtio_pci_enable_gso(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:609
static u64 virtio_pci_legacy_get_host_features(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:113
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS
Definition: pci.h:117
static void virtio_pci_set_mac(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:282
static int virtio_pci_send_ctrl_msg(vlib_main_t *vm, virtio_if_t *vif, struct virtio_ctrl_msg *data, u32 len)
Definition: pci.c:472
unsigned char u8
Definition: types.h:56
void virtio_pci_create_if(vlib_main_t *vm, virtio_pci_create_if_args_t *args)
Definition: pci.c:1166
double f64
Definition: types.h:142
static void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:70
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define clib_memcpy(d, s, n)
Definition: string.h:180
static void virtio_pci_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:348
clib_error_t * vlib_pci_read_write_config(vlib_main_t *vm, vlib_pci_dev_handle_t h, vlib_read_or_write_t read_or_write, uword address, void *data, u32 n_bytes)
Definition: pci.c:1016
u32 msix_enabled
Definition: virtio.h:154
static u32 virtio_pci_legacy_set_guest_features(vlib_main_t *vm, virtio_if_t *vif, u64 features)
Definition: pci.c:132
#define VIRTIO_PCI_CAP_COMMON_CFG
Definition: pci.h:121
struct vring_avail * avail
Definition: virtio.h:106
u64 features
Definition: virtio.h:158
int virtio_pci_reset_device(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:898
u32 hw_if_index
Definition: virtio.h:141
u8 * format_ethernet_address(u8 *s, va_list *args)
Definition: format.c:44
static u8 virtio_pci_queue_size_valid(u16 qsz)
Definition: pci.c:708
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
static u16 virtio_pci_legacy_set_queue_irq(vlib_main_t *vm, virtio_if_t *vif, u16 vec, u16 queue_id)
Definition: pci.c:238
#define virtio_log_error(vif, f,...)
Definition: virtio.h:243
#define PCI_DEVICE_ID_VIRTIO_NIC
Definition: pci.c:29
#define TX_QUEUE_ACCESS(X)
Definition: virtio.h:80
void device_status(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:371
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:136
static void virtio_negotiate_features(vlib_main_t *vm, virtio_if_t *vif, u64 req_features)
Definition: pci.c:842
vnet_hw_interface_flags_t flags
Definition: interface.h:523
void virtio_free_rx_buffers(vlib_main_t *vm, virtio_vring_t *vring)
Definition: virtio.c:138
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
clib_spinlock_t lockp
Definition: virtio.h:107
#define clib_error_return(e, args...)
Definition: error.h:99
#define VIRTIO_PCI_CAP_NOTIFY_CFG
Definition: pci.h:123
unsigned int u32
Definition: types.h:88
static void virtio_pci_legacy_read_config(vlib_main_t *vm, virtio_if_t *vif, void *dst, int len, u32 addr)
Definition: pci.c:53
#define virtio_log_warning(vif, f,...)
Definition: virtio.h:236
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET
Definition: pci.h:118
u16 queue_id
Definition: virtio.h:114
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:63
u16 num_txqs
Definition: virtio.h:165
u32 pci_dev_handle
Definition: virtio.h:155
#define TX_QUEUE(X)
Definition: virtio.h:78
static void virtio_pci_legacy_set_status(vlib_main_t *vm, virtio_if_t *vif, u8 status)
Definition: pci.c:156
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
#define VIRTIO_PCI_GUEST_FEATURES
Definition: pci.h:26
#define VIRTIO_NET_F_MTU
Definition: pci.h:105
static void virtio_pci_irq_1_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: pci.c:327
void vlib_pci_set_private_data(vlib_main_t *vm, vlib_pci_dev_handle_t h, uword private_data)
Definition: pci.c:155
unsigned short u16
Definition: types.h:57
#define VIRTIO_PCI_ISR_CONFIG
Definition: pci.h:48
u64 size
Definition: vhost_user.h:140
struct virtio_net_ctrl_hdr ctrl
Definition: pci.c:466
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
clib_error_t * vlib_pci_register_msix_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 start, u32 count, pci_msix_handler_function_t *msix_handler)
Definition: pci.c:825
#define PCI_MSIX_ENABLE
Definition: pci.c:37
uword vlib_pci_get_private_data(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:148
u32 vlib_pci_dev_handle_t
Definition: pci.h:97
static u16 virtio_pci_legacy_set_config_irq(vlib_main_t *vm, virtio_if_t *vif, u16 vec)
Definition: pci.c:227
void virtio_pci_read_device_feature(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:892
vl_api_address_t dst
Definition: gre.api:61
static u32 virtio_pci_legacy_get_guest_features(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:122
clib_error_t * virtio_pci_read_caps(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:931
static clib_error_t * virtio_pci_get_max_virtqueue_pairs(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:258
#define PCI_CAPABILITY_LIST
Definition: pci.c:33
vlib_main_t * vm
Definition: in2out_ed.c:1810
int virtio_pci_enable_disable_offloads(vlib_main_t *vm, virtio_if_t *vif, int gso_enabled, int checksum_offload_enabled, int offloads_disabled)
Definition: pci.c:1431
#define virtio_log_debug(vif, f,...)
Definition: virtio.h:229
u8 status
Definition: virtio.h:166
u8 len
Definition: ip_types.api:91
u16 desc_next
Definition: virtio.h:109
u8 * format_vlib_pci_addr(u8 *s, va_list *va)
Definition: pci.c:141
u8 slot
Definition: pci_types.api:22
#define VIRTIO_PCI_VRING_ALIGN
Definition: pci.h:133
u16 num_rxqs
Definition: virtio.h:164
virtio_vring_t * rxq_vrings
Definition: virtio.h:156
u32 vlib_pci_get_numa_node(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:170
u16 last_used_idx
Definition: virtio.h:119
u32 flags
Definition: vhost_user.h:141
#define VIRTIO_PCI_QUEUE_NOTIFY
Definition: pci.h:30
#define VIRTIO_PCI_ISR_INTR
Definition: pci.h:46
static void vlib_physmem_free(vlib_main_t *vm, void *p)
Definition: physmem_funcs.h:89
#define VIRTIO_RING_FLAG_MASK_INT
Definition: virtio.h:99
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
#define clib_warning(format, args...)
Definition: error.h:59
static u16 virtio_pci_is_link_up(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:301
void debug_device_config_space(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:399
void vlib_log(vlib_log_level_t level, vlib_log_class_t class, char *fmt,...)
Definition: log.c:87
u8 mac_addr[6]
Definition: virtio.h:167
static void virtio_pci_legacy_write_config(vlib_main_t *vm, virtio_if_t *vif, void *src, int len, u32 addr)
Definition: pci.c:83
u32 flags
Definition: virtio.h:138
clib_error_t * virtio_pci_control_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 queue_num)
Definition: pci.c:718
clib_error_t * error
Definition: virtio.h:161
static uword round_pow2(uword x, uword pow2)
Definition: clib.h:241
void virtio_pci_legacy_notify_queue(vlib_main_t *vm, virtio_if_t *vif, u16 queue_id)
Definition: pci.c:218
int virtio_pci_delete_if(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:1344
u32 numa_node
Definition: virtio.h:143
virtio_if_type_t type
Definition: virtio.h:145
void virtio_free_used_desc(vlib_main_t *vm, virtio_vring_t *vring)
Definition: virtio.c:175
#define PCI_DEVICE_ID_VIRTIO_NIC_MODERN
Definition: pci.c:31
#define PCI_CONFIG_SIZE(vif)
Definition: pci.c:39
#define ASSERT(truth)
static int virtio_pci_offloads(vlib_main_t *vm, virtio_if_t *vif, int gso_enabled, int csum_offload_enabled)
Definition: pci.c:630
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
Definition: devices.c:139
u64 remote_features
Definition: virtio.h:158
u8 data[128]
Definition: ipsec_types.api:87
#define VIRTIO_FEATURE(X)
Definition: virtio.h:76
static int virtio_pci_enable_checksum_offload(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:588
clib_error_t * vlib_pci_register_intx_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, pci_intx_handler_function_t *intx_handler)
Definition: pci.c:774
virtio_main_t virtio_main
Definition: virtio.c:37
static uword is_pow2(uword x)
Definition: clib.h:235
#define VIRTIO_PCI_QUEUE_SEL
Definition: pci.h:29
Definition: defs.h:56
static u64 vlib_physmem_get_pa(vlib_main_t *vm, void *mem)
#define RX_QUEUE_ACCESS(X)
Definition: virtio.h:81
virtio_net_ctrl_ack status
Definition: pci.c:467
int csum_offload_enabled
Definition: virtio.h:178
#define VIRTIO_PCI_CAP_DEVICE_CFG
Definition: pci.h:127
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
Definition: pci.h:104
#define PCI_CAP_ID_VNDR
Definition: pci.c:34
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:331
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
Definition: interface.c:492
VLIB buffer representation.
Definition: buffer.h:102
u8 data[1024]
Definition: pci.c:468
u64 uword
Definition: types.h:112
static void virtio_pci_irq_0_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: pci.c:315
#define clib_error_free(e)
Definition: error.h:86
clib_error_t * vlib_pci_io_region(vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 resource)
Definition: pci.c:1159
u32 * buffers
Definition: virtio.h:118
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.c:188
static u8 virtio_pci_legacy_reset(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:164
virtio_vring_t * cxq_vring
Definition: virtio.h:180
static u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:69
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
struct vring_desc * desc
Definition: virtio.h:104
#define CLIB_MEMORY_BARRIER()
Definition: clib.h:115
int vnet_hw_interface_set_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode mode)
Definition: devices.c:253
#define VIRTIO_PCI_CAP_PCI_CFG
Definition: pci.h:129
u16 max_queue_pairs
Definition: virtio.h:163
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
#define PCI_VENDOR_ID_VIRTIO
Definition: pci.c:28
static u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer_funcs.h:630
#define PCI_CAP_ID_MSIX
Definition: pci.c:35
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
clib_error_t * vlib_pci_device_open(vlib_main_t *vm, vlib_pci_addr_t *addr, pci_device_id_t ids[], vlib_pci_dev_handle_t *handle)
Definition: pci.c:1214
#define RX_QUEUE(X)
Definition: virtio.h:79
static u32 virtio_pci_get_mac(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:289
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:79
#define VIRTIO_NET_CTRL_MQ
Definition: vhost_user.h:40
#define VIRTIO_PCI_QUEUE_NUM
Definition: pci.h:28
u16 vendor_id
Definition: pci.h:127
static int virtio_pci_enable_multiqueue(vlib_main_t *vm, virtio_if_t *vif, u16 num_queues)
Definition: pci.c:691
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET
Definition: vhost_user.h:41
u16 desc_in_use
Definition: virtio.h:108
virtio_vring_t * txq_vrings
Definition: virtio.h:157
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT
Definition: pci.h:131
static_always_inline void virtio_kick(vlib_main_t *vm, virtio_vring_t *vring, virtio_if_t *vif)
Definition: virtio.h:214
#define VIRTIO_PCI_ISR
Definition: pci.h:32
static_always_inline void clib_memset_u32(void *p, u32 val, uword count)
Definition: string.h:332