Imported Upstream version 16.07.2
[deb_dpdk.git] / lib / librte_eal / common / eal_common_pci.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 /*   BSD LICENSE
34  *
35  *   Copyright 2013-2014 6WIND S.A.
36  *
37  *   Redistribution and use in source and binary forms, with or without
38  *   modification, are permitted provided that the following conditions
39  *   are met:
40  *
41  *     * Redistributions of source code must retain the above copyright
42  *       notice, this list of conditions and the following disclaimer.
43  *     * Redistributions in binary form must reproduce the above copyright
44  *       notice, this list of conditions and the following disclaimer in
45  *       the documentation and/or other materials provided with the
46  *       distribution.
47  *     * Neither the name of 6WIND S.A. nor the names of its
48  *       contributors may be used to endorse or promote products derived
49  *       from this software without specific prior written permission.
50  *
51  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
52  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
53  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
54  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
55  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
56  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
57  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
61  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63
64 #include <string.h>
65 #include <inttypes.h>
66 #include <stdint.h>
67 #include <stdlib.h>
68 #include <stdio.h>
69 #include <sys/queue.h>
70 #include <sys/mman.h>
71
72 #include <rte_interrupts.h>
73 #include <rte_log.h>
74 #include <rte_pci.h>
75 #include <rte_per_lcore.h>
76 #include <rte_memory.h>
77 #include <rte_memzone.h>
78 #include <rte_eal.h>
79 #include <rte_string_fns.h>
80 #include <rte_common.h>
81 #include <rte_devargs.h>
82
83 #include "eal_private.h"
84
85 struct pci_driver_list pci_driver_list;
86 struct pci_device_list pci_device_list;
87
88 #define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
89
90 const char *pci_get_sysfs_path(void)
91 {
92         const char *path = NULL;
93
94         path = getenv("SYSFS_PCI_DEVICES");
95         if (path == NULL)
96                 return SYSFS_PCI_DEVICES;
97
98         return path;
99 }
100
101 static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
102 {
103         struct rte_devargs *devargs;
104
105         TAILQ_FOREACH(devargs, &devargs_list, next) {
106                 if (devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI &&
107                         devargs->type != RTE_DEVTYPE_WHITELISTED_PCI)
108                         continue;
109                 if (!rte_eal_compare_pci_addr(&dev->addr, &devargs->pci.addr))
110                         return devargs;
111         }
112         return NULL;
113 }
114
115 /* map a particular resource from a file */
116 void *
117 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
118                  int additional_flags)
119 {
120         void *mapaddr;
121
122         /* Map the PCI memory resource of device */
123         mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
124                         MAP_SHARED | additional_flags, fd, offset);
125         if (mapaddr == MAP_FAILED) {
126                 RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
127                         __func__, fd, requested_addr,
128                         (unsigned long)size, (unsigned long)offset,
129                         strerror(errno), mapaddr);
130         } else
131                 RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
132
133         return mapaddr;
134 }
135
136 /* unmap a particular resource */
137 void
138 pci_unmap_resource(void *requested_addr, size_t size)
139 {
140         if (requested_addr == NULL)
141                 return;
142
143         /* Unmap the PCI memory resource of device */
144         if (munmap(requested_addr, size)) {
145                 RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
146                         __func__, requested_addr, (unsigned long)size,
147                         strerror(errno));
148         } else
149                 RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
150                                 requested_addr);
151 }
152
153 /*
154  * If vendor/device ID match, call the devinit() function of the
155  * driver.
156  */
157 static int
158 rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
159 {
160         int ret;
161         const struct rte_pci_id *id_table;
162
163         for (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {
164
165                 /* check if device's identifiers match the driver's ones */
166                 if (id_table->vendor_id != dev->id.vendor_id &&
167                                 id_table->vendor_id != PCI_ANY_ID)
168                         continue;
169                 if (id_table->device_id != dev->id.device_id &&
170                                 id_table->device_id != PCI_ANY_ID)
171                         continue;
172                 if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&
173                                 id_table->subsystem_vendor_id != PCI_ANY_ID)
174                         continue;
175                 if (id_table->subsystem_device_id != dev->id.subsystem_device_id &&
176                                 id_table->subsystem_device_id != PCI_ANY_ID)
177                         continue;
178                 if (id_table->class_id != dev->id.class_id &&
179                                 id_table->class_id != RTE_CLASS_ANY_ID)
180                         continue;
181
182                 struct rte_pci_addr *loc = &dev->addr;
183
184                 RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
185                                 loc->domain, loc->bus, loc->devid, loc->function,
186                                 dev->numa_node);
187
188                 /* no initialization when blacklisted, return without error */
189                 if (dev->devargs != NULL &&
190                         dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
191                         RTE_LOG(INFO, EAL, "  Device is blacklisted, not initializing\n");
192                         return 1;
193                 }
194
195                 RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
196                                 dev->id.device_id, dr->name);
197
198                 if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
199                         /* map resources for devices that use igb_uio */
200                         ret = rte_eal_pci_map_device(dev);
201                         if (ret != 0)
202                                 return ret;
203                 } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&
204                                 rte_eal_process_type() == RTE_PROC_PRIMARY) {
205                         /* unbind current driver */
206                         if (pci_unbind_kernel_driver(dev) < 0)
207                                 return -1;
208                 }
209
210                 /* reference driver structure */
211                 dev->driver = dr;
212
213                 /* call the driver devinit() function */
214                 return dr->devinit(dr, dev);
215         }
216         /* return positive value if driver doesn't support this device */
217         return 1;
218 }
219
220 /*
221  * If vendor/device ID match, call the devuninit() function of the
222  * driver.
223  */
224 static int
225 rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
226                 struct rte_pci_device *dev)
227 {
228         const struct rte_pci_id *id_table;
229
230         if ((dr == NULL) || (dev == NULL))
231                 return -EINVAL;
232
233         for (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {
234
235                 /* check if device's identifiers match the driver's ones */
236                 if (id_table->vendor_id != dev->id.vendor_id &&
237                                 id_table->vendor_id != PCI_ANY_ID)
238                         continue;
239                 if (id_table->device_id != dev->id.device_id &&
240                                 id_table->device_id != PCI_ANY_ID)
241                         continue;
242                 if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&
243                                 id_table->subsystem_vendor_id != PCI_ANY_ID)
244                         continue;
245                 if (id_table->subsystem_device_id != dev->id.subsystem_device_id &&
246                                 id_table->subsystem_device_id != PCI_ANY_ID)
247                         continue;
248
249                 struct rte_pci_addr *loc = &dev->addr;
250
251                 RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
252                                 loc->domain, loc->bus, loc->devid,
253                                 loc->function, dev->numa_node);
254
255                 RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
256                                 dev->id.device_id, dr->name);
257
258                 if (dr->devuninit && (dr->devuninit(dev) < 0))
259                         return -1;      /* negative value is an error */
260
261                 /* clear driver structure */
262                 dev->driver = NULL;
263
264                 if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
265                         /* unmap resources for devices that use igb_uio */
266                         rte_eal_pci_unmap_device(dev);
267
268                 return 0;
269         }
270
271         /* return positive value if driver doesn't support this device */
272         return 1;
273 }
274
275 /*
276  * If vendor/device ID match, call the devinit() function of all
277  * registered driver for the given device. Return -1 if initialization
278  * failed, return 1 if no driver is found for this device.
279  */
280 static int
281 pci_probe_all_drivers(struct rte_pci_device *dev)
282 {
283         struct rte_pci_driver *dr = NULL;
284         int rc = 0;
285
286         if (dev == NULL)
287                 return -1;
288
289         TAILQ_FOREACH(dr, &pci_driver_list, next) {
290                 rc = rte_eal_pci_probe_one_driver(dr, dev);
291                 if (rc < 0)
292                         /* negative value is an error */
293                         return -1;
294                 if (rc > 0)
295                         /* positive value means driver doesn't support it */
296                         continue;
297                 return 0;
298         }
299         return 1;
300 }
301
302 /*
303  * If vendor/device ID match, call the devuninit() function of all
304  * registered driver for the given device. Return -1 if initialization
305  * failed, return 1 if no driver is found for this device.
306  */
307 static int
308 pci_detach_all_drivers(struct rte_pci_device *dev)
309 {
310         struct rte_pci_driver *dr = NULL;
311         int rc = 0;
312
313         if (dev == NULL)
314                 return -1;
315
316         TAILQ_FOREACH(dr, &pci_driver_list, next) {
317                 rc = rte_eal_pci_detach_dev(dr, dev);
318                 if (rc < 0)
319                         /* negative value is an error */
320                         return -1;
321                 if (rc > 0)
322                         /* positive value means driver doesn't support it */
323                         continue;
324                 return 0;
325         }
326         return 1;
327 }
328
329 /*
330  * Find the pci device specified by pci address, then invoke probe function of
331  * the driver of the devive.
332  */
333 int
334 rte_eal_pci_probe_one(const struct rte_pci_addr *addr)
335 {
336         struct rte_pci_device *dev = NULL;
337         int ret = 0;
338
339         if (addr == NULL)
340                 return -1;
341
342         TAILQ_FOREACH(dev, &pci_device_list, next) {
343                 if (rte_eal_compare_pci_addr(&dev->addr, addr))
344                         continue;
345
346                 ret = pci_probe_all_drivers(dev);
347                 if (ret)
348                         goto err_return;
349                 return 0;
350         }
351         return -1;
352
353 err_return:
354         RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
355                         " cannot be used\n", dev->addr.domain, dev->addr.bus,
356                         dev->addr.devid, dev->addr.function);
357         return -1;
358 }
359
360 /*
361  * Detach device specified by its pci address.
362  */
363 int
364 rte_eal_pci_detach(const struct rte_pci_addr *addr)
365 {
366         struct rte_pci_device *dev = NULL;
367         int ret = 0;
368
369         if (addr == NULL)
370                 return -1;
371
372         TAILQ_FOREACH(dev, &pci_device_list, next) {
373                 if (rte_eal_compare_pci_addr(&dev->addr, addr))
374                         continue;
375
376                 ret = pci_detach_all_drivers(dev);
377                 if (ret < 0)
378                         goto err_return;
379
380                 TAILQ_REMOVE(&pci_device_list, dev, next);
381                 free(dev);
382                 return 0;
383         }
384         return -1;
385
386 err_return:
387         RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
388                         " cannot be used\n", dev->addr.domain, dev->addr.bus,
389                         dev->addr.devid, dev->addr.function);
390         return -1;
391 }
392
393 /*
394  * Scan the content of the PCI bus, and call the devinit() function for
395  * all registered drivers that have a matching entry in its id_table
396  * for discovered devices.
397  */
398 int
399 rte_eal_pci_probe(void)
400 {
401         struct rte_pci_device *dev = NULL;
402         struct rte_devargs *devargs;
403         int probe_all = 0;
404         int ret = 0;
405
406         if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
407                 probe_all = 1;
408
409         TAILQ_FOREACH(dev, &pci_device_list, next) {
410
411                 /* set devargs in PCI structure */
412                 devargs = pci_devargs_lookup(dev);
413                 if (devargs != NULL)
414                         dev->devargs = devargs;
415
416                 /* probe all or only whitelisted devices */
417                 if (probe_all)
418                         ret = pci_probe_all_drivers(dev);
419                 else if (devargs != NULL &&
420                         devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
421                         ret = pci_probe_all_drivers(dev);
422                 if (ret < 0)
423                         rte_exit(EXIT_FAILURE, "Requested device " PCI_PRI_FMT
424                                  " cannot be used\n", dev->addr.domain, dev->addr.bus,
425                                  dev->addr.devid, dev->addr.function);
426         }
427
428         return 0;
429 }
430
431 /* dump one device */
432 static int
433 pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
434 {
435         int i;
436
437         fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
438                dev->addr.devid, dev->addr.function);
439         fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
440                dev->id.device_id);
441
442         for (i = 0; i != sizeof(dev->mem_resource) /
443                 sizeof(dev->mem_resource[0]); i++) {
444                 fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
445                         dev->mem_resource[i].phys_addr,
446                         dev->mem_resource[i].len);
447         }
448         return 0;
449 }
450
451 /* dump devices on the bus */
452 void
453 rte_eal_pci_dump(FILE *f)
454 {
455         struct rte_pci_device *dev = NULL;
456
457         TAILQ_FOREACH(dev, &pci_device_list, next) {
458                 pci_dump_one_device(f, dev);
459         }
460 }
461
462 /* register a driver */
463 void
464 rte_eal_pci_register(struct rte_pci_driver *driver)
465 {
466         TAILQ_INSERT_TAIL(&pci_driver_list, driver, next);
467 }
468
469 /* unregister a driver */
470 void
471 rte_eal_pci_unregister(struct rte_pci_driver *driver)
472 {
473         TAILQ_REMOVE(&pci_driver_list, driver, next);
474 }