igb_uio: fix build with kernel older than 2.6.34
[dpdk.git] / lib / librte_eal / linuxapp / igb_uio / igb_uio.c
1 /*-
2  * GPL LICENSE SUMMARY
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of version 2 of the GNU General Public License as
8  *   published by the Free Software Foundation.
9  *
10  *   This program is distributed in the hope that it will be useful, but
11  *   WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *   General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18  *   The full GNU General Public License is included in this distribution
19  *   in the file called LICENSE.GPL.
20  *
21  *   Contact Information:
22  *   Intel Corporation
23  */
24
25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26
27 #include <linux/device.h>
28 #include <linux/module.h>
29 #include <linux/pci.h>
30 #include <linux/uio_driver.h>
31 #include <linux/io.h>
32 #include <linux/msi.h>
33 #include <linux/version.h>
34
35 #ifdef CONFIG_XEN_DOM0
36 #include <xen/xen.h>
37 #endif
38 #include <rte_pci_dev_features.h>
39
40 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
41 #define pci_cfg_access_lock   pci_block_user_cfg_access
42 #define pci_cfg_access_unlock pci_unblock_user_cfg_access
43 #endif
44
45 #ifdef RTE_PCI_CONFIG
46 #define PCI_SYS_FILE_BUF_SIZE      10
47 #define PCI_DEV_CAP_REG            0xA4
48 #define PCI_DEV_CTRL_REG           0xA8
49 #define PCI_DEV_CAP_EXT_TAG_MASK   0x20
50 #define PCI_DEV_CTRL_EXT_TAG_SHIFT 8
51 #define PCI_DEV_CTRL_EXT_TAG_MASK  (1 << PCI_DEV_CTRL_EXT_TAG_SHIFT)
52 #endif
53
54 /**
55  * A structure describing the private information for a uio device.
56  */
57 struct rte_uio_pci_dev {
58         struct uio_info info;
59         struct pci_dev *pdev;
60         enum rte_intr_mode mode;
61 };
62
63 static char *intr_mode = NULL;
64 static enum rte_intr_mode igbuio_intr_mode_preferred = RTE_INTR_MODE_MSIX;
65
66 static inline struct rte_uio_pci_dev *
67 igbuio_get_uio_pci_dev(struct uio_info *info)
68 {
69         return container_of(info, struct rte_uio_pci_dev, info);
70 }
71
72 /* sriov sysfs */
73 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
74 static int pci_num_vf(struct pci_dev *dev)
75 {
76         struct iov {
77                 int pos;
78                 int nres;
79                 u32 cap;
80                 u16 ctrl;
81                 u16 total;
82                 u16 initial;
83                 u16 nr_virtfn;
84         } *iov = (struct iov *)dev->sriov;
85
86         if (!dev->is_physfn)
87                 return 0;
88
89         return iov->nr_virtfn;
90 }
91 #endif
92
93 static ssize_t
94 show_max_vfs(struct device *dev, struct device_attribute *attr,
95              char *buf)
96 {
97         return snprintf(buf, 10, "%u\n",
98                         pci_num_vf(container_of(dev, struct pci_dev, dev)));
99 }
100
101 static ssize_t
102 store_max_vfs(struct device *dev, struct device_attribute *attr,
103               const char *buf, size_t count)
104 {
105         int err = 0;
106         unsigned long max_vfs;
107         struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
108
109         if (0 != strict_strtoul(buf, 0, &max_vfs))
110                 return -EINVAL;
111
112         if (0 == max_vfs)
113                 pci_disable_sriov(pdev);
114         else if (0 == pci_num_vf(pdev))
115                 err = pci_enable_sriov(pdev, max_vfs);
116         else /* do nothing if change max_vfs number */
117                 err = -EINVAL;
118
119         return err ? err : count;
120 }
121
122 #ifdef RTE_PCI_CONFIG
123 static ssize_t
124 show_extended_tag(struct device *dev, struct device_attribute *attr, char *buf)
125 {
126         struct pci_dev *pci_dev = container_of(dev, struct pci_dev, dev);
127         uint32_t val = 0;
128
129         pci_read_config_dword(pci_dev, PCI_DEV_CAP_REG, &val);
130         if (!(val & PCI_DEV_CAP_EXT_TAG_MASK)) /* Not supported */
131                 return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%s\n", "invalid");
132
133         val = 0;
134         pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
135                                         PCI_DEV_CTRL_REG, &val);
136
137         return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%s\n",
138                 (val & PCI_DEV_CTRL_EXT_TAG_MASK) ? "on" : "off");
139 }
140
141 static ssize_t
142 store_extended_tag(struct device *dev,
143                    struct device_attribute *attr,
144                    const char *buf,
145                    size_t count)
146 {
147         struct pci_dev *pci_dev = container_of(dev, struct pci_dev, dev);
148         uint32_t val = 0, enable;
149
150         if (strncmp(buf, "on", 2) == 0)
151                 enable = 1;
152         else if (strncmp(buf, "off", 3) == 0)
153                 enable = 0;
154         else
155                 return -EINVAL;
156
157         pci_cfg_access_lock(pci_dev);
158         pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
159                                         PCI_DEV_CAP_REG, &val);
160         if (!(val & PCI_DEV_CAP_EXT_TAG_MASK)) { /* Not supported */
161                 pci_cfg_access_unlock(pci_dev);
162                 return -EPERM;
163         }
164
165         val = 0;
166         pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
167                                         PCI_DEV_CTRL_REG, &val);
168         if (enable)
169                 val |= PCI_DEV_CTRL_EXT_TAG_MASK;
170         else
171                 val &= ~PCI_DEV_CTRL_EXT_TAG_MASK;
172         pci_bus_write_config_dword(pci_dev->bus, pci_dev->devfn,
173                                         PCI_DEV_CTRL_REG, val);
174         pci_cfg_access_unlock(pci_dev);
175
176         return count;
177 }
178
179 static ssize_t
180 show_max_read_request_size(struct device *dev,
181                            struct device_attribute *attr,
182                            char *buf)
183 {
184         struct pci_dev *pci_dev = container_of(dev, struct pci_dev, dev);
185         int val = pcie_get_readrq(pci_dev);
186
187         return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%d\n", val);
188 }
189
190 static ssize_t
191 store_max_read_request_size(struct device *dev,
192                             struct device_attribute *attr,
193                             const char *buf,
194                             size_t count)
195 {
196         struct pci_dev *pci_dev = container_of(dev, struct pci_dev, dev);
197         unsigned long size = 0;
198         int ret;
199
200         if (strict_strtoul(buf, 0, &size) != 0)
201                 return -EINVAL;
202
203         ret = pcie_set_readrq(pci_dev, (int)size);
204         if (ret < 0)
205                 return ret;
206
207         return count;
208 }
209 #endif
210
211 static DEVICE_ATTR(max_vfs, S_IRUGO | S_IWUSR, show_max_vfs, store_max_vfs);
212 #ifdef RTE_PCI_CONFIG
213 static DEVICE_ATTR(extended_tag, S_IRUGO | S_IWUSR, show_extended_tag,
214         store_extended_tag);
215 static DEVICE_ATTR(max_read_request_size, S_IRUGO | S_IWUSR,
216         show_max_read_request_size, store_max_read_request_size);
217 #endif
218
219 static struct attribute *dev_attrs[] = {
220         &dev_attr_max_vfs.attr,
221 #ifdef RTE_PCI_CONFIG
222         &dev_attr_extended_tag.attr,
223         &dev_attr_max_read_request_size.attr,
224 #endif
225         NULL,
226 };
227
228 static const struct attribute_group dev_attr_grp = {
229         .attrs = dev_attrs,
230 };
231
232 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
233 /* Check if INTX works to control irq's.
234  * Set's INTX_DISABLE flag and reads it back
235  */
236 static bool pci_intx_mask_supported(struct pci_dev *pdev)
237 {
238         bool mask_supported = false;
239         uint16_t orig, new;
240
241         pci_block_user_cfg_access(pdev);
242         pci_read_config_word(pdev, PCI_COMMAND, &orig);
243         pci_write_config_word(pdev, PCI_COMMAND,
244                               orig ^ PCI_COMMAND_INTX_DISABLE);
245         pci_read_config_word(pdev, PCI_COMMAND, &new);
246
247         if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
248                 dev_err(&pdev->dev, "Command register changed from "
249                         "0x%x to 0x%x: driver or hardware bug?\n", orig, new);
250         } else if ((new ^ orig) & PCI_COMMAND_INTX_DISABLE) {
251                 mask_supported = true;
252                 pci_write_config_word(pdev, PCI_COMMAND, orig);
253         }
254         pci_unblock_user_cfg_access(pdev);
255
256         return mask_supported;
257 }
258
259 static bool pci_check_and_mask_intx(struct pci_dev *pdev)
260 {
261         bool pending;
262         uint32_t status;
263
264         pci_block_user_cfg_access(pdev);
265         pci_read_config_dword(pdev, PCI_COMMAND, &status);
266
267         /* interrupt is not ours, goes to out */
268         pending = (((status >> 16) & PCI_STATUS_INTERRUPT) != 0);
269         if (pending) {
270                 uint16_t old, new;
271
272                 old = status;
273                 if (status != 0)
274                         new = old & (~PCI_COMMAND_INTX_DISABLE);
275                 else
276                         new = old | PCI_COMMAND_INTX_DISABLE;
277
278                 if (old != new)
279                         pci_write_config_word(pdev, PCI_COMMAND, new);
280         }
281         pci_unblock_user_cfg_access(pdev);
282
283         return pending;
284 }
285 #endif
286
287 /*
288  * It masks the msix on/off of generating MSI-X messages.
289  */
290 static void
291 igbuio_msix_mask_irq(struct msi_desc *desc, int32_t state)
292 {
293         u32 mask_bits = desc->masked;
294         unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
295                                                 PCI_MSIX_ENTRY_VECTOR_CTRL;
296
297         if (state != 0)
298                 mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
299         else
300                 mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
301
302         if (mask_bits != desc->masked) {
303                 writel(mask_bits, desc->mask_base + offset);
304                 readl(desc->mask_base);
305                 desc->masked = mask_bits;
306         }
307 }
308
309 static void
310 igbuio_msi_mask_irq(struct irq_data *data, u32 enable)
311 {
312         struct msi_desc *desc = irq_data_get_msi(data);
313         u32 mask_bits = desc->masked;
314         unsigned offset = data->irq - desc->dev->irq;
315         u32 mask = 1 << offset;
316         u32 flag = enable << offset;
317
318         mask_bits &= ~mask;
319         mask_bits |= flag;
320
321         if (desc->msi_attrib.maskbit && mask_bits != desc->masked) {
322                 pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
323                 desc->masked = mask_bits;
324         }
325 }
326
327 /**
328  * This is the irqcontrol callback to be registered to uio_info.
329  * It can be used to disable/enable interrupt from user space processes.
330  *
331  * @param info
332  *  pointer to uio_info.
333  * @param irq_state
334  *  state value. 1 to enable interrupt, 0 to disable interrupt.
335  *
336  * @return
337  *  - On success, 0.
338  *  - On failure, a negative value.
339  */
340 static int
341 igbuio_pci_irqcontrol(struct uio_info *info, s32 irq_state)
342 {
343         struct rte_uio_pci_dev *udev = igbuio_get_uio_pci_dev(info);
344         struct pci_dev *pdev = udev->pdev;
345
346         pci_cfg_access_lock(pdev);
347         if (udev->mode == RTE_INTR_MODE_LEGACY)
348                 pci_intx(pdev, !!irq_state);
349         else if (udev->mode == RTE_INTR_MODE_MSI) {
350                 struct irq_data *data = irq_get_irq_data(pdev->irq);
351
352                 igbuio_msi_mask_irq(data, !!irq_state);
353         } else if (udev->mode == RTE_INTR_MODE_MSIX) {
354                 struct msi_desc *desc;
355
356                 list_for_each_entry(desc, &pdev->msi_list, list)
357                         igbuio_msix_mask_irq(desc, irq_state);
358         }
359         pci_cfg_access_unlock(pdev);
360
361         return 0;
362 }
363
364 /**
365  * This is interrupt handler which will check if the interrupt is for the right device.
366  * If yes, disable it here and will be enable later.
367  */
368 static irqreturn_t
369 igbuio_pci_irqhandler(int irq, struct uio_info *info)
370 {
371         struct rte_uio_pci_dev *udev = igbuio_get_uio_pci_dev(info);
372
373         /* Legacy mode need to mask in hardware */
374         if (udev->mode == RTE_INTR_MODE_LEGACY &&
375             !pci_check_and_mask_intx(udev->pdev))
376                 return IRQ_NONE;
377
378         /* Message signal mode, no share IRQ and automasked */
379         return IRQ_HANDLED;
380 }
381
382 #ifdef CONFIG_XEN_DOM0
383 static int
384 igbuio_dom0_mmap_phys(struct uio_info *info, struct vm_area_struct *vma)
385 {
386         int idx;
387
388         idx = (int)vma->vm_pgoff;
389         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
390         vma->vm_page_prot.pgprot |= _PAGE_IOMAP;
391
392         return remap_pfn_range(vma,
393                         vma->vm_start,
394                         info->mem[idx].addr >> PAGE_SHIFT,
395                         vma->vm_end - vma->vm_start,
396                         vma->vm_page_prot);
397 }
398
399 /**
400  * This is uio device mmap method which will use igbuio mmap for Xen
401  * Dom0 environment.
402  */
403 static int
404 igbuio_dom0_pci_mmap(struct uio_info *info, struct vm_area_struct *vma)
405 {
406         int idx;
407
408         if (vma->vm_pgoff >= MAX_UIO_MAPS)
409                 return -EINVAL;
410
411         if (info->mem[vma->vm_pgoff].size == 0)
412                 return -EINVAL;
413
414         idx = (int)vma->vm_pgoff;
415         switch (info->mem[idx].memtype) {
416         case UIO_MEM_PHYS:
417                 return igbuio_dom0_mmap_phys(info, vma);
418         case UIO_MEM_LOGICAL:
419         case UIO_MEM_VIRTUAL:
420         default:
421                 return -EINVAL;
422         }
423 }
424 #endif
425
426 /* Remap pci resources described by bar #pci_bar in uio resource n. */
427 static int
428 igbuio_pci_setup_iomem(struct pci_dev *dev, struct uio_info *info,
429                        int n, int pci_bar, const char *name)
430 {
431         unsigned long addr, len;
432         void *internal_addr;
433
434         if (sizeof(info->mem) / sizeof(info->mem[0]) <= n)
435                 return -EINVAL;
436
437         addr = pci_resource_start(dev, pci_bar);
438         len = pci_resource_len(dev, pci_bar);
439         if (addr == 0 || len == 0)
440                 return -1;
441         internal_addr = ioremap(addr, len);
442         if (internal_addr == NULL)
443                 return -1;
444         info->mem[n].name = name;
445         info->mem[n].addr = addr;
446         info->mem[n].internal_addr = internal_addr;
447         info->mem[n].size = len;
448         info->mem[n].memtype = UIO_MEM_PHYS;
449         return 0;
450 }
451
452 /* Get pci port io resources described by bar #pci_bar in uio resource n. */
453 static int
454 igbuio_pci_setup_ioport(struct pci_dev *dev, struct uio_info *info,
455                 int n, int pci_bar, const char *name)
456 {
457         unsigned long addr, len;
458
459         if (sizeof(info->port) / sizeof(info->port[0]) <= n)
460                 return -EINVAL;
461
462         addr = pci_resource_start(dev, pci_bar);
463         len = pci_resource_len(dev, pci_bar);
464         if (addr == 0 || len == 0)
465                 return -EINVAL;
466
467         info->port[n].name = name;
468         info->port[n].start = addr;
469         info->port[n].size = len;
470         info->port[n].porttype = UIO_PORT_X86;
471
472         return 0;
473 }
474
475 /* Unmap previously ioremap'd resources */
476 static void
477 igbuio_pci_release_iomem(struct uio_info *info)
478 {
479         int i;
480
481         for (i = 0; i < MAX_UIO_MAPS; i++) {
482                 if (info->mem[i].internal_addr)
483                         iounmap(info->mem[i].internal_addr);
484         }
485 }
486
487 static int
488 igbuio_setup_bars(struct pci_dev *dev, struct uio_info *info)
489 {
490         int i, iom, iop, ret;
491         unsigned long flags;
492         static const char *bar_names[PCI_STD_RESOURCE_END + 1]  = {
493                 "BAR0",
494                 "BAR1",
495                 "BAR2",
496                 "BAR3",
497                 "BAR4",
498                 "BAR5",
499         };
500
501         iom = 0;
502         iop = 0;
503
504         for (i = 0; i != sizeof(bar_names) / sizeof(bar_names[0]); i++) {
505                 if (pci_resource_len(dev, i) != 0 &&
506                                 pci_resource_start(dev, i) != 0) {
507                         flags = pci_resource_flags(dev, i);
508                         if (flags & IORESOURCE_MEM) {
509                                 ret = igbuio_pci_setup_iomem(dev, info, iom,
510                                                              i, bar_names[i]);
511                                 if (ret != 0)
512                                         return ret;
513                                 iom++;
514                         } else if (flags & IORESOURCE_IO) {
515                                 ret = igbuio_pci_setup_ioport(dev, info, iop,
516                                                               i, bar_names[i]);
517                                 if (ret != 0)
518                                         return ret;
519                                 iop++;
520                         }
521                 }
522         }
523
524         return (iom != 0) ? ret : -ENOENT;
525 }
526
527 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
528 static int __devinit
529 #else
530 static int
531 #endif
532 igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
533 {
534         struct rte_uio_pci_dev *udev;
535         struct msix_entry msix_entry;
536         int err;
537
538         udev = kzalloc(sizeof(struct rte_uio_pci_dev), GFP_KERNEL);
539         if (!udev)
540                 return -ENOMEM;
541
542         /*
543          * enable device: ask low-level code to enable I/O and
544          * memory
545          */
546         err = pci_enable_device(dev);
547         if (err != 0) {
548                 dev_err(&dev->dev, "Cannot enable PCI device\n");
549                 goto fail_free;
550         }
551
552         /*
553          * reserve device's PCI memory regions for use by this
554          * module
555          */
556         err = pci_request_regions(dev, "igb_uio");
557         if (err != 0) {
558                 dev_err(&dev->dev, "Cannot request regions\n");
559                 goto fail_disable;
560         }
561
562         /* enable bus mastering on the device */
563         pci_set_master(dev);
564
565         /* remap IO memory */
566         err = igbuio_setup_bars(dev, &udev->info);
567         if (err != 0)
568                 goto fail_release_iomem;
569
570         /* set 64-bit DMA mask */
571         err = pci_set_dma_mask(dev,  DMA_BIT_MASK(64));
572         if (err != 0) {
573                 dev_err(&dev->dev, "Cannot set DMA mask\n");
574                 goto fail_release_iomem;
575         }
576
577         err = pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
578         if (err != 0) {
579                 dev_err(&dev->dev, "Cannot set consistent DMA mask\n");
580                 goto fail_release_iomem;
581         }
582
583         /* fill uio infos */
584         udev->info.name = "igb_uio";
585         udev->info.version = "0.1";
586         udev->info.handler = igbuio_pci_irqhandler;
587         udev->info.irqcontrol = igbuio_pci_irqcontrol;
588         udev->info.irq = dev->irq;
589 #ifdef CONFIG_XEN_DOM0
590         /* check if the driver run on Xen Dom0 */
591         if (xen_initial_domain())
592                 udev->info.mmap = igbuio_dom0_pci_mmap;
593 #endif
594         udev->info.priv = udev;
595         udev->pdev = dev;
596
597         switch (igbuio_intr_mode_preferred) {
598         case RTE_INTR_MODE_NONE:
599                 udev->info.irq = 0;
600                 break;
601         case RTE_INTR_MODE_MSIX:
602                 /* Only 1 msi-x vector needed */
603                 msix_entry.entry = 0;
604                 if (pci_enable_msix(dev, &msix_entry, 1) == 0) {
605                         dev_dbg(&dev->dev, "using MSI-X");
606                         udev->info.irq = msix_entry.vector;
607                         udev->mode = RTE_INTR_MODE_MSIX;
608                         break;
609                 }
610                 /* fall back to MSI */
611         case RTE_INTR_MODE_MSI:
612                 if (pci_enable_msi(dev) == 0) {
613                         dev_dbg(&dev->dev, "using MSI");
614                         udev->mode = RTE_INTR_MODE_MSI;
615                         break;
616                 }
617                 /* fall back to INTX */
618         case RTE_INTR_MODE_LEGACY:
619                 if (pci_intx_mask_supported(dev)) {
620                         dev_dbg(&dev->dev, "using INTX");
621                         udev->info.irq_flags = IRQF_SHARED;
622                         udev->mode = RTE_INTR_MODE_LEGACY;
623                 } else {
624                         dev_err(&dev->dev, "PCI INTX mask not supported\n");
625                         err = -EIO;
626                         goto fail_release_iomem;
627                 }
628                 break;
629         default:
630                 dev_err(&dev->dev, "invalid IRQ mode %u",
631                         igbuio_intr_mode_preferred);
632                 err = -EINVAL;
633                 goto fail_release_iomem;
634         }
635
636         err = sysfs_create_group(&dev->dev.kobj, &dev_attr_grp);
637         if (err != 0)
638                 goto fail_release_iomem;
639
640         /* register uio driver */
641         err = uio_register_device(&dev->dev, &udev->info);
642         if (err != 0)
643                 goto fail_remove_group;
644
645         pci_set_drvdata(dev, udev);
646
647         dev_info(&dev->dev, "uio device registered with irq %lx\n",
648                  udev->info.irq);
649
650         return 0;
651
652 fail_remove_group:
653         sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);
654 fail_release_iomem:
655         igbuio_pci_release_iomem(&udev->info);
656         if (udev->mode == RTE_INTR_MODE_MSIX)
657                 pci_disable_msix(udev->pdev);
658         else if (udev->mode == RTE_INTR_MODE_MSI)
659                 pci_disable_msi(udev->pdev);
660         pci_release_regions(dev);
661 fail_disable:
662         pci_disable_device(dev);
663 fail_free:
664         kfree(udev);
665
666         return err;
667 }
668
669 static void
670 igbuio_pci_remove(struct pci_dev *dev)
671 {
672         struct uio_info *info = pci_get_drvdata(dev);
673         struct rte_uio_pci_dev *udev = igbuio_get_uio_pci_dev(info);
674
675         if (info->priv == NULL) {
676                 pr_notice("Not igbuio device\n");
677                 return;
678         }
679
680         sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);
681         uio_unregister_device(info);
682         igbuio_pci_release_iomem(info);
683         if (udev->mode == RTE_INTR_MODE_MSIX)
684                 pci_disable_msix(dev);
685         else if (udev->mode == RTE_INTR_MODE_MSI)
686                 pci_disable_msi(dev);
687         pci_release_regions(dev);
688         pci_disable_device(dev);
689         pci_set_drvdata(dev, NULL);
690         kfree(info);
691 }
692
693 static int
694 igbuio_config_intr_mode(char *intr_str)
695 {
696         if (!intr_str) {
697                 pr_info("Use MSIX interrupt by default\n");
698                 return 0;
699         }
700
701         if (!strcmp(intr_str, RTE_INTR_MODE_MSIX_NAME)) {
702                 igbuio_intr_mode_preferred = RTE_INTR_MODE_MSIX;
703                 pr_info("Use MSIX interrupt\n");
704         } else if (!strcmp(intr_str, RTE_INTR_MODE_MSI_NAME)) {
705                 igbuio_intr_mode_preferred = RTE_INTR_MODE_MSI;
706                 pr_info("Use MSI interrupt\n");
707         } else if (!strcmp(intr_str, RTE_INTR_MODE_LEGACY_NAME)) {
708                 igbuio_intr_mode_preferred = RTE_INTR_MODE_LEGACY;
709                 pr_info("Use legacy interrupt\n");
710         } else {
711                 pr_info("Error: bad parameter - %s\n", intr_str);
712                 return -EINVAL;
713         }
714
715         return 0;
716 }
717
718 static struct pci_driver igbuio_pci_driver = {
719         .name = "igb_uio",
720         .id_table = NULL,
721         .probe = igbuio_pci_probe,
722         .remove = igbuio_pci_remove,
723 };
724
725 static int __init
726 igbuio_pci_init_module(void)
727 {
728         int ret;
729
730         ret = igbuio_config_intr_mode(intr_mode);
731         if (ret < 0)
732                 return ret;
733
734         return pci_register_driver(&igbuio_pci_driver);
735 }
736
737 static void __exit
738 igbuio_pci_exit_module(void)
739 {
740         pci_unregister_driver(&igbuio_pci_driver);
741 }
742
743 module_init(igbuio_pci_init_module);
744 module_exit(igbuio_pci_exit_module);
745
746 module_param(intr_mode, charp, S_IRUGO);
747 MODULE_PARM_DESC(intr_mode,
748 "igb_uio interrupt mode (default=msix):\n"
749 "    " RTE_INTR_MODE_MSIX_NAME "       Use MSIX interrupt\n"
750 "    " RTE_INTR_MODE_MSI_NAME "        Use MSI interrupt\n"
751 "    " RTE_INTR_MODE_LEGACY_NAME "     Use Legacy interrupt\n"
752 "\n");
753
754 MODULE_DESCRIPTION("UIO driver for Intel IGB PCI cards");
755 MODULE_LICENSE("GPL");
756 MODULE_AUTHOR("Intel Corporation");