net/virtio: move PCI device init in dedicated file
[dpdk.git] / drivers / net / virtio / virtio_pci_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation
3  */
4
5 #include <stdint.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <errno.h>
9 #include <unistd.h>
10
11 #include <ethdev_driver.h>
12 #include <ethdev_pci.h>
13 #include <rte_pci.h>
14 #include <rte_bus_pci.h>
15 #include <rte_errno.h>
16
17 #include <rte_memory.h>
18 #include <rte_eal.h>
19 #include <rte_dev.h>
20 #include <rte_kvargs.h>
21
22 #include "virtio_ethdev.h"
23 #include "virtio_pci.h"
24 #include "virtio_logs.h"
25
26 /*
27  * The set of PCI devices this driver supports
28  */
29 static const struct rte_pci_id pci_id_virtio_map[] = {
30         { RTE_PCI_DEVICE(VIRTIO_PCI_VENDORID, VIRTIO_PCI_LEGACY_DEVICEID_NET) },
31         { RTE_PCI_DEVICE(VIRTIO_PCI_VENDORID, VIRTIO_PCI_MODERN_DEVICEID_NET) },
32         { .vendor_id = 0, /* sentinel */ },
33 };
34
35 static int
36 eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
37 {
38         return eth_virtio_dev_init(eth_dev);
39 }
40
41 static int
42 eth_virtio_pci_uninit(struct rte_eth_dev *eth_dev)
43 {
44         int ret;
45         PMD_INIT_FUNC_TRACE();
46
47         if (rte_eal_process_type() == RTE_PROC_SECONDARY)
48                 return 0;
49
50         ret = virtio_dev_stop(eth_dev);
51         virtio_dev_close(eth_dev);
52
53         PMD_INIT_LOG(DEBUG, "dev_uninit completed");
54
55         return ret;
56 }
57
58 static int vdpa_check_handler(__rte_unused const char *key,
59                 const char *value, void *ret_val)
60 {
61         if (strcmp(value, "1") == 0)
62                 *(int *)ret_val = 1;
63         else
64                 *(int *)ret_val = 0;
65
66         return 0;
67 }
68
69 #define VIRTIO_ARG_VDPA       "vdpa"
70
71 static int
72 virtio_pci_devargs_parse(struct rte_devargs *devargs, int *vdpa)
73 {
74         struct rte_kvargs *kvlist;
75         int ret = 0;
76
77         if (devargs == NULL)
78                 return 0;
79
80         kvlist = rte_kvargs_parse(devargs->args, NULL);
81         if (kvlist == NULL) {
82                 PMD_INIT_LOG(ERR, "error when parsing param");
83                 return 0;
84         }
85
86         if (rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
87                 /* vdpa mode selected when there's a key-value pair:
88                  * vdpa=1
89                  */
90                 ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
91                                 vdpa_check_handler, vdpa);
92                 if (ret < 0)
93                         PMD_INIT_LOG(ERR, "Failed to parse %s", VIRTIO_ARG_VDPA);
94         }
95
96         rte_kvargs_free(kvlist);
97
98         return ret;
99 }
100
101 static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
102         struct rte_pci_device *pci_dev)
103 {
104         int vdpa = 0;
105         int ret = 0;
106
107         ret = virtio_pci_devargs_parse(pci_dev->device.devargs, &vdpa);
108         if (ret < 0) {
109                 PMD_INIT_LOG(ERR, "devargs parsing is failed");
110                 return ret;
111         }
112         /* virtio pmd skips probe if device needs to work in vdpa mode */
113         if (vdpa == 1)
114                 return 1;
115
116         return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_pci_dev),
117                 eth_virtio_pci_init);
118 }
119
120 static int eth_virtio_pci_remove(struct rte_pci_device *pci_dev)
121 {
122         int ret;
123
124         ret = rte_eth_dev_pci_generic_remove(pci_dev, eth_virtio_pci_uninit);
125         /* Port has already been released by close. */
126         if (ret == -ENODEV)
127                 ret = 0;
128         return ret;
129 }
130
131 static struct rte_pci_driver rte_virtio_net_pci_pmd = {
132         .driver = {
133                 .name = "net_virtio",
134         },
135         .id_table = pci_id_virtio_map,
136         .drv_flags = 0,
137         .probe = eth_virtio_pci_probe,
138         .remove = eth_virtio_pci_remove,
139 };
140
141 RTE_INIT(rte_virtio_net_pci_pmd_init)
142 {
143         rte_eal_iopl_init();
144         rte_pci_register(&rte_virtio_net_pci_pmd);
145 }
146
147 RTE_PMD_REGISTER_PCI_TABLE(net_virtio, pci_id_virtio_map);
148 RTE_PMD_REGISTER_KMOD_DEP(net_virtio, "* igb_uio | uio_pci_generic | vfio-pci");
149 RTE_PMD_EXPORT_NAME(net_virtio, __COUNTER__);