net/virtio: move MSI-X detection to PCI ethdev
authorMaxime Coquelin <maxime.coquelin@redhat.com>
Tue, 26 Jan 2021 10:16:04 +0000 (11:16 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 29 Jan 2021 17:16:09 +0000 (18:16 +0100)
This patch introduces a new callback to notify the bus
driver some interrupt related operation was done.

This is used by Virtio PCI driver to check msix status.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
drivers/net/virtio/virtio_ethdev.c
drivers/net/virtio/virtio_pci.c
drivers/net/virtio/virtio_pci.h
drivers/net/virtio/virtio_pci_ethdev.c

index ca9351b..83253ed 100644 (file)
@@ -1287,8 +1287,8 @@ virtio_intr_unmask(struct rte_eth_dev *dev)
        if (rte_intr_ack(dev->intr_handle) < 0)
                return -1;
 
-       if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
-               hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
+       if (VTPCI_OPS(hw)->intr_detect)
+               VTPCI_OPS(hw)->intr_detect(hw);
 
        return 0;
 }
@@ -1301,8 +1301,8 @@ virtio_intr_enable(struct rte_eth_dev *dev)
        if (rte_intr_enable(dev->intr_handle) < 0)
                return -1;
 
-       if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
-               hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
+       if (VTPCI_OPS(hw)->intr_detect)
+               VTPCI_OPS(hw)->intr_detect(hw);
 
        return 0;
 }
@@ -1315,8 +1315,8 @@ virtio_intr_disable(struct rte_eth_dev *dev)
        if (rte_intr_disable(dev->intr_handle) < 0)
                return -1;
 
-       if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
-               hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
+       if (VTPCI_OPS(hw)->intr_detect)
+               VTPCI_OPS(hw)->intr_detect(hw);
 
        return 0;
 }
index 345d73f..556be1e 100644 (file)
@@ -47,6 +47,56 @@ check_vq_phys_addr_ok(struct virtqueue *vq)
        return 1;
 }
 
+#define PCI_MSIX_ENABLE 0x8000
+
+static enum virtio_msix_status
+vtpci_msix_detect(struct rte_pci_device *dev)
+{
+       uint8_t pos;
+       int ret;
+
+       ret = rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
+       if (ret != 1) {
+               PMD_INIT_LOG(DEBUG,
+                            "failed to read pci capability list, ret %d", ret);
+               return VIRTIO_MSIX_NONE;
+       }
+
+       while (pos) {
+               uint8_t cap[2];
+
+               ret = rte_pci_read_config(dev, cap, sizeof(cap), pos);
+               if (ret != sizeof(cap)) {
+                       PMD_INIT_LOG(DEBUG,
+                                    "failed to read pci cap at pos: %x ret %d",
+                                    pos, ret);
+                       break;
+               }
+
+               if (cap[0] == PCI_CAP_ID_MSIX) {
+                       uint16_t flags;
+
+                       ret = rte_pci_read_config(dev, &flags, sizeof(flags),
+                                       pos + sizeof(cap));
+                       if (ret != sizeof(flags)) {
+                               PMD_INIT_LOG(DEBUG,
+                                            "failed to read pci cap at pos:"
+                                            " %x ret %d", pos + 2, ret);
+                               break;
+                       }
+
+                       if (flags & PCI_MSIX_ENABLE)
+                               return VIRTIO_MSIX_ENABLED;
+                       else
+                               return VIRTIO_MSIX_DISABLED;
+               }
+
+               pos = cap[1];
+       }
+
+       return VIRTIO_MSIX_NONE;
+}
+
 /*
  * Since we are in legacy mode:
  * http://ozlabs.org/~rusty/virtio-spec/virtio-0.9.5.pdf
@@ -241,6 +291,12 @@ legacy_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
                VIRTIO_PCI_QUEUE_NOTIFY);
 }
 
+static void
+legacy_intr_detect(struct virtio_hw *hw)
+{
+       hw->use_msix = vtpci_msix_detect(VTPCI_DEV(hw));
+}
+
 const struct virtio_pci_ops legacy_ops = {
        .read_dev_cfg   = legacy_read_dev_config,
        .write_dev_cfg  = legacy_write_dev_config,
@@ -255,6 +311,7 @@ const struct virtio_pci_ops legacy_ops = {
        .setup_queue    = legacy_setup_queue,
        .del_queue      = legacy_del_queue,
        .notify_queue   = legacy_notify_queue,
+       .intr_detect    = legacy_intr_detect,
 };
 
 static inline void
@@ -446,6 +503,14 @@ modern_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
        rte_write32(notify_data, vq->notify_addr);
 }
 
+
+
+static void
+modern_intr_detect(struct virtio_hw *hw)
+{
+       hw->use_msix = vtpci_msix_detect(VTPCI_DEV(hw));
+}
+
 const struct virtio_pci_ops modern_ops = {
        .read_dev_cfg   = modern_read_dev_config,
        .write_dev_cfg  = modern_write_dev_config,
@@ -460,6 +525,7 @@ const struct virtio_pci_ops modern_ops = {
        .setup_queue    = modern_setup_queue,
        .del_queue      = modern_del_queue,
        .notify_queue   = modern_notify_queue,
+       .intr_detect    = modern_intr_detect,
 };
 
 
@@ -562,8 +628,6 @@ get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
        return base + offset;
 }
 
-#define PCI_MSIX_ENABLE 0x8000
-
 static int
 virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
 {
@@ -700,7 +764,7 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
                PMD_INIT_LOG(INFO, "modern virtio pci detected.");
                virtio_hw_internal[hw->port_id].vtpci_ops = &modern_ops;
                hw->bus_type = VIRTIO_BUS_PCI_MODERN;
-               return 0;
+               goto msix_detect;
        }
 
        PMD_INIT_LOG(INFO, "trying with legacy virtio pci.");
@@ -720,53 +784,9 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
        virtio_hw_internal[hw->port_id].vtpci_ops = &legacy_ops;
        hw->bus_type = VIRTIO_BUS_PCI_LEGACY;
 
+msix_detect:
+       VTPCI_OPS(hw)->intr_detect(hw);
+
        return 0;
 }
 
-enum virtio_msix_status
-vtpci_msix_detect(struct rte_pci_device *dev)
-{
-       uint8_t pos;
-       int ret;
-
-       ret = rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
-       if (ret != 1) {
-               PMD_INIT_LOG(DEBUG,
-                            "failed to read pci capability list, ret %d", ret);
-               return VIRTIO_MSIX_NONE;
-       }
-
-       while (pos) {
-               uint8_t cap[2];
-
-               ret = rte_pci_read_config(dev, cap, sizeof(cap), pos);
-               if (ret != sizeof(cap)) {
-                       PMD_INIT_LOG(DEBUG,
-                                    "failed to read pci cap at pos: %x ret %d",
-                                    pos, ret);
-                       break;
-               }
-
-               if (cap[0] == PCI_CAP_ID_MSIX) {
-                       uint16_t flags;
-
-                       ret = rte_pci_read_config(dev, &flags, sizeof(flags),
-                                       pos + sizeof(cap));
-                       if (ret != sizeof(flags)) {
-                               PMD_INIT_LOG(DEBUG,
-                                            "failed to read pci cap at pos:"
-                                            " %x ret %d", pos + 2, ret);
-                               break;
-                       }
-
-                       if (flags & PCI_MSIX_ENABLE)
-                               return VIRTIO_MSIX_ENABLED;
-                       else
-                               return VIRTIO_MSIX_DISABLED;
-               }
-
-               pos = cap[1];
-       }
-
-       return VIRTIO_MSIX_NONE;
-}
index 6793d33..a0f7d1f 100644 (file)
@@ -239,6 +239,7 @@ struct virtio_pci_ops {
        int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
        void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
        void (*notify_queue)(struct virtio_hw *hw, struct virtqueue *vq);
+       void (*intr_detect)(struct virtio_hw *hw);
 };
 
 struct virtio_net_config;
@@ -303,10 +304,13 @@ struct virtio_pci_dev {
 struct virtio_hw_internal {
        const struct virtio_pci_ops *vtpci_ops;
        struct rte_pci_ioport io;
+       struct rte_pci_device *dev;
 };
 
 #define VTPCI_OPS(hw)  (virtio_hw_internal[(hw)->port_id].vtpci_ops)
 #define VTPCI_IO(hw)   (&virtio_hw_internal[(hw)->port_id].io)
+#define VTPCI_DEV(hw)  (virtio_hw_internal[(hw)->port_id].dev)
+
 
 extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
 
@@ -383,8 +387,6 @@ void vtpci_read_dev_config(struct virtio_hw *, size_t, void *, int);
 
 uint8_t vtpci_isr(struct virtio_hw *);
 
-enum virtio_msix_status vtpci_msix_detect(struct rte_pci_device *dev);
-
 extern const struct virtio_pci_ops legacy_ops;
 extern const struct virtio_pci_ops modern_ops;
 extern const struct virtio_pci_ops virtio_user_ops;
index 8793bf7..d2f0ca6 100644 (file)
@@ -73,6 +73,8 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
        int ret;
 
+       VTPCI_DEV(hw) = pci_dev;
+
        if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
                ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
                if (ret) {