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