/*
 * Copyright (c) 2018 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <fcntl.h>
#include <sys/ioctl.h>

#include <vppinfra/types.h>
#include <vlib/vlib.h>
#include <vlib/pci/pci.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/ip/ip4_packet.h>
#include <vnet/ip/ip6_packet.h>
#include <vnet/devices/virtio/virtio.h>
#include <vnet/devices/virtio/pci.h>
#include <vnet/interface/rx_queue_funcs.h>

#define PCI_VENDOR_ID_VIRTIO				0x1af4
#define PCI_DEVICE_ID_VIRTIO_NIC			0x1000
/* Doesn't support modern device */
#define PCI_DEVICE_ID_VIRTIO_NIC_MODERN			0x1041

#define PCI_CAPABILITY_LIST     0x34
#define PCI_CAP_ID_VNDR         0x09
#define PCI_CAP_ID_MSIX         0x11

#define PCI_MSIX_ENABLE 0x8000

static pci_device_id_t virtio_pci_device_ids[] = {
  {
   .vendor_id = PCI_VENDOR_ID_VIRTIO,
   .device_id = PCI_DEVICE_ID_VIRTIO_NIC},
  {
   .vendor_id = PCI_VENDOR_ID_VIRTIO,
   .device_id = PCI_DEVICE_ID_VIRTIO_NIC_MODERN},
  {0},
};

static u32
virtio_pci_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw,
			u32 flags)
{
  return 0;
}

static clib_error_t *
virtio_pci_get_max_virtqueue_pairs (vlib_main_t * vm, virtio_if_t * vif)
{
  clib_error_t *error = 0;
  u16 max_queue_pairs = 1;

  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ))
    {
      max_queue_pairs = vif->virtio_pci_func->get_max_queue_pairs (vm, vif);
    }

  virtio_log_debug (vif, "max queue pair is %x", max_queue_pairs);
  if (max_queue_pairs < 1 || max_queue_pairs > 0x8000)
    return clib_error_return (error, "max queue pair is %x,"
			      " should be in range [1, 0x8000]",
			      max_queue_pairs);

  vif->max_queue_pairs = max_queue_pairs;
  return error;
}

static void
virtio_pci_set_mac (vlib_main_t * vm, virtio_if_t * vif)
{
  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MAC))
    vif->virtio_pci_func->set_mac (vm, vif);
}

static u32
virtio_pci_get_mac (vlib_main_t * vm, virtio_if_t * vif)
{
  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MAC))
    {
      vif->virtio_pci_func->get_mac (vm, vif);
      return 0;
    }
  return 1;
}

static u16
virtio_pci_is_link_up (vlib_main_t * vm, virtio_if_t * vif)
{
  /*
   * Minimal driver: assumes link is up
   */
  u16 status = 1;
  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_STATUS))
    status = vif->virtio_pci_func->get_device_status (vm, vif);
  return status;
}

static void
virtio_pci_irq_queue_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			      u16 line)
{
  vnet_main_t *vnm = vnet_get_main ();
  virtio_main_t *vim = &virtio_main;
  uword pd = vlib_pci_get_private_data (vm, h);
  virtio_if_t *vif = pool_elt_at_index (vim->interfaces, pd);
  line--;
  u16 qid = line;

  vnet_virtio_vring_t *vring = vec_elt_at_index (vif->rxq_vrings, qid);
  vnet_hw_if_rx_queue_set_int_pending (vnm, vring->queue_index);
}

static void
virtio_pci_irq_config_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			       u16 line)
{
  vnet_main_t *vnm = vnet_get_main ();
  virtio_main_t *vim = &virtio_main;
  uword pd = vlib_pci_get_private_data (vm, h);
  virtio_if_t *vif = pool_elt_at_index (vim->interfaces, pd);

  if (virtio_pci_is_link_up (vm, vif) & VIRTIO_NET_S_LINK_UP)
    {
      vnet_hw_interface_set_flags (vnm, vif->hw_if_index,
				   VNET_HW_INTERFACE_FLAG_LINK_UP);
    }
  else
    {
      vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
    }
}

static void
virtio_pci_irq_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h)
{
  virtio_main_t *vim = &virtio_main;
  uword pd = vlib_pci_get_private_data (vm, h);
  virtio_if_t *vif = pool_elt_at_index (vim->interfaces, pd);
  u8 isr = 0;
  u16 line = 0;

  isr = vif->virtio_pci_func->get_isr (vm, vif);

  /*
   * If the lower bit is set: look through the used rings of
   * all virtqueues for the device, to see if any progress has
   * been made by the device which requires servicing.
   */
  if (isr & VIRTIO_PCI_ISR_INTR)
    {
      for (; line < vif->num_rxqs; line++)
	virtio_pci_irq_queue_handler (vm, h, (line + 1));
    }

  if (isr & VIRTIO_PCI_ISR_CONFIG)
    virtio_pci_irq_config_handler (vm, h, line);
}

inline void
device_status (vlib_main_t * vm, virtio_if_t * vif)
{
  struct status_struct
  {
    u8 bit;
    char *str;
  };
  struct status_struct *status_entry;
  static struct status_struct status_array[] = {
#define _(s,b) { .str = #s, .bit = b, },
    foreach_virtio_config_status_flags
#undef _
    {.str = NULL}
  };

  vlib_cli_output (vm, "  status 0x%x", vif->status);

  status_entry = (struct status_struct *) &status_array;
  while (status_entry->str)
    {
      if (vif->status & status_entry->bit)
	vlib_cli_output (vm, "    %s (%x)", status_entry->str,
			 status_entry->bit);
      status_entry++;
    }
}

static int
virtio_pci_send_ctrl_msg_packed (vlib_main_t * vm, virtio_if_t * vif,
				 virtio_ctrl_msg_t * data, u32 len)
{
  vnet_virtio_vring_t *vring = vif->cxq_vring;
  virtio_net_ctrl_ack_t status = VIRTIO_NET_ERR;
  virtio_ctrl_msg_t result;
  u32 buffer_index;
  vlib_buffer_t *b;
  u16 used, next;
  u16 sz = vring->queue_size;
  u16 flags = 0, first_desc_flags = 0;

  used = vring->desc_in_use;
  next = vring->desc_next;
  vnet_virtio_vring_packed_desc_t *d = &vring->packed_desc[next];

  if (vlib_buffer_alloc (vm, &buffer_index, 1))
    b = vlib_get_buffer (vm, buffer_index);
  else
    return VIRTIO_NET_ERR;
  /*
   * current_data may not be initialized with 0 and may contain
   * previous offset.
   */
  b->current_data = 0;
  clib_memcpy (vlib_buffer_get_current (b), data, sizeof (virtio_ctrl_msg_t));

  first_desc_flags = VRING_DESC_F_NEXT;
  if (vring->avail_wrap_counter)
    {
      first_desc_flags |= VRING_DESC_F_AVAIL;
      first_desc_flags &= ~VRING_DESC_F_USED;
    }
  else
    {
      first_desc_flags &= ~VRING_DESC_F_AVAIL;
      first_desc_flags |= VRING_DESC_F_USED;
    }
  d->addr = vlib_buffer_get_current_pa (vm, b);
  d->len = sizeof (virtio_net_ctrl_hdr_t);
  d->id = next;

  next++;
  if (next >= sz)
    {
      next = 0;
      vring->avail_wrap_counter ^= 1;
    }
  used++;

  d = &vring->packed_desc[next];
  flags = VRING_DESC_F_NEXT;
  if (vring->avail_wrap_counter)
    {
      flags |= VRING_DESC_F_AVAIL;
      flags &= ~VRING_DESC_F_USED;
    }
  else
    {
      flags &= ~VRING_DESC_F_AVAIL;
      flags |= VRING_DESC_F_USED;
    }
  d->addr = vlib_buffer_get_current_pa (vm, b) +
    STRUCT_OFFSET_OF (virtio_ctrl_msg_t, data);
  d->len = len;
  d->id = next;
  d->flags = flags;

  next++;
  if (next >= sz)
    {
      next = 0;
      vring->avail_wrap_counter ^= 1;
    }
  used++;

  d = &vring->packed_desc[next];
  flags = VRING_DESC_F_WRITE;
  if (vring->avail_wrap_counter)
    {
      flags |= VRING_DESC_F_AVAIL;
      flags &= ~VRING_DESC_F_USED;
    }
  else
    {
      flags &= ~VRING_DESC_F_AVAIL;
      flags |= VRING_DESC_F_USED;
    }
  d->addr = vlib_buffer_get_current_pa (vm, b) +
    STRUCT_OFFSET_OF (virtio_ctrl_msg_t, status);
  d->len = sizeof (data->status);
  d->id = next;
  d->flags = flags;

  next++;
  if (next >= sz)
    {
      next = 0;
      vring->avail_wrap_counter ^= 1;
    }
  used++;

  CLIB_MEMORY_STORE_BARRIER ();
  vring->packed_desc[vring->desc_next].flags = first_desc_flags;
  vring->desc_next = next;
  vring->desc_in_use = used;
  CLIB_MEMORY_BARRIER ();
  if (vring->device_event->flags != VRING_EVENT_F_DISABLE)
    {
      virtio_kick (vm, vring, vif);
    }

  u16 last = vring->last_used_idx;
  d = &vring->packed_desc[last];
  do
    {
      flags = d->flags;
    }
  while ((flags & VRING_DESC_F_AVAIL) != (vring->used_wrap_counter << 7)
	 || (flags & VRING_DESC_F_USED) != (vring->used_wrap_counter << 15));

  last += 3;
  if (last >= vring->queue_size)
    {
      last = last - vring->queue_size;
      vring->used_wrap_counter ^= 1;
    }
  vring->desc_in_use -= 3;
  vring->last_used_idx = last;

  CLIB_MEMORY_BARRIER ();
  clib_memcpy (&result, vlib_buffer_get_current (b),
	       sizeof (virtio_ctrl_msg_t));
  virtio_log_debug (vif, "ctrl-queue: status %u", result.status);
  status = result.status;
  vlib_buffer_free (vm, &buffer_index, 1);
  return status;
}

static int
virtio_pci_send_ctrl_msg_split (vlib_main_t * vm, virtio_if_t * vif,
				virtio_ctrl_msg_t * data, u32 len)
{
  vnet_virtio_vring_t *vring = vif->cxq_vring;
  virtio_net_ctrl_ack_t status = VIRTIO_NET_ERR;
  virtio_ctrl_msg_t result;
  u32 buffer_index;
  vlib_buffer_t *b;
  u16 used, next, avail;
  u16 sz = vring->queue_size;
  u16 mask = sz - 1;

  used = vring->desc_in_use;
  next = vring->desc_next;
  avail = vring->avail->idx;
  vnet_virtio_vring_desc_t *d = &vring->desc[next];

  if (vlib_buffer_alloc (vm, &buffer_index, 1))
    b = vlib_get_buffer (vm, buffer_index);
  else
    return VIRTIO_NET_ERR;
  /*
   * current_data may not be initialized with 0 and may contain
   * previous offset.
   */
  b->current_data = 0;
  clib_memcpy (vlib_buffer_get_current (b), data, sizeof (virtio_ctrl_msg_t));
  d->flags = VRING_DESC_F_NEXT;
  d->addr = vlib_buffer_get_current_pa (vm, b);
  d->len = sizeof (virtio_net_ctrl_hdr_t);
  vring->avail->ring[avail & mask] = next;
  avail++;
  next = (next + 1) & mask;
  d->next = next;
  used++;

  d = &vring->desc[next];
  d->flags = VRING_DESC_F_NEXT;
  d->addr = vlib_buffer_get_current_pa (vm, b) +
    STRUCT_OFFSET_OF (virtio_ctrl_msg_t, data);
  d->len = len;
  next = (next + 1) & mask;
  d->next = next;
  used++;

  d = &vring->desc[next];
  d->flags = VRING_DESC_F_WRITE;
  d->addr = vlib_buffer_get_current_pa (vm, b) +
    STRUCT_OFFSET_OF (virtio_ctrl_msg_t, status);
  d->len = sizeof (data->status);
  next = (next + 1) & mask;
  used++;

  CLIB_MEMORY_STORE_BARRIER ();
  vring->avail->idx = avail;
  vring->desc_next = next;
  vring->desc_in_use = used;

  if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0)
    {
      virtio_kick (vm, vring, vif);
    }

  u16 last = vring->last_used_idx, n_left = 0;
  n_left = vring->used->idx - last;

  while (n_left)
    {
      vnet_virtio_vring_used_elem_t *e = &vring->used->ring[last & mask];
      u16 slot = e->id;

      d = &vring->desc[slot];
      while (d->flags & VRING_DESC_F_NEXT)
	{
	  used--;
	  slot = d->next;
	  d = &vring->desc[slot];
	}
      used--;
      last++;
      n_left--;
    }
  vring->desc_in_use = used;
  vring->last_used_idx = last;

  CLIB_MEMORY_BARRIER ();
  clib_memcpy (&result, vlib_buffer_get_current (b),
	       sizeof (virtio_ctrl_msg_t));
  virtio_log_debug (vif, "ctrl-queue: status %u", result.status);
  status = result.status;
  vlib_buffer_free (vm, &buffer_index, 1);
  return status;
}

static int
virtio_pci_send_ctrl_msg (vlib_main_t * vm, virtio_if_t * vif,
			  virtio_ctrl_msg_t * data, u32 len)
{
  if (vif->is_packed)
    return virtio_pci_send_ctrl_msg_packed (vm, vif, data, len);
  else
    return virtio_pci_send_ctrl_msg_split (vm, vif, data, len);
}

static int
virtio_pci_disable_offload (vlib_main_t * vm, virtio_if_t * vif)
{
  virtio_ctrl_msg_t offload_hdr;
  virtio_net_ctrl_ack_t status = VIRTIO_NET_ERR;

  offload_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
  offload_hdr.ctrl.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
  offload_hdr.status = VIRTIO_NET_ERR;
  u64 offloads = 0ULL;
  clib_memcpy (offload_hdr.data, &offloads, sizeof (offloads));

  status =
    virtio_pci_send_ctrl_msg (vm, vif, &offload_hdr, sizeof (offloads));
  virtio_log_debug (vif, "disable offloads");
  vif->remote_features = vif->virtio_pci_func->get_device_features (vm, vif);
  vif->virtio_pci_func->get_driver_features (vm, vif);
  return status;
}

static int
virtio_pci_enable_checksum_offload (vlib_main_t * vm, virtio_if_t * vif)
{
  virtio_ctrl_msg_t csum_offload_hdr;
  virtio_net_ctrl_ack_t status = VIRTIO_NET_ERR;

  csum_offload_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
  csum_offload_hdr.ctrl.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
  csum_offload_hdr.status = VIRTIO_NET_ERR;
  u64 offloads = 0ULL;
  offloads |= VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM);
  clib_memcpy (csum_offload_hdr.data, &offloads, sizeof (offloads));

  status =
    virtio_pci_send_ctrl_msg (vm, vif, &csum_offload_hdr, sizeof (offloads));
  virtio_log_debug (vif, "enable checksum offload");
  vif->remote_features = vif->virtio_pci_func->get_device_features (vm, vif);
  vif->features = vif->virtio_pci_func->get_driver_features (vm, vif);
  return status;
}

static int
virtio_pci_enable_gso (vlib_main_t * vm, virtio_if_t * vif)
{
  virtio_ctrl_msg_t gso_hdr;
  virtio_net_ctrl_ack_t status = VIRTIO_NET_ERR;

  gso_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
  gso_hdr.ctrl.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
  gso_hdr.status = VIRTIO_NET_ERR;
  u64 offloads = VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6);
  clib_memcpy (gso_hdr.data, &offloads, sizeof (offloads));

  status = virtio_pci_send_ctrl_msg (vm, vif, &gso_hdr, sizeof (offloads));
  virtio_log_debug (vif, "enable gso");
  vif->remote_features = vif->virtio_pci_func->get_device_features (vm, vif);
  vif->virtio_pci_func->get_driver_features (vm, vif);
  return status;
}

static int
virtio_pci_offloads (vlib_main_t * vm, virtio_if_t * vif, int gso_enabled,
		     int csum_offload_enabled)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_hw_if_caps_change_t cc = {};

  if ((vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) &&
      (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)))
    {
      if (gso_enabled
	  && (vif->features & (VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO4) |
			       VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO6))))
	{
	  if (virtio_pci_enable_gso (vm, vif))
	    {
	      virtio_log_warning (vif, "gso is not enabled");
	    }
	  else
	    {
	      vif->gso_enabled = 1;
	      vif->csum_offload_enabled = 1;
	      cc.val = cc.mask = VNET_HW_IF_CAP_TCP_GSO |
				 VNET_HW_IF_CAP_TX_TCP_CKSUM |
				 VNET_HW_IF_CAP_TX_UDP_CKSUM;
	    }
	}
      else if (csum_offload_enabled
	       && (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CSUM)))
	{
	  if (virtio_pci_enable_checksum_offload (vm, vif))
	    {
	      virtio_log_warning (vif, "checksum offload is not enabled");
	    }
	  else
	    {
	      vif->csum_offload_enabled = 1;
	      vif->gso_enabled = 0;
	      cc.val =
		VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM;
	      cc.mask = VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_TX_TCP_CKSUM |
			VNET_HW_IF_CAP_TX_UDP_CKSUM;
	    }
	}
      else
	{
	  if (virtio_pci_disable_offload (vm, vif))
	    {
	      virtio_log_warning (vif, "offloads are not disabled");
	    }
	  else
	    {
	      vif->csum_offload_enabled = 0;
	      vif->gso_enabled = 0;
	      cc.val = 0;
	      cc.mask = VNET_HW_IF_CAP_L4_TX_CKSUM | VNET_HW_IF_CAP_TCP_GSO;
	    }
	}
    }

  if (cc.mask)
    vnet_hw_if_change_caps (vnm, vif->hw_if_index, &cc);

  return 0;
}

static int
virtio_pci_enable_multiqueue (vlib_main_t * vm, virtio_if_t * vif,
			      u16 num_queues)
{
  virtio_ctrl_msg_t mq_hdr;
  virtio_net_ctrl_ack_t status = VIRTIO_NET_ERR;

  mq_hdr.ctrl.class = VIRTIO_NET_CTRL_MQ;
  mq_hdr.ctrl.cmd = VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET;
  mq_hdr.status = VIRTIO_NET_ERR;
  clib_memcpy (mq_hdr.data, &num_queues, sizeof (num_queues));

  status = virtio_pci_send_ctrl_msg (vm, vif, &mq_hdr, sizeof (num_queues));
  virtio_log_debug (vif, "multi-queue enable %u queues", num_queues);
  return status;
}

static u8
virtio_pci_queue_size_valid (u16 qsz)
{
  if (qsz < 64 || qsz > 4096)
    return 0;
  if ((qsz % 64) != 0)
    return 0;
  return 1;
}

clib_error_t *
virtio_pci_control_vring_packed_init (vlib_main_t * vm, virtio_if_t * vif,
				      u16 queue_num)
{
  clib_error_t *error = 0;
  u16 queue_size = 0;
  vnet_virtio_vring_t *vring;
  u32 i = 0;
  void *ptr = NULL;

  queue_size = vif->virtio_pci_func->get_queue_size (vm, vif, queue_num);

  if (queue_size > 32768)
    return clib_error_return (0, "ring size must be 32768 or lower");

  if (queue_size == 0)
    queue_size = 256;

  vec_validate_aligned (vif->cxq_vring, 0, CLIB_CACHE_LINE_BYTES);
  vring = vec_elt_at_index (vif->cxq_vring, 0);

  i = (((queue_size * sizeof (vnet_virtio_vring_packed_desc_t)) +
	sizeof (vnet_virtio_vring_desc_event_t) + VNET_VIRTIO_PCI_VRING_ALIGN -
	1) &
       ~(VNET_VIRTIO_PCI_VRING_ALIGN - 1)) +
      sizeof (vnet_virtio_vring_desc_event_t);

  ptr = vlib_physmem_alloc_aligned_on_numa (vm, i, VNET_VIRTIO_PCI_VRING_ALIGN,
					    vif->numa_node);
  if (!ptr)
    return vlib_physmem_last_error (vm);
  clib_memset (ptr, 0, i);

  vring->packed_desc = ptr;

  vring->driver_event =
    ptr + (queue_size * sizeof (vnet_virtio_vring_packed_desc_t));
  vring->driver_event->off_wrap = 0;
  vring->driver_event->flags = VRING_EVENT_F_DISABLE;

  vring->device_event =
    ptr + (((queue_size * sizeof (vnet_virtio_vring_packed_desc_t)) +
	    sizeof (vnet_virtio_vring_desc_event_t) +
	    VNET_VIRTIO_PCI_VRING_ALIGN - 1) &
	   ~(VNET_VIRTIO_PCI_VRING_ALIGN - 1));
  vring->device_event->off_wrap = 0;
  vring->device_event->flags = 0;

  vring->total_packets = 0;
  vring->queue_id = queue_num;
  vring->queue_size = queue_size;
  vring->avail_wrap_counter = 1;
  vring->used_wrap_counter = 1;

  ASSERT (vring->buffers == 0);

  virtio_log_debug (vif, "control-queue: number %u, size %u", queue_num,
		    queue_size);
  vif->virtio_pci_func->setup_queue (vm, vif, queue_num, vring);
  vring->queue_notify_offset =
    vif->notify_off_multiplier *
    vif->virtio_pci_func->get_queue_notify_off (vm, vif, queue_num);
  virtio_log_debug (vif, "queue-notify-offset: number %u, offset %u",
		    queue_num, vring->queue_notify_offset);
  return error;
}

clib_error_t *
virtio_pci_control_vring_split_init (vlib_main_t * vm, virtio_if_t * vif,
				     u16 queue_num)
{
  clib_error_t *error = 0;
  u16 queue_size = 0;
  vnet_virtio_vring_t *vring;
  u32 i = 0;
  void *ptr = NULL;

  queue_size = vif->virtio_pci_func->get_queue_size (vm, vif, queue_num);
  if (!virtio_pci_queue_size_valid (queue_size))
    clib_warning ("queue size is not valid");

  if (!is_pow2 (queue_size))
    return clib_error_return (0, "ring size must be power of 2");

  if (queue_size > 32768)
    return clib_error_return (0, "ring size must be 32768 or lower");

  if (queue_size == 0)
    queue_size = 256;

  vec_validate_aligned (vif->cxq_vring, 0, CLIB_CACHE_LINE_BYTES);
  vring = vec_elt_at_index (vif->cxq_vring, 0);
  i = vnet_virtio_vring_size (queue_size, VNET_VIRTIO_PCI_VRING_ALIGN);
  i = round_pow2 (i, VNET_VIRTIO_PCI_VRING_ALIGN);
  ptr = vlib_physmem_alloc_aligned_on_numa (vm, i, VNET_VIRTIO_PCI_VRING_ALIGN,
					    vif->numa_node);
  if (!ptr)
    return vlib_physmem_last_error (vm);
  clib_memset (ptr, 0, i);
  vnet_virtio_vring_init (vring, queue_size, ptr, VNET_VIRTIO_PCI_VRING_ALIGN);
  vring->queue_id = queue_num;
  vring->total_packets = 0;

  ASSERT (vring->buffers == 0);
  virtio_log_debug (vif, "control-queue: number %u, size %u", queue_num,
		    queue_size);
  vif->virtio_pci_func->setup_queue (vm, vif, queue_num, vring);
  vring->queue_notify_offset =
    vif->notify_off_multiplier *
    vif->virtio_pci_func->get_queue_notify_off (vm, vif, queue_num);
  virtio_log_debug (vif, "queue-notify-offset: number %u, offset %u",
		    queue_num, vring->queue_notify_offset);

  return error;
}

clib_error_t *
virtio_pci_control_vring_init (vlib_main_t * vm, virtio_if_t * vif,
			       u16 queue_num)
{
  if (vif->is_packed)
    return virtio_pci_control_vring_packed_init (vm, vif, queue_num);
  else
    return virtio_pci_control_vring_split_init (vm, vif, queue_num);
}

clib_error_t *
virtio_pci_vring_split_init (vlib_main_t *vm, virtio_if_t *vif, u16 queue_num,
			     u16 txq_size)
{
  clib_error_t *error = 0;
  u16 queue_size = 0;
  vnet_virtio_vring_t *vring;
  u32 i = 0;
  void *ptr = NULL;

  queue_size = vif->virtio_pci_func->get_queue_size (vm, vif, queue_num);
  if (!virtio_pci_queue_size_valid (queue_size))
    clib_warning ("queue size is not valid");

  if (!is_pow2 (queue_size))
    return clib_error_return (0, "ring size must be power of 2");

  if (queue_size > 32768)
    return clib_error_return (0, "ring size must be 32768 or lower");

  if (queue_size == 0)
    queue_size = 256;

  if (queue_num % 2)
    {
      if (txq_size)
	{
	  virtio_log_debug (vif, "tx-queue: number %u, default-size %u",
			    queue_num, queue_size);
	  vif->virtio_pci_func->set_queue_size (vm, vif, queue_num, txq_size);
	  queue_size =
	    vif->virtio_pci_func->get_queue_size (vm, vif, queue_num);
	  virtio_log_debug (vif, "tx-queue: number %u, new size %u", queue_num,
			    queue_size);
	}
      vec_validate_aligned (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num),
			    CLIB_CACHE_LINE_BYTES);
      vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num));
      clib_spinlock_init (&vring->lockp);
    }
  else
    {
      vec_validate_aligned (vif->rxq_vrings, RX_QUEUE_ACCESS (queue_num),
			    CLIB_CACHE_LINE_BYTES);
      vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS (queue_num));
    }
  i = vnet_virtio_vring_size (queue_size, VNET_VIRTIO_PCI_VRING_ALIGN);
  i = round_pow2 (i, VNET_VIRTIO_PCI_VRING_ALIGN);
  ptr = vlib_physmem_alloc_aligned_on_numa (vm, i, VNET_VIRTIO_PCI_VRING_ALIGN,
					    vif->numa_node);
  if (!ptr)
    return vlib_physmem_last_error (vm);
  clib_memset (ptr, 0, i);
  vnet_virtio_vring_init (vring, queue_size, ptr, VNET_VIRTIO_PCI_VRING_ALIGN);
  vring->queue_id = queue_num;
  vring->avail->flags = VIRTIO_RING_FLAG_MASK_INT;
  vring->flow_table = 0;
  vring->total_packets = 0;

  ASSERT (vring->buffers == 0);
  vec_validate_aligned (vring->buffers, queue_size, CLIB_CACHE_LINE_BYTES);
  if (queue_num % 2)
    {
      virtio_log_debug (vif, "tx-queue: number %u, size %u", queue_num,
			queue_size);
      clib_memset_u32 (vring->buffers, ~0, queue_size);
    }
  else
    {
      virtio_log_debug (vif, "rx-queue: number %u, size %u", queue_num,
			queue_size);
    }
  vring->queue_size = queue_size;
  if (vif->virtio_pci_func->setup_queue (vm, vif, queue_num, vring))
    return clib_error_return (0, "error in queue address setup");

  vring->queue_notify_offset =
    vif->notify_off_multiplier *
    vif->virtio_pci_func->get_queue_notify_off (vm, vif, queue_num);
  virtio_log_debug (vif, "queue-notify-offset: number %u, offset %u",
		    queue_num, vring->queue_notify_offset);
  return error;
}

clib_error_t *
virtio_pci_vring_packed_init (vlib_main_t * vm, virtio_if_t * vif,
			      u16 queue_num)
{
  clib_error_t *error = 0;
  u16 queue_size = 0;
  vnet_virtio_vring_t *vring;
  u32 i = 0;
  void *ptr = NULL;

  queue_size = vif->virtio_pci_func->get_queue_size (vm, vif, queue_num);

  if (queue_size > 32768)
    return clib_error_return (0, "ring size must be 32768 or lower");

  if (queue_size == 0)
    queue_size = 256;

  if (queue_num % 2)
    {
      vec_validate_aligned (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num),
			    CLIB_CACHE_LINE_BYTES);
      vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num));
      clib_spinlock_init (&vring->lockp);
    }
  else
    {
      vec_validate_aligned (vif->rxq_vrings, RX_QUEUE_ACCESS (queue_num),
			    CLIB_CACHE_LINE_BYTES);
      vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS (queue_num));
    }

  i = (((queue_size * sizeof (vnet_virtio_vring_packed_desc_t)) +
	sizeof (vnet_virtio_vring_desc_event_t) + VNET_VIRTIO_PCI_VRING_ALIGN -
	1) &
       ~(VNET_VIRTIO_PCI_VRING_ALIGN - 1)) +
      sizeof (vnet_virtio_vring_desc_event_t);

  ptr = vlib_physmem_alloc_aligned_on_numa (vm, i, VNET_VIRTIO_PCI_VRING_ALIGN,
					    vif->numa_node);
  if (!ptr)
    return vlib_physmem_last_error (vm);

  clib_memset (ptr, 0, i);
  vring->packed_desc = ptr;

  vring->driver_event =
    ptr + (queue_size * sizeof (vnet_virtio_vring_packed_desc_t));
  vring->driver_event->off_wrap = 0;
  vring->driver_event->flags = VRING_EVENT_F_DISABLE;

  vring->device_event =
    ptr + (((queue_size * sizeof (vnet_virtio_vring_packed_desc_t)) +
	    sizeof (vnet_virtio_vring_desc_event_t) +
	    VNET_VIRTIO_PCI_VRING_ALIGN - 1) &
	   ~(VNET_VIRTIO_PCI_VRING_ALIGN - 1));
  vring->device_event->off_wrap = 0;
  vring->device_event->flags = 0;

  vring->queue_id = queue_num;

  vring->avail_wrap_counter = 1;
  vring->used_wrap_counter = 1;
  vring->total_packets = 0;

  ASSERT (vring->buffers == 0);
  vec_validate_aligned (vring->buffers, queue_size, CLIB_CACHE_LINE_BYTES);
  if (queue_num % 2)
    {
      virtio_log_debug (vif, "tx-queue: number %u, size %u", queue_num,
			queue_size);
      clib_memset_u32 (vring->buffers, ~0, queue_size);
    }
  else
    {
      virtio_log_debug (vif, "rx-queue: number %u, size %u", queue_num,
			queue_size);
    }
  vring->queue_size = queue_size;
  if (vif->virtio_pci_func->setup_queue (vm, vif, queue_num, vring))
    return clib_error_return (0, "error in queue address setup");

  vring->queue_notify_offset =
    vif->notify_off_multiplier *
    vif->virtio_pci_func->get_queue_notify_off (vm, vif, queue_num);
  virtio_log_debug (vif, "queue-notify-offset: number %u, offset %u",
		    queue_num, vring->queue_notify_offset);

  return error;
}

clib_error_t *
virtio_pci_vring_init (vlib_main_t *vm, virtio_if_t *vif, u16 queue_num,
		       u16 txq_size)
{
  if (vif->is_packed)
    return virtio_pci_vring_packed_init (vm, vif, queue_num);
  else
    return virtio_pci_vring_split_init (vm, vif, queue_num, txq_size);
}

static void
virtio_negotiate_features (vlib_main_t * vm, virtio_if_t * vif,
			   u64 req_features)
{
  /*
   * if features are not requested
   * default: all supported features
   */
  u64 supported_features = VIRTIO_FEATURE (VIRTIO_NET_F_CSUM)
    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
    | VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)
    | VIRTIO_FEATURE (VIRTIO_NET_F_MTU)
    | VIRTIO_FEATURE (VIRTIO_NET_F_MAC)
    | VIRTIO_FEATURE (VIRTIO_NET_F_GSO)
    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6)
    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO)
    | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO4)
    | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO6)
    | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_UFO)
    | VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)
    | VIRTIO_FEATURE (VIRTIO_NET_F_STATUS)
    | VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)
    | VIRTIO_FEATURE (VIRTIO_NET_F_MQ)
    | VIRTIO_FEATURE (VIRTIO_F_NOTIFY_ON_EMPTY)
    | VIRTIO_FEATURE (VIRTIO_F_ANY_LAYOUT)
    | VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC);

  if (vif->is_modern)
    supported_features |= VIRTIO_FEATURE (VIRTIO_F_VERSION_1);

  if (vif->is_packed)
    {
      supported_features |=
	(VIRTIO_FEATURE (VIRTIO_F_RING_PACKED) |
	 VIRTIO_FEATURE (VIRTIO_F_IN_ORDER));
    }

  if (req_features == 0)
    {
      req_features = supported_features;
    }

  vif->features = req_features & vif->remote_features & supported_features;

  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MTU))
    {
      u16 mtu = 0;
      mtu = vif->virtio_pci_func->get_mtu (vm, vif);

      if (mtu < 64)
	vif->features &= ~VIRTIO_FEATURE (VIRTIO_NET_F_MTU);
    }

  if ((vif->features & (VIRTIO_FEATURE (VIRTIO_F_RING_PACKED))) == 0)
    vif->is_packed = 0;

  vif->virtio_pci_func->set_driver_features (vm, vif, vif->features);
  vif->features = vif->virtio_pci_func->get_driver_features (vm, vif);
}

void
virtio_pci_read_device_feature (vlib_main_t * vm, virtio_if_t * vif)
{
  vif->remote_features = vif->virtio_pci_func->get_device_features (vm, vif);
}

int
virtio_pci_reset_device (vlib_main_t * vm, virtio_if_t * vif)
{
  u8 status = 0;

  /*
   * Reset the device
   */
  status = vif->virtio_pci_func->device_reset (vm, vif);

  /*
   * Set the Acknowledge status bit
   */
  vif->virtio_pci_func->set_status (vm, vif, VIRTIO_CONFIG_STATUS_ACK);

  /*
   * Set the Driver status bit
   */
  vif->virtio_pci_func->set_status (vm, vif, VIRTIO_CONFIG_STATUS_DRIVER);

  /*
   * Read the status and verify it
   */
  status = vif->virtio_pci_func->get_status (vm, vif);
  if ((status & VIRTIO_CONFIG_STATUS_ACK)
      && (status & VIRTIO_CONFIG_STATUS_DRIVER))
    vif->status = status;
  else
    return -1;

  return 0;
}

clib_error_t *
virtio_pci_read_caps (vlib_main_t * vm, virtio_if_t * vif, void **bar)
{
  clib_error_t *error = 0;
  virtio_pci_cap_t cap;
  u8 pos, common_cfg = 0, notify = 0, dev_cfg = 0, isr = 0, pci_cfg = 0;
  vlib_pci_dev_handle_t h = vif->pci_dev_handle;

  if ((error = vlib_pci_read_config_u8 (vm, h, PCI_CAPABILITY_LIST, &pos)))
    {
      virtio_log_error (vif, "error in reading capabilty list position");
      return clib_error_return (error,
				"error in reading capabilty list position");
    }
  while (pos)
    {
      if ((error =
	   vlib_pci_read_write_config (vm, h, VLIB_READ, pos, &cap,
				       sizeof (cap))))
	{
	  virtio_log_error (vif, "%s [%2x]",
			    "error in reading the capability at", pos);
	  return clib_error_return (error,
				    "error in reading the capability at [%2x]",
				    pos);
	}

      if (cap.cap_vndr == PCI_CAP_ID_MSIX)
	{
	  u16 flags, table_size, table_size_mask = 0x07FF;

	  if ((error =
	       vlib_pci_read_write_config (vm, h, VLIB_READ, pos + 2, &flags,
					   sizeof (flags))))
	    return clib_error_return (error,
				      "error in reading the capability at [%2x]",
				      pos + 2);

	  table_size = flags & table_size_mask;
	  virtio_log_debug (vif, "flags:0x%x %s 0x%x", flags,
			    "msix interrupt vector table-size", table_size);

	  if (flags & PCI_MSIX_ENABLE)
	    {
	      virtio_log_debug (vif, "msix interrupt enabled");
	      vif->msix_enabled = VIRTIO_MSIX_ENABLED;
	      vif->msix_table_size = table_size;
	    }
	  else
	    {
	      virtio_log_debug (vif, "msix interrupt disabled");
	      vif->msix_enabled = VIRTIO_MSIX_DISABLED;
	      vif->msix_table_size = 0;
	    }
	}

      if (cap.cap_vndr != PCI_CAP_ID_VNDR)
	{
	  virtio_log_debug (vif, "[%2x] %s %2x ", pos,
			    "skipping non VNDR cap id:", cap.cap_vndr);
	  goto next;
	}

      virtio_log_debug (vif,
			"[%4x] cfg type: %u, bar: %u, offset: %04x, len: %u",
			pos, cap.cfg_type, cap.bar, cap.offset, cap.length);

      if (cap.bar >= 0 && cap.bar <= 5)
	{
	  vif->bar = bar[cap.bar];
	  vif->bar_id = cap.bar;
	}
      else
	return clib_error_return (error, "invalid bar %u", cap.bar);

      switch (cap.cfg_type)
	{
	case VIRTIO_PCI_CAP_COMMON_CFG:
	  vif->common_offset = cap.offset;
	  common_cfg = 1;
	  break;
	case VIRTIO_PCI_CAP_NOTIFY_CFG:
	  if ((error =
	       vlib_pci_read_write_config (vm, h, VLIB_READ,
					   pos + sizeof (cap),
					   &vif->notify_off_multiplier,
					   sizeof
					   (vif->notify_off_multiplier))))
	    {
	      virtio_log_error (vif, "notify off multiplier is not given");
	    }
	  else
	    {
	      virtio_log_debug (vif, "notify off multiplier is %u",
				vif->notify_off_multiplier);
	      vif->notify_offset = cap.offset;
	      notify = 1;
	    }
	  break;
	case VIRTIO_PCI_CAP_DEVICE_CFG:
	  vif->device_offset = cap.offset;
	  dev_cfg = 1;
	  break;
	case VIRTIO_PCI_CAP_ISR_CFG:
	  vif->isr_offset = cap.offset;
	  isr = 1;
	  break;
	case VIRTIO_PCI_CAP_PCI_CFG:
	  if (cap.bar == 0)
	    pci_cfg = 1;
	  break;
	}
    next:
      pos = cap.cap_next;
    }

  if (common_cfg == 0 || notify == 0 || dev_cfg == 0 || isr == 0)
    {
      vif->virtio_pci_func = &virtio_pci_legacy_func;
      vif->notify_off_multiplier = 0;
      virtio_log_debug (vif, "legacy virtio pci device found");
      return error;
    }

  vif->is_modern = 1;
  vif->virtio_pci_func = &virtio_pci_modern_func;

  if (!pci_cfg)
    {
      virtio_log_debug (vif, "modern virtio pci device found");
    }
  else
    {
      virtio_log_debug (vif, "transitional virtio pci device found");
    }

  return error;
}

static clib_error_t *
virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif,
			virtio_pci_create_if_args_t * args, void **bar)
{
  clib_error_t *error = 0;
  u8 status = 0;

  if ((error = virtio_pci_read_caps (vm, vif, bar)))
    {
      args->rv = VNET_API_ERROR_UNSUPPORTED;
      virtio_log_error (vif, "Device is not supported");
      return clib_error_return (error, "Device is not supported");
    }

  if (virtio_pci_reset_device (vm, vif) < 0)
    {
      args->rv = VNET_API_ERROR_INIT_FAILED;
      virtio_log_error (vif, "Failed to reset the device");
      return clib_error_return (error, "Failed to reset the device");
    }
  /*
   * read device features and negotiate (user) requested features
   */
  virtio_pci_read_device_feature (vm, vif);
  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC)) ==
      0)
    {
      virtio_log_warning (vif, "error encountered: vhost-net backend doesn't "
			  "support VIRTIO_RING_F_INDIRECT_DESC features");
    }
  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)) == 0)
    {
      virtio_log_warning (vif, "error encountered: vhost-net backend doesn't "
			  "support VIRTIO_NET_F_MRG_RXBUF features");
    }
  virtio_negotiate_features (vm, vif, args->features);

  /*
   * After FEATURE_OK, driver should not accept new feature bits
   */
  vif->virtio_pci_func->set_status (vm, vif,
				    VIRTIO_CONFIG_STATUS_FEATURES_OK);
  status = vif->virtio_pci_func->get_status (vm, vif);
  if (!(status & VIRTIO_CONFIG_STATUS_FEATURES_OK))
    {
      args->rv = VNET_API_ERROR_UNSUPPORTED;
      virtio_log_error (vif,
			"error encountered: Device doesn't support requested features");
      return clib_error_return (error,
				"Device doesn't support requested features");
    }
  vif->status = status;

  /*
   * get or set the mac address
   */
  if (virtio_pci_get_mac (vm, vif))
    {
      f64 now = vlib_time_now (vm);
      u32 rnd;
      rnd = (u32) (now * 1e6);
      rnd = random_u32 (&rnd);

      memcpy (vif->mac_addr + 2, &rnd, sizeof (rnd));
      vif->mac_addr[0] = 2;
      vif->mac_addr[1] = 0xfe;
      virtio_pci_set_mac (vm, vif);
    }

  virtio_set_net_hdr_size (vif);

  /*
   * Initialize the virtqueues
   */
  if ((error = virtio_pci_get_max_virtqueue_pairs (vm, vif)))
    {
      args->rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
      goto err;
    }

  if (vif->msix_enabled == VIRTIO_MSIX_ENABLED)
    {
      if (vif->msix_table_size <= vif->max_queue_pairs)
	{
	  virtio_log_error (vif,
			    "error MSIX lines (%u) <= Number of RXQs (%u)",
			    vif->msix_table_size, vif->max_queue_pairs);
	  return clib_error_return (error,
				    "error MSIX lines (%u) <= Number of RXQs (%u)",
				    vif->msix_table_size,
				    vif->max_queue_pairs);
	}
    }

  for (int i = 0; i < vif->max_queue_pairs; i++)
    {
      if ((error = virtio_pci_vring_init (vm, vif, RX_QUEUE (i), 0)))
	{
	  args->rv = VNET_API_ERROR_INIT_FAILED;
	  virtio_log_error (vif, "%s (%u) %s", "error in rxq-queue",
			    RX_QUEUE (i), "initialization");
	  error =
	    clib_error_return (error, "%s (%u) %s", "error in rxq-queue",
			       RX_QUEUE (i), "initialization");
	  goto err;
	}
      else
	{
	  vif->num_rxqs++;
	}

      if ((error = virtio_pci_vring_init (vm, vif, TX_QUEUE (i),
					  args->tx_queue_size)))
	{
	  args->rv = VNET_API_ERROR_INIT_FAILED;
	  virtio_log_error (vif, "%s (%u) %s", "error in txq-queue",
			    TX_QUEUE (i), "initialization");
	  error =
	    clib_error_return (error, "%s (%u) %s", "error in txq-queue",
			       TX_QUEUE (i), "initialization");
	  goto err;
	}
      else
	{
	  vif->num_txqs++;
	}
    }

  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
    {
      if ((error =
	   virtio_pci_control_vring_init (vm, vif, vif->max_queue_pairs * 2)))
	{
	  virtio_log_warning (vif, "%s (%u) %s", "error in control-queue",
			      vif->max_queue_pairs * 2, "initialization");
	  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ))
	    vif->features &= ~VIRTIO_FEATURE (VIRTIO_NET_F_MQ);
	}
    }
  else
    {
      virtio_log_debug (vif, "control queue is not available");
      vif->cxq_vring = NULL;
    }

  /*
   * set the msix interrupts
   */
  if (vif->msix_enabled == VIRTIO_MSIX_ENABLED)
    {
      int i, j;
      if (vif->virtio_pci_func->set_config_irq (vm, vif, 0) ==
	  VIRTIO_MSI_NO_VECTOR)
	{
	  virtio_log_warning (vif, "config vector 0 is not set");
	}
      else
	{
	  virtio_log_debug (vif, "config msix vector is set at 0");
	}
      for (i = 0, j = 1; i < vif->max_queue_pairs; i++, j++)
	{
	  if (vif->virtio_pci_func->set_queue_irq (vm, vif, j,
						   RX_QUEUE (i)) ==
	      VIRTIO_MSI_NO_VECTOR)
	    {
	      virtio_log_warning (vif, "queue (%u) vector is not set at %u",
				  RX_QUEUE (i), j);
	    }
	  else
	    {
	      virtio_log_debug (vif, "%s (%u) %s %u", "queue",
				RX_QUEUE (i), "msix vector is set at", j);
	    }
	}
    }

  /*
   * set the driver status OK
   */
  vif->virtio_pci_func->set_status (vm, vif, VIRTIO_CONFIG_STATUS_DRIVER_OK);
  vif->status = vif->virtio_pci_func->get_status (vm, vif);
err:
  return error;
}

void
virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args)
{
  vnet_main_t *vnm = vnet_get_main ();
  virtio_main_t *vim = &virtio_main;
  virtio_if_t *vif;
  vlib_pci_dev_handle_t h;
  clib_error_t *error = 0;
  u32 interrupt_count = 0;

  pool_foreach (vif, vim->interfaces)  {
    if (vif->pci_addr.as_u32 == args->addr)
      {
	args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
	args->error =
	  clib_error_return (error, "PCI address in use");
	  vlib_log (VLIB_LOG_LEVEL_ERR, vim->log_default, "%U: %s",
                format_vlib_pci_addr, &args->addr,
                " PCI address in use");
	return;
      }
  }

  if (args->bind)
    {
      vlib_pci_addr_t pci = { .as_u32 = args->addr };
      error = vlib_pci_bind_to_uio (vm, &pci, (char *) "auto",
				    VIRTIO_BIND_FORCE == args->bind);
      if (error)
	{
	  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
	  args->error =
	    clib_error_return (error, "%U: %s", format_vlib_pci_addr, &pci,
			       "error encountered on binding pci device");
	  vlib_log (VLIB_LOG_LEVEL_ERR, vim->log_default, "%U: %s",
		    format_vlib_pci_addr, &pci,
		    "error encountered on binding pci devicee");
	  return;
	}
    }

  pool_get (vim->interfaces, vif);
  vif->dev_instance = vif - vim->interfaces;
  vif->per_interface_next_index = ~0;
  vif->pci_addr.as_u32 = args->addr;
  if (args->virtio_flags & VIRTIO_FLAG_PACKED)
    vif->is_packed = 1;

  if ((error =
       vlib_pci_device_open (vm, (vlib_pci_addr_t *) & vif->pci_addr,
			     virtio_pci_device_ids, &h)))
    {
      args->rv = VNET_API_ERROR_INVALID_INTERFACE;
      args->error =
	clib_error_return (error, "pci-addr %U", format_vlib_pci_addr,
			   &vif->pci_addr);
      vlib_log (VLIB_LOG_LEVEL_ERR, vim->log_default, "%U: %s",
		format_vlib_pci_addr, &vif->pci_addr,
		"error encountered on pci device open");
      pool_put (vim->interfaces, vif);
      return;
    }
  vif->pci_dev_handle = h;
  vlib_pci_set_private_data (vm, h, vif->dev_instance);
  vif->numa_node = vlib_pci_get_numa_node (vm, h);
  vif->type = VIRTIO_IF_TYPE_PCI;

  if ((error = vlib_pci_bus_master_enable (vm, h)))
    {
      virtio_log_error (vif, "error encountered on pci bus master enable");
      goto error;
    }

  void *bar[6];
  for (u32 i = 0; i <= 5; i++)
    {

      if ((error = vlib_pci_map_region (vm, h, i, &bar[i])))
	{
	  virtio_log_debug (vif, "no pci map region for bar %u", i);
	}
      else
	{
	  virtio_log_debug (vif, "pci map region for bar %u at %p", i,
			    bar[i]);
	}
    }

  if ((error = vlib_pci_io_region (vm, h, 0)))
    {
      virtio_log_error (vif, "error encountered on pci io region");
      goto error;
    }

  interrupt_count = vlib_pci_get_num_msix_interrupts (vm, h);
  if (interrupt_count > 1)
    {
      if ((error = vlib_pci_register_msix_handler (vm, h, 0, 1,
						   &virtio_pci_irq_config_handler)))
	{
	  args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
	  virtio_log_error (vif,
			    "error encountered on pci register msix handler 0");
	  goto error;
	}

      if ((error =
	   vlib_pci_register_msix_handler (vm, h, 1, (interrupt_count - 1),
					   &virtio_pci_irq_queue_handler)))
	{
	  args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
	  virtio_log_error (vif,
			    "error encountered on pci register msix handler 1");
	  goto error;
	}

      if ((error = vlib_pci_enable_msix_irq (vm, h, 0, interrupt_count)))
	{
	  virtio_log_error (vif, "error encountered on pci enable msix irq");
	  goto error;
	}
      vif->support_int_mode = 1;
      virtio_log_debug (vif, "device supports msix interrupts");
    }
  else
    {
      /*
       * WARN: performance will be sub-optimal.
       * Fall back to intX, if msix table-size is 1 or
       * if UIO driver is being used.
       */
      if ((error =
	   vlib_pci_register_intx_handler (vm, h, &virtio_pci_irq_handler)))
	{
	  virtio_log_error (vif,
			    "error encountered on pci register interrupt handler");
	  goto error;
	}
      vif->support_int_mode = 1;
      virtio_log_debug (vif, "pci register interrupt handler");
    }

  if ((error = vlib_pci_intr_enable (vm, h)))
    {
      virtio_log_error (vif, "error encountered on pci interrupt enable");
      goto error;
    }

  if ((error = virtio_pci_device_init (vm, vif, args, bar)))
    {
      virtio_log_error (vif, "error encountered on device init");
      goto error;
    }

  /* create interface */
  vnet_eth_interface_registration_t eir = {};
  eir.dev_class_index = virtio_device_class.index;
  eir.dev_instance = vif->dev_instance;
  eir.address = vif->mac_addr;
  eir.cb.flag_change = virtio_pci_flag_change;
  vif->hw_if_index = vnet_eth_register_interface (vnm, &eir);

  vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vif->hw_if_index);
  vif->sw_if_index = sw->sw_if_index;
  args->sw_if_index = sw->sw_if_index;

  vnet_hw_if_set_caps (vnm, vif->hw_if_index, VNET_HW_IF_CAP_INT_MODE);

  if (args->virtio_flags & VIRTIO_FLAG_BUFFERING)
    {
      error = virtio_set_packet_buffering (vif, args->buffering_size);
      if (error)
	{
	  args->rv = VNET_API_ERROR_INIT_FAILED;
	  virtio_log_error (vif,
			    "error encountered during packet buffering init");
	  goto error;
	}
      /*
       * packet buffering flag needs to be set 1 before calling the
       * virtio_pre_input_node_enable but after the successful initialization
       * of buffering queues above.
       * Packet buffering flag set to 0 if there will be any error during
       * buffering initialization.
       */
      vif->packet_buffering = 1;
      virtio_pre_input_node_enable (vm, vif);
    }

  virtio_vring_set_rx_queues (vm, vif);
  virtio_vring_set_tx_queues (vm, vif);

  if (virtio_pci_is_link_up (vm, vif) & VIRTIO_NET_S_LINK_UP)
    {
      vnet_hw_interface_set_flags (vnm, vif->hw_if_index,
				   VNET_HW_INTERFACE_FLAG_LINK_UP);
    }
  else
    vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);

  virtio_pci_offloads (vm, vif, args->gso_enabled,
		       args->checksum_offload_enabled);

  if ((vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) &&
      (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ)))
    {
      if (virtio_pci_enable_multiqueue (vm, vif, vif->max_queue_pairs))
	virtio_log_warning (vif, "multiqueue is not set");
    }
  return;

error:
  virtio_pci_delete_if (vm, vif);
  if (args->rv == 0)
    args->rv = VNET_API_ERROR_INVALID_INTERFACE;
  args->error = error;
}

int
virtio_pci_delete_if (vlib_main_t * vm, virtio_if_t * vif)
{
  vnet_main_t *vnm = vnet_get_main ();
  virtio_main_t *vim = &virtio_main;
  u32 i = 0;

  if (vif->type != VIRTIO_IF_TYPE_PCI)
    return VNET_API_ERROR_INVALID_INTERFACE;

  vlib_pci_intr_disable (vm, vif->pci_dev_handle);

  if (vif->virtio_pci_func)
    {
      for (i = 0; i < vif->max_queue_pairs; i++)
	{
	  vif->virtio_pci_func->del_queue (vm, vif, RX_QUEUE (i));
	  vif->virtio_pci_func->del_queue (vm, vif, TX_QUEUE (i));
	}

      if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
	vif->virtio_pci_func->del_queue (vm, vif, vif->max_queue_pairs * 2);

      vif->virtio_pci_func->device_reset (vm, vif);
    }

  if (vif->hw_if_index)
    {
      vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
      ethernet_delete_interface (vnm, vif->hw_if_index);
    }

  vlib_pci_device_close (vm, vif->pci_dev_handle);

  vec_foreach_index (i, vif->rxq_vrings)
  {
    vnet_virtio_vring_t *vring = vec_elt_at_index (vif->rxq_vrings, i);
    if (vring->used)
      {
	virtio_free_buffers (vm, vring);
      }
    vec_free (vring->buffers);
    vlib_physmem_free (vm, vring->desc);
  }

  if (vif->packet_buffering)
    virtio_pre_input_node_disable (vm, vif);

  vec_foreach_index (i, vif->txq_vrings)
  {
    vnet_virtio_vring_t *vring = vec_elt_at_index (vif->txq_vrings, i);
    if (vring->used)
      {
	virtio_free_buffers (vm, vring);
      }
    vec_free (vring->buffers);
    gro_flow_table_free (vring->flow_table);
    virtio_vring_buffering_free (vm, vring->buffering);
    clib_spinlock_free (&vring->lockp);
    vlib_physmem_free (vm, vring->desc);
  }

  if (vif->cxq_vring != NULL)
    {
      u16 last = vif->cxq_vring->last_used_idx;
      u16 n_left = vif->cxq_vring->used->idx - last;
      while (n_left)
	{
	  last++;
	  n_left--;
	}

      vif->cxq_vring->last_used_idx = last;
      vlib_physmem_free (vm, vif->cxq_vring->desc);
    }

  vec_free (vif->rxq_vrings);
  vec_free (vif->txq_vrings);
  vec_free (vif->cxq_vring);

  clib_error_free (vif->error);
  memset (vif, 0, sizeof (*vif));
  pool_put (vim->interfaces, vif);

  return 0;
}

int
virtio_pci_enable_disable_offloads (vlib_main_t * vm, virtio_if_t * vif,
				    int gso_enabled,
				    int checksum_offload_enabled,
				    int offloads_disabled)
{
  if (vif->type != VIRTIO_IF_TYPE_PCI)
    return VNET_API_ERROR_INVALID_INTERFACE;

  if (gso_enabled)
    virtio_pci_offloads (vm, vif, 1, 0);
  else if (checksum_offload_enabled)
    virtio_pci_offloads (vm, vif, 0, 1);
  else if (offloads_disabled)
    virtio_pci_offloads (vm, vif, 0, 0);

  return 0;
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
