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