Deleted Added
full compact
26c26
< * $FreeBSD: stable/10/usr.sbin/bhyve/pci_virtio_net.c 268953 2014-07-21 19:08:02Z jhb $
---
> * $FreeBSD: stable/10/usr.sbin/bhyve/pci_virtio_net.c 271685 2014-09-16 19:08:54Z grehan $
30c30
< __FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/pci_virtio_net.c 268953 2014-07-21 19:08:02Z jhb $");
---
> __FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/pci_virtio_net.c 271685 2014-09-16 19:08:54Z grehan $");
138c138,139
< uint32_t vsc_features;
---
> uint64_t vsc_features; /* negotiated features */
>
142a144,145
> int rx_vhdrlen;
> int rx_merge; /* merged rx bufs in use */
153a157
> static void pci_vtnet_neg_features(void *, uint64_t);
162a167
> pci_vtnet_neg_features, /* apply negotiated features */
214a220,221
> sc->rx_merge = 1;
> sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr);
255a263,283
> static __inline struct iovec *
> rx_iov_trim(struct iovec *iov, int *niov, int tlen)
> {
> struct iovec *riov;
>
> /* XXX short-cut: assume first segment is >= tlen */
> assert(iov[0].iov_len >= tlen);
>
> iov[0].iov_len -= tlen;
> if (iov[0].iov_len == 0) {
> assert(*niov > 1);
> *niov -= 1;
> riov = &iov[1];
> } else {
> iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base + tlen);
> riov = &iov[0];
> }
>
> return (riov);
> }
>
258a287
> struct iovec iov[VTNET_MAXSEGS], *riov;
260,263c289,290
< struct virtio_net_rxhdr *vrx;
< uint8_t *buf;
< int len;
< struct iovec iov;
---
> void *vrx;
> int len, n;
299,301c326
< * Get descriptor chain, which should have just
< * one descriptor in it.
< * ??? allow guests to use multiple descs?
---
> * Get descriptor chain.
303c328,329
< assert(vq_getchain(vq, &iov, 1, NULL) == 1);
---
> n = vq_getchain(vq, iov, VTNET_MAXSEGS, NULL);
> assert(n >= 1 && n <= VTNET_MAXSEGS);
309,310c335,336
< vrx = iov.iov_base;
< buf = (uint8_t *)(vrx + 1);
---
> vrx = iov[0].iov_base;
> riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen);
312,313c338
< len = read(sc->vsc_tapfd, buf,
< iov.iov_len - sizeof(struct virtio_net_rxhdr));
---
> len = readv(sc->vsc_tapfd, riov, n);
326,327c351
< * number of buffers, which is always 1 without TSO
< * support.
---
> * number of buffers if merged rx bufs were negotiated.
329,330c353
< memset(vrx, 0, sizeof(struct virtio_net_rxhdr));
< vrx->vrh_bufs = 1;
---
> memset(vrx, 0, sc->rx_vhdrlen);
331a355,361
> if (sc->rx_merge) {
> struct virtio_net_rxhdr *vrxh;
>
> vrxh = vrx;
> vrxh->vrh_bufs = 1;
> }
>
335c365
< vq_relchain(vq, len + sizeof(struct virtio_net_rxhdr));
---
> vq_relchain(vq, len + sc->rx_vhdrlen);
625a656,657
> sc->rx_merge = 1;
> sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr);
658a691
> /* silently ignore other writes */
660d692
< return (1);
661a694
>
675a709,722
> static void
> pci_vtnet_neg_features(void *vsc, uint64_t negotiated_features)
> {
> struct pci_vtnet_softc *sc = vsc;
>
> sc->vsc_features = negotiated_features;
>
> if (!(sc->vsc_features & VIRTIO_NET_F_MRG_RXBUF)) {
> sc->rx_merge = 0;
> /* non-merge rx header is 2 bytes shorter */
> sc->rx_vhdrlen -= 2;
> }
> }
>