Deleted Added
full compact
if_vtnet.c (267279) if_vtnet.c (268010)
1/*-
2 * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
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

--- 13 unchanged lines hidden (view full) ---

22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27/* Driver for VirtIO network devices. */
28
29#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
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

--- 13 unchanged lines hidden (view full) ---

22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27/* Driver for VirtIO network devices. */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: stable/10/sys/dev/virtio/network/if_vtnet.c 267279 2014-06-09 15:09:05Z luigi $");
30__FBSDID("$FreeBSD: stable/10/sys/dev/virtio/network/if_vtnet.c 268010 2014-06-29 00:37:59Z bryanv $");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/kernel.h>
35#include <sys/sockio.h>
36#include <sys/mbuf.h>
37#include <sys/malloc.h>
38#include <sys/module.h>

--- 506 unchanged lines hidden (view full) ---

545 if (vtnet_tunable_int(sc, "csum_disable", vtnet_csum_disable)) {
546 mask |= VIRTIO_NET_F_CSUM | VIRTIO_NET_F_GUEST_CSUM;
547 mask |= VTNET_TSO_FEATURES | VTNET_LRO_FEATURES;
548 }
549 if (vtnet_tunable_int(sc, "tso_disable", vtnet_tso_disable))
550 mask |= VTNET_TSO_FEATURES;
551 if (vtnet_tunable_int(sc, "lro_disable", vtnet_lro_disable))
552 mask |= VTNET_LRO_FEATURES;
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/kernel.h>
35#include <sys/sockio.h>
36#include <sys/mbuf.h>
37#include <sys/malloc.h>
38#include <sys/module.h>

--- 506 unchanged lines hidden (view full) ---

545 if (vtnet_tunable_int(sc, "csum_disable", vtnet_csum_disable)) {
546 mask |= VIRTIO_NET_F_CSUM | VIRTIO_NET_F_GUEST_CSUM;
547 mask |= VTNET_TSO_FEATURES | VTNET_LRO_FEATURES;
548 }
549 if (vtnet_tunable_int(sc, "tso_disable", vtnet_tso_disable))
550 mask |= VTNET_TSO_FEATURES;
551 if (vtnet_tunable_int(sc, "lro_disable", vtnet_lro_disable))
552 mask |= VTNET_LRO_FEATURES;
553#ifndef VTNET_LEGACY_TX
553 if (vtnet_tunable_int(sc, "mq_disable", vtnet_mq_disable))
554 mask |= VIRTIO_NET_F_MQ;
554 if (vtnet_tunable_int(sc, "mq_disable", vtnet_mq_disable))
555 mask |= VIRTIO_NET_F_MQ;
555#ifdef VTNET_LEGACY_TX
556#else
556 mask |= VIRTIO_NET_F_MQ;
557#endif
558
559 features = VTNET_FEATURES & ~mask;
560 sc->vtnet_features = virtio_negotiate_features(dev, features);
561
557 mask |= VIRTIO_NET_F_MQ;
558#endif
559
560 features = VTNET_FEATURES & ~mask;
561 sc->vtnet_features = virtio_negotiate_features(dev, features);
562
562 if (virtio_with_feature(dev, VTNET_LRO_FEATURES) == 0)
563 return;
564 if (virtio_with_feature(dev, VIRTIO_NET_F_MRG_RXBUF))
565 return;
563 if (virtio_with_feature(dev, VTNET_LRO_FEATURES) &&
564 virtio_with_feature(dev, VIRTIO_NET_F_MRG_RXBUF) == 0) {
565 /*
566 * LRO without mergeable buffers requires special care. This
567 * is not ideal because every receive buffer must be large
568 * enough to hold the maximum TCP packet, the Ethernet header,
569 * and the header. This requires up to 34 descriptors with
570 * MCLBYTES clusters. If we do not have indirect descriptors,
571 * LRO is disabled since the virtqueue will not contain very
572 * many receive buffers.
573 */
574 if (!virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC)) {
575 device_printf(dev,
576 "LRO disabled due to both mergeable buffers and "
577 "indirect descriptors not negotiated\n");
566
578
567 /*
568 * LRO without mergeable buffers requires special care. This is not
569 * ideal because every receive buffer must be large enough to hold
570 * the maximum TCP packet, the Ethernet header, and the header. This
571 * requires up to 34 descriptors with MCLBYTES clusters. If we do
572 * not have indirect descriptors, LRO is disabled since the virtqueue
573 * will not contain very many receive buffers.
574 */
575 if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC) == 0) {
576 device_printf(dev,
577 "LRO disabled due to both mergeable buffers and indirect "
578 "descriptors not negotiated\n");
579
580 features &= ~VTNET_LRO_FEATURES;
581 sc->vtnet_features = virtio_negotiate_features(dev, features);
582 } else
583 sc->vtnet_flags |= VTNET_FLAG_LRO_NOMRG;
579 features &= ~VTNET_LRO_FEATURES;
580 sc->vtnet_features =
581 virtio_negotiate_features(dev, features);
582 } else
583 sc->vtnet_flags |= VTNET_FLAG_LRO_NOMRG;
584 }
584}
585
586static void
587vtnet_setup_features(struct vtnet_softc *sc)
588{
589 device_t dev;
590 int max_pairs, max;
591

--- 1514 unchanged lines hidden (view full) ---

2106 *m_head = NULL;
2107
2108 return (ENOBUFS);
2109}
2110
2111static int
2112vtnet_txq_encap(struct vtnet_txq *txq, struct mbuf **m_head)
2113{
585}
586
587static void
588vtnet_setup_features(struct vtnet_softc *sc)
589{
590 device_t dev;
591 int max_pairs, max;
592

--- 1514 unchanged lines hidden (view full) ---

2107 *m_head = NULL;
2108
2109 return (ENOBUFS);
2110}
2111
2112static int
2113vtnet_txq_encap(struct vtnet_txq *txq, struct mbuf **m_head)
2114{
2114 struct vtnet_softc *sc;
2115 struct vtnet_tx_header *txhdr;
2116 struct virtio_net_hdr *hdr;
2117 struct mbuf *m;
2118 int error;
2119
2115 struct vtnet_tx_header *txhdr;
2116 struct virtio_net_hdr *hdr;
2117 struct mbuf *m;
2118 int error;
2119
2120 sc = txq->vtntx_sc;
2121 m = *m_head;
2122 M_ASSERTPKTHDR(m);
2123
2124 txhdr = uma_zalloc(vtnet_tx_header_zone, M_NOWAIT | M_ZERO);
2125 if (txhdr == NULL) {
2126 m_freem(m);
2127 *m_head = NULL;
2128 return (ENOMEM);

--- 810 unchanged lines hidden (view full) ---

2939 }
2940
2941 sc->vtnet_act_vq_pairs = npairs;
2942}
2943
2944static int
2945vtnet_reinit(struct vtnet_softc *sc)
2946{
2120 m = *m_head;
2121 M_ASSERTPKTHDR(m);
2122
2123 txhdr = uma_zalloc(vtnet_tx_header_zone, M_NOWAIT | M_ZERO);
2124 if (txhdr == NULL) {
2125 m_freem(m);
2126 *m_head = NULL;
2127 return (ENOMEM);

--- 810 unchanged lines hidden (view full) ---

2938 }
2939
2940 sc->vtnet_act_vq_pairs = npairs;
2941}
2942
2943static int
2944vtnet_reinit(struct vtnet_softc *sc)
2945{
2947 device_t dev;
2948 struct ifnet *ifp;
2949 int error;
2950
2946 struct ifnet *ifp;
2947 int error;
2948
2951 dev = sc->vtnet_dev;
2952 ifp = sc->vtnet_ifp;
2953
2954 /* Use the current MAC address. */
2955 bcopy(IF_LLADDR(ifp), sc->vtnet_hwaddr, ETHER_ADDR_LEN);
2956 vtnet_set_hwaddr(sc);
2957
2958 vtnet_set_active_vq_pairs(sc);
2959

--- 104 unchanged lines hidden (view full) ---

3064 */
3065 virtqueue_notify(vq);
3066 virtqueue_poll(vq, NULL);
3067}
3068
3069static int
3070vtnet_ctrl_mac_cmd(struct vtnet_softc *sc, uint8_t *hwaddr)
3071{
2949 ifp = sc->vtnet_ifp;
2950
2951 /* Use the current MAC address. */
2952 bcopy(IF_LLADDR(ifp), sc->vtnet_hwaddr, ETHER_ADDR_LEN);
2953 vtnet_set_hwaddr(sc);
2954
2955 vtnet_set_active_vq_pairs(sc);
2956

--- 104 unchanged lines hidden (view full) ---

3061 */
3062 virtqueue_notify(vq);
3063 virtqueue_poll(vq, NULL);
3064}
3065
3066static int
3067vtnet_ctrl_mac_cmd(struct vtnet_softc *sc, uint8_t *hwaddr)
3068{
3072 struct virtio_net_ctrl_hdr hdr;
3069 struct virtio_net_ctrl_hdr hdr __aligned(2);
3073 struct sglist_seg segs[3];
3074 struct sglist sg;
3075 uint8_t ack;
3076 int error;
3077
3078 hdr.class = VIRTIO_NET_CTRL_MAC;
3079 hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
3080 ack = VIRTIO_NET_ERR;

--- 17 unchanged lines hidden (view full) ---

3098 struct sglist_seg segs[3];
3099 struct sglist sg;
3100 struct {
3101 struct virtio_net_ctrl_hdr hdr;
3102 uint8_t pad1;
3103 struct virtio_net_ctrl_mq mq;
3104 uint8_t pad2;
3105 uint8_t ack;
3070 struct sglist_seg segs[3];
3071 struct sglist sg;
3072 uint8_t ack;
3073 int error;
3074
3075 hdr.class = VIRTIO_NET_CTRL_MAC;
3076 hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
3077 ack = VIRTIO_NET_ERR;

--- 17 unchanged lines hidden (view full) ---

3095 struct sglist_seg segs[3];
3096 struct sglist sg;
3097 struct {
3098 struct virtio_net_ctrl_hdr hdr;
3099 uint8_t pad1;
3100 struct virtio_net_ctrl_mq mq;
3101 uint8_t pad2;
3102 uint8_t ack;
3106 } s;
3103 } s __aligned(2);
3107 int error;
3108
3109 s.hdr.class = VIRTIO_NET_CTRL_MQ;
3110 s.hdr.cmd = VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET;
3111 s.mq.virtqueue_pairs = npairs;
3112 s.ack = VIRTIO_NET_ERR;
3113
3114 sglist_init(&sg, 3, segs);

--- 15 unchanged lines hidden (view full) ---

3130 struct sglist_seg segs[3];
3131 struct sglist sg;
3132 struct {
3133 struct virtio_net_ctrl_hdr hdr;
3134 uint8_t pad1;
3135 uint8_t onoff;
3136 uint8_t pad2;
3137 uint8_t ack;
3104 int error;
3105
3106 s.hdr.class = VIRTIO_NET_CTRL_MQ;
3107 s.hdr.cmd = VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET;
3108 s.mq.virtqueue_pairs = npairs;
3109 s.ack = VIRTIO_NET_ERR;
3110
3111 sglist_init(&sg, 3, segs);

--- 15 unchanged lines hidden (view full) ---

3127 struct sglist_seg segs[3];
3128 struct sglist sg;
3129 struct {
3130 struct virtio_net_ctrl_hdr hdr;
3131 uint8_t pad1;
3132 uint8_t onoff;
3133 uint8_t pad2;
3134 uint8_t ack;
3138 } s;
3135 } s __aligned(2);
3139 int error;
3140
3141 KASSERT(sc->vtnet_flags & VTNET_FLAG_CTRL_RX,
3142 ("%s: CTRL_RX feature not negotiated", __func__));
3143
3144 s.hdr.class = VIRTIO_NET_CTRL_RX;
3145 s.hdr.cmd = cmd;
3146 s.onoff = !!on;

--- 66 unchanged lines hidden (view full) ---

3213 if (vtnet_set_allmulti(sc, ifp->if_flags & IFF_ALLMULTI) != 0)
3214 device_printf(dev, "cannot %s all-multicast mode\n",
3215 ifp->if_flags & IFF_ALLMULTI ? "enable" : "disable");
3216}
3217
3218static void
3219vtnet_rx_filter_mac(struct vtnet_softc *sc)
3220{
3136 int error;
3137
3138 KASSERT(sc->vtnet_flags & VTNET_FLAG_CTRL_RX,
3139 ("%s: CTRL_RX feature not negotiated", __func__));
3140
3141 s.hdr.class = VIRTIO_NET_CTRL_RX;
3142 s.hdr.cmd = cmd;
3143 s.onoff = !!on;

--- 66 unchanged lines hidden (view full) ---

3210 if (vtnet_set_allmulti(sc, ifp->if_flags & IFF_ALLMULTI) != 0)
3211 device_printf(dev, "cannot %s all-multicast mode\n",
3212 ifp->if_flags & IFF_ALLMULTI ? "enable" : "disable");
3213}
3214
3215static void
3216vtnet_rx_filter_mac(struct vtnet_softc *sc)
3217{
3221 struct virtio_net_ctrl_hdr hdr;
3218 struct virtio_net_ctrl_hdr hdr __aligned(2);
3222 struct vtnet_mac_filter *filter;
3223 struct sglist_seg segs[4];
3224 struct sglist sg;
3225 struct ifnet *ifp;
3226 struct ifaddr *ifa;
3227 struct ifmultiaddr *ifma;
3228 int ucnt, mcnt, promisc, allmulti, error;
3229 uint8_t ack;

--- 96 unchanged lines hidden (view full) ---

3326 struct sglist_seg segs[3];
3327 struct sglist sg;
3328 struct {
3329 struct virtio_net_ctrl_hdr hdr;
3330 uint8_t pad1;
3331 uint16_t tag;
3332 uint8_t pad2;
3333 uint8_t ack;
3219 struct vtnet_mac_filter *filter;
3220 struct sglist_seg segs[4];
3221 struct sglist sg;
3222 struct ifnet *ifp;
3223 struct ifaddr *ifa;
3224 struct ifmultiaddr *ifma;
3225 int ucnt, mcnt, promisc, allmulti, error;
3226 uint8_t ack;

--- 96 unchanged lines hidden (view full) ---

3323 struct sglist_seg segs[3];
3324 struct sglist sg;
3325 struct {
3326 struct virtio_net_ctrl_hdr hdr;
3327 uint8_t pad1;
3328 uint16_t tag;
3329 uint8_t pad2;
3330 uint8_t ack;
3334 } s;
3331 } s __aligned(2);
3335 int error;
3336
3337 s.hdr.class = VIRTIO_NET_CTRL_VLAN;
3338 s.hdr.cmd = add ? VIRTIO_NET_CTRL_VLAN_ADD : VIRTIO_NET_CTRL_VLAN_DEL;
3339 s.tag = tag;
3340 s.ack = VIRTIO_NET_ERR;
3341
3342 sglist_init(&sg, 3, segs);

--- 495 unchanged lines hidden ---
3332 int error;
3333
3334 s.hdr.class = VIRTIO_NET_CTRL_VLAN;
3335 s.hdr.cmd = add ? VIRTIO_NET_CTRL_VLAN_ADD : VIRTIO_NET_CTRL_VLAN_DEL;
3336 s.tag = tag;
3337 s.ack = VIRTIO_NET_ERR;
3338
3339 sglist_init(&sg, 3, segs);

--- 495 unchanged lines hidden ---