spi: New support and problem adjustment of SPI rockchip
[platform/kernel/linux-rpi.git] / drivers / vdpa / ifcvf / ifcvf_main.c
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");