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 --- |