Imported Upstream version 16.11.1
[deb_dpdk.git] / drivers / net / virtio / virtio_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 #include <stdint.h>
34
35 #ifdef RTE_EXEC_ENV_LINUXAPP
36  #include <dirent.h>
37  #include <fcntl.h>
38 #endif
39
40 #include "virtio_pci.h"
41 #include "virtio_logs.h"
42 #include "virtqueue.h"
43
44 /*
45  * Following macros are derived from linux/pci_regs.h, however,
46  * we can't simply include that header here, as there is no such
47  * file for non-Linux platform.
48  */
49 #define PCI_CAPABILITY_LIST     0x34
50 #define PCI_CAP_ID_VNDR         0x09
51
52 /*
53  * The remaining space is defined by each driver as the per-driver
54  * configuration space.
55  */
56 #define VIRTIO_PCI_CONFIG(hw) (((hw)->use_msix) ? 24 : 20)
57
58 static inline int
59 check_vq_phys_addr_ok(struct virtqueue *vq)
60 {
61         /* Virtio PCI device VIRTIO_PCI_QUEUE_PF register is 32bit,
62          * and only accepts 32 bit page frame number.
63          * Check if the allocated physical memory exceeds 16TB.
64          */
65         if ((vq->vq_ring_mem + vq->vq_ring_size - 1) >>
66                         (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) {
67                 PMD_INIT_LOG(ERR, "vring address shouldn't be above 16TB!");
68                 return 0;
69         }
70
71         return 1;
72 }
73
74 /*
75  * Since we are in legacy mode:
76  * http://ozlabs.org/~rusty/virtio-spec/virtio-0.9.5.pdf
77  *
78  * "Note that this is possible because while the virtio header is PCI (i.e.
79  * little) endian, the device-specific region is encoded in the native endian of
80  * the guest (where such distinction is applicable)."
81  *
82  * For powerpc which supports both, qemu supposes that cpu is big endian and
83  * enforces this for the virtio-net stuff.
84  */
85 static void
86 legacy_read_dev_config(struct virtio_hw *hw, size_t offset,
87                        void *dst, int length)
88 {
89 #ifdef RTE_ARCH_PPC_64
90         int size;
91
92         while (length > 0) {
93                 if (length >= 4) {
94                         size = 4;
95                         rte_eal_pci_ioport_read(VTPCI_IO(hw), dst, size,
96                                 VIRTIO_PCI_CONFIG(hw) + offset);
97                         *(uint32_t *)dst = rte_be_to_cpu_32(*(uint32_t *)dst);
98                 } else if (length >= 2) {
99                         size = 2;
100                         rte_eal_pci_ioport_read(VTPCI_IO(hw), dst, size,
101                                 VIRTIO_PCI_CONFIG(hw) + offset);
102                         *(uint16_t *)dst = rte_be_to_cpu_16(*(uint16_t *)dst);
103                 } else {
104                         size = 1;
105                         rte_eal_pci_ioport_read(VTPCI_IO(hw), dst, size,
106                                 VIRTIO_PCI_CONFIG(hw) + offset);
107                 }
108
109                 dst = (char *)dst + size;
110                 offset += size;
111                 length -= size;
112         }
113 #else
114         rte_eal_pci_ioport_read(VTPCI_IO(hw), dst, length,
115                                 VIRTIO_PCI_CONFIG(hw) + offset);
116 #endif
117 }
118
119 static void
120 legacy_write_dev_config(struct virtio_hw *hw, size_t offset,
121                         const void *src, int length)
122 {
123 #ifdef RTE_ARCH_PPC_64
124         union {
125                 uint32_t u32;
126                 uint16_t u16;
127         } tmp;
128         int size;
129
130         while (length > 0) {
131                 if (length >= 4) {
132                         size = 4;
133                         tmp.u32 = rte_cpu_to_be_32(*(const uint32_t *)src);
134                         rte_eal_pci_ioport_write(VTPCI_IO(hw), &tmp.u32, size,
135                                 VIRTIO_PCI_CONFIG(hw) + offset);
136                 } else if (length >= 2) {
137                         size = 2;
138                         tmp.u16 = rte_cpu_to_be_16(*(const uint16_t *)src);
139                         rte_eal_pci_ioport_write(VTPCI_IO(hw), &tmp.u16, size,
140                                 VIRTIO_PCI_CONFIG(hw) + offset);
141                 } else {
142                         size = 1;
143                         rte_eal_pci_ioport_write(VTPCI_IO(hw), src, size,
144                                 VIRTIO_PCI_CONFIG(hw) + offset);
145                 }
146
147                 src = (const char *)src + size;
148                 offset += size;
149                 length -= size;
150         }
151 #else
152         rte_eal_pci_ioport_write(VTPCI_IO(hw), src, length,
153                                  VIRTIO_PCI_CONFIG(hw) + offset);
154 #endif
155 }
156
157 static uint64_t
158 legacy_get_features(struct virtio_hw *hw)
159 {
160         uint32_t dst;
161
162         rte_eal_pci_ioport_read(VTPCI_IO(hw), &dst, 4,
163                                 VIRTIO_PCI_HOST_FEATURES);
164         return dst;
165 }
166
167 static void
168 legacy_set_features(struct virtio_hw *hw, uint64_t features)
169 {
170         if ((features >> 32) != 0) {
171                 PMD_DRV_LOG(ERR,
172                         "only 32 bit features are allowed for legacy virtio!");
173                 return;
174         }
175         rte_eal_pci_ioport_write(VTPCI_IO(hw), &features, 4,
176                                  VIRTIO_PCI_GUEST_FEATURES);
177 }
178
179 static uint8_t
180 legacy_get_status(struct virtio_hw *hw)
181 {
182         uint8_t dst;
183
184         rte_eal_pci_ioport_read(VTPCI_IO(hw), &dst, 1, VIRTIO_PCI_STATUS);
185         return dst;
186 }
187
188 static void
189 legacy_set_status(struct virtio_hw *hw, uint8_t status)
190 {
191         rte_eal_pci_ioport_write(VTPCI_IO(hw), &status, 1, VIRTIO_PCI_STATUS);
192 }
193
194 static void
195 legacy_reset(struct virtio_hw *hw)
196 {
197         legacy_set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
198 }
199
200 static uint8_t
201 legacy_get_isr(struct virtio_hw *hw)
202 {
203         uint8_t dst;
204
205         rte_eal_pci_ioport_read(VTPCI_IO(hw), &dst, 1, VIRTIO_PCI_ISR);
206         return dst;
207 }
208
209 /* Enable one vector (0) for Link State Intrerrupt */
210 static uint16_t
211 legacy_set_config_irq(struct virtio_hw *hw, uint16_t vec)
212 {
213         uint16_t dst;
214
215         rte_eal_pci_ioport_write(VTPCI_IO(hw), &vec, 2,
216                                  VIRTIO_MSI_CONFIG_VECTOR);
217         rte_eal_pci_ioport_read(VTPCI_IO(hw), &dst, 2,
218                                 VIRTIO_MSI_CONFIG_VECTOR);
219         return dst;
220 }
221
222 static uint16_t
223 legacy_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
224 {
225         uint16_t dst;
226
227         rte_eal_pci_ioport_write(VTPCI_IO(hw), &queue_id, 2,
228                                  VIRTIO_PCI_QUEUE_SEL);
229         rte_eal_pci_ioport_read(VTPCI_IO(hw), &dst, 2, VIRTIO_PCI_QUEUE_NUM);
230         return dst;
231 }
232
233 static int
234 legacy_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
235 {
236         uint32_t src;
237
238         if (!check_vq_phys_addr_ok(vq))
239                 return -1;
240
241         rte_eal_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
242                          VIRTIO_PCI_QUEUE_SEL);
243         src = vq->vq_ring_mem >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
244         rte_eal_pci_ioport_write(VTPCI_IO(hw), &src, 4, VIRTIO_PCI_QUEUE_PFN);
245
246         return 0;
247 }
248
249 static void
250 legacy_del_queue(struct virtio_hw *hw, struct virtqueue *vq)
251 {
252         uint32_t src = 0;
253
254         rte_eal_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
255                          VIRTIO_PCI_QUEUE_SEL);
256         rte_eal_pci_ioport_write(VTPCI_IO(hw), &src, 4, VIRTIO_PCI_QUEUE_PFN);
257 }
258
259 static void
260 legacy_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
261 {
262         rte_eal_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
263                          VIRTIO_PCI_QUEUE_NOTIFY);
264 }
265
266 #ifdef RTE_EXEC_ENV_LINUXAPP
267 static int
268 legacy_virtio_has_msix(const struct rte_pci_addr *loc)
269 {
270         DIR *d;
271         char dirname[PATH_MAX];
272
273         snprintf(dirname, sizeof(dirname),
274                      "%s/" PCI_PRI_FMT "/msi_irqs", pci_get_sysfs_path(),
275                      loc->domain, loc->bus, loc->devid, loc->function);
276
277         d = opendir(dirname);
278         if (d)
279                 closedir(d);
280
281         return d != NULL;
282 }
283 #else
284 static int
285 legacy_virtio_has_msix(const struct rte_pci_addr *loc __rte_unused)
286 {
287         /* nic_uio does not enable interrupts, return 0 (false). */
288         return 0;
289 }
290 #endif
291
292 static int
293 legacy_virtio_resource_init(struct rte_pci_device *pci_dev,
294                             struct virtio_hw *hw, uint32_t *dev_flags)
295 {
296         if (rte_eal_pci_ioport_map(pci_dev, 0, VTPCI_IO(hw)) < 0)
297                 return -1;
298
299         if (pci_dev->intr_handle.type != RTE_INTR_HANDLE_UNKNOWN)
300                 *dev_flags |= RTE_ETH_DEV_INTR_LSC;
301         else
302                 *dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
303
304         return 0;
305 }
306
307 const struct virtio_pci_ops legacy_ops = {
308         .read_dev_cfg   = legacy_read_dev_config,
309         .write_dev_cfg  = legacy_write_dev_config,
310         .reset          = legacy_reset,
311         .get_status     = legacy_get_status,
312         .set_status     = legacy_set_status,
313         .get_features   = legacy_get_features,
314         .set_features   = legacy_set_features,
315         .get_isr        = legacy_get_isr,
316         .set_config_irq = legacy_set_config_irq,
317         .get_queue_num  = legacy_get_queue_num,
318         .setup_queue    = legacy_setup_queue,
319         .del_queue      = legacy_del_queue,
320         .notify_queue   = legacy_notify_queue,
321 };
322
323
324 static inline uint8_t
325 io_read8(uint8_t *addr)
326 {
327         return *(volatile uint8_t *)addr;
328 }
329
330 static inline void
331 io_write8(uint8_t val, uint8_t *addr)
332 {
333         *(volatile uint8_t *)addr = val;
334 }
335
336 static inline uint16_t
337 io_read16(uint16_t *addr)
338 {
339         return *(volatile uint16_t *)addr;
340 }
341
342 static inline void
343 io_write16(uint16_t val, uint16_t *addr)
344 {
345         *(volatile uint16_t *)addr = val;
346 }
347
348 static inline uint32_t
349 io_read32(uint32_t *addr)
350 {
351         return *(volatile uint32_t *)addr;
352 }
353
354 static inline void
355 io_write32(uint32_t val, uint32_t *addr)
356 {
357         *(volatile uint32_t *)addr = val;
358 }
359
360 static inline void
361 io_write64_twopart(uint64_t val, uint32_t *lo, uint32_t *hi)
362 {
363         io_write32(val & ((1ULL << 32) - 1), lo);
364         io_write32(val >> 32,                hi);
365 }
366
367 static void
368 modern_read_dev_config(struct virtio_hw *hw, size_t offset,
369                        void *dst, int length)
370 {
371         int i;
372         uint8_t *p;
373         uint8_t old_gen, new_gen;
374
375         do {
376                 old_gen = io_read8(&hw->common_cfg->config_generation);
377
378                 p = dst;
379                 for (i = 0;  i < length; i++)
380                         *p++ = io_read8((uint8_t *)hw->dev_cfg + offset + i);
381
382                 new_gen = io_read8(&hw->common_cfg->config_generation);
383         } while (old_gen != new_gen);
384 }
385
386 static void
387 modern_write_dev_config(struct virtio_hw *hw, size_t offset,
388                         const void *src, int length)
389 {
390         int i;
391         const uint8_t *p = src;
392
393         for (i = 0;  i < length; i++)
394                 io_write8(*p++, (uint8_t *)hw->dev_cfg + offset + i);
395 }
396
397 static uint64_t
398 modern_get_features(struct virtio_hw *hw)
399 {
400         uint32_t features_lo, features_hi;
401
402         io_write32(0, &hw->common_cfg->device_feature_select);
403         features_lo = io_read32(&hw->common_cfg->device_feature);
404
405         io_write32(1, &hw->common_cfg->device_feature_select);
406         features_hi = io_read32(&hw->common_cfg->device_feature);
407
408         return ((uint64_t)features_hi << 32) | features_lo;
409 }
410
411 static void
412 modern_set_features(struct virtio_hw *hw, uint64_t features)
413 {
414         io_write32(0, &hw->common_cfg->guest_feature_select);
415         io_write32(features & ((1ULL << 32) - 1),
416                 &hw->common_cfg->guest_feature);
417
418         io_write32(1, &hw->common_cfg->guest_feature_select);
419         io_write32(features >> 32,
420                 &hw->common_cfg->guest_feature);
421 }
422
423 static uint8_t
424 modern_get_status(struct virtio_hw *hw)
425 {
426         return io_read8(&hw->common_cfg->device_status);
427 }
428
429 static void
430 modern_set_status(struct virtio_hw *hw, uint8_t status)
431 {
432         io_write8(status, &hw->common_cfg->device_status);
433 }
434
435 static void
436 modern_reset(struct virtio_hw *hw)
437 {
438         modern_set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
439         modern_get_status(hw);
440 }
441
442 static uint8_t
443 modern_get_isr(struct virtio_hw *hw)
444 {
445         return io_read8(hw->isr);
446 }
447
448 static uint16_t
449 modern_set_config_irq(struct virtio_hw *hw, uint16_t vec)
450 {
451         io_write16(vec, &hw->common_cfg->msix_config);
452         return io_read16(&hw->common_cfg->msix_config);
453 }
454
455 static uint16_t
456 modern_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
457 {
458         io_write16(queue_id, &hw->common_cfg->queue_select);
459         return io_read16(&hw->common_cfg->queue_size);
460 }
461
462 static int
463 modern_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
464 {
465         uint64_t desc_addr, avail_addr, used_addr;
466         uint16_t notify_off;
467
468         if (!check_vq_phys_addr_ok(vq))
469                 return -1;
470
471         desc_addr = vq->vq_ring_mem;
472         avail_addr = desc_addr + vq->vq_nentries * sizeof(struct vring_desc);
473         used_addr = RTE_ALIGN_CEIL(avail_addr + offsetof(struct vring_avail,
474                                                          ring[vq->vq_nentries]),
475                                    VIRTIO_PCI_VRING_ALIGN);
476
477         io_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
478
479         io_write64_twopart(desc_addr, &hw->common_cfg->queue_desc_lo,
480                                       &hw->common_cfg->queue_desc_hi);
481         io_write64_twopart(avail_addr, &hw->common_cfg->queue_avail_lo,
482                                        &hw->common_cfg->queue_avail_hi);
483         io_write64_twopart(used_addr, &hw->common_cfg->queue_used_lo,
484                                       &hw->common_cfg->queue_used_hi);
485
486         notify_off = io_read16(&hw->common_cfg->queue_notify_off);
487         vq->notify_addr = (void *)((uint8_t *)hw->notify_base +
488                                 notify_off * hw->notify_off_multiplier);
489
490         io_write16(1, &hw->common_cfg->queue_enable);
491
492         PMD_INIT_LOG(DEBUG, "queue %u addresses:", vq->vq_queue_index);
493         PMD_INIT_LOG(DEBUG, "\t desc_addr: %" PRIx64, desc_addr);
494         PMD_INIT_LOG(DEBUG, "\t aval_addr: %" PRIx64, avail_addr);
495         PMD_INIT_LOG(DEBUG, "\t used_addr: %" PRIx64, used_addr);
496         PMD_INIT_LOG(DEBUG, "\t notify addr: %p (notify offset: %u)",
497                 vq->notify_addr, notify_off);
498
499         return 0;
500 }
501
502 static void
503 modern_del_queue(struct virtio_hw *hw, struct virtqueue *vq)
504 {
505         io_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
506
507         io_write64_twopart(0, &hw->common_cfg->queue_desc_lo,
508                                   &hw->common_cfg->queue_desc_hi);
509         io_write64_twopart(0, &hw->common_cfg->queue_avail_lo,
510                                   &hw->common_cfg->queue_avail_hi);
511         io_write64_twopart(0, &hw->common_cfg->queue_used_lo,
512                                   &hw->common_cfg->queue_used_hi);
513
514         io_write16(0, &hw->common_cfg->queue_enable);
515 }
516
517 static void
518 modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue *vq)
519 {
520         io_write16(1, vq->notify_addr);
521 }
522
523 const struct virtio_pci_ops modern_ops = {
524         .read_dev_cfg   = modern_read_dev_config,
525         .write_dev_cfg  = modern_write_dev_config,
526         .reset          = modern_reset,
527         .get_status     = modern_get_status,
528         .set_status     = modern_set_status,
529         .get_features   = modern_get_features,
530         .set_features   = modern_set_features,
531         .get_isr        = modern_get_isr,
532         .set_config_irq = modern_set_config_irq,
533         .get_queue_num  = modern_get_queue_num,
534         .setup_queue    = modern_setup_queue,
535         .del_queue      = modern_del_queue,
536         .notify_queue   = modern_notify_queue,
537 };
538
539
540 void
541 vtpci_read_dev_config(struct virtio_hw *hw, size_t offset,
542                       void *dst, int length)
543 {
544         VTPCI_OPS(hw)->read_dev_cfg(hw, offset, dst, length);
545 }
546
547 void
548 vtpci_write_dev_config(struct virtio_hw *hw, size_t offset,
549                        const void *src, int length)
550 {
551         VTPCI_OPS(hw)->write_dev_cfg(hw, offset, src, length);
552 }
553
554 uint64_t
555 vtpci_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
556 {
557         uint64_t features;
558
559         /*
560          * Limit negotiated features to what the driver, virtqueue, and
561          * host all support.
562          */
563         features = host_features & hw->guest_features;
564         VTPCI_OPS(hw)->set_features(hw, features);
565
566         return features;
567 }
568
569 void
570 vtpci_reset(struct virtio_hw *hw)
571 {
572         VTPCI_OPS(hw)->set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
573         /* flush status write */
574         VTPCI_OPS(hw)->get_status(hw);
575 }
576
577 void
578 vtpci_reinit_complete(struct virtio_hw *hw)
579 {
580         vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
581 }
582
583 void
584 vtpci_set_status(struct virtio_hw *hw, uint8_t status)
585 {
586         if (status != VIRTIO_CONFIG_STATUS_RESET)
587                 status |= VTPCI_OPS(hw)->get_status(hw);
588
589         VTPCI_OPS(hw)->set_status(hw, status);
590 }
591
592 uint8_t
593 vtpci_get_status(struct virtio_hw *hw)
594 {
595         return VTPCI_OPS(hw)->get_status(hw);
596 }
597
598 uint8_t
599 vtpci_isr(struct virtio_hw *hw)
600 {
601         return VTPCI_OPS(hw)->get_isr(hw);
602 }
603
604
605 /* Enable one vector (0) for Link State Intrerrupt */
606 uint16_t
607 vtpci_irq_config(struct virtio_hw *hw, uint16_t vec)
608 {
609         return VTPCI_OPS(hw)->set_config_irq(hw, vec);
610 }
611
612 static void *
613 get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
614 {
615         uint8_t  bar    = cap->bar;
616         uint32_t length = cap->length;
617         uint32_t offset = cap->offset;
618         uint8_t *base;
619
620         if (bar > 5) {
621                 PMD_INIT_LOG(ERR, "invalid bar: %u", bar);
622                 return NULL;
623         }
624
625         if (offset + length < offset) {
626                 PMD_INIT_LOG(ERR, "offset(%u) + length(%u) overflows",
627                         offset, length);
628                 return NULL;
629         }
630
631         if (offset + length > dev->mem_resource[bar].len) {
632                 PMD_INIT_LOG(ERR,
633                         "invalid cap: overflows bar space: %u > %" PRIu64,
634                         offset + length, dev->mem_resource[bar].len);
635                 return NULL;
636         }
637
638         base = dev->mem_resource[bar].addr;
639         if (base == NULL) {
640                 PMD_INIT_LOG(ERR, "bar %u base addr is NULL", bar);
641                 return NULL;
642         }
643
644         return base + offset;
645 }
646
647 static int
648 virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
649 {
650         uint8_t pos;
651         struct virtio_pci_cap cap;
652         int ret;
653
654         if (rte_eal_pci_map_device(dev)) {
655                 PMD_INIT_LOG(DEBUG, "failed to map pci device!");
656                 return -1;
657         }
658
659         ret = rte_eal_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
660         if (ret < 0) {
661                 PMD_INIT_LOG(DEBUG, "failed to read pci capability list");
662                 return -1;
663         }
664
665         while (pos) {
666                 ret = rte_eal_pci_read_config(dev, &cap, sizeof(cap), pos);
667                 if (ret < 0) {
668                         PMD_INIT_LOG(ERR,
669                                 "failed to read pci cap at pos: %x", pos);
670                         break;
671                 }
672
673                 if (cap.cap_vndr != PCI_CAP_ID_VNDR) {
674                         PMD_INIT_LOG(DEBUG,
675                                 "[%2x] skipping non VNDR cap id: %02x",
676                                 pos, cap.cap_vndr);
677                         goto next;
678                 }
679
680                 PMD_INIT_LOG(DEBUG,
681                         "[%2x] cfg type: %u, bar: %u, offset: %04x, len: %u",
682                         pos, cap.cfg_type, cap.bar, cap.offset, cap.length);
683
684                 switch (cap.cfg_type) {
685                 case VIRTIO_PCI_CAP_COMMON_CFG:
686                         hw->common_cfg = get_cfg_addr(dev, &cap);
687                         break;
688                 case VIRTIO_PCI_CAP_NOTIFY_CFG:
689                         rte_eal_pci_read_config(dev, &hw->notify_off_multiplier,
690                                                 4, pos + sizeof(cap));
691                         hw->notify_base = get_cfg_addr(dev, &cap);
692                         break;
693                 case VIRTIO_PCI_CAP_DEVICE_CFG:
694                         hw->dev_cfg = get_cfg_addr(dev, &cap);
695                         break;
696                 case VIRTIO_PCI_CAP_ISR_CFG:
697                         hw->isr = get_cfg_addr(dev, &cap);
698                         break;
699                 }
700
701 next:
702                 pos = cap.cap_next;
703         }
704
705         if (hw->common_cfg == NULL || hw->notify_base == NULL ||
706             hw->dev_cfg == NULL    || hw->isr == NULL) {
707                 PMD_INIT_LOG(INFO, "no modern virtio pci device found.");
708                 return -1;
709         }
710
711         PMD_INIT_LOG(INFO, "found modern virtio pci device.");
712
713         PMD_INIT_LOG(DEBUG, "common cfg mapped at: %p", hw->common_cfg);
714         PMD_INIT_LOG(DEBUG, "device cfg mapped at: %p", hw->dev_cfg);
715         PMD_INIT_LOG(DEBUG, "isr cfg mapped at: %p", hw->isr);
716         PMD_INIT_LOG(DEBUG, "notify base: %p, notify off multiplier: %u",
717                 hw->notify_base, hw->notify_off_multiplier);
718
719         return 0;
720 }
721
722 /*
723  * Return -1:
724  *   if there is error mapping with VFIO/UIO.
725  *   if port map error when driver type is KDRV_NONE.
726  *   if whitelisted but driver type is KDRV_UNKNOWN.
727  * Return 1 if kernel driver is managing the device.
728  * Return 0 on success.
729  */
730 int
731 vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw,
732            uint32_t *dev_flags)
733 {
734         hw->dev = dev;
735
736         /*
737          * Try if we can succeed reading virtio pci caps, which exists
738          * only on modern pci device. If failed, we fallback to legacy
739          * virtio handling.
740          */
741         if (virtio_read_caps(dev, hw) == 0) {
742                 PMD_INIT_LOG(INFO, "modern virtio pci detected.");
743                 virtio_hw_internal[hw->port_id].vtpci_ops = &modern_ops;
744                 hw->modern = 1;
745                 *dev_flags |= RTE_ETH_DEV_INTR_LSC;
746                 return 0;
747         }
748
749         PMD_INIT_LOG(INFO, "trying with legacy virtio pci.");
750         if (legacy_virtio_resource_init(dev, hw, dev_flags) < 0) {
751                 if (dev->kdrv == RTE_KDRV_UNKNOWN &&
752                     (!dev->device.devargs ||
753                      dev->device.devargs->type !=
754                         RTE_DEVTYPE_WHITELISTED_PCI)) {
755                         PMD_INIT_LOG(INFO,
756                                 "skip kernel managed virtio device.");
757                         return 1;
758                 }
759                 return -1;
760         }
761
762         virtio_hw_internal[hw->port_id].vtpci_ops = &legacy_ops;
763         hw->use_msix = legacy_virtio_has_msix(&dev->addr);
764         hw->modern   = 0;
765
766         return 0;
767 }