Author: jrtc27
Date: Mon Jun  8 21:51:36 2020
New Revision: 361944
URL: https://svnweb.freebsd.org/changeset/base/361944

Log:
  virtio: Support non-legacy network device and queue
  
  The non-legacy interface always defines num_buffers in the header,
  regardless of whether VIRTIO_NET_F_MRG_RXBUF, just leaving it unused. We
  also need to ensure our virtqueue doesn't filter out VIRTIO_F_VERSION_1
  during negotiation, as it supports non-legacy transports just fine. This
  fixes network packet transmission on TinyEMU.
  
  Reviewed by:  br, brooks (mentor), jhb (mentor)
  Approved by:  br, brooks (mentor), jhb (mentor)
  Differential Revision:        https://reviews.freebsd.org/D25132

Modified:
  head/sys/dev/virtio/network/if_vtnet.c
  head/sys/dev/virtio/network/if_vtnetvar.h
  head/sys/dev/virtio/virtio.c
  head/sys/dev/virtio/virtqueue.c

Modified: head/sys/dev/virtio/network/if_vtnet.c
==============================================================================
--- head/sys/dev/virtio/network/if_vtnet.c      Mon Jun  8 21:49:42 2020        
(r361943)
+++ head/sys/dev/virtio/network/if_vtnet.c      Mon Jun  8 21:51:36 2020        
(r361944)
@@ -640,10 +640,13 @@ vtnet_setup_features(struct vtnet_softc *sc)
                sc->vtnet_flags |= VTNET_FLAG_MAC;
        }
 
-       if (virtio_with_feature(dev, VIRTIO_NET_F_MRG_RXBUF)) {
+       if (virtio_with_feature(dev, VIRTIO_NET_F_MRG_RXBUF))
                sc->vtnet_flags |= VTNET_FLAG_MRG_RXBUFS;
+
+       if (virtio_with_feature(dev, VIRTIO_NET_F_MRG_RXBUF) ||
+           virtio_with_feature(dev, VIRTIO_F_VERSION_1))
                sc->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
-       } else
+       else
                sc->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
 
        if (sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS)
@@ -1459,9 +1462,10 @@ vtnet_rxq_enqueue_buf(struct vtnet_rxq *rxq, struct mb
 
        sglist_reset(sg);
        if ((sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) == 0) {
-               MPASS(sc->vtnet_hdr_size == sizeof(struct virtio_net_hdr));
+               MPASS(sc->vtnet_hdr_size == sizeof(rxhdr->vrh_uhdr.hdr) ||
+                   sc->vtnet_hdr_size == sizeof(rxhdr->vrh_uhdr.mhdr));
                rxhdr = (struct vtnet_rx_header *) mdata;
-               sglist_append(sg, &rxhdr->vrh_hdr, sc->vtnet_hdr_size);
+               sglist_append(sg, &rxhdr->vrh_uhdr, sc->vtnet_hdr_size);
                offset = sizeof(struct vtnet_rx_header);
        } else
                offset = 0;

Modified: head/sys/dev/virtio/network/if_vtnetvar.h
==============================================================================
--- head/sys/dev/virtio/network/if_vtnetvar.h   Mon Jun  8 21:49:42 2020        
(r361943)
+++ head/sys/dev/virtio/network/if_vtnetvar.h   Mon Jun  8 21:51:36 2020        
(r361944)
@@ -219,15 +219,20 @@ struct vtnet_softc {
  * When mergeable buffers are not negotiated, the vtnet_rx_header structure
  * below is placed at the beginning of the mbuf data. Use 4 bytes of pad to
  * both keep the VirtIO header and the data non-contiguous and to keep the
- * frame's payload 4 byte aligned.
+ * frame's payload 4 byte aligned. Note that non-legacy drivers still want
+ * room for a full mergeable buffer header.
  *
  * When mergeable buffers are negotiated, the host puts the VirtIO header in
  * the beginning of the first mbuf's data.
  */
 #define VTNET_RX_HEADER_PAD    4
 struct vtnet_rx_header {
-       struct virtio_net_hdr   vrh_hdr;
-       char                    vrh_pad[VTNET_RX_HEADER_PAD];
+       union {
+               struct virtio_net_hdr           hdr;
+               struct virtio_net_hdr_mrg_rxbuf mhdr;
+       } vrh_uhdr;
+
+       char    vrh_pad[VTNET_RX_HEADER_PAD];
 } __packed;
 
 /*
@@ -296,7 +301,8 @@ CTASSERT(sizeof(struct vtnet_mac_filter) <= PAGE_SIZE)
      VIRTIO_NET_F_MRG_RXBUF            | \
      VIRTIO_NET_F_MQ                   | \
      VIRTIO_RING_F_EVENT_IDX           | \
-     VIRTIO_RING_F_INDIRECT_DESC)
+     VIRTIO_RING_F_INDIRECT_DESC       | \
+     VIRTIO_F_VERSION_1)
 
 /*
  * The VIRTIO_NET_F_HOST_TSO[46] features permit us to send the host

Modified: head/sys/dev/virtio/virtio.c
==============================================================================
--- head/sys/dev/virtio/virtio.c        Mon Jun  8 21:49:42 2020        
(r361943)
+++ head/sys/dev/virtio/virtio.c        Mon Jun  8 21:51:36 2020        
(r361944)
@@ -79,6 +79,7 @@ static struct virtio_feature_desc virtio_common_featur
        { VIRTIO_RING_F_INDIRECT_DESC,  "RingIndirect"  },
        { VIRTIO_RING_F_EVENT_IDX,      "EventIdx"      },
        { VIRTIO_F_BAD_FEATURE,         "BadFeature"    },
+       { VIRTIO_F_VERSION_1,           "Version1"      },
 
        { 0, NULL }
 };

Modified: head/sys/dev/virtio/virtqueue.c
==============================================================================
--- head/sys/dev/virtio/virtqueue.c     Mon Jun  8 21:49:42 2020        
(r361943)
+++ head/sys/dev/virtio/virtqueue.c     Mon Jun  8 21:51:36 2020        
(r361944)
@@ -142,6 +142,7 @@ virtqueue_filter_features(uint64_t features)
        mask = (1 << VIRTIO_TRANSPORT_F_START) - 1;
        mask |= VIRTIO_RING_F_INDIRECT_DESC;
        mask |= VIRTIO_RING_F_EVENT_IDX;
+       mask |= VIRTIO_F_VERSION_1;
 
        return (features & mask);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to