1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Intel IFC VF NIC driver for virtio dataplane offloading 4 * 5 * Copyright (C) 2020 Intel Corporation. 6 * 7 * Author: Zhu Lingshan <lingshan.zhu@intel.com> 8 * 9 */ 10 11 #include <linux/interrupt.h> 12 #include <linux/module.h> 13 #include <linux/pci.h> 14 #include <linux/sysfs.h> 15 #include "ifcvf_base.h" 16 17 #define DRIVER_AUTHOR "Intel Corporation" 18 #define IFCVF_DRIVER_NAME "ifcvf" 19 20 static irqreturn_t ifcvf_config_changed(int irq, void *arg) 21 { 22 struct ifcvf_hw *vf = arg; 23 24 if (vf->config_cb.callback) 25 return vf->config_cb.callback(vf->config_cb.private); 26 27 return IRQ_HANDLED; 28 } 29 30 static irqreturn_t ifcvf_intr_handler(int irq, void *arg) 31 { 32 struct vring_info *vring = arg; 33 34 if (vring->cb.callback) 35 return vring->cb.callback(vring->cb.private); 36 37 return IRQ_HANDLED; 38 } 39 40 static void ifcvf_free_irq_vectors(void *data) 41 { 42 pci_free_irq_vectors(data); 43 } 44 45 static void ifcvf_free_irq(struct ifcvf_adapter *adapter, int queues) 46 { 47 struct pci_dev *pdev = adapter->pdev; 48 struct ifcvf_hw *vf = &adapter->vf; 49 int i; 50 51 52 for (i = 0; i < queues; i++) { 53 devm_free_irq(&pdev->dev, vf->vring[i].irq, &vf->vring[i]); 54 vf->vring[i].irq = -EINVAL; 55 } 56 57 devm_free_irq(&pdev->dev, vf->config_irq, vf); 58 ifcvf_free_irq_vectors(pdev); 59 } 60 61 static int ifcvf_request_irq(struct ifcvf_adapter *adapter) 62 { 63 struct pci_dev *pdev = adapter->pdev; 64 struct ifcvf_hw *vf = &adapter->vf; 65 int vector, i, ret, irq; 66 u16 max_intr; 67 68 /* all queues and config interrupt */ 69 max_intr = vf->nr_vring + 1; 70 71 ret = pci_alloc_irq_vectors(pdev, max_intr, 72 max_intr, PCI_IRQ_MSIX); 73 if (ret < 0) { 74 IFCVF_ERR(pdev, "Failed to alloc IRQ vectors\n"); 75 return ret; 76 } 77 78 snprintf(vf->config_msix_name, 256, "ifcvf[%s]-config\n", 79 pci_name(pdev)); 80 vector = 0; 81 vf->config_irq = pci_irq_vector(pdev, vector); 82 ret = devm_request_irq(&pdev->dev, vf->config_irq, 83 ifcvf_config_changed, 0, 84 vf->config_msix_name, vf); 85 if (ret) { 86 IFCVF_ERR(pdev, "Failed to request config irq\n"); 87 return ret; 88 } 89 90 for (i = 0; i < vf->nr_vring; i++) { 91 snprintf(vf->vring[i].msix_name, 256, "ifcvf[%s]-%d\n", 92 pci_name(pdev), i); 93 vector = i + IFCVF_MSI_QUEUE_OFF; 94 irq = pci_irq_vector(pdev, vector); 95 ret = devm_request_irq(&pdev->dev, irq, 96 ifcvf_intr_handler, 0, 97 vf->vring[i].msix_name, 98 &vf->vring[i]); 99 if (ret) { 100 IFCVF_ERR(pdev, 101 "Failed to request irq for vq %d\n", i); 102 ifcvf_free_irq(adapter, i); 103 104 return ret; 105 } 106 107 vf->vring[i].irq = irq; 108 } 109 110 return 0; 111 } 112 113 static int ifcvf_start_datapath(void *private) 114 { 115 struct ifcvf_hw *vf = ifcvf_private_to_vf(private); 116 u8 status; 117 int ret; 118 119 ret = ifcvf_start_hw(vf); 120 if (ret < 0) { 121 status = ifcvf_get_status(vf); 122 status |= VIRTIO_CONFIG_S_FAILED; 123 ifcvf_set_status(vf, status); 124 } 125 126 return ret; 127 } 128 129 static int ifcvf_stop_datapath(void *private) 130 { 131 struct ifcvf_hw *vf = ifcvf_private_to_vf(private); 132 int i; 133 134 for (i = 0; i < vf->nr_vring; i++) 135 vf->vring[i].cb.callback = NULL; 136 137 ifcvf_stop_hw(vf); 138 139 return 0; 140 } 141 142 static void ifcvf_reset_vring(struct ifcvf_adapter *adapter) 143 { 144 struct ifcvf_hw *vf = ifcvf_private_to_vf(adapter); 145 int i; 146 147 for (i = 0; i < vf->nr_vring; i++) { 148 vf->vring[i].last_avail_idx = 0; 149 vf->vring[i].desc = 0; 150 vf->vring[i].avail = 0; 151 vf->vring[i].used = 0; 152 vf->vring[i].ready = 0; 153 vf->vring[i].cb.callback = NULL; 154 vf->vring[i].cb.private = NULL; 155 } 156 157 ifcvf_reset(vf); 158 } 159 160 static struct ifcvf_adapter *vdpa_to_adapter(struct vdpa_device *vdpa_dev) 161 { 162 return container_of(vdpa_dev, struct ifcvf_adapter, vdpa); 163 } 164 165 static struct ifcvf_hw *vdpa_to_vf(struct vdpa_device *vdpa_dev) 166 { 167 struct ifcvf_adapter *adapter = vdpa_to_adapter(vdpa_dev); 168 169 return &adapter->vf; 170 } 171 172 static u64 ifcvf_vdpa_get_device_features(struct vdpa_device *vdpa_dev) 173 { 174 struct ifcvf_adapter *adapter = vdpa_to_adapter(vdpa_dev); 175 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 176 struct pci_dev *pdev = adapter->pdev; 177 u32 type = vf->dev_type; 178 u64 features; 179 180 if (type == VIRTIO_ID_NET || type == VIRTIO_ID_BLOCK) 181 features = ifcvf_get_features(vf); 182 else { 183 features = 0; 184 IFCVF_ERR(pdev, "VIRTIO ID %u not supported\n", vf->dev_type); 185 } 186 187 return features; 188 } 189 190 static int ifcvf_vdpa_set_driver_features(struct vdpa_device *vdpa_dev, u64 features) 191 { 192 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 193 int ret; 194 195 ret = ifcvf_verify_min_features(vf, features); 196 if (ret) 197 return ret; 198 199 vf->req_features = features; 200 201 return 0; 202 } 203 204 static u64 ifcvf_vdpa_get_driver_features(struct vdpa_device *vdpa_dev) 205 { 206 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 207 208 return vf->req_features; 209 } 210 211 static u8 ifcvf_vdpa_get_status(struct vdpa_device *vdpa_dev) 212 { 213 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 214 215 return ifcvf_get_status(vf); 216 } 217 218 static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status) 219 { 220 struct ifcvf_adapter *adapter; 221 struct ifcvf_hw *vf; 222 u8 status_old; 223 int ret; 224 225 vf = vdpa_to_vf(vdpa_dev); 226 adapter = vdpa_to_adapter(vdpa_dev); 227 status_old = ifcvf_get_status(vf); 228 229 if (status_old == status) 230 return; 231 232 if ((status & VIRTIO_CONFIG_S_DRIVER_OK) && 233 !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) { 234 ret = ifcvf_request_irq(adapter); 235 if (ret) { 236 status = ifcvf_get_status(vf); 237 status |= VIRTIO_CONFIG_S_FAILED; 238 ifcvf_set_status(vf, status); 239 return; 240 } 241 242 if (ifcvf_start_datapath(adapter) < 0) 243 IFCVF_ERR(adapter->pdev, 244 "Failed to set ifcvf vdpa status %u\n", 245 status); 246 } 247 248 ifcvf_set_status(vf, status); 249 } 250 251 static int ifcvf_vdpa_reset(struct vdpa_device *vdpa_dev) 252 { 253 struct ifcvf_adapter *adapter; 254 struct ifcvf_hw *vf; 255 u8 status_old; 256 257 vf = vdpa_to_vf(vdpa_dev); 258 adapter = vdpa_to_adapter(vdpa_dev); 259 status_old = ifcvf_get_status(vf); 260 261 if (status_old == 0) 262 return 0; 263 264 if (status_old & VIRTIO_CONFIG_S_DRIVER_OK) { 265 ifcvf_stop_datapath(adapter); 266 ifcvf_free_irq(adapter, vf->nr_vring); 267 } 268 269 ifcvf_reset_vring(adapter); 270 271 return 0; 272 } 273 274 static u16 ifcvf_vdpa_get_vq_num_max(struct vdpa_device *vdpa_dev) 275 { 276 return IFCVF_QUEUE_MAX; 277 } 278 279 static int ifcvf_vdpa_get_vq_state(struct vdpa_device *vdpa_dev, u16 qid, 280 struct vdpa_vq_state *state) 281 { 282 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 283 284 state->split.avail_index = ifcvf_get_vq_state(vf, qid); 285 return 0; 286 } 287 288 static int ifcvf_vdpa_set_vq_state(struct vdpa_device *vdpa_dev, u16 qid, 289 const struct vdpa_vq_state *state) 290 { 291 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 292 293 return ifcvf_set_vq_state(vf, qid, state->split.avail_index); 294 } 295 296 static void ifcvf_vdpa_set_vq_cb(struct vdpa_device *vdpa_dev, u16 qid, 297 struct vdpa_callback *cb) 298 { 299 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 300 301 vf->vring[qid].cb = *cb; 302 } 303 304 static void ifcvf_vdpa_set_vq_ready(struct vdpa_device *vdpa_dev, 305 u16 qid, bool ready) 306 { 307 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 308 309 vf->vring[qid].ready = ready; 310 } 311 312 static bool ifcvf_vdpa_get_vq_ready(struct vdpa_device *vdpa_dev, u16 qid) 313 { 314 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 315 316 return vf->vring[qid].ready; 317 } 318 319 static void ifcvf_vdpa_set_vq_num(struct vdpa_device *vdpa_dev, u16 qid, 320 u32 num) 321 { 322 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 323 324 vf->vring[qid].size = num; 325 } 326 327 static int ifcvf_vdpa_set_vq_address(struct vdpa_device *vdpa_dev, u16 qid, 328 u64 desc_area, u64 driver_area, 329 u64 device_area) 330 { 331 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 332 333 vf->vring[qid].desc = desc_area; 334 vf->vring[qid].avail = driver_area; 335 vf->vring[qid].used = device_area; 336 337 return 0; 338 } 339 340 static void ifcvf_vdpa_kick_vq(struct vdpa_device *vdpa_dev, u16 qid) 341 { 342 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 343 344 ifcvf_notify_queue(vf, qid); 345 } 346 347 static u32 ifcvf_vdpa_get_generation(struct vdpa_device *vdpa_dev) 348 { 349 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 350 351 return ioread8(&vf->common_cfg->config_generation); 352 } 353 354 static u32 ifcvf_vdpa_get_device_id(struct vdpa_device *vdpa_dev) 355 { 356 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 357 358 return vf->dev_type; 359 } 360 361 static u32 ifcvf_vdpa_get_vendor_id(struct vdpa_device *vdpa_dev) 362 { 363 struct ifcvf_adapter *adapter = vdpa_to_adapter(vdpa_dev); 364 struct pci_dev *pdev = adapter->pdev; 365 366 return pdev->subsystem_vendor; 367 } 368 369 static u32 ifcvf_vdpa_get_vq_align(struct vdpa_device *vdpa_dev) 370 { 371 return IFCVF_QUEUE_ALIGNMENT; 372 } 373 374 static size_t ifcvf_vdpa_get_config_size(struct vdpa_device *vdpa_dev) 375 { 376 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 377 378 return vf->config_size; 379 } 380 381 static void ifcvf_vdpa_get_config(struct vdpa_device *vdpa_dev, 382 unsigned int offset, 383 void *buf, unsigned int len) 384 { 385 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 386 387 ifcvf_read_dev_config(vf, offset, buf, len); 388 } 389 390 static void ifcvf_vdpa_set_config(struct vdpa_device *vdpa_dev, 391 unsigned int offset, const void *buf, 392 unsigned int len) 393 { 394 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 395 396 ifcvf_write_dev_config(vf, offset, buf, len); 397 } 398 399 static void ifcvf_vdpa_set_config_cb(struct vdpa_device *vdpa_dev, 400 struct vdpa_callback *cb) 401 { 402 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 403 404 vf->config_cb.callback = cb->callback; 405 vf->config_cb.private = cb->private; 406 } 407 408 static int ifcvf_vdpa_get_vq_irq(struct vdpa_device *vdpa_dev, 409 u16 qid) 410 { 411 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 412 413 return vf->vring[qid].irq; 414 } 415 416 static struct vdpa_notification_area ifcvf_get_vq_notification(struct vdpa_device *vdpa_dev, 417 u16 idx) 418 { 419 struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); 420 struct vdpa_notification_area area; 421 422 area.addr = vf->vring[idx].notify_pa; 423 if (!vf->notify_off_multiplier) 424 area.size = PAGE_SIZE; 425 else 426 area.size = vf->notify_off_multiplier; 427 428 return area; 429 } 430 431 /* 432 * IFCVF currently does't have on-chip IOMMU, so not 433 * implemented set_map()/dma_map()/dma_unmap() 434 */ 435 static const struct vdpa_config_ops ifc_vdpa_ops = { 436 .get_device_features = ifcvf_vdpa_get_device_features, 437 .set_driver_features = ifcvf_vdpa_set_driver_features, 438 .get_driver_features = ifcvf_vdpa_get_driver_features, 439 .get_status = ifcvf_vdpa_get_status, 440 .set_status = ifcvf_vdpa_set_status, 441 .reset = ifcvf_vdpa_reset, 442 .get_vq_num_max = ifcvf_vdpa_get_vq_num_max, 443 .get_vq_state = ifcvf_vdpa_get_vq_state, 444 .set_vq_state = ifcvf_vdpa_set_vq_state, 445 .set_vq_cb = ifcvf_vdpa_set_vq_cb, 446 .set_vq_ready = ifcvf_vdpa_set_vq_ready, 447 .get_vq_ready = ifcvf_vdpa_get_vq_ready, 448 .set_vq_num = ifcvf_vdpa_set_vq_num, 449 .set_vq_address = ifcvf_vdpa_set_vq_address, 450 .get_vq_irq = ifcvf_vdpa_get_vq_irq, 451 .kick_vq = ifcvf_vdpa_kick_vq, 452 .get_generation = ifcvf_vdpa_get_generation, 453 .get_device_id = ifcvf_vdpa_get_device_id, 454 .get_vendor_id = ifcvf_vdpa_get_vendor_id, 455 .get_vq_align = ifcvf_vdpa_get_vq_align, 456 .get_config_size = ifcvf_vdpa_get_config_size, 457 .get_config = ifcvf_vdpa_get_config, 458 .set_config = ifcvf_vdpa_set_config, 459 .set_config_cb = ifcvf_vdpa_set_config_cb, 460 .get_vq_notification = ifcvf_get_vq_notification, 461 }; 462 463 static struct virtio_device_id id_table_net[] = { 464 {VIRTIO_ID_NET, VIRTIO_DEV_ANY_ID}, 465 {0}, 466 }; 467 468 static struct virtio_device_id id_table_blk[] = { 469 {VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID}, 470 {0}, 471 }; 472 473 static u32 get_dev_type(struct pci_dev *pdev) 474 { 475 u32 dev_type; 476 477 /* This drirver drives both modern virtio devices and transitional 478 * devices in modern mode. 479 * vDPA requires feature bit VIRTIO_F_ACCESS_PLATFORM, 480 * so legacy devices and transitional devices in legacy 481 * mode will not work for vDPA, this driver will not 482 * drive devices with legacy interface. 483 */ 484 485 if (pdev->device < 0x1040) 486 dev_type = pdev->subsystem_device; 487 else 488 dev_type = pdev->device - 0x1040; 489 490 return dev_type; 491 } 492 493 static int ifcvf_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name, 494 const struct vdpa_dev_set_config *config) 495 { 496 struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev; 497 struct ifcvf_adapter *adapter; 498 struct pci_dev *pdev; 499 struct ifcvf_hw *vf; 500 struct device *dev; 501 int ret, i; 502 503 ifcvf_mgmt_dev = container_of(mdev, struct ifcvf_vdpa_mgmt_dev, mdev); 504 if (ifcvf_mgmt_dev->adapter) 505 return -EOPNOTSUPP; 506 507 pdev = ifcvf_mgmt_dev->pdev; 508 dev = &pdev->dev; 509 adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, 510 dev, &ifc_vdpa_ops, name, false); 511 if (IS_ERR(adapter)) { 512 IFCVF_ERR(pdev, "Failed to allocate vDPA structure"); 513 return PTR_ERR(adapter); 514 } 515 516 ifcvf_mgmt_dev->adapter = adapter; 517 pci_set_drvdata(pdev, ifcvf_mgmt_dev); 518 519 vf = &adapter->vf; 520 vf->dev_type = get_dev_type(pdev); 521 vf->base = pcim_iomap_table(pdev); 522 523 adapter->pdev = pdev; 524 adapter->vdpa.dma_dev = &pdev->dev; 525 526 ret = ifcvf_init_hw(vf, pdev); 527 if (ret) { 528 IFCVF_ERR(pdev, "Failed to init IFCVF hw\n"); 529 goto err; 530 } 531 532 for (i = 0; i < vf->nr_vring; i++) 533 vf->vring[i].irq = -EINVAL; 534 535 vf->hw_features = ifcvf_get_hw_features(vf); 536 vf->config_size = ifcvf_get_config_size(vf); 537 538 adapter->vdpa.mdev = &ifcvf_mgmt_dev->mdev; 539 ret = _vdpa_register_device(&adapter->vdpa, vf->nr_vring); 540 if (ret) { 541 IFCVF_ERR(pdev, "Failed to register to vDPA bus"); 542 goto err; 543 } 544 545 return 0; 546 547 err: 548 put_device(&adapter->vdpa.dev); 549 return ret; 550 } 551 552 static void ifcvf_vdpa_dev_del(struct vdpa_mgmt_dev *mdev, struct vdpa_device *dev) 553 { 554 struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev; 555 556 ifcvf_mgmt_dev = container_of(mdev, struct ifcvf_vdpa_mgmt_dev, mdev); 557 _vdpa_unregister_device(dev); 558 ifcvf_mgmt_dev->adapter = NULL; 559 } 560 561 static const struct vdpa_mgmtdev_ops ifcvf_vdpa_mgmt_dev_ops = { 562 .dev_add = ifcvf_vdpa_dev_add, 563 .dev_del = ifcvf_vdpa_dev_del 564 }; 565 566 static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id) 567 { 568 struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev; 569 struct device *dev = &pdev->dev; 570 u32 dev_type; 571 int ret; 572 573 ifcvf_mgmt_dev = kzalloc(sizeof(struct ifcvf_vdpa_mgmt_dev), GFP_KERNEL); 574 if (!ifcvf_mgmt_dev) { 575 IFCVF_ERR(pdev, "Failed to alloc memory for the vDPA management device\n"); 576 return -ENOMEM; 577 } 578 579 dev_type = get_dev_type(pdev); 580 switch (dev_type) { 581 case VIRTIO_ID_NET: 582 ifcvf_mgmt_dev->mdev.id_table = id_table_net; 583 break; 584 case VIRTIO_ID_BLOCK: 585 ifcvf_mgmt_dev->mdev.id_table = id_table_blk; 586 break; 587 default: 588 IFCVF_ERR(pdev, "VIRTIO ID %u not supported\n", dev_type); 589 ret = -EOPNOTSUPP; 590 goto err; 591 } 592 593 ifcvf_mgmt_dev->mdev.ops = &ifcvf_vdpa_mgmt_dev_ops; 594 ifcvf_mgmt_dev->mdev.device = dev; 595 ifcvf_mgmt_dev->pdev = pdev; 596 597 ret = pcim_enable_device(pdev); 598 if (ret) { 599 IFCVF_ERR(pdev, "Failed to enable device\n"); 600 goto err; 601 } 602 603 ret = pcim_iomap_regions(pdev, BIT(0) | BIT(2) | BIT(4), 604 IFCVF_DRIVER_NAME); 605 if (ret) { 606 IFCVF_ERR(pdev, "Failed to request MMIO region\n"); 607 goto err; 608 } 609 610 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); 611 if (ret) { 612 IFCVF_ERR(pdev, "No usable DMA configuration\n"); 613 goto err; 614 } 615 616 ret = devm_add_action_or_reset(dev, ifcvf_free_irq_vectors, pdev); 617 if (ret) { 618 IFCVF_ERR(pdev, 619 "Failed for adding devres for freeing irq vectors\n"); 620 goto err; 621 } 622 623 pci_set_master(pdev); 624 625 ret = vdpa_mgmtdev_register(&ifcvf_mgmt_dev->mdev); 626 if (ret) { 627 IFCVF_ERR(pdev, 628 "Failed to initialize the management interfaces\n"); 629 goto err; 630 } 631 632 return 0; 633 634 err: 635 kfree(ifcvf_mgmt_dev); 636 return ret; 637 } 638 639 static void ifcvf_remove(struct pci_dev *pdev) 640 { 641 struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev; 642 643 ifcvf_mgmt_dev = pci_get_drvdata(pdev); 644 vdpa_mgmtdev_unregister(&ifcvf_mgmt_dev->mdev); 645 kfree(ifcvf_mgmt_dev); 646 } 647 648 static struct pci_device_id ifcvf_pci_ids[] = { 649 /* N3000 network device */ 650 { PCI_DEVICE_SUB(PCI_VENDOR_ID_REDHAT_QUMRANET, 651 N3000_DEVICE_ID, 652 PCI_VENDOR_ID_INTEL, 653 N3000_SUBSYS_DEVICE_ID) }, 654 /* C5000X-PL network device */ 655 { PCI_DEVICE_SUB(PCI_VENDOR_ID_REDHAT_QUMRANET, 656 VIRTIO_TRANS_ID_NET, 657 PCI_VENDOR_ID_INTEL, 658 VIRTIO_ID_NET) }, 659 /* C5000X-PL block device */ 660 { PCI_DEVICE_SUB(PCI_VENDOR_ID_REDHAT_QUMRANET, 661 VIRTIO_TRANS_ID_BLOCK, 662 PCI_VENDOR_ID_INTEL, 663 VIRTIO_ID_BLOCK) }, 664 665 { 0 }, 666 }; 667 MODULE_DEVICE_TABLE(pci, ifcvf_pci_ids); 668 669 static struct pci_driver ifcvf_driver = { 670 .name = IFCVF_DRIVER_NAME, 671 .id_table = ifcvf_pci_ids, 672 .probe = ifcvf_probe, 673 .remove = ifcvf_remove, 674 }; 675 676 module_pci_driver(ifcvf_driver); 677 678 MODULE_LICENSE("GPL v2"); 679