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