X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_pci.c;h=345d73f86820b0cc2e22470754f4962e7ff1bafb;hb=512e27eeb7435780cfe6915e17dbf840e0f4df20;hp=c8883c32e96c806524b8f3b5e0b61d418fb3382c;hpb=ecfae1510edc1391285aa566a2d31e7eae8fc6d2;p=dpdk.git diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c index c8883c32e9..345d73f868 100644 --- a/drivers/net/virtio/virtio_pci.c +++ b/drivers/net/virtio/virtio_pci.c @@ -3,7 +3,7 @@ */ #include -#ifdef RTE_EXEC_ENV_LINUXAPP +#ifdef RTE_EXEC_ENV_LINUX #include #include #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 = { @@ -657,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 @@ -672,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"))) { @@ -690,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; }