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