virtio: code-style cleanup
[dpdk.git] / lib / librte_pmd_virtio / virtio_ethdev.c
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
34 #include <stdint.h>
35 #include <string.h>
36 #include <stdio.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #ifdef RTE_EXEC_ENV_LINUXAPP
40 #include <dirent.h>
41 #endif
42
43 #include <rte_ethdev.h>
44 #include <rte_memcpy.h>
45 #include <rte_string_fns.h>
46 #include <rte_memzone.h>
47 #include <rte_malloc.h>
48 #include <rte_atomic.h>
49 #include <rte_branch_prediction.h>
50 #include <rte_pci.h>
51 #include <rte_ether.h>
52 #include <rte_common.h>
53
54 #include <rte_memory.h>
55 #include <rte_eal.h>
56 #include <rte_dev.h>
57
58 #include "virtio_ethdev.h"
59 #include "virtio_pci.h"
60 #include "virtio_logs.h"
61 #include "virtqueue.h"
62
63
64 static int eth_virtio_dev_init(struct eth_driver *eth_drv,
65                 struct rte_eth_dev *eth_dev);
66 static int  virtio_dev_configure(struct rte_eth_dev *dev);
67 static int  virtio_dev_start(struct rte_eth_dev *dev);
68 static void virtio_dev_stop(struct rte_eth_dev *dev);
69 static void virtio_dev_info_get(struct rte_eth_dev *dev,
70                                 struct rte_eth_dev_info *dev_info);
71 static int virtio_dev_link_update(struct rte_eth_dev *dev,
72         __rte_unused int wait_to_complete);
73
74 static void virtio_set_hwaddr(struct virtio_hw *hw);
75 static void virtio_get_hwaddr(struct virtio_hw *hw);
76
77 static void virtio_dev_rx_queue_release(__rte_unused void *rxq);
78 static void virtio_dev_tx_queue_release(__rte_unused void *txq);
79
80 static void virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
81 static void virtio_dev_stats_reset(struct rte_eth_dev *dev);
82 static void virtio_dev_free_mbufs(struct rte_eth_dev *dev);
83
84 /*
85  * The set of PCI devices this driver supports
86  */
87 static struct rte_pci_id pci_id_virtio_map[] = {
88
89 #define RTE_PCI_DEV_ID_DECL_VIRTIO(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
90 #include "rte_pci_dev_ids.h"
91
92 { .vendor_id = 0, /* sentinel */ },
93 };
94
95 int virtio_dev_queue_setup(struct rte_eth_dev *dev,
96                         int queue_type,
97                         uint16_t queue_idx,
98                         uint8_t  vtpci_queue_idx,
99                         uint16_t nb_desc,
100                         unsigned int socket_id,
101                         struct virtqueue **pvq)
102 {
103         char vq_name[VIRTQUEUE_MAX_NAME_SZ];
104         const struct rte_memzone *mz;
105         uint16_t vq_size;
106         int size;
107         struct virtio_hw *hw = 
108                 VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
109         struct virtqueue  *vq = NULL;
110
111         /* Write the virtqueue index to the Queue Select Field */
112         VIRTIO_WRITE_REG_2(hw, VIRTIO_PCI_QUEUE_SEL, vtpci_queue_idx);
113         PMD_INIT_LOG(DEBUG, "selecting queue: %d\n", vtpci_queue_idx);
114
115         /*
116          * Read the virtqueue size from the Queue Size field
117          * Always power of 2 and if 0 virtqueue does not exist
118          */
119         vq_size = VIRTIO_READ_REG_2(hw, VIRTIO_PCI_QUEUE_NUM);
120         PMD_INIT_LOG(DEBUG, "vq_size: %d nb_desc:%d\n", vq_size, nb_desc);
121         if (nb_desc == 0)
122                 nb_desc = vq_size;
123         if (vq_size == 0) {
124                 PMD_INIT_LOG(ERR, "%s: virtqueue does not exist\n", __func__);
125                 return (-EINVAL);
126         } else if (!rte_is_power_of_2(vq_size)) {
127                 PMD_INIT_LOG(ERR, "%s: virtqueue size is not powerof 2\n", __func__);
128                 return (-EINVAL);
129         } else if (nb_desc != vq_size) {
130                 PMD_INIT_LOG(ERR, "Warning: nb_desc(%d) is not equal to vq size (%d), fall to vq size\n",
131                         nb_desc, vq_size);
132                 nb_desc = vq_size;
133         }
134
135         if (queue_type == VTNET_RQ) {
136                 rte_snprintf(vq_name, sizeof(vq_name), "port%d_rvq%d",
137                         dev->data->port_id, queue_idx);
138                 vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
139                         vq_size * sizeof(struct vq_desc_extra), CACHE_LINE_SIZE);
140                 memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
141         } else if(queue_type == VTNET_TQ) {
142                 rte_snprintf(vq_name, sizeof(vq_name), "port%d_tvq%d",
143                         dev->data->port_id, queue_idx);
144                 vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
145                         vq_size * sizeof(struct vq_desc_extra), CACHE_LINE_SIZE);
146                 memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
147         } else if(queue_type == VTNET_CQ) {
148                 rte_snprintf(vq_name, sizeof(vq_name), "port%d_cvq",
149                 vq = rte_zmalloc(vq_name, sizeof(struct virtqueue),
150                         dev->data->port_id);
151                         CACHE_LINE_SIZE);
152                 memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
153         }
154         if (vq == NULL) {
155                 PMD_INIT_LOG(ERR, "%s: Can not allocate virtqueue\n", __func__);
156                 return (-ENOMEM); 
157         }
158
159         vq->hw = hw;
160         vq->port_id = dev->data->port_id;
161         vq->queue_id = queue_idx;
162         vq->vq_queue_index = vtpci_queue_idx;
163         vq->vq_alignment = VIRTIO_PCI_VRING_ALIGN;
164         vq->vq_nentries = vq_size;
165         vq->vq_free_cnt = vq_size;
166
167         /*
168          * Reserve a memzone for vring elements
169          */
170         size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
171         vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
172         PMD_INIT_LOG(DEBUG, "vring_size: %d, rounded_vring_size: %d\n", size, vq->vq_ring_size);
173
174         mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
175                 socket_id, 0, VIRTIO_PCI_VRING_ALIGN);
176         if (mz == NULL) {
177                 rte_free(vq);
178                 return (-ENOMEM);
179         }
180
181         /*
182         * Virtio PCI device VIRTIO_PCI_QUEUE_PF register is 32bit,
183         * and only accepts 32 bit page frame number. 
184         * Check if the allocated physical memory exceeds 16TB.
185         */
186         if ( (mz->phys_addr + vq->vq_ring_size - 1) >> (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32) ) {
187                 PMD_INIT_LOG(ERR, "vring address shouldn't be above 16TB!\n");
188                 rte_free(vq);
189                 return (-ENOMEM);
190         }
191
192         memset(mz->addr, 0, sizeof(mz->len));
193         vq->mz = mz;
194         vq->vq_ring_mem = mz->phys_addr;
195         vq->vq_ring_virt_mem = mz->addr;
196         PMD_INIT_LOG(DEBUG, "vq->vq_ring_mem:      0x%"PRIx64"\n", (uint64_t)mz->phys_addr);
197         PMD_INIT_LOG(DEBUG, "vq->vq_ring_virt_mem: 0x%"PRIx64"\n", (uint64_t)mz->addr);
198         vq->virtio_net_hdr_mz  = NULL;
199         vq->virtio_net_hdr_mem = (void *)NULL;
200
201         if (queue_type == VTNET_TQ) {
202                 /* 
203                  * For each xmit packet, allocate a virtio_net_hdr
204                  */
205                 rte_snprintf(vq_name, sizeof(vq_name), "port%d_tvq%d_hdrzone",
206                         dev->data->port_id, queue_idx);
207                 vq->virtio_net_hdr_mz = rte_memzone_reserve_aligned(vq_name,
208                         vq_size * sizeof(struct virtio_net_hdr),
209                         socket_id, 0, CACHE_LINE_SIZE);
210                 if (vq->virtio_net_hdr_mz == NULL) {
211                         rte_free(vq);
212                         return -ENOMEM;
213                 }
214                 vq->virtio_net_hdr_mem =
215                         (void *)(uintptr_t)vq->virtio_net_hdr_mz->phys_addr;
216                 memset(vq->virtio_net_hdr_mz->addr, 0,
217                         vq_size * sizeof(struct virtio_net_hdr));
218         } else if (queue_type == VTNET_CQ) {
219                 /* Allocate a page for control vq command, data and status */
220                 rte_snprintf(vq_name, sizeof(vq_name), "port%d_cvq_hdrzone",
221                         dev->data->port_id);
222                 vq->virtio_net_hdr_mz = rte_memzone_reserve_aligned(vq_name,
223                         PAGE_SIZE, socket_id, 0, CACHE_LINE_SIZE);
224                 if (vq->virtio_net_hdr_mz == NULL) {
225                         rte_free(vq);
226                         return -ENOMEM;
227                 }
228                 vq->virtio_net_hdr_mem =
229                         (void *)(uintptr_t)vq->virtio_net_hdr_mz->phys_addr;
230                 memset(vq->virtio_net_hdr_mz->addr, 0, PAGE_SIZE);
231         }
232
233         /*
234          * Set guest physical address of the virtqueue
235          * in VIRTIO_PCI_QUEUE_PFN config register of device
236          */
237         VIRTIO_WRITE_REG_4(hw, VIRTIO_PCI_QUEUE_PFN,
238                         mz->phys_addr >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
239         *pvq = vq;
240         return 0;
241 }
242
243 static int
244 virtio_dev_cq_queue_setup(struct rte_eth_dev *dev,
245                 unsigned int socket_id)
246 {
247         struct virtqueue *vq;
248         uint16_t nb_desc = 0;
249         int ret;
250         struct virtio_hw *hw =
251                 VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
252
253         PMD_INIT_FUNC_TRACE();
254         ret = virtio_dev_queue_setup(dev, VTNET_CQ, 0, VTNET_SQ_CQ_QUEUE_IDX,
255                         nb_desc, socket_id, &vq);
256         if (ret < 0) {
257                 PMD_INIT_LOG(ERR, "control vq initialization failed\n");
258                 return ret;
259         }
260
261         hw->cvq = vq;
262         return 0;
263 }
264
265 static void
266 virtio_dev_close(struct rte_eth_dev *dev)
267 {
268         PMD_INIT_LOG(DEBUG, "virtio_dev_close");
269
270         virtio_dev_stop(dev);
271 }
272
273 /*
274  * dev_ops for virtio, bare necessities for basic operation
275  */
276 static struct eth_dev_ops virtio_eth_dev_ops = {
277         .dev_configure           = virtio_dev_configure,
278         .dev_start               = virtio_dev_start,
279         .dev_stop                = virtio_dev_stop,
280         .dev_close               = virtio_dev_close,
281
282         .dev_infos_get           = virtio_dev_info_get,
283         .stats_get               = virtio_dev_stats_get,
284         .stats_reset             = virtio_dev_stats_reset,
285         .link_update             = virtio_dev_link_update,
286         .mac_addr_add            = NULL,
287         .mac_addr_remove         = NULL,
288         .rx_queue_setup          = virtio_dev_rx_queue_setup,
289         /* meaningfull only to multiple queue */
290         .rx_queue_release        = virtio_dev_rx_queue_release,
291         .tx_queue_setup          = virtio_dev_tx_queue_setup,
292         /* meaningfull only to multiple queue */
293         .tx_queue_release        = virtio_dev_tx_queue_release,
294 };
295
296 static inline int
297 virtio_dev_atomic_read_link_status(struct rte_eth_dev *dev,
298                                 struct rte_eth_link *link)
299 {
300         struct rte_eth_link *dst = link;
301         struct rte_eth_link *src = &(dev->data->dev_link);
302
303         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
304                         *(uint64_t *)src) == 0)
305                 return (-1);
306
307         return (0);
308 }
309
310 /**
311  * Atomically writes the link status information into global
312  * structure rte_eth_dev.
313  *
314  * @param dev
315  *   - Pointer to the structure rte_eth_dev to read from.
316  *   - Pointer to the buffer to be saved with the link status.
317  *
318  * @return
319  *   - On success, zero.
320  *   - On failure, negative value.
321  */
322 static inline int
323 virtio_dev_atomic_write_link_status(struct rte_eth_dev *dev,
324                 struct rte_eth_link *link)
325 {
326         struct rte_eth_link *dst = &(dev->data->dev_link);
327         struct rte_eth_link *src = link;
328
329         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
330                                         *(uint64_t *)src) == 0)
331                 return (-1);
332
333         return (0);
334 }
335
336 static void
337 virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
338 {
339         struct virtio_hw *hw =
340                 VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
341         if(stats)
342                 memcpy(stats, &hw->eth_stats, sizeof(*stats));
343 }
344
345 static void
346 virtio_dev_stats_reset(struct rte_eth_dev *dev)
347 {
348         struct virtio_hw *hw =
349                 VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
350         /* Reset software totals */
351         memset(&hw->eth_stats, 0, sizeof(hw->eth_stats));
352 }
353
354 static void
355 virtio_set_hwaddr(struct virtio_hw *hw)
356 {
357         vtpci_write_dev_config(hw,
358                         offsetof(struct virtio_net_config, mac),
359                         &hw->mac_addr, ETHER_ADDR_LEN);
360 }
361
362 static void
363 virtio_get_hwaddr(struct virtio_hw *hw)
364 {
365         if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC)) {
366                 vtpci_read_dev_config(hw,
367                         offsetof(struct virtio_net_config, mac),
368                         &hw->mac_addr, ETHER_ADDR_LEN);
369         } else {
370                 eth_random_addr(&hw->mac_addr[0]);
371                 virtio_set_hwaddr(hw);
372         }
373 }
374
375
376 static void
377 virtio_negotiate_features(struct virtio_hw *hw)
378 {
379         uint32_t guest_features, mask;
380         mask = VIRTIO_NET_F_CTRL_VQ | VIRTIO_NET_F_CTRL_RX | VIRTIO_NET_F_CTRL_VLAN;
381         mask |= VIRTIO_NET_F_CSUM | VIRTIO_NET_F_GUEST_CSUM ;
382
383         /* TSO and LRO are only available when their corresponding
384          * checksum offload feature is also negotiated.
385          */
386         mask |= VIRTIO_NET_F_HOST_TSO4 | VIRTIO_NET_F_HOST_TSO6 | VIRTIO_NET_F_HOST_ECN;
387         mask |= VIRTIO_NET_F_GUEST_TSO4 | VIRTIO_NET_F_GUEST_TSO6 | VIRTIO_NET_F_GUEST_ECN;
388         mask |= VTNET_LRO_FEATURES;
389
390         /* rx_mbuf should not be in multiple merged segments */
391         mask |= VIRTIO_NET_F_MRG_RXBUF;
392
393         /* not negotiating INDIRECT descriptor table support */
394         mask |= VIRTIO_RING_F_INDIRECT_DESC;
395
396         /* Prepare guest_features: feature that driver wants to support */
397         guest_features = VTNET_FEATURES & ~mask;
398
399         /* Read device(host) feature bits */
400         hw->host_features = VIRTIO_READ_REG_4(hw, VIRTIO_PCI_HOST_FEATURES);
401
402         /* Negotiate features: Subset of device feature bits are written back (guest feature bits) */
403         hw->guest_features = vtpci_negotiate_features(hw, guest_features);
404 }
405
406 #ifdef RTE_EXEC_ENV_LINUXAPP
407 static int
408 parse_sysfs_value(const char *filename, unsigned long *val)
409 {
410         FILE *f;
411         char buf[BUFSIZ];
412         char *end = NULL;
413
414         if ((f = fopen(filename, "r")) == NULL) {
415                 PMD_INIT_LOG(ERR, "%s(): cannot open sysfs value %s\n",
416                              __func__, filename);
417                 return -1;
418         }
419
420         if (fgets(buf, sizeof(buf), f) == NULL) {
421                 PMD_INIT_LOG(ERR, "%s(): cannot read sysfs value %s\n",
422                              __func__, filename);
423                 fclose(f);
424                 return -1;
425         }
426         *val = strtoul(buf, &end, 0);
427         if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
428                 PMD_INIT_LOG(ERR, "%s(): cannot parse sysfs value %s\n",
429                              __func__, filename);
430                 fclose(f);
431                 return -1;
432         }
433         fclose(f);
434         return 0;
435 }
436
437 static int get_uio_dev(struct rte_pci_addr *loc, char *buf, unsigned int buflen)
438 {
439         unsigned int uio_num;
440         struct dirent *e;
441         DIR *dir;
442         char dirname[PATH_MAX];
443
444         /* depending on kernel version, uio can be located in uio/uioX
445          * or uio:uioX */
446         rte_snprintf(dirname, sizeof(dirname),
447                  SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/uio",
448                  loc->domain, loc->bus, loc->devid, loc->function);
449         dir = opendir(dirname);
450         if (dir == NULL) {
451                 /* retry with the parent directory */
452                 rte_snprintf(dirname, sizeof(dirname),
453                          SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
454                          loc->domain, loc->bus, loc->devid, loc->function);
455                 dir = opendir(dirname);
456
457                 if (dir == NULL) {
458                         PMD_INIT_LOG(ERR, "Cannot opendir %s\n", dirname);
459                         return -1;
460                 }
461         }
462
463         /* take the first file starting with "uio" */
464         while ((e = readdir(dir)) != NULL) {
465                 /* format could be uio%d ...*/
466                 int shortprefix_len = sizeof("uio") - 1;
467                 /* ... or uio:uio%d */
468                 int longprefix_len = sizeof("uio:uio") - 1;
469                 char *endptr;
470
471                 if (strncmp(e->d_name, "uio", 3) != 0)
472                         continue;
473
474                 /* first try uio%d */
475                 errno = 0;
476                 uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
477                 if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
478                         rte_snprintf(buf, buflen, "%s/uio%u", dirname, uio_num);
479                         break;
480                 }
481
482                 /* then try uio:uio%d */
483                 errno = 0;
484                 uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
485                 if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
486                         rte_snprintf(buf, buflen, "%s/uio:uio%u", dirname,
487                                      uio_num);
488                         break;
489                 }
490         }
491         closedir(dir);
492
493         /* No uio resource found */
494         if (e == NULL) {
495                 PMD_INIT_LOG(ERR, "Could not find uio resource\n");
496                 return -1;
497         }
498
499         return 0;
500 }
501 #endif
502
503 /*
504  * This function is based on probe() function in virtio_pci.c
505  * It returns 0 on success.
506  */
507 static int
508 eth_virtio_dev_init(__rte_unused struct eth_driver *eth_drv,
509                 struct rte_eth_dev *eth_dev)
510 {
511         struct rte_pci_device *pci_dev;
512         struct virtio_hw *hw =
513                 VIRTIO_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
514         if (RTE_PKTMBUF_HEADROOM < sizeof(struct virtio_net_hdr) ) {
515                 PMD_INIT_LOG(ERR, 
516                         "MBUF HEADROOM should be enough to hold virtio net hdr\n");
517                 return (-1); 
518         }
519
520         if (! (rte_eal_get_configuration()->flags & EAL_FLG_HIGH_IOPL)) {
521                 PMD_INIT_LOG(ERR,
522                         "IOPL call failed in EAL init - cannot use virtio PMD driver\n");
523                 return (-1);
524         }
525
526         eth_dev->dev_ops = &virtio_eth_dev_ops;
527         eth_dev->rx_pkt_burst = &virtio_recv_pkts;
528         eth_dev->tx_pkt_burst = &virtio_xmit_pkts;
529
530         if(rte_eal_process_type() == RTE_PROC_SECONDARY)
531                 return 0;
532
533         pci_dev = eth_dev->pci_dev;
534
535         hw->device_id = pci_dev->id.device_id;
536         hw->vendor_id = pci_dev->id.vendor_id;
537 #ifdef RTE_EXEC_ENV_LINUXAPP
538         {
539                 char dirname[PATH_MAX];
540                 char filename[PATH_MAX];
541                 unsigned long start,size;
542
543                 if (get_uio_dev(&pci_dev->addr, dirname, sizeof(dirname)) < 0)
544                         return -1;
545
546                 /* get portio size */
547                 rte_snprintf(filename, sizeof(filename),
548                              "%s/portio/port0/size", dirname);
549                 if (parse_sysfs_value(filename, &size) < 0) {
550                         PMD_INIT_LOG(ERR, "%s(): cannot parse size\n",
551                                      __func__);
552                         return -1;
553                 }
554
555                 /* get portio start */
556                 rte_snprintf(filename, sizeof(filename),
557                              "%s/portio/port0/start", dirname);
558                 if (parse_sysfs_value(filename, &start) < 0) {
559                         PMD_INIT_LOG(ERR, "%s(): cannot parse portio start\n",
560                                      __func__);
561                         return -1;
562                 }
563                 pci_dev->mem_resource[0].addr = (void *)(uintptr_t)start;
564                 pci_dev->mem_resource[0].len =  (uint64_t)size;
565                 PMD_INIT_LOG(DEBUG, "PCI Port IO found start=0x%lx with "
566                              "size=0x%lx\n", start, size);
567         }
568 #endif
569         hw->io_base = (uint32_t)(uintptr_t)pci_dev->mem_resource[0].addr;
570
571         hw->max_rx_queues = VIRTIO_MAX_RX_QUEUES;
572         hw->max_tx_queues = VIRTIO_MAX_TX_QUEUES;
573
574         /* Reset the device although not necessary at startup */
575         vtpci_reset(hw);
576
577         /* Tell the host we've noticed this device. */
578         vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
579
580         /* Tell the host we've known how to drive the device. */
581         vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
582         virtio_negotiate_features(hw);
583
584         /* Setting up rx_header size for the device */
585         if(vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))
586                 hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
587         else
588                 hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
589
590         /* Allocate memory for storing MAC addresses */
591         eth_dev->data->mac_addrs = rte_zmalloc("virtio", ETHER_ADDR_LEN, 0);
592         if (eth_dev->data->mac_addrs == NULL) {
593                 PMD_INIT_LOG(ERR,
594                         "Failed to allocate %d bytes needed to store MAC addresses",
595                         ETHER_ADDR_LEN);
596                 return (-ENOMEM);
597         }
598
599         /* Copy the permanent MAC address to: virtio_hw */
600         virtio_get_hwaddr(hw);
601         ether_addr_copy((struct ether_addr *) hw->mac_addr,
602                         &eth_dev->data->mac_addrs[0]);
603         PMD_INIT_LOG(DEBUG, "PORT MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", hw->mac_addr[0],
604                         hw->mac_addr[1],hw->mac_addr[2], hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
605
606         if(vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
607                 virtio_dev_cq_queue_setup(eth_dev, SOCKET_ID_ANY);
608
609         PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
610                         eth_dev->data->port_id, pci_dev->id.vendor_id,
611                         pci_dev->id.device_id);
612         return 0;
613 }
614
615 static struct eth_driver rte_virtio_pmd = {
616         {
617                 .name = "rte_virtio_pmd",
618                 .id_table = pci_id_virtio_map,
619         },
620         .eth_dev_init = eth_virtio_dev_init,
621         .dev_private_size = sizeof(struct virtio_adapter),
622 };
623
624 /*
625  * Driver initialization routine.
626  * Invoked once at EAL init time.
627  * Register itself as the [Poll Mode] Driver of PCI virtio devices.
628  * Returns 0 on success.
629  */
630 static int
631 rte_virtio_pmd_init(const char *name __rte_unused, const char *param __rte_unused)
632 {
633         rte_eth_driver_register(&rte_virtio_pmd);
634         return (0);
635 }
636
637 /*
638  * Only 1 queue is supported, no queue release related operation
639  */
640 static void
641 virtio_dev_rx_queue_release(__rte_unused void *rxq)
642 {
643 }
644
645 static void
646 virtio_dev_tx_queue_release(__rte_unused void *txq)
647 {
648 }
649
650 /*
651  * Configure virtio device
652  * It returns 0 on success.
653  */
654 static int
655 virtio_dev_configure(__rte_unused struct rte_eth_dev *dev)
656 {
657         return (0);
658 }
659
660
661 static int
662 virtio_dev_start(struct rte_eth_dev *dev)
663 {
664         uint16_t status;
665         struct virtio_hw *hw =
666                 VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
667
668         /* Tell the host we've noticed this device. */
669         vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
670
671         /* Tell the host we've known how to drive the device. */
672         vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
673
674         hw->adapter_stopped = 0;
675
676         /* Do final configuration before rx/tx engine starts */
677         virtio_dev_rxtx_start(dev);
678
679         /* Check VIRTIO_NET_F_STATUS for link status*/
680         if(vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
681                 vtpci_read_dev_config(hw,
682                                 offsetof(struct virtio_net_config, status),
683                                 &status, sizeof(status));
684                 if((status & VIRTIO_NET_S_LINK_UP) == 0) {
685                         PMD_INIT_LOG(ERR,     "Port: %d Link is DOWN\n", dev->data->port_id);
686                         return (-EIO);
687                 } else {
688                         PMD_INIT_LOG(DEBUG, "Port: %d Link is UP\n",  dev->data->port_id);
689                 }
690         }
691         vtpci_reinit_complete(hw);
692
693         /*Notify the backend
694          *Otherwise the tap backend might already stop its queue due to fullness.
695          *vhost backend will have no chance to be waked up
696          */
697         virtqueue_notify(dev->data->rx_queues[0]);
698         PMD_INIT_LOG(DEBUG, "Notified backend at initialization\n");
699         return (0);
700 }
701
702 static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
703 {
704         struct rte_mbuf * buf;
705         int i = 0;
706         PMD_INIT_LOG(DEBUG, "Before freeing rxq used and unused buf \n");
707         VIRTQUEUE_DUMP((struct virtqueue *)dev->data->rx_queues[0]);
708         while( (buf =(struct rte_mbuf *)virtqueue_detatch_unused(dev->data->rx_queues[0])) != NULL) {
709                 rte_pktmbuf_free_seg(buf);
710                 i++;
711         }
712         PMD_INIT_LOG(DEBUG, "free %d mbufs\n", i);
713         PMD_INIT_LOG(DEBUG, "After freeing rxq used and unused buf\n");
714         VIRTQUEUE_DUMP((struct virtqueue *)dev->data->rx_queues[0]);
715         PMD_INIT_LOG(DEBUG, "Before freeing txq used and unused bufs\n");
716         VIRTQUEUE_DUMP((struct virtqueue *)dev->data->tx_queues[0]);
717         i = 0;
718         while( (buf = (struct rte_mbuf *)virtqueue_detatch_unused(dev->data->tx_queues[0])) != NULL) {
719                 rte_pktmbuf_free_seg(buf);
720                 i++;
721         }
722         PMD_INIT_LOG(DEBUG, "free %d mbufs\n", i);
723         PMD_INIT_LOG(DEBUG, "After freeing txq used and unused buf\n");
724         VIRTQUEUE_DUMP((struct virtqueue *)dev->data->tx_queues[0]);
725 }
726
727 /*
728  * Stop device: disable rx and tx functions to allow for reconfiguring.
729  */
730 static void
731 virtio_dev_stop(struct rte_eth_dev *dev)
732 {
733         struct virtio_hw *hw =
734                 VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
735
736         /* reset the NIC */
737         vtpci_reset(hw);
738         virtio_dev_free_mbufs(dev);
739 }
740
741 static int
742 virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
743 {
744         struct rte_eth_link link, old;
745         uint16_t status;
746         struct virtio_hw *hw =
747                 VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
748         memset(&link, 0, sizeof(link));
749         virtio_dev_atomic_read_link_status(dev, &link);
750         old = link;
751         link.link_duplex = FULL_DUPLEX ;
752         link.link_speed  = SPEED_10G ;
753         if(vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
754                 PMD_INIT_LOG(DEBUG, "Get link status from hw\n");
755                 vtpci_read_dev_config(hw,
756                                 offsetof(struct virtio_net_config, status),
757                                 &status, sizeof(status));
758                 if((status & VIRTIO_NET_S_LINK_UP) == 0) {
759                         link.link_status = 0;
760                         PMD_INIT_LOG(DEBUG, "Port %d is down\n",dev->data->port_id);
761                 } else {
762                         link.link_status = 1;
763                         PMD_INIT_LOG(DEBUG, "Port %d is up\n",dev->data->port_id);
764                 }
765         } else {
766                 link.link_status = 1;   //Link up
767         }
768         virtio_dev_atomic_write_link_status(dev, &link);
769         if(old.link_status == link.link_status)
770                 return (-1);
771         /*changed*/
772         return (0);
773 }
774
775 static void
776 virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
777 {
778         struct virtio_hw *hw = VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
779         dev_info->driver_name = dev->driver->pci_drv.name;
780         dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
781         dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
782         dev_info->min_rx_bufsize = VIRTIO_MIN_RX_BUFSIZE;
783         dev_info->max_rx_pktlen = VIRTIO_MAX_RX_PKTLEN;
784         dev_info->max_mac_addrs = VIRTIO_MAX_MAC_ADDRS;
785 }
786
787 static struct rte_driver rte_virtio_driver = {
788         .type = PMD_PDEV,
789         .init = rte_virtio_pmd_init,
790 };
791
792 PMD_REGISTER_DRIVER(rte_virtio_driver);