Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/virtio/network/if_vtnet.c
Show First 20 Lines • Show All 634 Lines • ▼ Show 20 Lines | vtnet_setup_features(struct vtnet_softc *sc) | ||||
if (virtio_with_feature(dev, VIRTIO_RING_F_EVENT_IDX)) | if (virtio_with_feature(dev, VIRTIO_RING_F_EVENT_IDX)) | ||||
sc->vtnet_flags |= VTNET_FLAG_EVENT_IDX; | sc->vtnet_flags |= VTNET_FLAG_EVENT_IDX; | ||||
if (virtio_with_feature(dev, VIRTIO_NET_F_MAC)) { | if (virtio_with_feature(dev, VIRTIO_NET_F_MAC)) { | ||||
/* This feature should always be negotiated. */ | /* This feature should always be negotiated. */ | ||||
sc->vtnet_flags |= VTNET_FLAG_MAC; | 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; | 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); | sc->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf); | ||||
else | } else | ||||
sc->vtnet_hdr_size = sizeof(struct virtio_net_hdr); | sc->vtnet_hdr_size = sizeof(struct virtio_net_hdr); | ||||
if (sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) | if (sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) | ||||
sc->vtnet_rx_nsegs = VTNET_MRG_RX_SEGS; | sc->vtnet_rx_nsegs = VTNET_MRG_RX_SEGS; | ||||
else if (sc->vtnet_flags & VTNET_FLAG_LRO_NOMRG) | else if (sc->vtnet_flags & VTNET_FLAG_LRO_NOMRG) | ||||
sc->vtnet_rx_nsegs = VTNET_MAX_RX_SEGS; | sc->vtnet_rx_nsegs = VTNET_MAX_RX_SEGS; | ||||
else | else | ||||
sc->vtnet_rx_nsegs = VTNET_MIN_RX_SEGS; | sc->vtnet_rx_nsegs = VTNET_MIN_RX_SEGS; | ||||
▲ Show 20 Lines • Show All 799 Lines • ▼ Show 20 Lines | vtnet_rxq_enqueue_buf(struct vtnet_rxq *rxq, struct mbuf *m) | ||||
KASSERT(sc->vtnet_flags & VTNET_FLAG_LRO_NOMRG || m->m_next == NULL, | KASSERT(sc->vtnet_flags & VTNET_FLAG_LRO_NOMRG || m->m_next == NULL, | ||||
("%s: chained mbuf without LRO_NOMRG", __func__)); | ("%s: chained mbuf without LRO_NOMRG", __func__)); | ||||
KASSERT(m->m_len == sc->vtnet_rx_clsize, | KASSERT(m->m_len == sc->vtnet_rx_clsize, | ||||
("%s: unexpected cluster size %d/%d", __func__, m->m_len, | ("%s: unexpected cluster size %d/%d", __func__, m->m_len, | ||||
sc->vtnet_rx_clsize)); | sc->vtnet_rx_clsize)); | ||||
sglist_reset(sg); | sglist_reset(sg); | ||||
if ((sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) == 0) { | if ((sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) == 0) { | ||||
MPASS(sc->vtnet_hdr_size == sizeof(rxhdr->vrh_uhdr.hdr) || | MPASS(sc->vtnet_hdr_size == sizeof(struct virtio_net_hdr)); | ||||
sc->vtnet_hdr_size == sizeof(rxhdr->vrh_uhdr.mhdr)); | |||||
rxhdr = (struct vtnet_rx_header *) mdata; | rxhdr = (struct vtnet_rx_header *) mdata; | ||||
sglist_append(sg, &rxhdr->vrh_uhdr, sc->vtnet_hdr_size); | sglist_append(sg, &rxhdr->vrh_hdr, sc->vtnet_hdr_size); | ||||
offset = sizeof(struct vtnet_rx_header); | offset = sizeof(struct vtnet_rx_header); | ||||
} else | } else | ||||
offset = 0; | offset = 0; | ||||
sglist_append(sg, mdata + offset, m->m_len - offset); | sglist_append(sg, mdata + offset, m->m_len - offset); | ||||
if (m->m_next != NULL) { | if (m->m_next != NULL) { | ||||
error = sglist_append_mbuf(sg, m->m_next); | error = sglist_append_mbuf(sg, m->m_next); | ||||
MPASS(error == 0); | MPASS(error == 0); | ||||
▲ Show 20 Lines • Show All 337 Lines • ▼ Show 20 Lines | if (len < sc->vtnet_hdr_size + ETHER_HDR_LEN) { | ||||
continue; | continue; | ||||
} | } | ||||
if ((sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) == 0) { | if ((sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) == 0) { | ||||
nbufs = 1; | nbufs = 1; | ||||
adjsz = sizeof(struct vtnet_rx_header); | adjsz = sizeof(struct vtnet_rx_header); | ||||
/* | /* | ||||
* Account for our pad inserted between the header | * Account for our pad inserted between the header | ||||
* and the actual start of the frame. This includes | * and the actual start of the frame. | ||||
* the unused num_buffers when using a legacy device. | |||||
*/ | */ | ||||
len += adjsz - sc->vtnet_hdr_size; | len += VTNET_RX_HEADER_PAD; | ||||
} else { | } else { | ||||
mhdr = mtod(m, struct virtio_net_hdr_mrg_rxbuf *); | mhdr = mtod(m, struct virtio_net_hdr_mrg_rxbuf *); | ||||
nbufs = mhdr->num_buffers; | nbufs = mhdr->num_buffers; | ||||
adjsz = sizeof(struct virtio_net_hdr_mrg_rxbuf); | adjsz = sizeof(struct virtio_net_hdr_mrg_rxbuf); | ||||
} | } | ||||
/* | /* | ||||
* If we have enough data in first mbuf, run it through | * If we have enough data in first mbuf, run it through | ||||
▲ Show 20 Lines • Show All 2,291 Lines • Show Last 20 Lines |