Date: Wed, 31 Dec 2014 10:08:18 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r276468 - projects/ifnet/sys/dev/virtio/network Message-ID: <201412311008.sBVA8IQn049877@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Wed Dec 31 10:08:17 2014 New Revision: 276468 URL: https://svnweb.freebsd.org/changeset/base/276468 Log: Convert vtnet(4) to new interface API. This is a more complex example than loop(4) and can be used as reference when converting other drivers. - Don't include if_var.h. - Declare static struct ifdriver, and if_attach_args on stack of vtnet_setup_interface(). - Use methods to access properties of interface. - Use if_foreach_addr() and if_foreach_maddr() to iterate over interface addresses. - Use buf_ring(9) directly instead of drbr(9). [1] [1] The drbr(9) goes away very soon as well as interface output queues. ALTQ will be implemented as interceptor of interface if_ops. Sponsored by: Netflix Sponsored by: Nginx, Inc. Modified: projects/ifnet/sys/dev/virtio/network/if_vtnet.c projects/ifnet/sys/dev/virtio/network/if_vtnetvar.h Modified: projects/ifnet/sys/dev/virtio/network/if_vtnet.c ============================================================================== --- projects/ifnet/sys/dev/virtio/network/if_vtnet.c Wed Dec 31 10:05:42 2014 (r276467) +++ projects/ifnet/sys/dev/virtio/network/if_vtnet.c Wed Dec 31 10:08:17 2014 (r276468) @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include <sys/eventhandler.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/buf_ring.h> #include <sys/sockio.h> #include <sys/mbuf.h> #include <sys/malloc.h> @@ -51,12 +52,9 @@ __FBSDID("$FreeBSD$"); #include <net/ethernet.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_arp.h> #include <net/if_dl.h> -#include <net/if_types.h> #include <net/if_media.h> -#include <net/if_vlan_var.h> #include <net/bpf.h> @@ -79,6 +77,10 @@ __FBSDID("$FreeBSD$"); #include <dev/virtio/network/virtio_net.h> #include <dev/virtio/network/if_vtnetvar.h> +#ifdef DEV_NETMAP +#include <dev/netmap/if_vtnet_netmap.h> +#endif /* DEV_NETMAP */ + #include "virtio_if.h" #include "opt_inet.h" @@ -104,10 +106,10 @@ static void vtnet_free_rxtx_queues(struc static int vtnet_alloc_rx_filters(struct vtnet_softc *); static void vtnet_free_rx_filters(struct vtnet_softc *); static int vtnet_alloc_virtqueues(struct vtnet_softc *); -static int vtnet_setup_interface(struct vtnet_softc *); +static void vtnet_setup_interface(struct vtnet_softc *); static int vtnet_change_mtu(struct vtnet_softc *, int); -static int vtnet_ioctl(struct ifnet *, u_long, caddr_t); -static uint64_t vtnet_get_counter(struct ifnet *, ift_counter); +static int vtnet_ioctl(if_t, u_long, caddr_t); +static uint64_t vtnet_get_counter(if_t, ift_counter); static int vtnet_rxq_populate(struct vtnet_rxq *); static void vtnet_rxq_free_mbufs(struct vtnet_rxq *); @@ -142,23 +144,15 @@ static struct mbuf * static int vtnet_txq_enqueue_buf(struct vtnet_txq *, struct mbuf **, struct vtnet_tx_header *); static int vtnet_txq_encap(struct vtnet_txq *, struct mbuf **); -#ifdef VTNET_LEGACY_TX -static void vtnet_start_locked(struct vtnet_txq *, struct ifnet *); -static void vtnet_start(struct ifnet *); -#else static int vtnet_txq_mq_start_locked(struct vtnet_txq *, struct mbuf *); -static int vtnet_txq_mq_start(struct ifnet *, struct mbuf *); +static int vtnet_txq_mq_start(if_t, struct mbuf *); static void vtnet_txq_tq_deferred(void *, int); -#endif static void vtnet_txq_start(struct vtnet_txq *); static void vtnet_txq_tq_intr(void *, int); static int vtnet_txq_eof(struct vtnet_txq *); static void vtnet_tx_vq_intr(void *); static void vtnet_tx_start_all(struct vtnet_softc *); - -#ifndef VTNET_LEGACY_TX -static void vtnet_qflush(struct ifnet *); -#endif +static void vtnet_qflush(if_t); static int vtnet_watchdog(struct vtnet_txq *); static void vtnet_accum_stats(struct vtnet_softc *, @@ -196,13 +190,13 @@ static void vtnet_rx_filter_mac(struct v static int vtnet_exec_vlan_filter(struct vtnet_softc *, int, uint16_t); static void vtnet_rx_filter_vlan(struct vtnet_softc *); static void vtnet_update_vlan_filter(struct vtnet_softc *, int, uint16_t); -static void vtnet_register_vlan(void *, struct ifnet *, uint16_t); -static void vtnet_unregister_vlan(void *, struct ifnet *, uint16_t); +static void vtnet_register_vlan(void *, if_t, uint16_t); +static void vtnet_unregister_vlan(void *, if_t, uint16_t); static int vtnet_is_link_up(struct vtnet_softc *); static void vtnet_update_link_status(struct vtnet_softc *); -static int vtnet_ifmedia_upd(struct ifnet *); -static void vtnet_ifmedia_sts(struct ifnet *, struct ifmediareq *); +static int vtnet_ifmedia_upd(if_t); +static void vtnet_ifmedia_sts(if_t, struct ifmediareq *); static void vtnet_get_hwaddr(struct vtnet_softc *); static void vtnet_set_hwaddr(struct vtnet_softc *); static void vtnet_vlan_tag_remove(struct mbuf *); @@ -287,10 +281,6 @@ static device_method_t vtnet_methods[] = DEVMETHOD_END }; -#ifdef DEV_NETMAP -#include <dev/netmap/if_vtnet_netmap.h> -#endif /* DEV_NETMAP */ - static driver_t vtnet_driver = { "vtnet", vtnet_methods, @@ -305,6 +295,20 @@ DRIVER_MODULE(vtnet, virtio_pci, vtnet_d MODULE_VERSION(vtnet, 1); MODULE_DEPEND(vtnet, virtio, 1, 1, 1); +static struct ifdriver vtnet_ifdrv = { + .ifdrv_ops = { + .ifop_origin = IFOP_ORIGIN_DRIVER, + .ifop_ioctl = vtnet_ioctl, + .ifop_init = vtnet_init, + .ifop_get_counter = vtnet_get_counter, + .ifop_transmit = vtnet_txq_mq_start, + .ifop_qflush = vtnet_qflush, + }, + .ifdrv_dname = "vtnet", + .ifdrv_type = IFT_ETHER, + .ifdrv_hdrlen = sizeof(struct ether_vlan_header), +}; + static int vtnet_modevent(module_t mod, int type, void *unused) { @@ -385,20 +389,14 @@ vtnet_attach(device_t dev) goto fail; } - error = vtnet_setup_interface(sc); - if (error) { - device_printf(dev, "cannot setup interface\n"); - goto fail; - } - error = virtio_setup_intr(dev, INTR_TYPE_NET); if (error) { device_printf(dev, "cannot setup virtqueue interrupts\n"); - /* BMV: This will crash if during boot! */ - ether_ifdetach(sc->vtnet_ifp); goto fail; } + vtnet_setup_interface(sc); + #ifdef DEV_NETMAP vtnet_netmap_attach(sc); #endif /* DEV_NETMAP */ @@ -416,10 +414,8 @@ static int vtnet_detach(device_t dev) { struct vtnet_softc *sc; - struct ifnet *ifp; sc = device_get_softc(dev); - ifp = sc->vtnet_ifp; if (device_is_attached(dev)) { VTNET_CORE_LOCK(sc); @@ -429,13 +425,13 @@ vtnet_detach(device_t dev) callout_drain(&sc->vtnet_tick_ch); vtnet_drain_taskqueues(sc); - ether_ifdetach(ifp); - } - #ifdef DEV_NETMAP - netmap_detach(ifp); + netmap_detach(sc->vtnet_ifp); #endif /* DEV_NETMAP */ + if_detach(sc->vtnet_ifp); + } + vtnet_free_taskqueues(sc); if (sc->vtnet_vlan_attach != NULL) { @@ -449,11 +445,6 @@ vtnet_detach(device_t dev) ifmedia_removeall(&sc->vtnet_media); - if (ifp != NULL) { - if_free(ifp); - sc->vtnet_ifp = NULL; - } - vtnet_free_rxtx_queues(sc); vtnet_free_rx_filters(sc); @@ -484,13 +475,13 @@ static int vtnet_resume(device_t dev) { struct vtnet_softc *sc; - struct ifnet *ifp; + if_t ifp; sc = device_get_softc(dev); ifp = sc->vtnet_ifp; VTNET_CORE_LOCK(sc); - if (ifp->if_flags & IFF_UP) + if (if_getflags(ifp, IF_FLAGS) & IFF_UP) vtnet_init_locked(sc); sc->vtnet_flags &= ~VTNET_FLAG_SUSPENDED; VTNET_CORE_UNLOCK(sc); @@ -555,12 +546,8 @@ vtnet_negotiate_features(struct vtnet_so mask |= VTNET_TSO_FEATURES; if (vtnet_tunable_int(sc, "lro_disable", vtnet_lro_disable)) mask |= VTNET_LRO_FEATURES; -#ifndef VTNET_LEGACY_TX if (vtnet_tunable_int(sc, "mq_disable", vtnet_mq_disable)) mask |= VIRTIO_NET_F_MQ; -#else - mask |= VIRTIO_NET_F_MQ; -#endif features = VTNET_FEATURES & ~mask; sc->vtnet_features = virtio_negotiate_features(dev, features); @@ -711,14 +698,12 @@ vtnet_init_txq(struct vtnet_softc *sc, i if (txq->vtntx_sg == NULL) return (ENOMEM); -#ifndef VTNET_LEGACY_TX txq->vtntx_br = buf_ring_alloc(VTNET_DEFAULT_BUFRING_SIZE, M_DEVBUF, M_NOWAIT, &txq->vtntx_mtx); if (txq->vtntx_br == NULL) return (ENOMEM); TASK_INIT(&txq->vtntx_defrtask, 0, vtnet_txq_tq_deferred, txq); -#endif TASK_INIT(&txq->vtntx_intrtask, 0, vtnet_txq_tq_intr, txq); txq->vtntx_tq = taskqueue_create(txq->vtntx_name, M_NOWAIT, taskqueue_thread_enqueue, &txq->vtntx_tq); @@ -784,12 +769,10 @@ vtnet_destroy_txq(struct vtnet_txq *txq) txq->vtntx_sg = NULL; } -#ifndef VTNET_LEGACY_TX if (txq->vtntx_br != NULL) { buf_ring_free(txq->vtntx_br, M_DEVBUF); txq->vtntx_br = NULL; } -#endif if (mtx_initialized(&txq->vtntx_mtx) != 0) mtx_destroy(&txq->vtntx_mtx); @@ -901,101 +884,75 @@ vtnet_alloc_virtqueues(struct vtnet_soft return (error); } -static int +static void vtnet_setup_interface(struct vtnet_softc *sc) { + struct if_attach_args ifat = { + .ifat_version = IF_ATTACH_VERSION, + .ifat_drv = &vtnet_ifdrv, + .ifat_softc = sc, + .ifat_baudrate = IF_Gbps(10), /* Approx. */ + .ifat_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, + .ifat_capabilities = IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU, + }; device_t dev; - struct ifnet *ifp; dev = sc->vtnet_dev; - - ifp = sc->vtnet_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "cannot allocate ifnet structure\n"); - return (ENOSPC); - } - - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_baudrate = IF_Gbps(10); /* Approx. */ - ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = vtnet_init; - ifp->if_ioctl = vtnet_ioctl; - ifp->if_get_counter = vtnet_get_counter; -#ifndef VTNET_LEGACY_TX - ifp->if_transmit = vtnet_txq_mq_start; - ifp->if_qflush = vtnet_qflush; -#else - struct virtqueue *vq = sc->vtnet_txqs[0].vtntx_vq; - ifp->if_start = vtnet_start; - IFQ_SET_MAXLEN(&ifp->if_snd, virtqueue_size(vq) - 1); - ifp->if_snd.ifq_drv_maxlen = virtqueue_size(vq) - 1; - IFQ_SET_READY(&ifp->if_snd); -#endif - - ifmedia_init(&sc->vtnet_media, IFM_IMASK, vtnet_ifmedia_upd, - vtnet_ifmedia_sts); - ifmedia_add(&sc->vtnet_media, VTNET_MEDIATYPE, 0, NULL); - ifmedia_set(&sc->vtnet_media, VTNET_MEDIATYPE); - /* Read (or generate) the MAC address for the adapter. */ vtnet_get_hwaddr(sc); - ether_ifattach(ifp, sc->vtnet_hwaddr); + ifat.ifat_dunit = device_get_unit(dev); + ifat.ifat_lla = sc->vtnet_hwaddr; if (virtio_with_feature(dev, VIRTIO_NET_F_STATUS)) - ifp->if_capabilities |= IFCAP_LINKSTATE; - - /* Tell the upper layer(s) we support long frames. */ - ifp->if_hdrlen = sizeof(struct ether_vlan_header); - ifp->if_capabilities |= IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU; + ifat.ifat_capabilities |= IFCAP_LINKSTATE; if (virtio_with_feature(dev, VIRTIO_NET_F_CSUM)) { - ifp->if_capabilities |= IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6; + ifat.ifat_capabilities |= IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6; if (virtio_with_feature(dev, VIRTIO_NET_F_GSO)) { - ifp->if_capabilities |= IFCAP_TSO4 | IFCAP_TSO6; + ifat.ifat_capabilities |= IFCAP_TSO4 | IFCAP_TSO6; sc->vtnet_flags |= VTNET_FLAG_TSO_ECN; } else { if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_TSO4)) - ifp->if_capabilities |= IFCAP_TSO4; + ifat.ifat_capabilities |= IFCAP_TSO4; if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_TSO6)) - ifp->if_capabilities |= IFCAP_TSO6; + ifat.ifat_capabilities |= IFCAP_TSO6; if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_ECN)) sc->vtnet_flags |= VTNET_FLAG_TSO_ECN; } - if (ifp->if_capabilities & IFCAP_TSO) - ifp->if_capabilities |= IFCAP_VLAN_HWTSO; + if (ifat.ifat_capabilities & IFCAP_TSO) + ifat.ifat_capabilities |= IFCAP_VLAN_HWTSO; } if (virtio_with_feature(dev, VIRTIO_NET_F_GUEST_CSUM)) { - ifp->if_capabilities |= IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6; + ifat.ifat_capabilities |= IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6; if (virtio_with_feature(dev, VIRTIO_NET_F_GUEST_TSO4) || virtio_with_feature(dev, VIRTIO_NET_F_GUEST_TSO6)) - ifp->if_capabilities |= IFCAP_LRO; + ifat.ifat_capabilities |= IFCAP_LRO; } - if (ifp->if_capabilities & IFCAP_HWCSUM) { + if (ifat.ifat_capabilities & IFCAP_HWCSUM) { /* * VirtIO does not support VLAN tagging, but we can fake * it by inserting and removing the 802.1Q header during * transmit and receive. We are then able to do checksum * offloading of VLAN frames. */ - ifp->if_capabilities |= + ifat.ifat_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM; } - ifp->if_capenable = ifp->if_capabilities; + ifat.ifat_capenable = ifat.ifat_capabilities; /* * Capabilities after here are not enabled by default. */ if (sc->vtnet_flags & VTNET_FLAG_VLAN_FILTER) { - ifp->if_capabilities |= IFCAP_VLAN_HWFILTER; + ifat.ifat_capabilities |= IFCAP_VLAN_HWFILTER; sc->vtnet_vlan_attach = EVENTHANDLER_REGISTER(vlan_config, vtnet_register_vlan, sc, EVENTHANDLER_PRI_FIRST); @@ -1006,13 +963,18 @@ vtnet_setup_interface(struct vtnet_softc vtnet_set_rx_process_limit(sc); vtnet_set_tx_intr_threshold(sc); - return (0); + ifmedia_init(&sc->vtnet_media, IFM_IMASK, vtnet_ifmedia_upd, + vtnet_ifmedia_sts); + ifmedia_add(&sc->vtnet_media, VTNET_MEDIATYPE, 0, NULL); + ifmedia_set(&sc->vtnet_media, VTNET_MEDIATYPE); + + sc->vtnet_ifp = if_attach(&ifat); } static int vtnet_change_mtu(struct vtnet_softc *sc, int new_mtu) { - struct ifnet *ifp; + if_t ifp; int frame_size, clsize; ifp = sc->vtnet_ifp; @@ -1037,11 +999,11 @@ vtnet_change_mtu(struct vtnet_softc *sc, } else clsize = MJUMPAGESIZE; - ifp->if_mtu = new_mtu; + if_setflags(ifp, IF_MTU, new_mtu); sc->vtnet_rx_new_clsize = clsize; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if (if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) { + if_clrflags(ifp, IF_DRV_FLAGS, IFF_DRV_RUNNING); vtnet_init_locked(sc); } @@ -1049,19 +1011,19 @@ vtnet_change_mtu(struct vtnet_softc *sc, } static int -vtnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +vtnet_ioctl(if_t ifp, u_long cmd, caddr_t data) { struct vtnet_softc *sc; struct ifreq *ifr; - int reinit, mask, error; + int reinit, capenable, mask, error; - sc = ifp->if_softc; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); ifr = (struct ifreq *) data; error = 0; switch (cmd) { case SIOCSIFMTU: - if (ifp->if_mtu != ifr->ifr_mtu) { + if (if_getflags(ifp, IF_MTU) != ifr->ifr_mtu) { VTNET_CORE_LOCK(sc); error = vtnet_change_mtu(sc, ifr->ifr_mtu); VTNET_CORE_UNLOCK(sc); @@ -1070,11 +1032,11 @@ vtnet_ioctl(struct ifnet *ifp, u_long cm case SIOCSIFFLAGS: VTNET_CORE_LOCK(sc); - if ((ifp->if_flags & IFF_UP) == 0) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if ((if_getflags(ifp, IF_FLAGS) & IFF_UP) == 0) { + if (if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) vtnet_stop(sc); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if ((ifp->if_flags ^ sc->vtnet_if_flags) & + } else if (if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) { + if ((if_getflags(ifp, IF_FLAGS) ^ sc->vtnet_if_flags) & (IFF_PROMISC | IFF_ALLMULTI)) { if (sc->vtnet_flags & VTNET_FLAG_CTRL_RX) vtnet_rx_filter(sc); @@ -1085,7 +1047,7 @@ vtnet_ioctl(struct ifnet *ifp, u_long cm vtnet_init_locked(sc); if (error == 0) - sc->vtnet_if_flags = ifp->if_flags; + sc->vtnet_if_flags = if_getflags(ifp, IF_FLAGS); VTNET_CORE_UNLOCK(sc); break; @@ -1094,7 +1056,7 @@ vtnet_ioctl(struct ifnet *ifp, u_long cm if ((sc->vtnet_flags & VTNET_FLAG_CTRL_RX) == 0) break; VTNET_CORE_LOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) vtnet_rx_filter_mac(sc); VTNET_CORE_UNLOCK(sc); break; @@ -1106,16 +1068,17 @@ vtnet_ioctl(struct ifnet *ifp, u_long cm case SIOCSIFCAP: VTNET_CORE_LOCK(sc); - mask = ifr->ifr_reqcap ^ ifp->if_capenable; + capenable = if_getflags(ifp, IF_CAPENABLE); + mask = ifr->ifr_reqcap ^ capenable; if (mask & IFCAP_TXCSUM) - ifp->if_capenable ^= IFCAP_TXCSUM; + capenable ^= IFCAP_TXCSUM; if (mask & IFCAP_TXCSUM_IPV6) - ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; + capenable ^= IFCAP_TXCSUM_IPV6; if (mask & IFCAP_TSO4) - ifp->if_capenable ^= IFCAP_TSO4; + capenable ^= IFCAP_TSO4; if (mask & IFCAP_TSO6) - ifp->if_capenable ^= IFCAP_TSO6; + capenable ^= IFCAP_TSO6; if (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 | IFCAP_LRO | IFCAP_VLAN_HWFILTER)) { @@ -1123,33 +1086,35 @@ vtnet_ioctl(struct ifnet *ifp, u_long cm reinit = 1; if (mask & IFCAP_RXCSUM) - ifp->if_capenable ^= IFCAP_RXCSUM; + capenable ^= IFCAP_RXCSUM; if (mask & IFCAP_RXCSUM_IPV6) - ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; + capenable ^= IFCAP_RXCSUM_IPV6; if (mask & IFCAP_LRO) - ifp->if_capenable ^= IFCAP_LRO; + capenable ^= IFCAP_LRO; if (mask & IFCAP_VLAN_HWFILTER) - ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; + capenable ^= IFCAP_VLAN_HWFILTER; } else reinit = 0; if (mask & IFCAP_VLAN_HWTSO) - ifp->if_capenable ^= IFCAP_VLAN_HWTSO; + capenable ^= IFCAP_VLAN_HWTSO; if (mask & IFCAP_VLAN_HWTAGGING) - ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; + capenable ^= IFCAP_VLAN_HWTAGGING; - if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if (reinit && + (if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING)) { + if_clrflags(ifp, IF_DRV_FLAGS, IFF_DRV_RUNNING); vtnet_init_locked(sc); } VTNET_CORE_UNLOCK(sc); - VLAN_CAPABILITIES(ifp); + + if_capenable(ifp, capenable); break; default: - error = ether_ioctl(ifp, cmd, data); + error = EOPNOTSUPP; break; } @@ -1633,14 +1598,12 @@ static int vtnet_rxq_merged_eof(struct vtnet_rxq *rxq, struct mbuf *m_head, int nbufs) { struct vtnet_softc *sc; - struct ifnet *ifp; struct virtqueue *vq; struct mbuf *m, *m_tail; int len; sc = rxq->vtnrx_sc; vq = rxq->vtnrx_vq; - ifp = sc->vtnet_ifp; m_tail = m_head; while (--nbufs > 0) { @@ -1683,13 +1646,13 @@ vtnet_rxq_input(struct vtnet_rxq *rxq, s struct virtio_net_hdr *hdr) { struct vtnet_softc *sc; - struct ifnet *ifp; + if_t ifp; struct ether_header *eh; sc = rxq->vtnrx_sc; ifp = sc->vtnet_ifp; - if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) { + if (if_getflags(ifp, IF_CAPENABLE) & IFCAP_VLAN_HWTAGGING) { eh = mtod(m, struct ether_header *); if (eh->ether_type == htons(ETHERTYPE_VLAN)) { vtnet_vlan_tag_remove(m); @@ -1722,7 +1685,7 @@ vtnet_rxq_input(struct vtnet_rxq *rxq, s rxq->vtnrx_stats.vrxs_ibytes += m->m_pkthdr.len; VTNET_RXQ_UNLOCK(rxq); - (*ifp->if_input)(ifp, m); + if_input(ifp, m); VTNET_RXQ_LOCK(rxq); } @@ -1731,7 +1694,7 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq) { struct virtio_net_hdr lhdr, *hdr; struct vtnet_softc *sc; - struct ifnet *ifp; + if_t ifp; struct virtqueue *vq; struct mbuf *m; struct virtio_net_hdr_mrg_rxbuf *mhdr; @@ -1811,7 +1774,7 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq) vtnet_rxq_input(rxq, m, hdr); /* Must recheck after dropping the Rx lock. */ - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) == 0) break; } @@ -1826,7 +1789,7 @@ vtnet_rx_vq_intr(void *xrxq) { struct vtnet_softc *sc; struct vtnet_rxq *rxq; - struct ifnet *ifp; + if_t ifp; int tries, more; rxq = xrxq; @@ -1848,7 +1811,7 @@ vtnet_rx_vq_intr(void *xrxq) VTNET_RXQ_LOCK(rxq); again: - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) == 0) { VTNET_RXQ_UNLOCK(rxq); return; } @@ -1876,7 +1839,7 @@ vtnet_rxq_tq_intr(void *xrxq, int pendin { struct vtnet_softc *sc; struct vtnet_rxq *rxq; - struct ifnet *ifp; + if_t ifp; int more; rxq = xrxq; @@ -1885,7 +1848,7 @@ vtnet_rxq_tq_intr(void *xrxq, int pendin VTNET_RXQ_LOCK(rxq); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) == 0) { VTNET_RXQ_UNLOCK(rxq); return; } @@ -2205,81 +2168,13 @@ fail: return (error); } -#ifdef VTNET_LEGACY_TX - -static void -vtnet_start_locked(struct vtnet_txq *txq, struct ifnet *ifp) -{ - struct vtnet_softc *sc; - struct virtqueue *vq; - struct mbuf *m0; - int tries, enq; - - sc = txq->vtntx_sc; - vq = txq->vtntx_vq; - tries = 0; - - VTNET_TXQ_LOCK_ASSERT(txq); - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - sc->vtnet_link_active == 0) - return; - - vtnet_txq_eof(txq); - -again: - enq = 0; - - while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { - if (virtqueue_full(vq)) - break; - - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - - if (vtnet_txq_encap(txq, &m0) != 0) { - if (m0 != NULL) - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - break; - } - - enq++; - ETHER_BPF_MTAP(ifp, m0); - } - - if (enq > 0 && vtnet_txq_notify(txq) != 0) { - if (tries++ < VTNET_NOTIFY_RETRIES) - goto again; - - txq->vtntx_stats.vtxs_rescheduled++; - taskqueue_enqueue(txq->vtntx_tq, &txq->vtntx_intrtask); - } -} - -static void -vtnet_start(struct ifnet *ifp) -{ - struct vtnet_softc *sc; - struct vtnet_txq *txq; - - sc = ifp->if_softc; - txq = &sc->vtnet_txqs[0]; - - VTNET_TXQ_LOCK(txq); - vtnet_start_locked(txq, ifp); - VTNET_TXQ_UNLOCK(txq); -} - -#else /* !VTNET_LEGACY_TX */ - static int vtnet_txq_mq_start_locked(struct vtnet_txq *txq, struct mbuf *m) { struct vtnet_softc *sc; struct virtqueue *vq; struct buf_ring *br; - struct ifnet *ifp; + if_t ifp; int enq, tries, error; sc = txq->vtntx_sc; @@ -2291,15 +2186,15 @@ vtnet_txq_mq_start_locked(struct vtnet_t VTNET_TXQ_LOCK_ASSERT(txq); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || + if ((if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) == 0 || sc->vtnet_link_active == 0) { if (m != NULL) - error = drbr_enqueue(ifp, br, m); + error = buf_ring_enqueue(br, m); return (error); } if (m != NULL) { - error = drbr_enqueue(ifp, br, m); + error = buf_ring_enqueue(br, m); if (error) return (error); } @@ -2309,23 +2204,23 @@ vtnet_txq_mq_start_locked(struct vtnet_t again: enq = 0; - while ((m = drbr_peek(ifp, br)) != NULL) { + while ((m = buf_ring_peek(br)) != NULL) { if (virtqueue_full(vq)) { - drbr_putback(ifp, br, m); + buf_ring_putback_sc(br, m); break; } if (vtnet_txq_encap(txq, &m) != 0) { if (m != NULL) - drbr_putback(ifp, br, m); + buf_ring_putback_sc(br, m); else - drbr_advance(ifp, br); + buf_ring_advance_sc(br); break; } - drbr_advance(ifp, br); + buf_ring_advance_sc(br); enq++; - ETHER_BPF_MTAP(ifp, m); + if_mtap(ifp, m, NULL, 0); } if (enq > 0 && vtnet_txq_notify(txq) != 0) { @@ -2340,13 +2235,13 @@ again: } static int -vtnet_txq_mq_start(struct ifnet *ifp, struct mbuf *m) +vtnet_txq_mq_start(if_t ifp, struct mbuf *m) { struct vtnet_softc *sc; struct vtnet_txq *txq; int i, npairs, error; - sc = ifp->if_softc; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); npairs = sc->vtnet_act_vq_pairs; /* check if flowid is set */ @@ -2361,7 +2256,7 @@ vtnet_txq_mq_start(struct ifnet *ifp, st error = vtnet_txq_mq_start_locked(txq, m); VTNET_TXQ_UNLOCK(txq); } else { - error = drbr_enqueue(ifp, txq->vtntx_br, m); + error = buf_ring_enqueue(txq->vtntx_br, m); taskqueue_enqueue(txq->vtntx_tq, &txq->vtntx_defrtask); } @@ -2378,29 +2273,20 @@ vtnet_txq_tq_deferred(void *xtxq, int pe sc = txq->vtntx_sc; VTNET_TXQ_LOCK(txq); - if (!drbr_empty(sc->vtnet_ifp, txq->vtntx_br)) + if (!buf_ring_empty(txq->vtntx_br)) vtnet_txq_mq_start_locked(txq, NULL); VTNET_TXQ_UNLOCK(txq); } -#endif /* VTNET_LEGACY_TX */ - static void vtnet_txq_start(struct vtnet_txq *txq) { struct vtnet_softc *sc; - struct ifnet *ifp; sc = txq->vtntx_sc; - ifp = sc->vtnet_ifp; -#ifdef VTNET_LEGACY_TX - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - vtnet_start_locked(txq, ifp); -#else - if (!drbr_empty(ifp, txq->vtntx_br)) + if (!buf_ring_empty(txq->vtntx_br)) vtnet_txq_mq_start_locked(txq, NULL); -#endif } static void @@ -2408,7 +2294,7 @@ vtnet_txq_tq_intr(void *xtxq, int pendin { struct vtnet_softc *sc; struct vtnet_txq *txq; - struct ifnet *ifp; + if_t ifp; txq = xtxq; sc = txq->vtntx_sc; @@ -2416,7 +2302,7 @@ vtnet_txq_tq_intr(void *xtxq, int pendin VTNET_TXQ_LOCK(txq); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) == 0) { VTNET_TXQ_UNLOCK(txq); return; } @@ -2470,7 +2356,7 @@ vtnet_tx_vq_intr(void *xtxq) { struct vtnet_softc *sc; struct vtnet_txq *txq; - struct ifnet *ifp; + if_t ifp; txq = xtxq; sc = txq->vtntx_sc; @@ -2489,7 +2375,7 @@ vtnet_tx_vq_intr(void *xtxq) VTNET_TXQ_LOCK(txq); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((if_getflags(ifp, IF_DRV_FLAGS) & IFF_DRV_RUNNING) == 0) { VTNET_TXQ_UNLOCK(txq); return; } @@ -2517,16 +2403,15 @@ vtnet_tx_start_all(struct vtnet_softc *s } } -#ifndef VTNET_LEGACY_TX static void -vtnet_qflush(struct ifnet *ifp) +vtnet_qflush(if_t ifp) { struct vtnet_softc *sc; struct vtnet_txq *txq; struct mbuf *m; int i; - sc = ifp->if_softc; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); for (i = 0; i < sc->vtnet_act_vq_pairs; i++) { txq = &sc->vtnet_txqs[i]; @@ -2536,10 +2421,7 @@ vtnet_qflush(struct ifnet *ifp) m_freem(m); VTNET_TXQ_UNLOCK(txq); } - - if_qflush(ifp); } -#endif static int vtnet_watchdog(struct vtnet_txq *txq) @@ -2608,7 +2490,7 @@ vtnet_get_counter(if_t ifp, ift_counter struct vtnet_rxq_stats rxaccum; struct vtnet_txq_stats txaccum; - sc = if_getsoftc(ifp); + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); vtnet_accum_stats(sc, &rxaccum, &txaccum); switch (cnt) { @@ -2620,12 +2502,10 @@ vtnet_get_counter(if_t ifp, ift_counter return (rxaccum.vrxs_ierrors); case IFCOUNTER_OPACKETS: return (txaccum.vtxs_opackets); -#ifndef VTNET_LEGACY_TX case IFCOUNTER_OBYTES: return (txaccum.vtxs_obytes); case IFCOUNTER_OMCASTS: return (txaccum.vtxs_omcasts); -#endif default: return (if_get_counter_default(ifp, cnt)); } @@ -2648,7 +2528,7 @@ vtnet_tick(void *xsc) timedout |= vtnet_watchdog(&sc->vtnet_txqs[i]); if (timedout != 0) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_clrflags(ifp, IF_DRV_FLAGS, IFF_DRV_RUNNING); vtnet_init_locked(sc); } else callout_schedule(&sc->vtnet_tick_ch, hz); @@ -2729,9 +2609,7 @@ vtnet_drain_taskqueues(struct vtnet_soft txq = &sc->vtnet_txqs[i]; if (txq->vtntx_tq != NULL) { taskqueue_drain(txq->vtntx_tq, &txq->vtntx_intrtask); -#ifndef VTNET_LEGACY_TX taskqueue_drain(txq->vtntx_tq, &txq->vtntx_defrtask); -#endif } } } @@ -2787,7 +2665,7 @@ vtnet_stop(struct vtnet_softc *sc) VTNET_CORE_LOCK_ASSERT(sc); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_clrflags(ifp, IF_DRV_FLAGS, IFF_DRV_RUNNING); sc->vtnet_link_active = 0; callout_stop(&sc->vtnet_tick_ch); @@ -2812,7 +2690,8 @@ vtnet_virtio_reinit(struct vtnet_softc * device_t dev; struct ifnet *ifp; uint64_t features; - int mask, error; + uint32_t caps, capenable, mask; + int error; dev = sc->vtnet_dev; ifp = sc->vtnet_ifp; @@ -2829,26 +2708,27 @@ vtnet_virtio_reinit(struct vtnet_softc * /* * Re-negotiate with the host, removing any disabled receive * features. Transmit features are disabled only on our side - * via if_capenable and if_hwassist. + * via IF_CAPEANBLE and IF_HWASSIST. */ - - if (ifp->if_capabilities & mask) { + caps = if_getflags(ifp, IF_CAPABILITIES); + capenable = if_getflags(ifp, IF_CAPENABLE); + if (caps & mask) { /* * We require both IPv4 and IPv6 offloading to be enabled * in order to negotiated it: VirtIO does not distinguish * between the two. */ - if ((ifp->if_capenable & mask) != mask) + if ((capenable & mask) != mask) features &= ~VIRTIO_NET_F_GUEST_CSUM; } - if (ifp->if_capabilities & IFCAP_LRO) { - if ((ifp->if_capenable & IFCAP_LRO) == 0) + if (caps & IFCAP_LRO) { + if ((capenable & IFCAP_LRO) == 0) features &= ~VTNET_LRO_FEATURES; } - if (ifp->if_capabilities & IFCAP_VLAN_HWFILTER) { - if ((ifp->if_capenable & IFCAP_VLAN_HWFILTER) == 0) + if (caps & IFCAP_VLAN_HWFILTER) { + if ((capenable & IFCAP_VLAN_HWFILTER) == 0) features &= ~VIRTIO_NET_F_CTRL_VLAN; } @@ -2873,7 +2753,7 @@ vtnet_init_rx_filters(struct vtnet_softc vtnet_rx_filter_mac(sc); } - if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) + if (if_getflags(ifp, IF_CAPENABLE) & IFCAP_VLAN_HWFILTER) vtnet_rx_filter_vlan(sc); } @@ -2990,25 +2870,27 @@ static int vtnet_reinit(struct vtnet_softc *sc) { struct ifnet *ifp; + uint64_t hwassist; int error; ifp = sc->vtnet_ifp; /* Use the current MAC address. */ - bcopy(IF_LLADDR(ifp), sc->vtnet_hwaddr, ETHER_ADDR_LEN); + bcopy(if_lladdr(ifp), sc->vtnet_hwaddr, ETHER_ADDR_LEN); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201412311008.sBVA8IQn049877>