eal: remove Xen dom0 support
[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/irq.h>
33 #include <linux/msi.h>
34 #include <linux/version.h>
35 #include <linux/slab.h>
36
37 #include <rte_pci_dev_features.h>
38
39 #include "compat.h"
40
41 /**
42  * A structure describing the private information for a uio device.
43  */
44 struct rte_uio_pci_dev {
45         struct uio_info info;
46         struct pci_dev *pdev;
47         enum rte_intr_mode mode;
48 };
49
50 static char *intr_mode;
51 static enum rte_intr_mode igbuio_intr_mode_preferred = RTE_INTR_MODE_MSIX;
52
53 /* sriov sysfs */
54 static ssize_t
55 show_max_vfs(struct device *dev, struct device_attribute *attr,
56              char *buf)
57 {
58         return snprintf(buf, 10, "%u\n", dev_num_vf(dev));
59 }
60
61 static ssize_t
62 store_max_vfs(struct device *dev, struct device_attribute *attr,
63               const char *buf, size_t count)
64 {
65         int err = 0;
66         unsigned long max_vfs;
67         struct pci_dev *pdev = to_pci_dev(dev);
68
69         if (0 != kstrtoul(buf, 0, &max_vfs))
70                 return -EINVAL;
71
72         if (0 == max_vfs)
73                 pci_disable_sriov(pdev);
74         else if (0 == pci_num_vf(pdev))
75                 err = pci_enable_sriov(pdev, max_vfs);
76         else /* do nothing if change max_vfs number */
77                 err = -EINVAL;
78
79         return err ? err : count;
80 }
81
82 static DEVICE_ATTR(max_vfs, S_IRUGO | S_IWUSR, show_max_vfs, store_max_vfs);
83
84 static struct attribute *dev_attrs[] = {
85         &dev_attr_max_vfs.attr,
86         NULL,
87 };
88
89 static const struct attribute_group dev_attr_grp = {
90         .attrs = dev_attrs,
91 };
92
93 /**
94  * This is the irqcontrol callback to be registered to uio_info.
95  * It can be used to disable/enable interrupt from user space processes.
96  *
97  * @param info
98  *  pointer to uio_info.
99  * @param irq_state
100  *  state value. 1 to enable interrupt, 0 to disable interrupt.
101  *
102  * @return
103  *  - On success, 0.
104  *  - On failure, a negative value.
105  */
106 static int
107 igbuio_pci_irqcontrol(struct uio_info *info, s32 irq_state)
108 {
109         struct rte_uio_pci_dev *udev = info->priv;
110         struct pci_dev *pdev = udev->pdev;
111
112 #ifdef HAVE_IRQ_DATA
113         struct irq_data *irq = irq_get_irq_data(udev->info.irq);
114 #else
115         unsigned int irq = udev->info.irq;
116 #endif
117
118         pci_cfg_access_lock(pdev);
119
120         if (udev->mode == RTE_INTR_MODE_MSIX || udev->mode == RTE_INTR_MODE_MSI) {
121 #ifdef HAVE_PCI_MSI_MASK_IRQ
122                 if (irq_state == 1)
123                         pci_msi_unmask_irq(irq);
124                 else
125                         pci_msi_mask_irq(irq);
126 #else
127                 if (irq_state == 1)
128                         unmask_msi_irq(irq);
129                 else
130                         mask_msi_irq(irq);
131 #endif
132         }
133
134         if (udev->mode == RTE_INTR_MODE_LEGACY)
135                 pci_intx(pdev, !!irq_state);
136
137         pci_cfg_access_unlock(pdev);
138
139         return 0;
140 }
141
142 /**
143  * This is interrupt handler which will check if the interrupt is for the right device.
144  * If yes, disable it here and will be enable later.
145  */
146 static irqreturn_t
147 igbuio_pci_irqhandler(int irq, struct uio_info *info)
148 {
149         struct rte_uio_pci_dev *udev = info->priv;
150
151         /* Legacy mode need to mask in hardware */
152         if (udev->mode == RTE_INTR_MODE_LEGACY &&
153             !pci_check_and_mask_intx(udev->pdev))
154                 return IRQ_NONE;
155
156         /* Message signal mode, no share IRQ and automasked */
157         return IRQ_HANDLED;
158 }
159
160 /**
161  * This gets called while opening uio device file.
162  */
163 static int
164 igbuio_pci_open(struct uio_info *info, struct inode *inode)
165 {
166         struct rte_uio_pci_dev *udev = info->priv;
167         struct pci_dev *dev = udev->pdev;
168
169         pci_reset_function(dev);
170
171         /* set bus master, which was cleared by the reset function */
172         pci_set_master(dev);
173
174         return 0;
175 }
176
177 static int
178 igbuio_pci_release(struct uio_info *info, struct inode *inode)
179 {
180         struct rte_uio_pci_dev *udev = info->priv;
181         struct pci_dev *dev = udev->pdev;
182
183         /* stop the device from further DMA */
184         pci_clear_master(dev);
185
186         pci_reset_function(dev);
187
188         return 0;
189 }
190
191 /* Remap pci resources described by bar #pci_bar in uio resource n. */
192 static int
193 igbuio_pci_setup_iomem(struct pci_dev *dev, struct uio_info *info,
194                        int n, int pci_bar, const char *name)
195 {
196         unsigned long addr, len;
197         void *internal_addr;
198
199         if (n >= ARRAY_SIZE(info->mem))
200                 return -EINVAL;
201
202         addr = pci_resource_start(dev, pci_bar);
203         len = pci_resource_len(dev, pci_bar);
204         if (addr == 0 || len == 0)
205                 return -1;
206         internal_addr = ioremap(addr, len);
207         if (internal_addr == NULL)
208                 return -1;
209         info->mem[n].name = name;
210         info->mem[n].addr = addr;
211         info->mem[n].internal_addr = internal_addr;
212         info->mem[n].size = len;
213         info->mem[n].memtype = UIO_MEM_PHYS;
214         return 0;
215 }
216
217 /* Get pci port io resources described by bar #pci_bar in uio resource n. */
218 static int
219 igbuio_pci_setup_ioport(struct pci_dev *dev, struct uio_info *info,
220                 int n, int pci_bar, const char *name)
221 {
222         unsigned long addr, len;
223
224         if (n >= ARRAY_SIZE(info->port))
225                 return -EINVAL;
226
227         addr = pci_resource_start(dev, pci_bar);
228         len = pci_resource_len(dev, pci_bar);
229         if (addr == 0 || len == 0)
230                 return -EINVAL;
231
232         info->port[n].name = name;
233         info->port[n].start = addr;
234         info->port[n].size = len;
235         info->port[n].porttype = UIO_PORT_X86;
236
237         return 0;
238 }
239
240 /* Unmap previously ioremap'd resources */
241 static void
242 igbuio_pci_release_iomem(struct uio_info *info)
243 {
244         int i;
245
246         for (i = 0; i < MAX_UIO_MAPS; i++) {
247                 if (info->mem[i].internal_addr)
248                         iounmap(info->mem[i].internal_addr);
249         }
250 }
251
252 static int
253 igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev)
254 {
255         int err = 0;
256 #ifndef HAVE_ALLOC_IRQ_VECTORS
257         struct msix_entry msix_entry;
258 #endif
259
260         switch (igbuio_intr_mode_preferred) {
261         case RTE_INTR_MODE_MSIX:
262                 /* Only 1 msi-x vector needed */
263 #ifndef HAVE_ALLOC_IRQ_VECTORS
264                 msix_entry.entry = 0;
265                 if (pci_enable_msix(udev->pdev, &msix_entry, 1) == 0) {
266                         dev_dbg(&udev->pdev->dev, "using MSI-X");
267                         udev->info.irq_flags = IRQF_NO_THREAD;
268                         udev->info.irq = msix_entry.vector;
269                         udev->mode = RTE_INTR_MODE_MSIX;
270                         break;
271                 }
272 #else
273                 if (pci_alloc_irq_vectors(udev->pdev, 1, 1, PCI_IRQ_MSIX) == 1) {
274                         dev_dbg(&udev->pdev->dev, "using MSI-X");
275                         udev->info.irq_flags = IRQF_NO_THREAD;
276                         udev->info.irq = pci_irq_vector(udev->pdev, 0);
277                         udev->mode = RTE_INTR_MODE_MSIX;
278                         break;
279                 }
280 #endif
281         /* fall back to MSI */
282         case RTE_INTR_MODE_MSI:
283 #ifndef HAVE_ALLOC_IRQ_VECTORS
284                 if (pci_enable_msi(udev->pdev) == 0) {
285                         dev_dbg(&udev->pdev->dev, "using MSI");
286                         udev->info.irq_flags = IRQF_NO_THREAD;
287                         udev->info.irq = udev->pdev->irq;
288                         udev->mode = RTE_INTR_MODE_MSI;
289                         break;
290                 }
291 #else
292                 if (pci_alloc_irq_vectors(udev->pdev, 1, 1, PCI_IRQ_MSI) == 1) {
293                         dev_dbg(&udev->pdev->dev, "using MSI");
294                         udev->info.irq_flags = IRQF_NO_THREAD;
295                         udev->info.irq = pci_irq_vector(udev->pdev, 0);
296                         udev->mode = RTE_INTR_MODE_MSI;
297                         break;
298                 }
299 #endif
300         /* fall back to INTX */
301         case RTE_INTR_MODE_LEGACY:
302                 if (pci_intx_mask_supported(udev->pdev)) {
303                         dev_dbg(&udev->pdev->dev, "using INTX");
304                         udev->info.irq_flags = IRQF_SHARED | IRQF_NO_THREAD;
305                         udev->info.irq = udev->pdev->irq;
306                         udev->mode = RTE_INTR_MODE_LEGACY;
307                         break;
308                 }
309                 dev_notice(&udev->pdev->dev, "PCI INTX mask not supported\n");
310         /* fall back to no IRQ */
311         case RTE_INTR_MODE_NONE:
312                 udev->mode = RTE_INTR_MODE_NONE;
313                 udev->info.irq = UIO_IRQ_NONE;
314                 break;
315
316         default:
317                 dev_err(&udev->pdev->dev, "invalid IRQ mode %u",
318                         igbuio_intr_mode_preferred);
319                 err = -EINVAL;
320         }
321
322         return err;
323 }
324
325 static void
326 igbuio_pci_disable_interrupts(struct rte_uio_pci_dev *udev)
327 {
328 #ifndef HAVE_ALLOC_IRQ_VECTORS
329         if (udev->mode == RTE_INTR_MODE_MSIX)
330                 pci_disable_msix(udev->pdev);
331         if (udev->mode == RTE_INTR_MODE_MSI)
332                 pci_disable_msi(udev->pdev);
333 #else
334         if (udev->mode == RTE_INTR_MODE_MSIX ||
335             udev->mode == RTE_INTR_MODE_MSI)
336                 pci_free_irq_vectors(udev->pdev);
337 #endif
338 }
339
340 static int
341 igbuio_setup_bars(struct pci_dev *dev, struct uio_info *info)
342 {
343         int i, iom, iop, ret;
344         unsigned long flags;
345         static const char *bar_names[PCI_STD_RESOURCE_END + 1]  = {
346                 "BAR0",
347                 "BAR1",
348                 "BAR2",
349                 "BAR3",
350                 "BAR4",
351                 "BAR5",
352         };
353
354         iom = 0;
355         iop = 0;
356
357         for (i = 0; i < ARRAY_SIZE(bar_names); i++) {
358                 if (pci_resource_len(dev, i) != 0 &&
359                                 pci_resource_start(dev, i) != 0) {
360                         flags = pci_resource_flags(dev, i);
361                         if (flags & IORESOURCE_MEM) {
362                                 ret = igbuio_pci_setup_iomem(dev, info, iom,
363                                                              i, bar_names[i]);
364                                 if (ret != 0)
365                                         return ret;
366                                 iom++;
367                         } else if (flags & IORESOURCE_IO) {
368                                 ret = igbuio_pci_setup_ioport(dev, info, iop,
369                                                               i, bar_names[i]);
370                                 if (ret != 0)
371                                         return ret;
372                                 iop++;
373                         }
374                 }
375         }
376
377         return (iom != 0 || iop != 0) ? ret : -ENOENT;
378 }
379
380 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
381 static int __devinit
382 #else
383 static int
384 #endif
385 igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
386 {
387         struct rte_uio_pci_dev *udev;
388         dma_addr_t map_dma_addr;
389         void *map_addr;
390         int err;
391
392         udev = kzalloc(sizeof(struct rte_uio_pci_dev), GFP_KERNEL);
393         if (!udev)
394                 return -ENOMEM;
395
396         /*
397          * enable device: ask low-level code to enable I/O and
398          * memory
399          */
400         err = pci_enable_device(dev);
401         if (err != 0) {
402                 dev_err(&dev->dev, "Cannot enable PCI device\n");
403                 goto fail_free;
404         }
405
406         /* enable bus mastering on the device */
407         pci_set_master(dev);
408
409         /* remap IO memory */
410         err = igbuio_setup_bars(dev, &udev->info);
411         if (err != 0)
412                 goto fail_release_iomem;
413
414         /* set 64-bit DMA mask */
415         err = pci_set_dma_mask(dev,  DMA_BIT_MASK(64));
416         if (err != 0) {
417                 dev_err(&dev->dev, "Cannot set DMA mask\n");
418                 goto fail_release_iomem;
419         }
420
421         err = pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
422         if (err != 0) {
423                 dev_err(&dev->dev, "Cannot set consistent DMA mask\n");
424                 goto fail_release_iomem;
425         }
426
427         /* fill uio infos */
428         udev->info.name = "igb_uio";
429         udev->info.version = "0.1";
430         udev->info.handler = igbuio_pci_irqhandler;
431         udev->info.irqcontrol = igbuio_pci_irqcontrol;
432         udev->info.open = igbuio_pci_open;
433         udev->info.release = igbuio_pci_release;
434         udev->info.priv = udev;
435         udev->pdev = dev;
436
437         err = igbuio_pci_enable_interrupts(udev);
438         if (err != 0)
439                 goto fail_release_iomem;
440
441         err = sysfs_create_group(&dev->dev.kobj, &dev_attr_grp);
442         if (err != 0)
443                 goto fail_disable_interrupts;
444
445         /* register uio driver */
446         err = uio_register_device(&dev->dev, &udev->info);
447         if (err != 0)
448                 goto fail_remove_group;
449
450         pci_set_drvdata(dev, udev);
451
452         dev_info(&dev->dev, "uio device registered with irq %lx\n",
453                  udev->info.irq);
454
455         /*
456          * Doing a harmless dma mapping for attaching the device to
457          * the iommu identity mapping if kernel boots with iommu=pt.
458          * Note this is not a problem if no IOMMU at all.
459          */
460         map_addr = dma_alloc_coherent(&dev->dev, 1024, &map_dma_addr,
461                         GFP_KERNEL);
462         if (map_addr)
463                 memset(map_addr, 0, 1024);
464
465         if (!map_addr)
466                 dev_info(&dev->dev, "dma mapping failed\n");
467         else {
468                 dev_info(&dev->dev, "mapping 1K dma=%#llx host=%p\n",
469                          (unsigned long long)map_dma_addr, map_addr);
470
471                 dma_free_coherent(&dev->dev, 1024, map_addr, map_dma_addr);
472                 dev_info(&dev->dev, "unmapping 1K dma=%#llx host=%p\n",
473                          (unsigned long long)map_dma_addr, map_addr);
474         }
475
476         return 0;
477
478 fail_remove_group:
479         sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);
480 fail_disable_interrupts:
481         igbuio_pci_disable_interrupts(udev);
482 fail_release_iomem:
483         igbuio_pci_release_iomem(&udev->info);
484         pci_disable_device(dev);
485 fail_free:
486         kfree(udev);
487
488         return err;
489 }
490
491 static void
492 igbuio_pci_remove(struct pci_dev *dev)
493 {
494         struct rte_uio_pci_dev *udev = pci_get_drvdata(dev);
495
496         sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);
497         uio_unregister_device(&udev->info);
498         igbuio_pci_disable_interrupts(udev);
499         igbuio_pci_release_iomem(&udev->info);
500         pci_disable_device(dev);
501         pci_set_drvdata(dev, NULL);
502         kfree(udev);
503 }
504
505 static int
506 igbuio_config_intr_mode(char *intr_str)
507 {
508         if (!intr_str) {
509                 pr_info("Use MSIX interrupt by default\n");
510                 return 0;
511         }
512
513         if (!strcmp(intr_str, RTE_INTR_MODE_MSIX_NAME)) {
514                 igbuio_intr_mode_preferred = RTE_INTR_MODE_MSIX;
515                 pr_info("Use MSIX interrupt\n");
516         } else if (!strcmp(intr_str, RTE_INTR_MODE_MSI_NAME)) {
517                 igbuio_intr_mode_preferred = RTE_INTR_MODE_MSI;
518                 pr_info("Use MSI interrupt\n");
519         } else if (!strcmp(intr_str, RTE_INTR_MODE_LEGACY_NAME)) {
520                 igbuio_intr_mode_preferred = RTE_INTR_MODE_LEGACY;
521                 pr_info("Use legacy interrupt\n");
522         } else {
523                 pr_info("Error: bad parameter - %s\n", intr_str);
524                 return -EINVAL;
525         }
526
527         return 0;
528 }
529
530 static struct pci_driver igbuio_pci_driver = {
531         .name = "igb_uio",
532         .id_table = NULL,
533         .probe = igbuio_pci_probe,
534         .remove = igbuio_pci_remove,
535 };
536
537 static int __init
538 igbuio_pci_init_module(void)
539 {
540         int ret;
541
542         ret = igbuio_config_intr_mode(intr_mode);
543         if (ret < 0)
544                 return ret;
545
546         return pci_register_driver(&igbuio_pci_driver);
547 }
548
549 static void __exit
550 igbuio_pci_exit_module(void)
551 {
552         pci_unregister_driver(&igbuio_pci_driver);
553 }
554
555 module_init(igbuio_pci_init_module);
556 module_exit(igbuio_pci_exit_module);
557
558 module_param(intr_mode, charp, S_IRUGO);
559 MODULE_PARM_DESC(intr_mode,
560 "igb_uio interrupt mode (default=msix):\n"
561 "    " RTE_INTR_MODE_MSIX_NAME "       Use MSIX interrupt\n"
562 "    " RTE_INTR_MODE_MSI_NAME "        Use MSI interrupt\n"
563 "    " RTE_INTR_MODE_LEGACY_NAME "     Use Legacy interrupt\n"
564 "\n");
565
566 MODULE_DESCRIPTION("UIO driver for Intel IGB PCI cards");
567 MODULE_LICENSE("GPL");
568 MODULE_AUTHOR("Intel Corporation");