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
This commit is contained in:
parent
16ca3d0f59
commit
8c3988dff9
@ -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 mbuf *m)
|
||||
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -79,6 +79,7 @@ static struct virtio_feature_desc virtio_common_feature_desc[] = {
|
||||
{ VIRTIO_RING_F_INDIRECT_DESC, "RingIndirect" },
|
||||
{ VIRTIO_RING_F_EVENT_IDX, "EventIdx" },
|
||||
{ VIRTIO_F_BAD_FEATURE, "BadFeature" },
|
||||
{ VIRTIO_F_VERSION_1, "Version1" },
|
||||
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user