net/virtio-user: support to report net status
[dpdk.git] / drivers / net / virtio / virtio_user_ethdev.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2016 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
34 #include <stdint.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37
38 #include <rte_malloc.h>
39 #include <rte_kvargs.h>
40 #include <rte_vdev.h>
41
42 #include "virtio_ethdev.h"
43 #include "virtio_logs.h"
44 #include "virtio_pci.h"
45 #include "virtqueue.h"
46 #include "virtio_rxtx.h"
47 #include "virtio_user/virtio_user_dev.h"
48
49 #define virtio_user_get_dev(hw) \
50         ((struct virtio_user_dev *)(hw)->virtio_user_dev)
51
52 static void
53 virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
54                      void *dst, int length)
55 {
56         int i;
57         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
58
59         if (offset == offsetof(struct virtio_net_config, mac) &&
60             length == ETHER_ADDR_LEN) {
61                 for (i = 0; i < ETHER_ADDR_LEN; ++i)
62                         ((uint8_t *)dst)[i] = dev->mac_addr[i];
63                 return;
64         }
65
66         if (offset == offsetof(struct virtio_net_config, status))
67                 *(uint16_t *)dst = dev->status;
68
69         if (offset == offsetof(struct virtio_net_config, max_virtqueue_pairs))
70                 *(uint16_t *)dst = dev->max_queue_pairs;
71 }
72
73 static void
74 virtio_user_write_dev_config(struct virtio_hw *hw, size_t offset,
75                       const void *src, int length)
76 {
77         int i;
78         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
79
80         if ((offset == offsetof(struct virtio_net_config, mac)) &&
81             (length == ETHER_ADDR_LEN))
82                 for (i = 0; i < ETHER_ADDR_LEN; ++i)
83                         dev->mac_addr[i] = ((const uint8_t *)src)[i];
84         else
85                 PMD_DRV_LOG(ERR, "not supported offset=%zu, len=%d",
86                             offset, length);
87 }
88
89 static void
90 virtio_user_reset(struct virtio_hw *hw)
91 {
92         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
93
94         if (dev->status & VIRTIO_CONFIG_STATUS_DRIVER_OK)
95                 virtio_user_stop_device(dev);
96 }
97
98 static void
99 virtio_user_set_status(struct virtio_hw *hw, uint8_t status)
100 {
101         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
102
103         if (status & VIRTIO_CONFIG_STATUS_DRIVER_OK)
104                 virtio_user_start_device(dev);
105         else if (status == VIRTIO_CONFIG_STATUS_RESET)
106                 virtio_user_reset(hw);
107         dev->status = status;
108 }
109
110 static uint8_t
111 virtio_user_get_status(struct virtio_hw *hw)
112 {
113         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
114
115         return dev->status;
116 }
117
118 static uint64_t
119 virtio_user_get_features(struct virtio_hw *hw)
120 {
121         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
122
123         /* unmask feature bits defined in vhost user protocol */
124         return dev->device_features & VIRTIO_PMD_SUPPORTED_GUEST_FEATURES;
125 }
126
127 static void
128 virtio_user_set_features(struct virtio_hw *hw, uint64_t features)
129 {
130         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
131
132         dev->features = features & dev->device_features;
133 }
134
135 static uint8_t
136 virtio_user_get_isr(struct virtio_hw *hw __rte_unused)
137 {
138         /* rxq interrupts and config interrupt are separated in virtio-user,
139          * here we only report config change.
140          */
141         return VIRTIO_PCI_ISR_CONFIG;
142 }
143
144 static uint16_t
145 virtio_user_set_config_irq(struct virtio_hw *hw __rte_unused,
146                     uint16_t vec __rte_unused)
147 {
148         return 0;
149 }
150
151 static uint16_t
152 virtio_user_set_queue_irq(struct virtio_hw *hw __rte_unused,
153                           struct virtqueue *vq __rte_unused,
154                           uint16_t vec)
155 {
156         /* pretend we have done that */
157         return vec;
158 }
159
160 /* This function is to get the queue size, aka, number of descs, of a specified
161  * queue. Different with the VHOST_USER_GET_QUEUE_NUM, which is used to get the
162  * max supported queues.
163  */
164 static uint16_t
165 virtio_user_get_queue_num(struct virtio_hw *hw, uint16_t queue_id __rte_unused)
166 {
167         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
168
169         /* Currently, each queue has same queue size */
170         return dev->queue_size;
171 }
172
173 static int
174 virtio_user_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
175 {
176         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
177         uint16_t queue_idx = vq->vq_queue_index;
178         uint64_t desc_addr, avail_addr, used_addr;
179
180         desc_addr = (uintptr_t)vq->vq_ring_virt_mem;
181         avail_addr = desc_addr + vq->vq_nentries * sizeof(struct vring_desc);
182         used_addr = RTE_ALIGN_CEIL(avail_addr + offsetof(struct vring_avail,
183                                                          ring[vq->vq_nentries]),
184                                    VIRTIO_PCI_VRING_ALIGN);
185
186         dev->vrings[queue_idx].num = vq->vq_nentries;
187         dev->vrings[queue_idx].desc = (void *)(uintptr_t)desc_addr;
188         dev->vrings[queue_idx].avail = (void *)(uintptr_t)avail_addr;
189         dev->vrings[queue_idx].used = (void *)(uintptr_t)used_addr;
190
191         return 0;
192 }
193
194 static void
195 virtio_user_del_queue(struct virtio_hw *hw, struct virtqueue *vq)
196 {
197         /* For legacy devices, write 0 to VIRTIO_PCI_QUEUE_PFN port, QEMU
198          * correspondingly stops the ioeventfds, and reset the status of
199          * the device.
200          * For modern devices, set queue desc, avail, used in PCI bar to 0,
201          * not see any more behavior in QEMU.
202          *
203          * Here we just care about what information to deliver to vhost-user
204          * or vhost-kernel. So we just close ioeventfd for now.
205          */
206         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
207
208         close(dev->callfds[vq->vq_queue_index]);
209         close(dev->kickfds[vq->vq_queue_index]);
210 }
211
212 static void
213 virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
214 {
215         uint64_t buf = 1;
216         struct virtio_user_dev *dev = virtio_user_get_dev(hw);
217
218         if (hw->cvq && (hw->cvq->vq == vq)) {
219                 virtio_user_handle_cq(dev, vq->vq_queue_index);
220                 return;
221         }
222
223         if (write(dev->kickfds[vq->vq_queue_index], &buf, sizeof(buf)) < 0)
224                 PMD_DRV_LOG(ERR, "failed to kick backend: %s",
225                             strerror(errno));
226 }
227
228 const struct virtio_pci_ops virtio_user_ops = {
229         .read_dev_cfg   = virtio_user_read_dev_config,
230         .write_dev_cfg  = virtio_user_write_dev_config,
231         .reset          = virtio_user_reset,
232         .get_status     = virtio_user_get_status,
233         .set_status     = virtio_user_set_status,
234         .get_features   = virtio_user_get_features,
235         .set_features   = virtio_user_set_features,
236         .get_isr        = virtio_user_get_isr,
237         .set_config_irq = virtio_user_set_config_irq,
238         .set_queue_irq  = virtio_user_set_queue_irq,
239         .get_queue_num  = virtio_user_get_queue_num,
240         .setup_queue    = virtio_user_setup_queue,
241         .del_queue      = virtio_user_del_queue,
242         .notify_queue   = virtio_user_notify_queue,
243 };
244
245 static const char *valid_args[] = {
246 #define VIRTIO_USER_ARG_QUEUES_NUM     "queues"
247         VIRTIO_USER_ARG_QUEUES_NUM,
248 #define VIRTIO_USER_ARG_CQ_NUM         "cq"
249         VIRTIO_USER_ARG_CQ_NUM,
250 #define VIRTIO_USER_ARG_MAC            "mac"
251         VIRTIO_USER_ARG_MAC,
252 #define VIRTIO_USER_ARG_PATH           "path"
253         VIRTIO_USER_ARG_PATH,
254 #define VIRTIO_USER_ARG_QUEUE_SIZE     "queue_size"
255         VIRTIO_USER_ARG_QUEUE_SIZE,
256 #define VIRTIO_USER_ARG_INTERFACE_NAME "iface"
257         VIRTIO_USER_ARG_INTERFACE_NAME,
258         NULL
259 };
260
261 #define VIRTIO_USER_DEF_CQ_EN   0
262 #define VIRTIO_USER_DEF_Q_NUM   1
263 #define VIRTIO_USER_DEF_Q_SZ    256
264
265 static int
266 get_string_arg(const char *key __rte_unused,
267                const char *value, void *extra_args)
268 {
269         if (!value || !extra_args)
270                 return -EINVAL;
271
272         *(char **)extra_args = strdup(value);
273
274         if (!*(char **)extra_args)
275                 return -ENOMEM;
276
277         return 0;
278 }
279
280 static int
281 get_integer_arg(const char *key __rte_unused,
282                 const char *value, void *extra_args)
283 {
284         if (!value || !extra_args)
285                 return -EINVAL;
286
287         *(uint64_t *)extra_args = strtoull(value, NULL, 0);
288
289         return 0;
290 }
291
292 static struct rte_vdev_driver virtio_user_driver;
293
294 static struct rte_eth_dev *
295 virtio_user_eth_dev_alloc(const char *name)
296 {
297         struct rte_eth_dev *eth_dev;
298         struct rte_eth_dev_data *data;
299         struct virtio_hw *hw;
300         struct virtio_user_dev *dev;
301
302         eth_dev = rte_eth_dev_allocate(name);
303         if (!eth_dev) {
304                 PMD_INIT_LOG(ERR, "cannot alloc rte_eth_dev");
305                 return NULL;
306         }
307
308         data = eth_dev->data;
309
310         hw = rte_zmalloc(NULL, sizeof(*hw), 0);
311         if (!hw) {
312                 PMD_INIT_LOG(ERR, "malloc virtio_hw failed");
313                 rte_eth_dev_release_port(eth_dev);
314                 return NULL;
315         }
316
317         dev = rte_zmalloc(NULL, sizeof(*dev), 0);
318         if (!dev) {
319                 PMD_INIT_LOG(ERR, "malloc virtio_user_dev failed");
320                 rte_eth_dev_release_port(eth_dev);
321                 rte_free(hw);
322                 return NULL;
323         }
324
325         hw->port_id = data->port_id;
326         dev->port_id = data->port_id;
327         virtio_hw_internal[hw->port_id].vtpci_ops = &virtio_user_ops;
328         hw->use_msix = 0;
329         hw->modern   = 0;
330         hw->use_simple_rxtx = 0;
331         hw->virtio_user_dev = dev;
332         data->dev_private = hw;
333         data->drv_name = virtio_user_driver.driver.name;
334         data->numa_node = SOCKET_ID_ANY;
335         data->kdrv = RTE_KDRV_NONE;
336         data->dev_flags = RTE_ETH_DEV_DETACHABLE;
337         eth_dev->driver = NULL;
338         return eth_dev;
339 }
340
341 static void
342 virtio_user_eth_dev_free(struct rte_eth_dev *eth_dev)
343 {
344         struct rte_eth_dev_data *data = eth_dev->data;
345         struct virtio_hw *hw = data->dev_private;
346
347         rte_free(hw->virtio_user_dev);
348         rte_free(hw);
349         rte_eth_dev_release_port(eth_dev);
350 }
351
352 /* Dev initialization routine. Invoked once for each virtio vdev at
353  * EAL init time, see rte_eal_dev_init().
354  * Returns 0 on success.
355  */
356 static int
357 virtio_user_pmd_probe(const char *name, const char *params)
358 {
359         struct rte_kvargs *kvlist = NULL;
360         struct rte_eth_dev *eth_dev;
361         struct virtio_hw *hw;
362         uint64_t queues = VIRTIO_USER_DEF_Q_NUM;
363         uint64_t cq = VIRTIO_USER_DEF_CQ_EN;
364         uint64_t queue_size = VIRTIO_USER_DEF_Q_SZ;
365         char *path = NULL;
366         char *ifname = NULL;
367         char *mac_addr = NULL;
368         int ret = -1;
369
370         if (!params || params[0] == '\0') {
371                 PMD_INIT_LOG(ERR, "arg %s is mandatory for virtio_user",
372                           VIRTIO_USER_ARG_QUEUE_SIZE);
373                 goto end;
374         }
375
376         kvlist = rte_kvargs_parse(params, valid_args);
377         if (!kvlist) {
378                 PMD_INIT_LOG(ERR, "error when parsing param");
379                 goto end;
380         }
381
382         if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_PATH) == 1) {
383                 if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_PATH,
384                                        &get_string_arg, &path) < 0) {
385                         PMD_INIT_LOG(ERR, "error to parse %s",
386                                      VIRTIO_USER_ARG_PATH);
387                         goto end;
388                 }
389         } else {
390                 PMD_INIT_LOG(ERR, "arg %s is mandatory for virtio_user",
391                           VIRTIO_USER_ARG_QUEUE_SIZE);
392                 goto end;
393         }
394
395         if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_INTERFACE_NAME) == 1) {
396                 if (is_vhost_user_by_type(path)) {
397                         PMD_INIT_LOG(ERR,
398                                 "arg %s applies only to vhost-kernel backend",
399                                 VIRTIO_USER_ARG_INTERFACE_NAME);
400                         goto end;
401                 }
402
403                 if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_INTERFACE_NAME,
404                                        &get_string_arg, &ifname) < 0) {
405                         PMD_INIT_LOG(ERR, "error to parse %s",
406                                      VIRTIO_USER_ARG_INTERFACE_NAME);
407                         goto end;
408                 }
409         }
410
411         if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_MAC) == 1) {
412                 if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_MAC,
413                                        &get_string_arg, &mac_addr) < 0) {
414                         PMD_INIT_LOG(ERR, "error to parse %s",
415                                      VIRTIO_USER_ARG_MAC);
416                         goto end;
417                 }
418         }
419
420         if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_QUEUE_SIZE) == 1) {
421                 if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_QUEUE_SIZE,
422                                        &get_integer_arg, &queue_size) < 0) {
423                         PMD_INIT_LOG(ERR, "error to parse %s",
424                                      VIRTIO_USER_ARG_QUEUE_SIZE);
425                         goto end;
426                 }
427         }
428
429         if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_QUEUES_NUM) == 1) {
430                 if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_QUEUES_NUM,
431                                        &get_integer_arg, &queues) < 0) {
432                         PMD_INIT_LOG(ERR, "error to parse %s",
433                                      VIRTIO_USER_ARG_QUEUES_NUM);
434                         goto end;
435                 }
436         }
437
438         if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_CQ_NUM) == 1) {
439                 if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_CQ_NUM,
440                                        &get_integer_arg, &cq) < 0) {
441                         PMD_INIT_LOG(ERR, "error to parse %s",
442                                      VIRTIO_USER_ARG_CQ_NUM);
443                         goto end;
444                 }
445         } else if (queues > 1) {
446                 cq = 1;
447         }
448
449         if (queues > 1 && cq == 0) {
450                 PMD_INIT_LOG(ERR, "multi-q requires ctrl-q");
451                 goto end;
452         }
453
454         if (queues > VIRTIO_MAX_VIRTQUEUE_PAIRS) {
455                 PMD_INIT_LOG(ERR, "arg %s %" PRIu64 " exceeds the limit %u",
456                         VIRTIO_USER_ARG_QUEUES_NUM, queues,
457                         VIRTIO_MAX_VIRTQUEUE_PAIRS);
458                 goto end;
459         }
460
461         eth_dev = virtio_user_eth_dev_alloc(name);
462         if (!eth_dev) {
463                 PMD_INIT_LOG(ERR, "virtio_user fails to alloc device");
464                 goto end;
465         }
466
467         hw = eth_dev->data->dev_private;
468         if (virtio_user_dev_init(hw->virtio_user_dev, path, queues, cq,
469                                  queue_size, mac_addr, &ifname) < 0) {
470                 PMD_INIT_LOG(ERR, "virtio_user_dev_init fails");
471                 virtio_user_eth_dev_free(eth_dev);
472                 goto end;
473         }
474
475         /* previously called by rte_eal_pci_probe() for physical dev */
476         if (eth_virtio_dev_init(eth_dev) < 0) {
477                 PMD_INIT_LOG(ERR, "eth_virtio_dev_init fails");
478                 virtio_user_eth_dev_free(eth_dev);
479                 goto end;
480         }
481         ret = 0;
482
483 end:
484         if (kvlist)
485                 rte_kvargs_free(kvlist);
486         if (path)
487                 free(path);
488         if (mac_addr)
489                 free(mac_addr);
490         if (ifname)
491                 free(ifname);
492         return ret;
493 }
494
495 /** Called by rte_eth_dev_detach() */
496 static int
497 virtio_user_pmd_remove(const char *name)
498 {
499         struct rte_eth_dev *eth_dev;
500         struct virtio_hw *hw;
501         struct virtio_user_dev *dev;
502
503         if (!name)
504                 return -EINVAL;
505
506         PMD_DRV_LOG(INFO, "Un-Initializing %s", name);
507         eth_dev = rte_eth_dev_allocated(name);
508         if (!eth_dev)
509                 return -ENODEV;
510
511         /* make sure the device is stopped, queues freed */
512         rte_eth_dev_close(eth_dev->data->port_id);
513
514         hw = eth_dev->data->dev_private;
515         dev = hw->virtio_user_dev;
516         virtio_user_dev_uninit(dev);
517
518         rte_free(eth_dev->data->dev_private);
519         rte_free(eth_dev->data);
520         rte_eth_dev_release_port(eth_dev);
521
522         return 0;
523 }
524
525 static struct rte_vdev_driver virtio_user_driver = {
526         .probe = virtio_user_pmd_probe,
527         .remove = virtio_user_pmd_remove,
528 };
529
530 RTE_PMD_REGISTER_VDEV(net_virtio_user, virtio_user_driver);
531 RTE_PMD_REGISTER_ALIAS(net_virtio_user, virtio_user);
532 RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user,
533         "path=<path> "
534         "mac=<mac addr> "
535         "cq=<int> "
536         "queue_size=<int> "
537         "queues=<int> "
538         "iface=<string>");