X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Flinuxapp%2Figb_uio%2Figb_uio.c;h=da71e052f266e8b1abb86cb8e23499a55cd926ab;hb=e1a45fc4945fd83528b03a6a23d817860994a2b8;hp=6885e72e00be1d2c3dc02cfebf6a295abbb5190a;hpb=d26fc87aa26953f97e6c93d07ee9cc1415e44e20;p=dpdk.git diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c index 6885e72e00..da71e052f2 100644 --- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c +++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -91,27 +92,6 @@ static struct attribute *dev_attrs[] = { static const struct attribute_group dev_attr_grp = { .attrs = dev_attrs, }; -/* - * It masks the msix on/off of generating MSI-X messages. - */ -static void -igbuio_msix_mask_irq(struct msi_desc *desc, int32_t state) -{ - u32 mask_bits = desc->masked; - unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL; - - if (state != 0) - mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - else - mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; - - if (mask_bits != desc->masked) { - writel(mask_bits, desc->mask_base + offset); - readl(desc->mask_base); - desc->masked = mask_bits; - } -} /** * This is the irqcontrol callback to be registered to uio_info. @@ -132,21 +112,31 @@ igbuio_pci_irqcontrol(struct uio_info *info, s32 irq_state) struct rte_uio_pci_dev *udev = info->priv; struct pci_dev *pdev = udev->pdev; - pci_cfg_access_lock(pdev); - if (udev->mode == RTE_INTR_MODE_LEGACY) - pci_intx(pdev, !!irq_state); +#ifdef HAVE_IRQ_DATA + struct irq_data *irq = irq_get_irq_data(udev->info.irq); +#else + unsigned int irq = udev->info.irq; +#endif - else if (udev->mode == RTE_INTR_MODE_MSIX) { - struct msi_desc *desc; + pci_cfg_access_lock(pdev); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)) - list_for_each_entry(desc, &pdev->msi_list, list) - igbuio_msix_mask_irq(desc, irq_state); + if (udev->mode == RTE_INTR_MODE_MSIX || udev->mode == RTE_INTR_MODE_MSI) { +#ifdef HAVE_PCI_MSI_MASK_IRQ + if (irq_state == 1) + pci_msi_unmask_irq(irq); + else + pci_msi_mask_irq(irq); #else - list_for_each_entry(desc, &pdev->dev.msi_list, list) - igbuio_msix_mask_irq(desc, irq_state); + if (irq_state == 1) + unmask_msi_irq(irq); + else + mask_msi_irq(irq); #endif } + + if (udev->mode == RTE_INTR_MODE_LEGACY) + pci_intx(pdev, !!irq_state); + pci_cfg_access_unlock(pdev); return 0; @@ -336,6 +326,25 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev) udev->mode = RTE_INTR_MODE_MSIX; break; } +#endif + /* fall back to MSI */ + case RTE_INTR_MODE_MSI: +#ifndef HAVE_ALLOC_IRQ_VECTORS + if (pci_enable_msi(udev->pdev) == 0) { + dev_dbg(&udev->pdev->dev, "using MSI"); + udev->info.irq_flags = IRQF_NO_THREAD; + udev->info.irq = udev->pdev->irq; + udev->mode = RTE_INTR_MODE_MSI; + break; + } +#else + if (pci_alloc_irq_vectors(udev->pdev, 1, 1, PCI_IRQ_MSI) == 1) { + dev_dbg(&udev->pdev->dev, "using MSI"); + udev->info.irq_flags = IRQF_NO_THREAD; + udev->info.irq = pci_irq_vector(udev->pdev, 0); + udev->mode = RTE_INTR_MODE_MSI; + break; + } #endif /* fall back to INTX */ case RTE_INTR_MODE_LEGACY: @@ -347,10 +356,10 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev) break; } dev_notice(&udev->pdev->dev, "PCI INTX mask not supported\n"); - /* fall back to no IRQ */ + /* fall back to no IRQ */ case RTE_INTR_MODE_NONE: udev->mode = RTE_INTR_MODE_NONE; - udev->info.irq = 0; + udev->info.irq = UIO_IRQ_NONE; break; default: @@ -368,8 +377,11 @@ igbuio_pci_disable_interrupts(struct rte_uio_pci_dev *udev) #ifndef HAVE_ALLOC_IRQ_VECTORS if (udev->mode == RTE_INTR_MODE_MSIX) pci_disable_msix(udev->pdev); + if (udev->mode == RTE_INTR_MODE_MSI) + pci_disable_msi(udev->pdev); #else - if (udev->mode == RTE_INTR_MODE_MSIX) + if (udev->mode == RTE_INTR_MODE_MSIX || + udev->mode == RTE_INTR_MODE_MSI) pci_free_irq_vectors(udev->pdev); #endif } @@ -482,7 +494,7 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) err = sysfs_create_group(&dev->dev.kobj, &dev_attr_grp); if (err != 0) - goto fail_release_iomem; + goto fail_disable_interrupts; /* register uio driver */ err = uio_register_device(&dev->dev, &udev->info); @@ -519,9 +531,10 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) fail_remove_group: sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp); +fail_disable_interrupts: + igbuio_pci_disable_interrupts(udev); fail_release_iomem: igbuio_pci_release_iomem(&udev->info); - igbuio_pci_disable_interrupts(udev); pci_disable_device(dev); fail_free: kfree(udev); @@ -536,8 +549,8 @@ igbuio_pci_remove(struct pci_dev *dev) sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp); uio_unregister_device(&udev->info); - igbuio_pci_release_iomem(&udev->info); igbuio_pci_disable_interrupts(udev); + igbuio_pci_release_iomem(&udev->info); pci_disable_device(dev); pci_set_drvdata(dev, NULL); kfree(udev); @@ -554,6 +567,9 @@ igbuio_config_intr_mode(char *intr_str) if (!strcmp(intr_str, RTE_INTR_MODE_MSIX_NAME)) { igbuio_intr_mode_preferred = RTE_INTR_MODE_MSIX; pr_info("Use MSIX interrupt\n"); + } else if (!strcmp(intr_str, RTE_INTR_MODE_MSI_NAME)) { + igbuio_intr_mode_preferred = RTE_INTR_MODE_MSI; + pr_info("Use MSI interrupt\n"); } else if (!strcmp(intr_str, RTE_INTR_MODE_LEGACY_NAME)) { igbuio_intr_mode_preferred = RTE_INTR_MODE_LEGACY; pr_info("Use legacy interrupt\n"); @@ -597,6 +613,7 @@ module_param(intr_mode, charp, S_IRUGO); MODULE_PARM_DESC(intr_mode, "igb_uio interrupt mode (default=msix):\n" " " RTE_INTR_MODE_MSIX_NAME " Use MSIX interrupt\n" +" " RTE_INTR_MODE_MSI_NAME " Use MSI interrupt\n" " " RTE_INTR_MODE_LEGACY_NAME " Use Legacy interrupt\n" "\n");