virtio: add modern device support

Type: feature

Change-Id: I205f7c146a213d603d9d1e46fcf5195a876608dc
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h
index e1ba71d..7a5dcd8 100644
--- a/src/vnet/devices/virtio/virtio.h
+++ b/src/vnet/devices/virtio/virtio.h
@@ -57,7 +57,7 @@
 /* The Host publishes the avail index for which it expects a kick \
  * at the end of the used ring. Guest should ignore the used->flags field. */ \
   _ (VHOST_USER_F_PROTOCOL_FEATURES, 30) \
-  _ (VIRTIO_F_VERSION_1, 32)
+  _ (VIRTIO_F_VERSION_1, 32)  /* v1.0 compliant. */           \
 
 #define foreach_virtio_if_flag		\
   _(0, ADMIN_UP, "admin-up")		\
@@ -130,6 +130,7 @@
   u32 as_u32;
 } pci_addr_t;
 
+/* forward declaration */
 typedef struct _virtio_pci_func virtio_pci_func_t;
 
 typedef struct
@@ -161,35 +162,49 @@
 
     CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
   int packet_coalesce;
-  union
-  {
-    u32 id;
-    pci_addr_t pci_addr;
-  };
-  int *vhost_fds;
   u32 dev_instance;
   u32 numa_node;
   u64 remote_features;
 
   /* error */
   clib_error_t *error;
-  u8 support_int_mode;		/* support interrupt mode */
-  u16 max_queue_pairs;
-  u16 msix_table_size;
-  u8 status;
   u8 mac_addr[6];
-  u8 *host_if_name;
-  u8 *net_ns;
-  u8 *host_bridge;
-  u8 host_mac_addr[6];
-  ip4_address_t host_ip4_addr;
-  u8 host_ip4_prefix_len;
-  ip6_address_t host_ip6_addr;
-  u8 host_ip6_prefix_len;
-  u32 host_mtu_size;
-  u32 tap_flags;
-  int ifindex;
-  virtio_vring_t *cxq_vring;
+  union
+  {
+    struct			/* tun/tap interface */
+    {
+      ip6_address_t host_ip6_addr;
+      int *vhost_fds;
+      u8 *host_if_name;
+      u8 *net_ns;
+      u8 *host_bridge;
+      u8 host_mac_addr[6];
+      u32 id;
+      u32 host_mtu_size;
+      u32 tap_flags;
+      int ifindex;
+      ip4_address_t host_ip4_addr;
+      u8 host_ip4_prefix_len;
+      u8 host_ip6_prefix_len;
+    };
+    struct			/* native virtio */
+    {
+      void *bar;
+      virtio_vring_t *cxq_vring;
+      pci_addr_t pci_addr;
+      u32 bar_id;
+      u32 notify_off_multiplier;
+      u32 is_modern;
+      u16 common_offset;
+      u16 notify_offset;
+      u16 device_offset;
+      u16 isr_offset;
+      u16 max_queue_pairs;
+      u16 msix_table_size;
+      u8 support_int_mode;	/* support interrupt mode */
+      u8 status;
+    };
+  };
   const virtio_pci_func_t *virtio_pci_func;
 } virtio_if_t;
 
@@ -221,6 +236,8 @@
 extern void virtio_set_packet_coalesce (virtio_if_t * vif);
 extern void virtio_pci_legacy_notify_queue (vlib_main_t * vm,
 					    virtio_if_t * vif, u16 queue_id);
+extern void virtio_pci_modern_notify_queue (vlib_main_t * vm,
+					    virtio_if_t * vif, u16 queue_id);
 format_function_t format_virtio_device_name;
 format_function_t format_virtio_log_name;
 
@@ -228,7 +245,12 @@
 virtio_kick (vlib_main_t * vm, virtio_vring_t * vring, virtio_if_t * vif)
 {
   if (vif->type == VIRTIO_IF_TYPE_PCI)
-    virtio_pci_legacy_notify_queue (vm, vif, vring->queue_id);
+    {
+      if (vif->is_modern)
+	virtio_pci_modern_notify_queue (vm, vif, vring->queue_id);
+      else
+	virtio_pci_legacy_notify_queue (vm, vif, vring->queue_id);
+    }
   else
     {
       u64 x = 1;