]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/pci_virtio_net.c
Use a separate mutex for the receive path instead of overloading the softc
[FreeBSD/FreeBSD.git] / usr.sbin / bhyve / pci_virtio_net.c
1 /*-
2  * Copyright (c) 2011 NetApp, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/linker_set.h>
34 #include <sys/select.h>
35 #include <sys/uio.h>
36 #include <sys/ioctl.h>
37
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <stdint.h>
43 #include <string.h>
44 #include <strings.h>
45 #include <unistd.h>
46 #include <assert.h>
47 #include <md5.h>
48 #include <pthread.h>
49 #include <pthread_np.h>
50
51 #include "bhyverun.h"
52 #include "pci_emul.h"
53 #include "mevent.h"
54 #include "virtio.h"
55
56 #define VTNET_RINGSZ    1024
57
58 #define VTNET_MAXSEGS   32
59
60 /*
61  * PCI config-space register offsets
62  */
63 #define VTNET_R_CFG0    24
64 #define VTNET_R_CFG1    25
65 #define VTNET_R_CFG2    26
66 #define VTNET_R_CFG3    27
67 #define VTNET_R_CFG4    28
68 #define VTNET_R_CFG5    29
69 #define VTNET_R_CFG6    30
70 #define VTNET_R_CFG7    31
71 #define VTNET_R_MAX     31
72
73 #define VTNET_REGSZ     VTNET_R_MAX+1
74
75 /*
76  * Host capabilities
77  */
78 #define VTNET_S_HOSTCAPS      \
79   ( 0x00000020 |        /* host supplies MAC */ \
80     0x00008000 |        /* host can merge Rx buffers */ \
81     0x00010000 )        /* config status available */
82
83 /*
84  * Queue definitions.
85  */
86 #define VTNET_RXQ       0
87 #define VTNET_TXQ       1
88 #define VTNET_CTLQ      2
89
90 #define VTNET_MAXQ      3
91
92 static int use_msix = 1;
93
94 struct vring_hqueue {
95         /* Internal state */
96         uint16_t        hq_size;
97         uint16_t        hq_cur_aidx;            /* trails behind 'avail_idx' */
98
99          /* Host-context pointers to the queue */
100         struct virtio_desc *hq_dtable;
101         uint16_t        *hq_avail_flags;
102         uint16_t        *hq_avail_idx;          /* monotonically increasing */
103         uint16_t        *hq_avail_ring;
104
105         uint16_t        *hq_used_flags;
106         uint16_t        *hq_used_idx;           /* monotonically increasing */
107         struct virtio_used *hq_used_ring;
108 };
109
110 /*
111  * Fixed network header size
112  */
113 struct virtio_net_rxhdr {
114         uint8_t         vrh_flags;
115         uint8_t         vrh_gso_type;
116         uint16_t        vrh_hdr_len;
117         uint16_t        vrh_gso_size;
118         uint16_t        vrh_csum_start;
119         uint16_t        vrh_csum_offset;
120         uint16_t        vrh_bufs;
121 } __packed;
122
123 /*
124  * Debug printf
125  */
126 static int pci_vtnet_debug;
127 #define DPRINTF(params) if (pci_vtnet_debug) printf params
128 #define WPRINTF(params) printf params
129
130 /*
131  * Per-device softc
132  */
133 struct pci_vtnet_softc {
134         struct pci_devinst *vsc_pi;
135         pthread_mutex_t vsc_mtx;
136         struct mevent   *vsc_mevp;
137
138         int             vsc_curq;
139         int             vsc_status;
140         int             vsc_isr;
141         int             vsc_tapfd;
142         int             vsc_rx_ready;
143         int             resetting;
144
145         uint32_t        vsc_features;
146         uint8_t         vsc_macaddr[6];
147
148         uint64_t        vsc_pfn[VTNET_MAXQ];
149         struct  vring_hqueue vsc_hq[VTNET_MAXQ];
150         uint16_t        vsc_msix_table_idx[VTNET_MAXQ];
151
152         pthread_mutex_t rx_mtx;
153         int             rx_in_progress;
154
155         pthread_t       tx_tid;
156         pthread_mutex_t tx_mtx;
157         pthread_cond_t  tx_cond;
158         int             tx_in_progress;
159 };
160 #define vtnet_ctx(sc)   ((sc)->vsc_pi->pi_vmctx)
161
162 /*
163  * Return the size of IO BAR that maps virtio header and device specific
164  * region. The size would vary depending on whether MSI-X is enabled or
165  * not.
166  */
167 static uint64_t
168 pci_vtnet_iosize(struct pci_devinst *pi)
169 {
170         if (pci_msix_enabled(pi))
171                 return (VTNET_REGSZ);
172         else
173                 return (VTNET_REGSZ - (VTCFG_R_CFG1 - VTCFG_R_MSIX));
174 }
175
176 /*
177  * Return the number of available descriptors in the vring taking care
178  * of the 16-bit index wraparound.
179  */
180 static int
181 hq_num_avail(struct vring_hqueue *hq)
182 {
183         uint16_t ndesc;
184
185         /*
186          * We're just computing (a-b) mod 2^16
187          *
188          * The only glitch here is that in standard C,
189          * uint16_t promotes to (signed) int when int has
190          * more than 16 bits (pretty much always now), so
191          * we have to force it back to unsigned.
192          */
193         ndesc = (unsigned)*hq->hq_avail_idx - (unsigned)hq->hq_cur_aidx;
194
195         assert(ndesc <= hq->hq_size);
196
197         return (ndesc);
198 }
199
200 static uint16_t
201 pci_vtnet_qsize(int qnum)
202 {
203         /* XXX no ctl queue currently */
204         if (qnum == VTNET_CTLQ) {
205                 return (0);
206         }
207
208         /* XXX fixed currently. Maybe different for tx/rx/ctl */
209         return (VTNET_RINGSZ);
210 }
211
212 static void
213 pci_vtnet_ring_reset(struct pci_vtnet_softc *sc, int ring)
214 {
215         struct vring_hqueue *hq;
216
217         assert(ring < VTNET_MAXQ);
218
219         hq = &sc->vsc_hq[ring];
220
221         /*
222          * Reset all soft state
223          */
224         hq->hq_cur_aidx = 0;
225 }
226
227 /*
228  * If the transmit thread is active then stall until it is done.
229  */
230 static void
231 pci_vtnet_txwait(struct pci_vtnet_softc *sc)
232 {
233
234         pthread_mutex_lock(&sc->tx_mtx);
235         while (sc->tx_in_progress) {
236                 pthread_mutex_unlock(&sc->tx_mtx);
237                 usleep(10000);
238                 pthread_mutex_lock(&sc->tx_mtx);
239         }
240         pthread_mutex_unlock(&sc->tx_mtx);
241 }
242
243 /*
244  * If the receive thread is active then stall until it is done.
245  */
246 static void
247 pci_vtnet_rxwait(struct pci_vtnet_softc *sc)
248 {
249
250         pthread_mutex_lock(&sc->rx_mtx);
251         while (sc->rx_in_progress) {
252                 pthread_mutex_unlock(&sc->rx_mtx);
253                 usleep(10000);
254                 pthread_mutex_lock(&sc->rx_mtx);
255         }
256         pthread_mutex_unlock(&sc->rx_mtx);
257 }
258
259 static void
260 pci_vtnet_update_status(struct pci_vtnet_softc *sc, uint32_t value)
261 {
262
263         if (value == 0) {
264                 DPRINTF(("vtnet: device reset requested !\n"));
265                 
266                 sc->resetting = 1;
267
268                 /*
269                  * Wait for the transmit and receive threads to finish their
270                  * processing.
271                  */
272                 pci_vtnet_txwait(sc);
273                 pci_vtnet_rxwait(sc);
274
275                 sc->vsc_rx_ready = 0;
276                 pci_vtnet_ring_reset(sc, VTNET_RXQ);
277                 pci_vtnet_ring_reset(sc, VTNET_TXQ);
278
279                 sc->resetting = 0;
280         }
281
282         sc->vsc_status = value;
283 }
284
285 /*
286  * Called to send a buffer chain out to the tap device
287  */
288 static void
289 pci_vtnet_tap_tx(struct pci_vtnet_softc *sc, struct iovec *iov, int iovcnt,
290                  int len)
291 {
292         char pad[60];
293
294         if (sc->vsc_tapfd == -1)
295                 return;
296
297         /*
298          * If the length is < 60, pad out to that and add the
299          * extra zero'd segment to the iov. It is guaranteed that
300          * there is always an extra iov available by the caller.
301          */
302         if (len < 60) {
303                 memset(pad, 0, 60 - len);
304                 iov[iovcnt].iov_base = pad;
305                 iov[iovcnt].iov_len = 60 - len;
306                 iovcnt++;
307         }
308         (void) writev(sc->vsc_tapfd, iov, iovcnt);
309 }
310
311 /*
312  *  Called when there is read activity on the tap file descriptor.
313  * Each buffer posted by the guest is assumed to be able to contain
314  * an entire ethernet frame + rx header.
315  *  MP note: the dummybuf is only used for discarding frames, so there
316  * is no need for it to be per-vtnet or locked.
317  */
318 static uint8_t dummybuf[2048];
319
320 static void
321 pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
322 {
323         struct virtio_desc *vd;
324         struct virtio_used *vu;
325         struct vring_hqueue *hq;
326         struct virtio_net_rxhdr *vrx;
327         uint8_t *buf;
328         int i;
329         int len;
330         int ndescs;
331         int didx, uidx, aidx;   /* descriptor, avail and used index */
332
333         /*
334          * Should never be called without a valid tap fd
335          */
336         assert(sc->vsc_tapfd != -1);
337
338         /*
339          * But, will be called when the rx ring hasn't yet
340          * been set up or the guest is resetting the device.
341          */
342         if (!sc->vsc_rx_ready || sc->resetting) {
343                 /*
344                  * Drop the packet and try later.
345                  */
346                 (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf));
347                 return;
348         }
349
350         /*
351          * Calculate the number of available rx buffers
352          */
353         hq = &sc->vsc_hq[VTNET_RXQ];
354
355         ndescs = hq_num_avail(hq);
356
357         if (ndescs == 0) {
358                 /*
359                  * Drop the packet and try later
360                  */
361                 (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf));
362                 return;
363         }
364
365         aidx = hq->hq_cur_aidx;
366         uidx = *hq->hq_used_idx;
367         for (i = 0; i < ndescs; i++) {
368                 /*
369                  * 'aidx' indexes into the an array of descriptor indexes
370                  */
371                 didx = hq->hq_avail_ring[aidx % hq->hq_size];
372                 assert(didx >= 0 && didx < hq->hq_size);
373
374                 vd = &hq->hq_dtable[didx];
375
376                 /*
377                  * Get a pointer to the rx header, and use the
378                  * data immediately following it for the packet buffer.
379                  */
380                 vrx = paddr_guest2host(vtnet_ctx(sc), vd->vd_addr, vd->vd_len);
381                 buf = (uint8_t *)(vrx + 1);
382
383                 len = read(sc->vsc_tapfd, buf,
384                            vd->vd_len - sizeof(struct virtio_net_rxhdr));
385
386                 if (len < 0 && errno == EWOULDBLOCK) {
387                         break;
388                 }
389
390                 /*
391                  * The only valid field in the rx packet header is the
392                  * number of buffers, which is always 1 without TSO
393                  * support.
394                  */
395                 memset(vrx, 0, sizeof(struct virtio_net_rxhdr));
396                 vrx->vrh_bufs = 1;
397
398                 /*
399                  * Write this descriptor into the used ring
400                  */
401                 vu = &hq->hq_used_ring[uidx % hq->hq_size];
402                 vu->vu_idx = didx;
403                 vu->vu_tlen = len + sizeof(struct virtio_net_rxhdr);
404                 uidx++;
405                 aidx++;
406         }
407
408         /*
409          * Update the used pointer, and signal an interrupt if allowed
410          */
411         *hq->hq_used_idx = uidx;
412         hq->hq_cur_aidx = aidx;
413
414         if ((*hq->hq_avail_flags & VRING_AVAIL_F_NO_INTERRUPT) == 0) {
415                 if (use_msix) {
416                         pci_generate_msix(sc->vsc_pi,
417                                           sc->vsc_msix_table_idx[VTNET_RXQ]);
418                 } else {
419                         sc->vsc_isr |= 1;
420                         pci_generate_msi(sc->vsc_pi, 0);
421                 }
422         }
423 }
424
425 static void
426 pci_vtnet_tap_callback(int fd, enum ev_type type, void *param)
427 {
428         struct pci_vtnet_softc *sc = param;
429
430         pthread_mutex_lock(&sc->rx_mtx);
431         sc->rx_in_progress = 1;
432         pci_vtnet_tap_rx(sc);
433         sc->rx_in_progress = 0;
434         pthread_mutex_unlock(&sc->rx_mtx);
435
436 }
437
438 static void
439 pci_vtnet_ping_rxq(struct pci_vtnet_softc *sc)
440 {
441         /*
442          * A qnotify means that the rx process can now begin
443          */
444         if (sc->vsc_rx_ready == 0) {
445                 sc->vsc_rx_ready = 1;
446         }
447 }
448
449 static void
450 pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vring_hqueue *hq)
451 {
452         struct iovec iov[VTNET_MAXSEGS + 1];
453         struct virtio_desc *vd;
454         struct virtio_used *vu;
455         int i;
456         int plen;
457         int tlen;
458         int uidx, aidx, didx;
459
460         uidx = *hq->hq_used_idx;
461         aidx = hq->hq_cur_aidx;
462         didx = hq->hq_avail_ring[aidx % hq->hq_size];
463         assert(didx >= 0 && didx < hq->hq_size);
464
465         vd = &hq->hq_dtable[didx];
466
467         /*
468          * Run through the chain of descriptors, ignoring the
469          * first header descriptor. However, include the header
470          * length in the total length that will be put into the
471          * used queue.
472          */
473         tlen = vd->vd_len;
474         vd = &hq->hq_dtable[vd->vd_next];
475
476         for (i = 0, plen = 0;
477              i < VTNET_MAXSEGS;
478              i++, vd = &hq->hq_dtable[vd->vd_next]) {
479                 iov[i].iov_base = paddr_guest2host(vtnet_ctx(sc),
480                                                    vd->vd_addr, vd->vd_len);
481                 iov[i].iov_len = vd->vd_len;
482                 plen += vd->vd_len;
483                 tlen += vd->vd_len;
484
485                 if ((vd->vd_flags & VRING_DESC_F_NEXT) == 0)
486                         break;
487         }
488         assert(i < VTNET_MAXSEGS);
489
490         DPRINTF(("virtio: packet send, %d bytes, %d segs\n\r", plen, i + 1));
491         pci_vtnet_tap_tx(sc, iov, i + 1, plen);
492
493         /*
494          * Return this chain back to the host
495          */
496         vu = &hq->hq_used_ring[uidx % hq->hq_size];
497         vu->vu_idx = didx;
498         vu->vu_tlen = tlen;
499         hq->hq_cur_aidx = aidx + 1;
500         *hq->hq_used_idx = uidx + 1;
501 }
502
503 static void
504 pci_vtnet_ping_txq(struct pci_vtnet_softc *sc)
505 {
506         struct vring_hqueue *hq = &sc->vsc_hq[VTNET_TXQ];
507         int ndescs;
508
509         /*
510          * Calculate number of ring entries to process
511          */
512         ndescs = hq_num_avail(hq);
513
514         if (ndescs == 0)
515                 return;
516
517         /* Signal the tx thread for processing */
518         pthread_mutex_lock(&sc->tx_mtx);
519         if (sc->tx_in_progress == 0)
520                 pthread_cond_signal(&sc->tx_cond);
521         pthread_mutex_unlock(&sc->tx_mtx);
522 }
523
524 /*
525  * Thread which will handle processing of TX desc
526  */
527 static void *
528 pci_vtnet_tx_thread(void *param)
529 {
530         struct pci_vtnet_softc *sc = (struct pci_vtnet_softc *) param;
531         struct vring_hqueue *hq; 
532         int i, ndescs, needintr,error;
533         
534         needintr = 0;
535         hq = &sc->vsc_hq[VTNET_TXQ];
536         
537         /* 
538          * Let us wait till the tx queue pointers get initialised & 
539          * first tx signaled 
540          */
541         pthread_mutex_lock(&sc->tx_mtx);
542         error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx);
543         assert(error == 0);
544         
545         for (;;) {
546                 pthread_mutex_lock(&sc->tx_mtx);
547                 for (;;) {
548                         if (sc->resetting) {
549                                 ndescs = 0;
550                                 needintr = 0;
551                         } else
552                                 ndescs = hq_num_avail(hq);
553                         
554                         if (ndescs != 0) 
555                                 break;
556                         
557                         if (needintr) {
558                                 /*
559                                  * Generate an interrupt if able
560                                  */
561                                 if ((*hq->hq_avail_flags &
562                                      VRING_AVAIL_F_NO_INTERRUPT) == 0) {
563                                         if (use_msix) {
564                                                 pci_generate_msix(sc->vsc_pi,
565                                                      sc->vsc_msix_table_idx[VTNET_TXQ]);
566                                         } else {
567                                                 sc->vsc_isr |= 1;
568                                                 pci_generate_msi(sc->vsc_pi, 0);
569                                         }
570                                 }
571                         }
572                         needintr = 0;
573                         sc->tx_in_progress = 0;
574                         error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx);
575                         assert(error == 0);
576                 }
577                 sc->tx_in_progress = 1;
578                 pthread_mutex_unlock(&sc->tx_mtx);
579
580                 while (ndescs > 0) {
581                         /*
582                          * Run through all the entries, placing them into
583                          * iovecs and sending when an end-of-packet is found
584                          */
585                         for (i = 0; i < ndescs; i++)
586                                 pci_vtnet_proctx(sc, hq);
587                         needintr = 1;
588                         ndescs = hq_num_avail(hq);
589                 }
590         }
591 }       
592
593 static void
594 pci_vtnet_ping_ctlq(struct pci_vtnet_softc *sc)
595 {
596
597         DPRINTF(("vtnet: control qnotify!\n\r"));       
598 }
599
600 static void
601 pci_vtnet_ring_init(struct pci_vtnet_softc *sc, uint64_t pfn)
602 {
603         struct vring_hqueue *hq;
604         int qnum = sc->vsc_curq;
605
606         assert(qnum < VTNET_MAXQ);
607
608         sc->vsc_pfn[qnum] = pfn << VRING_PFN;
609         
610         /*
611          * Set up host pointers to the various parts of the
612          * queue
613          */
614         hq = &sc->vsc_hq[qnum];
615         hq->hq_size = pci_vtnet_qsize(qnum);
616
617         hq->hq_dtable = paddr_guest2host(vtnet_ctx(sc), pfn << VRING_PFN,
618                                          vring_size(hq->hq_size));
619         hq->hq_avail_flags =  (uint16_t *)(hq->hq_dtable + hq->hq_size);
620         hq->hq_avail_idx = hq->hq_avail_flags + 1;
621         hq->hq_avail_ring = hq->hq_avail_flags + 2;
622         hq->hq_used_flags = (uint16_t *)roundup2((uintptr_t)hq->hq_avail_ring,
623                                                  VRING_ALIGN);
624         hq->hq_used_idx = hq->hq_used_flags + 1;
625         hq->hq_used_ring = (struct virtio_used *)(hq->hq_used_flags + 2);
626
627         /*
628          * Initialize queue indexes
629          */
630         hq->hq_cur_aidx = 0;
631 }
632
633 static int
634 pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
635 {
636         MD5_CTX mdctx;
637         unsigned char digest[16];
638         char nstr[80];
639         char tname[MAXCOMLEN + 1];
640         struct pci_vtnet_softc *sc;
641         const char *env_msi;
642
643         sc = malloc(sizeof(struct pci_vtnet_softc));
644         memset(sc, 0, sizeof(struct pci_vtnet_softc));
645
646         pi->pi_arg = sc;
647         sc->vsc_pi = pi;
648
649         pthread_mutex_init(&sc->vsc_mtx, NULL);
650  
651         /*
652          * Use MSI if set by user
653          */
654         if ((env_msi = getenv("BHYVE_USE_MSI")) != NULL) {
655                 if (strcasecmp(env_msi, "yes") == 0)
656                         use_msix = 0;
657         }
658
659         /*
660          * Attempt to open the tap device
661          */
662         sc->vsc_tapfd = -1;
663         if (opts != NULL) {
664                 char tbuf[80];
665
666                 strcpy(tbuf, "/dev/");
667                 strlcat(tbuf, opts, sizeof(tbuf));
668
669                 sc->vsc_tapfd = open(tbuf, O_RDWR);
670                 if (sc->vsc_tapfd == -1) {
671                         WPRINTF(("open of tap device %s failed\n", tbuf));
672                 } else {
673                         /*
674                          * Set non-blocking and register for read
675                          * notifications with the event loop
676                          */
677                         int opt = 1;
678                         if (ioctl(sc->vsc_tapfd, FIONBIO, &opt) < 0) {
679                                 WPRINTF(("tap device O_NONBLOCK failed\n"));
680                                 close(sc->vsc_tapfd);
681                                 sc->vsc_tapfd = -1;
682                         }
683
684                         sc->vsc_mevp = mevent_add(sc->vsc_tapfd,
685                                                   EVF_READ,
686                                                   pci_vtnet_tap_callback,
687                                                   sc);
688                         if (sc->vsc_mevp == NULL) {
689                                 WPRINTF(("Could not register event\n"));
690                                 close(sc->vsc_tapfd);
691                                 sc->vsc_tapfd = -1;
692                         }
693                 }               
694         }
695
696         /*
697          * The MAC address is the standard NetApp OUI of 00-a0-98,
698          * followed by an MD5 of the vm name. The slot/func number is
699          * prepended to this for slots other than 1:0, so that 
700          * a bootloader can netboot from the equivalent of slot 1.
701          */
702         if (pi->pi_slot == 1 && pi->pi_func == 0) {
703                 strncpy(nstr, vmname, sizeof(nstr));
704         } else {
705                 snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot,
706                     pi->pi_func, vmname);
707         }
708
709         MD5Init(&mdctx);
710         MD5Update(&mdctx, nstr, strlen(nstr));
711         MD5Final(digest, &mdctx);
712
713         sc->vsc_macaddr[0] = 0x00;
714         sc->vsc_macaddr[1] = 0xa0;
715         sc->vsc_macaddr[2] = 0x98;
716         sc->vsc_macaddr[3] = digest[0];
717         sc->vsc_macaddr[4] = digest[1];
718         sc->vsc_macaddr[5] = digest[2];
719
720         /* initialize config space */
721         pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_NET);
722         pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR);
723         pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK);
724         pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET);
725         
726         if (use_msix) {
727                 /* MSI-X support */
728                 int i;
729
730                 for (i = 0; i < VTNET_MAXQ; i++)
731                         sc->vsc_msix_table_idx[i] = VIRTIO_MSI_NO_VECTOR;
732
733                 /*
734                  * BAR 1 used to map MSI-X table and PBA
735                  */
736                 if (pci_emul_add_msixcap(pi, VTNET_MAXQ, 1))
737                         return (1);
738         } else {
739                 /* MSI support */
740                 pci_emul_add_msicap(pi, 1);
741         }
742         
743         pci_emul_alloc_bar(pi, 0, PCIBAR_IO, VTNET_REGSZ);
744
745         sc->resetting = 0;
746
747         sc->rx_in_progress = 0;
748         pthread_mutex_init(&sc->rx_mtx, NULL); 
749
750         /* 
751          * Initialize tx semaphore & spawn TX processing thread
752          * As of now, only one thread for TX desc processing is
753          * spawned. 
754          */
755         sc->tx_in_progress = 0;
756         pthread_mutex_init(&sc->tx_mtx, NULL);
757         pthread_cond_init(&sc->tx_cond, NULL);
758         pthread_create(&sc->tx_tid, NULL, pci_vtnet_tx_thread, (void *)sc);
759         snprintf(tname, sizeof(tname), "%s vtnet%d tx", vmname, pi->pi_slot);
760         pthread_set_name_np(sc->tx_tid, tname);
761
762         return (0);
763 }
764
765 /*
766  * Function pointer array to handle queue notifications
767  */
768 static void (*pci_vtnet_qnotify[VTNET_MAXQ])(struct pci_vtnet_softc *) = {
769         pci_vtnet_ping_rxq,
770         pci_vtnet_ping_txq,
771         pci_vtnet_ping_ctlq
772 };
773
774 static uint64_t
775 vtnet_adjust_offset(struct pci_devinst *pi, uint64_t offset)
776 {
777         /*
778          * Device specific offsets used by guest would change based on
779          * whether MSI-X capability is enabled or not
780          */
781         if (!pci_msix_enabled(pi)) {
782                 if (offset >= VTCFG_R_MSIX)
783                         return (offset + (VTCFG_R_CFG1 - VTCFG_R_MSIX));
784         }
785
786         return (offset);
787 }
788
789 static void
790 pci_vtnet_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
791                 int baridx, uint64_t offset, int size, uint64_t value)
792 {
793         struct pci_vtnet_softc *sc = pi->pi_arg;
794         void *ptr;
795
796         if (use_msix) {
797                 if (baridx == pci_msix_table_bar(pi) ||
798                     baridx == pci_msix_pba_bar(pi)) {
799                         pci_emul_msix_twrite(pi, offset, size, value);
800                         return;
801                 }
802         }
803
804         assert(baridx == 0);
805
806         if (offset + size > pci_vtnet_iosize(pi)) {
807                 DPRINTF(("vtnet_write: 2big, offset %ld size %d\n",
808                          offset, size));
809                 return;
810         }
811
812         pthread_mutex_lock(&sc->vsc_mtx);
813
814         offset = vtnet_adjust_offset(pi, offset);
815
816         switch (offset) {
817         case VTCFG_R_GUESTCAP:
818                 assert(size == 4);
819                 sc->vsc_features = value & VTNET_S_HOSTCAPS;
820                 break;
821         case VTCFG_R_PFN:
822                 assert(size == 4);
823                 pci_vtnet_ring_init(sc, value);
824                 break;
825         case VTCFG_R_QSEL:
826                 assert(size == 2);
827                 assert(value < VTNET_MAXQ);
828                 sc->vsc_curq = value;
829                 break;
830         case VTCFG_R_QNOTIFY:
831                 assert(size == 2);
832                 assert(value < VTNET_MAXQ);
833                 (*pci_vtnet_qnotify[value])(sc);
834                 break;
835         case VTCFG_R_STATUS:
836                 assert(size == 1);
837                 pci_vtnet_update_status(sc, value);
838                 break;
839         case VTCFG_R_CFGVEC:
840                 assert(size == 2);
841                 sc->vsc_msix_table_idx[VTNET_CTLQ] = value;
842                 break;
843         case VTCFG_R_QVEC:
844                 assert(size == 2);
845                 assert(sc->vsc_curq != VTNET_CTLQ);
846                 sc->vsc_msix_table_idx[sc->vsc_curq] = value;
847                 break;
848         case VTNET_R_CFG0:
849         case VTNET_R_CFG1:
850         case VTNET_R_CFG2:
851         case VTNET_R_CFG3:
852         case VTNET_R_CFG4:
853         case VTNET_R_CFG5:
854                 assert((size + offset) <= (VTNET_R_CFG5 + 1));
855                 ptr = &sc->vsc_macaddr[offset - VTNET_R_CFG0];
856                 /*
857                  * The driver is allowed to change the MAC address
858                  */
859                 sc->vsc_macaddr[offset - VTNET_R_CFG0] = value;
860                 if (size == 1) {
861                         *(uint8_t *) ptr = value;
862                 } else if (size == 2) {
863                         *(uint16_t *) ptr = value;
864                 } else {
865                         *(uint32_t *) ptr = value;
866                 }
867                 break;
868         case VTCFG_R_HOSTCAP:
869         case VTCFG_R_QNUM:
870         case VTCFG_R_ISR:
871         case VTNET_R_CFG6:
872         case VTNET_R_CFG7:
873                 DPRINTF(("vtnet: write to readonly reg %ld\n\r", offset));
874                 break;
875         default:
876                 DPRINTF(("vtnet: unknown i/o write offset %ld\n\r", offset));
877                 value = 0;
878                 break;
879         }
880
881         pthread_mutex_unlock(&sc->vsc_mtx);
882 }
883
884 uint64_t
885 pci_vtnet_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
886                int baridx, uint64_t offset, int size)
887 {
888         struct pci_vtnet_softc *sc = pi->pi_arg;
889         void *ptr;
890         uint64_t value;
891
892         if (use_msix) {
893                 if (baridx == pci_msix_table_bar(pi) ||
894                     baridx == pci_msix_pba_bar(pi)) {
895                         return (pci_emul_msix_tread(pi, offset, size));
896                 }
897         }
898
899         assert(baridx == 0);
900
901         if (offset + size > pci_vtnet_iosize(pi)) {
902                 DPRINTF(("vtnet_read: 2big, offset %ld size %d\n",
903                          offset, size));
904                 return (0);
905         }
906
907         pthread_mutex_lock(&sc->vsc_mtx);
908
909         offset = vtnet_adjust_offset(pi, offset);
910
911         switch (offset) {
912         case VTCFG_R_HOSTCAP:
913                 assert(size == 4);
914                 value = VTNET_S_HOSTCAPS;
915                 break;
916         case VTCFG_R_GUESTCAP:
917                 assert(size == 4);
918                 value = sc->vsc_features; /* XXX never read ? */
919                 break;
920         case VTCFG_R_PFN:
921                 assert(size == 4);
922                 value = sc->vsc_pfn[sc->vsc_curq] >> VRING_PFN;
923                 break;
924         case VTCFG_R_QNUM:
925                 assert(size == 2);
926                 value = pci_vtnet_qsize(sc->vsc_curq);
927                 break;
928         case VTCFG_R_QSEL:
929                 assert(size == 2);
930                 value = sc->vsc_curq;  /* XXX never read ? */
931                 break;
932         case VTCFG_R_QNOTIFY:
933                 assert(size == 2);
934                 value = sc->vsc_curq;  /* XXX never read ? */
935                 break;
936         case VTCFG_R_STATUS:
937                 assert(size == 1);
938                 value = sc->vsc_status;
939                 break;
940         case VTCFG_R_ISR:
941                 assert(size == 1);
942                 value = sc->vsc_isr;
943                 sc->vsc_isr = 0;     /* a read clears this flag */
944                 break;
945         case VTCFG_R_CFGVEC:
946                 assert(size == 2);
947                 value = sc->vsc_msix_table_idx[VTNET_CTLQ];
948                 break;
949         case VTCFG_R_QVEC:
950                 assert(size == 2);
951                 assert(sc->vsc_curq != VTNET_CTLQ);
952                 value = sc->vsc_msix_table_idx[sc->vsc_curq];
953                 break;
954         case VTNET_R_CFG0:
955         case VTNET_R_CFG1:
956         case VTNET_R_CFG2:
957         case VTNET_R_CFG3:
958         case VTNET_R_CFG4:
959         case VTNET_R_CFG5:
960                 assert((size + offset) <= (VTNET_R_CFG5 + 1));
961                 ptr = &sc->vsc_macaddr[offset - VTNET_R_CFG0];
962                 if (size == 1) {
963                         value = *(uint8_t *) ptr;
964                 } else if (size == 2) {
965                         value = *(uint16_t *) ptr;
966                 } else {
967                         value = *(uint32_t *) ptr;
968                 }
969                 break;
970         case VTNET_R_CFG6:
971                 assert(size != 4);
972                 value = 0x01; /* XXX link always up */
973                 break;
974         case VTNET_R_CFG7:
975                 assert(size == 1);
976                 value = 0; /* XXX link status in LSB */
977                 break;
978         default:
979                 DPRINTF(("vtnet: unknown i/o read offset %ld\n\r", offset));
980                 value = 0;
981                 break;
982         }
983
984         pthread_mutex_unlock(&sc->vsc_mtx);
985
986         return (value);
987 }
988
989 struct pci_devemu pci_de_vnet = {
990         .pe_emu =       "virtio-net",
991         .pe_init =      pci_vtnet_init,
992         .pe_barwrite =  pci_vtnet_write,
993         .pe_barread =   pci_vtnet_read
994 };
995 PCI_EMUL_SET(pci_de_vnet);