net/virtio: move PCI specific dev init to PCI ethdev init
[dpdk.git] / drivers / net / virtio / virtio_pci.c
index 21110cd..345d73f 100644 (file)
@@ -3,7 +3,7 @@
  */
 #include <stdint.h>
 
-#ifdef RTE_EXEC_ENV_LINUXAPP
+#ifdef RTE_EXEC_ENV_LINUX
  #include <dirent.h>
  #include <fcntl.h>
 #endif
@@ -416,9 +416,34 @@ modern_del_queue(struct virtio_hw *hw, struct virtqueue *vq)
 }
 
 static void
-modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue *vq)
+modern_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
-       rte_write16(vq->vq_queue_index, vq->notify_addr);
+       uint32_t notify_data;
+
+       if (!vtpci_with_feature(hw, VIRTIO_F_NOTIFICATION_DATA)) {
+               rte_write16(vq->vq_queue_index, vq->notify_addr);
+               return;
+       }
+
+       if (vtpci_with_feature(hw, VIRTIO_F_RING_PACKED)) {
+               /*
+                * Bit[0:15]: vq queue index
+                * Bit[16:30]: avail index
+                * Bit[31]: avail wrap counter
+                */
+               notify_data = ((uint32_t)(!!(vq->vq_packed.cached_flags &
+                               VRING_PACKED_DESC_F_AVAIL)) << 31) |
+                               ((uint32_t)vq->vq_avail_idx << 16) |
+                               vq->vq_queue_index;
+       } else {
+               /*
+                * Bit[0:15]: vq queue index
+                * Bit[16:31]: avail index
+                */
+               notify_data = ((uint32_t)vq->vq_avail_idx << 16) |
+                               vq->vq_queue_index;
+       }
+       rte_write32(notify_data, vq->notify_addr);
 }
 
 const struct virtio_pci_ops modern_ops = {
@@ -614,9 +639,15 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
                        hw->common_cfg = get_cfg_addr(dev, &cap);
                        break;
                case VIRTIO_PCI_CAP_NOTIFY_CFG:
-                       rte_pci_read_config(dev, &hw->notify_off_multiplier,
+                       ret = rte_pci_read_config(dev,
+                                       &hw->notify_off_multiplier,
                                        4, pos + sizeof(cap));
-                       hw->notify_base = get_cfg_addr(dev, &cap);
+                       if (ret != 4)
+                               PMD_INIT_LOG(DEBUG,
+                                       "failed to read notify_off_multiplier, ret %d",
+                                       ret);
+                       else
+                               hw->notify_base = get_cfg_addr(dev, &cap);
                        break;
                case VIRTIO_PCI_CAP_DEVICE_CFG:
                        hw->dev_cfg = get_cfg_addr(dev, &cap);
@@ -651,13 +682,15 @@ next:
  * Return -1:
  *   if there is error mapping with VFIO/UIO.
  *   if port map error when driver type is KDRV_NONE.
- *   if whitelisted but driver type is KDRV_UNKNOWN.
+ *   if marked as allowed but driver type is KDRV_UNKNOWN.
  * Return 1 if kernel driver is managing the device.
  * Return 0 on success.
  */
 int
 vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 {
+       RTE_BUILD_BUG_ON(offsetof(struct virtio_pci_dev, hw) != 0);
+
        /*
         * Try if we can succeed reading virtio pci caps, which exists
         * only on modern pci device. If failed, we fallback to legacy
@@ -666,13 +699,14 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
        if (virtio_read_caps(dev, hw) == 0) {
                PMD_INIT_LOG(INFO, "modern virtio pci detected.");
                virtio_hw_internal[hw->port_id].vtpci_ops = &modern_ops;
-               hw->modern = 1;
+               hw->bus_type = VIRTIO_BUS_PCI_MODERN;
                return 0;
        }
 
        PMD_INIT_LOG(INFO, "trying with legacy virtio pci.");
        if (rte_pci_ioport_map(dev, 0, VTPCI_IO(hw)) < 0) {
-               if (dev->kdrv == RTE_KDRV_UNKNOWN &&
+               rte_pci_unmap_device(dev);
+               if (dev->kdrv == RTE_PCI_KDRV_UNKNOWN &&
                    (!dev->device.devargs ||
                     dev->device.devargs->bus !=
                     rte_bus_find_by_name("pci"))) {
@@ -684,7 +718,7 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
        }
 
        virtio_hw_internal[hw->port_id].vtpci_ops = &legacy_ops;
-       hw->modern   = 0;
+       hw->bus_type = VIRTIO_BUS_PCI_LEGACY;
 
        return 0;
 }