Home | History | Annotate | Line # | Download | only in pci
if_vioif.c revision 1.98
      1 /*	$NetBSD: if_vioif.c,v 1.98 2023/03/23 02:42:49 yamaguchi Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2020 The NetBSD Foundation, Inc.
      5  * Copyright (c) 2010 Minoura Makoto.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.98 2023/03/23 02:42:49 yamaguchi Exp $");
     31 
     32 #ifdef _KERNEL_OPT
     33 #include "opt_net_mpsafe.h"
     34 #endif
     35 
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <sys/kernel.h>
     39 #include <sys/atomic.h>
     40 #include <sys/bus.h>
     41 #include <sys/condvar.h>
     42 #include <sys/device.h>
     43 #include <sys/evcnt.h>
     44 #include <sys/intr.h>
     45 #include <sys/kmem.h>
     46 #include <sys/mbuf.h>
     47 #include <sys/mutex.h>
     48 #include <sys/sockio.h>
     49 #include <sys/syslog.h>
     50 #include <sys/cpu.h>
     51 #include <sys/module.h>
     52 #include <sys/pcq.h>
     53 #include <sys/workqueue.h>
     54 #include <sys/xcall.h>
     55 
     56 #include <dev/pci/virtioreg.h>
     57 #include <dev/pci/virtiovar.h>
     58 
     59 #include <net/if.h>
     60 #include <net/if_dl.h>
     61 #include <net/if_media.h>
     62 #include <net/if_ether.h>
     63 
     64 #include <net/bpf.h>
     65 
     66 #include "ioconf.h"
     67 
     68 #ifdef NET_MPSAFE
     69 #define VIOIF_MPSAFE	1
     70 #define VIOIF_MULTIQ	1
     71 #endif
     72 
     73 /*
     74  * if_vioifreg.h:
     75  */
     76 /* Configuration registers */
     77 #define VIRTIO_NET_CONFIG_MAC		 0 /* 8bit x 6byte */
     78 #define VIRTIO_NET_CONFIG_STATUS	 6 /* 16bit */
     79 #define VIRTIO_NET_CONFIG_MAX_VQ_PAIRS	 8 /* 16bit */
     80 #define VIRTIO_NET_CONFIG_MTU		10 /* 16bit */
     81 
     82 /* Feature bits */
     83 #define VIRTIO_NET_F_CSUM		__BIT(0)
     84 #define VIRTIO_NET_F_GUEST_CSUM		__BIT(1)
     85 #define VIRTIO_NET_F_MAC		__BIT(5)
     86 #define VIRTIO_NET_F_GSO		__BIT(6)
     87 #define VIRTIO_NET_F_GUEST_TSO4		__BIT(7)
     88 #define VIRTIO_NET_F_GUEST_TSO6		__BIT(8)
     89 #define VIRTIO_NET_F_GUEST_ECN		__BIT(9)
     90 #define VIRTIO_NET_F_GUEST_UFO		__BIT(10)
     91 #define VIRTIO_NET_F_HOST_TSO4		__BIT(11)
     92 #define VIRTIO_NET_F_HOST_TSO6		__BIT(12)
     93 #define VIRTIO_NET_F_HOST_ECN		__BIT(13)
     94 #define VIRTIO_NET_F_HOST_UFO		__BIT(14)
     95 #define VIRTIO_NET_F_MRG_RXBUF		__BIT(15)
     96 #define VIRTIO_NET_F_STATUS		__BIT(16)
     97 #define VIRTIO_NET_F_CTRL_VQ		__BIT(17)
     98 #define VIRTIO_NET_F_CTRL_RX		__BIT(18)
     99 #define VIRTIO_NET_F_CTRL_VLAN		__BIT(19)
    100 #define VIRTIO_NET_F_CTRL_RX_EXTRA	__BIT(20)
    101 #define VIRTIO_NET_F_GUEST_ANNOUNCE	__BIT(21)
    102 #define VIRTIO_NET_F_MQ			__BIT(22)
    103 #define VIRTIO_NET_F_CTRL_MAC_ADDR 	__BIT(23)
    104 
    105 #define VIRTIO_NET_FLAG_BITS			\
    106 	VIRTIO_COMMON_FLAG_BITS			\
    107 	"b\x17" "CTRL_MAC\0"			\
    108 	"b\x16" "MQ\0"				\
    109 	"b\x15" "GUEST_ANNOUNCE\0"		\
    110 	"b\x14" "CTRL_RX_EXTRA\0"		\
    111 	"b\x13" "CTRL_VLAN\0"			\
    112 	"b\x12" "CTRL_RX\0"			\
    113 	"b\x11" "CTRL_VQ\0"			\
    114 	"b\x10" "STATUS\0"			\
    115 	"b\x0f" "MRG_RXBUF\0"			\
    116 	"b\x0e" "HOST_UFO\0"			\
    117 	"b\x0d" "HOST_ECN\0"			\
    118 	"b\x0c" "HOST_TSO6\0"			\
    119 	"b\x0b" "HOST_TSO4\0"			\
    120 	"b\x0a" "GUEST_UFO\0"			\
    121 	"b\x09" "GUEST_ECN\0"			\
    122 	"b\x08" "GUEST_TSO6\0"			\
    123 	"b\x07" "GUEST_TSO4\0"			\
    124 	"b\x06" "GSO\0"				\
    125 	"b\x05" "MAC\0"				\
    126 	"b\x01" "GUEST_CSUM\0"			\
    127 	"b\x00" "CSUM\0"
    128 
    129 /* Status */
    130 #define VIRTIO_NET_S_LINK_UP	1
    131 
    132 /* Packet header structure */
    133 struct virtio_net_hdr {
    134 	uint8_t		flags;
    135 	uint8_t		gso_type;
    136 	uint16_t	hdr_len;
    137 	uint16_t	gso_size;
    138 	uint16_t	csum_start;
    139 	uint16_t	csum_offset;
    140 
    141 	uint16_t	num_buffers; /* VIRTIO_NET_F_MRG_RXBUF enabled or v1 */
    142 } __packed;
    143 
    144 #define VIRTIO_NET_HDR_F_NEEDS_CSUM	1 /* flags */
    145 #define VIRTIO_NET_HDR_GSO_NONE		0 /* gso_type */
    146 #define VIRTIO_NET_HDR_GSO_TCPV4	1 /* gso_type */
    147 #define VIRTIO_NET_HDR_GSO_UDP		3 /* gso_type */
    148 #define VIRTIO_NET_HDR_GSO_TCPV6	4 /* gso_type */
    149 #define VIRTIO_NET_HDR_GSO_ECN		0x80 /* gso_type, |'ed */
    150 
    151 #define VIRTIO_NET_MAX_GSO_LEN		(65536+ETHER_HDR_LEN)
    152 
    153 /* Control virtqueue */
    154 struct virtio_net_ctrl_cmd {
    155 	uint8_t	class;
    156 	uint8_t	command;
    157 } __packed;
    158 #define VIRTIO_NET_CTRL_RX		0
    159 # define VIRTIO_NET_CTRL_RX_PROMISC	0
    160 # define VIRTIO_NET_CTRL_RX_ALLMULTI	1
    161 
    162 #define VIRTIO_NET_CTRL_MAC		1
    163 # define VIRTIO_NET_CTRL_MAC_TABLE_SET	0
    164 # define  VIRTIO_NET_CTRL_MAC_ADDR_SET	1
    165 
    166 #define VIRTIO_NET_CTRL_VLAN		2
    167 # define VIRTIO_NET_CTRL_VLAN_ADD	0
    168 # define VIRTIO_NET_CTRL_VLAN_DEL	1
    169 
    170 #define VIRTIO_NET_CTRL_MQ			4
    171 # define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET	0
    172 # define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN	1
    173 # define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX	0x8000
    174 
    175 struct virtio_net_ctrl_status {
    176 	uint8_t	ack;
    177 } __packed;
    178 #define VIRTIO_NET_OK			0
    179 #define VIRTIO_NET_ERR			1
    180 
    181 struct virtio_net_ctrl_rx {
    182 	uint8_t	onoff;
    183 } __packed;
    184 
    185 struct virtio_net_ctrl_mac_tbl {
    186 	uint32_t nentries;
    187 	uint8_t macs[][ETHER_ADDR_LEN];
    188 } __packed;
    189 
    190 struct virtio_net_ctrl_mac_addr {
    191 	uint8_t mac[ETHER_ADDR_LEN];
    192 } __packed;
    193 
    194 struct virtio_net_ctrl_vlan {
    195 	uint16_t id;
    196 } __packed;
    197 
    198 struct virtio_net_ctrl_mq {
    199 	uint16_t virtqueue_pairs;
    200 } __packed;
    201 
    202 /*
    203  * if_vioifvar.h:
    204  */
    205 
    206 /*
    207  * Locking notes:
    208  * + a field in vioif_netueue is protected by netq_lock (a spin mutex)
    209  *      - more than one lock cannot be held at onece
    210  * + a field in vioif_tx_context and vioif_rx_context is also protected
    211  *   by netq_lock.
    212  * + ctrlq_inuse is protected by ctrlq_wait_lock.
    213  *      - other fields in vioif_ctrlqueue are protected by ctrlq_inuse
    214  *      - netq_lock cannot be held along with ctrlq_wait_lock
    215  * + fields in vioif_softc except queues are protected by
    216  *   sc->sc_lock(an adaptive mutex)
    217  *      - the lock is held before acquisition of other locks
    218  */
    219 
    220 struct vioif_ctrl_cmdspec {
    221 	bus_dmamap_t	dmamap;
    222 	void		*buf;
    223 	bus_size_t	bufsize;
    224 };
    225 
    226 struct vioif_work {
    227 	struct work	 cookie;
    228 	void		(*func)(void *);
    229 	void		*arg;
    230 	unsigned int	 added;
    231 };
    232 
    233 struct vioif_net_map {
    234 	struct virtio_net_hdr	*vnm_hdr;
    235 	bus_dmamap_t		 vnm_hdr_map;
    236 	struct mbuf		*vnm_mbuf;
    237 	bus_dmamap_t		 vnm_mbuf_map;
    238 };
    239 
    240 #define VIOIF_NETQ_RX		0
    241 #define VIOIF_NETQ_TX		1
    242 #define VIOIF_NETQ_IDX		2
    243 #define VIOIF_NETQ_DIR(n)	((n) % VIOIF_NETQ_IDX)
    244 #define VIOIF_NETQ_PAIRIDX(n)	((n) / VIOIF_NETQ_IDX)
    245 #define VIOIF_NETQ_RXQID(n)	((n) * VIOIF_NETQ_IDX + VIOIF_NETQ_RX)
    246 #define VIOIF_NETQ_TXQID(n)	((n) * VIOIF_NETQ_IDX + VIOIF_NETQ_TX)
    247 
    248 struct vioif_netqueue {
    249 	kmutex_t		 netq_lock;
    250 	struct virtqueue	*netq_vq;
    251 	bool			 netq_stopping;
    252 	bool			 netq_running_handle;
    253 	void			*netq_maps_kva;
    254 	struct vioif_net_map	*netq_maps;
    255 
    256 	void			*netq_softint;
    257 	struct vioif_work	 netq_work;
    258 	bool			 netq_workqueue;
    259 
    260 	char			 netq_evgroup[32];
    261 	struct evcnt		 netq_mbuf_load_failed;
    262 	struct evcnt		 netq_enqueue_reserve_failed;
    263 
    264 	void			*netq_ctx;
    265 };
    266 
    267 struct vioif_tx_context {
    268 	bool			 txc_link_active;
    269 	pcq_t			*txc_intrq;
    270 	void			*txc_deferred_transmit;
    271 
    272 	struct evcnt		 txc_defrag_failed;
    273 };
    274 
    275 struct vioif_rx_context {
    276 	struct evcnt		 rxc_mbuf_enobufs;
    277 };
    278 struct vioif_ctrlqueue {
    279 	struct virtqueue		*ctrlq_vq;
    280 	enum {
    281 		FREE, INUSE, DONE
    282 	}				ctrlq_inuse;
    283 	kcondvar_t			ctrlq_wait;
    284 	kmutex_t			ctrlq_wait_lock;
    285 	struct lwp			*ctrlq_owner;
    286 
    287 	struct virtio_net_ctrl_cmd	*ctrlq_cmd;
    288 	struct virtio_net_ctrl_status	*ctrlq_status;
    289 	struct virtio_net_ctrl_rx	*ctrlq_rx;
    290 	struct virtio_net_ctrl_mac_tbl	*ctrlq_mac_tbl_uc;
    291 	struct virtio_net_ctrl_mac_tbl	*ctrlq_mac_tbl_mc;
    292 	struct virtio_net_ctrl_mac_addr	*ctrlq_mac_addr;
    293 	struct virtio_net_ctrl_mq	*ctrlq_mq;
    294 
    295 	bus_dmamap_t			ctrlq_cmd_dmamap;
    296 	bus_dmamap_t			ctrlq_status_dmamap;
    297 	bus_dmamap_t			ctrlq_rx_dmamap;
    298 	bus_dmamap_t			ctrlq_tbl_uc_dmamap;
    299 	bus_dmamap_t			ctrlq_tbl_mc_dmamap;
    300 	bus_dmamap_t			ctrlq_mac_addr_dmamap;
    301 	bus_dmamap_t			ctrlq_mq_dmamap;
    302 
    303 	struct evcnt			ctrlq_cmd_load_failed;
    304 	struct evcnt			ctrlq_cmd_failed;
    305 };
    306 
    307 struct vioif_softc {
    308 	device_t		sc_dev;
    309 	kmutex_t		sc_lock;
    310 	struct sysctllog	*sc_sysctllog;
    311 
    312 	struct virtio_softc	*sc_virtio;
    313 	struct virtqueue	*sc_vqs;
    314 	u_int			 sc_hdr_size;
    315 
    316 	int			sc_max_nvq_pairs;
    317 	int			sc_req_nvq_pairs;
    318 	int			sc_act_nvq_pairs;
    319 
    320 	uint8_t			sc_mac[ETHER_ADDR_LEN];
    321 	struct ethercom		sc_ethercom;
    322 	int			sc_link_state;
    323 
    324 	struct vioif_netqueue	*sc_netqs;
    325 
    326 	bool			sc_has_ctrl;
    327 	struct vioif_ctrlqueue	sc_ctrlq;
    328 
    329 	bus_dma_segment_t	sc_hdr_segs[1];
    330 	void			*sc_dmamem;
    331 	void			*sc_kmem;
    332 
    333 	void			*sc_ctl_softint;
    334 
    335 	struct workqueue	*sc_txrx_workqueue;
    336 	bool			 sc_txrx_workqueue_sysctl;
    337 	u_int			 sc_tx_intr_process_limit;
    338 	u_int			 sc_tx_process_limit;
    339 	u_int			 sc_rx_intr_process_limit;
    340 	u_int			 sc_rx_process_limit;
    341 };
    342 #define VIRTIO_NET_TX_MAXNSEGS		(16) /* XXX */
    343 #define VIRTIO_NET_CTRL_MAC_MAXENTRIES	(64) /* XXX */
    344 
    345 #define VIOIF_TX_INTR_PROCESS_LIMIT	256
    346 #define VIOIF_TX_PROCESS_LIMIT		256
    347 #define VIOIF_RX_INTR_PROCESS_LIMIT	0U
    348 #define VIOIF_RX_PROCESS_LIMIT		256
    349 
    350 #define VIOIF_WORKQUEUE_PRI		PRI_SOFTNET
    351 #define VIOIF_IS_LINK_ACTIVE(_sc)	((_sc)->sc_link_state == LINK_STATE_UP ? \
    352 					    true : false)
    353 
    354 /* cfattach interface functions */
    355 static int	vioif_match(device_t, cfdata_t, void *);
    356 static void	vioif_attach(device_t, device_t, void *);
    357 static int	vioif_finalize_teardown(device_t);
    358 
    359 /* ifnet interface functions */
    360 static int	vioif_init(struct ifnet *);
    361 static void	vioif_stop(struct ifnet *, int);
    362 static void	vioif_start(struct ifnet *);
    363 static void	vioif_start_locked(struct ifnet *, struct vioif_netqueue *);
    364 static int	vioif_transmit(struct ifnet *, struct mbuf *);
    365 static void	vioif_transmit_locked(struct ifnet *, struct vioif_netqueue *);
    366 static int	vioif_ioctl(struct ifnet *, u_long, void *);
    367 static void	vioif_watchdog(struct ifnet *);
    368 static int	vioif_ifflags_cb(struct ethercom *);
    369 
    370 /* tx & rx */
    371 static void	vioif_net_sched_handle(struct vioif_softc *,
    372 		    struct vioif_netqueue *);
    373 
    374 /* rx */
    375 static void	vioif_populate_rx_mbufs_locked(struct vioif_softc *,
    376 		    struct vioif_netqueue *);
    377 static void	vioif_rx_queue_clear(struct vioif_softc *, struct virtio_softc *,
    378 		    struct vioif_netqueue *);
    379 static bool	vioif_rx_deq_locked(struct vioif_softc *, struct virtio_softc *,
    380 		    struct vioif_netqueue *, u_int, size_t *);
    381 static int	vioif_rx_intr(void *);
    382 static void	vioif_rx_handle(void *);
    383 
    384 /* tx */
    385 static int	vioif_tx_intr(void *);
    386 static void	vioif_tx_handle(void *);
    387 static void	vioif_tx_queue_clear(struct vioif_softc *, struct virtio_softc *,
    388 		    struct vioif_netqueue *);
    389 static bool	vioif_tx_deq_locked(struct vioif_softc *, struct virtio_softc *,
    390 		    struct vioif_netqueue *, u_int);
    391 static void	vioif_deferred_transmit(void *);
    392 
    393 /* workqueue */
    394 static struct workqueue*
    395 		vioif_workq_create(const char *, pri_t, int, int);
    396 static void	vioif_workq_destroy(struct workqueue *);
    397 static void	vioif_workq_work(struct work *, void *);
    398 static void	vioif_work_set(struct vioif_work *, void(*)(void *), void *);
    399 static void	vioif_work_add(struct workqueue *, struct vioif_work *);
    400 static void	vioif_work_wait(struct workqueue *, struct vioif_work *);
    401 
    402 /* other control */
    403 static int	vioif_get_link_status(struct vioif_softc *);
    404 static void	vioif_update_link_status(struct vioif_softc *);
    405 static int	vioif_ctrl_rx(struct vioif_softc *, int, bool);
    406 static int	vioif_set_promisc(struct vioif_softc *, bool);
    407 static int	vioif_set_allmulti(struct vioif_softc *, bool);
    408 static int	vioif_set_rx_filter(struct vioif_softc *);
    409 static int	vioif_rx_filter(struct vioif_softc *);
    410 static int	vioif_set_mac_addr(struct vioif_softc *);
    411 static int	vioif_ctrl_intr(void *);
    412 static int	vioif_config_change(struct virtio_softc *);
    413 static void	vioif_ctl_softint(void *);
    414 static int	vioif_ctrl_mq_vq_pairs_set(struct vioif_softc *, int);
    415 static void	vioif_enable_interrupt_vqpairs(struct vioif_softc *);
    416 static void	vioif_disable_interrupt_vqpairs(struct vioif_softc *);
    417 static int	vioif_setup_sysctl(struct vioif_softc *);
    418 static void	vioif_setup_stats(struct vioif_softc *);
    419 static int	vioif_ifflags(struct vioif_softc *);
    420 static void	vioif_intr_barrier(void);
    421 
    422 CFATTACH_DECL_NEW(vioif, sizeof(struct vioif_softc),
    423 		  vioif_match, vioif_attach, NULL, NULL);
    424 
    425 static int
    426 vioif_match(device_t parent, cfdata_t match, void *aux)
    427 {
    428 	struct virtio_attach_args *va = aux;
    429 
    430 	if (va->sc_childdevid == VIRTIO_DEVICE_ID_NETWORK)
    431 		return 1;
    432 
    433 	return 0;
    434 }
    435 
    436 static int
    437 vioif_dmamap_create(struct vioif_softc *sc, bus_dmamap_t *map,
    438     bus_size_t size, int nsegs, const char *usage)
    439 {
    440 	int r;
    441 
    442 	r = bus_dmamap_create(virtio_dmat(sc->sc_virtio), size,
    443 	    nsegs, size, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, map);
    444 
    445 	if (r != 0) {
    446 		aprint_error_dev(sc->sc_dev, "%s dmamap creation failed, "
    447 		    "error code %d\n", usage, r);
    448 	}
    449 
    450 	return r;
    451 }
    452 
    453 static void
    454 vioif_dmamap_destroy(struct vioif_softc *sc, bus_dmamap_t *map)
    455 {
    456 
    457 	if (*map) {
    458 		bus_dmamap_destroy(virtio_dmat(sc->sc_virtio), *map);
    459 		*map = NULL;
    460 	}
    461 }
    462 
    463 static int
    464 vioif_dmamap_create_load(struct vioif_softc *sc, bus_dmamap_t *map,
    465     void *buf, bus_size_t size, int nsegs, int rw, const char *usage)
    466 {
    467 	int r;
    468 
    469 	r = vioif_dmamap_create(sc, map, size, nsegs, usage);
    470 	if (r != 0)
    471 		return 1;
    472 
    473 	r = bus_dmamap_load(virtio_dmat(sc->sc_virtio), *map, buf,
    474 	    size, NULL, rw | BUS_DMA_NOWAIT);
    475 	if (r != 0) {
    476 		vioif_dmamap_destroy(sc, map);
    477 		aprint_error_dev(sc->sc_dev, "%s dmamap load failed. "
    478 		    "error code %d\n", usage, r);
    479 	}
    480 
    481 	return r;
    482 }
    483 
    484 static void *
    485 vioif_assign_mem(intptr_t *p, size_t size)
    486 {
    487 	intptr_t rv;
    488 
    489 	rv = *p;
    490 	*p += size;
    491 
    492 	return (void *)rv;
    493 }
    494 
    495 static void
    496 vioif_alloc_queues(struct vioif_softc *sc)
    497 {
    498 	int nvq_pairs = sc->sc_max_nvq_pairs;
    499 	size_t nvqs, netq_num;
    500 
    501 	KASSERT(nvq_pairs <= VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX);
    502 
    503 	nvqs = netq_num = sc->sc_max_nvq_pairs * 2;
    504 	if (sc->sc_has_ctrl)
    505 		nvqs++;
    506 
    507 	sc->sc_vqs = kmem_zalloc(sizeof(sc->sc_vqs[0]) * nvqs, KM_SLEEP);
    508 	sc->sc_netqs = kmem_zalloc(sizeof(sc->sc_vqs[0]) * netq_num,
    509 	    KM_SLEEP);
    510 }
    511 
    512 static void
    513 vioif_free_queues(struct vioif_softc *sc)
    514 {
    515 	size_t nvqs, netq_num;
    516 
    517 	nvqs = netq_num = sc->sc_max_nvq_pairs * 2;
    518 	if (sc->sc_ctrlq.ctrlq_vq)
    519 		nvqs++;
    520 
    521 	kmem_free(sc->sc_netqs, sizeof(sc->sc_netqs[0]) * netq_num);
    522 	kmem_free(sc->sc_vqs, sizeof(sc->sc_vqs[0]) * nvqs);
    523 	sc->sc_netqs = NULL;
    524 	sc->sc_vqs = NULL;
    525 }
    526 
    527 static int
    528 vioif_netqueue_init(struct vioif_softc *sc, struct virtio_softc *vsc,
    529     size_t qid, u_int softint_flags)
    530 {
    531 	static const struct {
    532 		const char	*dirname;
    533 		int		 segsize;
    534 		int		 nsegs;
    535 		int 		(*intrhand)(void *);
    536 		void		(*sihand)(void *);
    537 	} params[VIOIF_NETQ_IDX] = {
    538 		[VIOIF_NETQ_RX] = {
    539 			.dirname	= "rx",
    540 			.segsize	= MCLBYTES,
    541 			.nsegs		= 2,
    542 			.intrhand	= vioif_rx_intr,
    543 			.sihand		= vioif_rx_handle,
    544 		},
    545 		[VIOIF_NETQ_TX] = {
    546 			.dirname	= "tx",
    547 			.segsize	= ETHER_MAX_LEN - ETHER_HDR_LEN,
    548 			.nsegs		= 2,
    549 			.intrhand	= vioif_tx_intr,
    550 			.sihand		= vioif_tx_handle,
    551 		}
    552 	};
    553 
    554 	struct virtqueue *vq;
    555 	struct vioif_netqueue *netq;
    556 	struct vioif_tx_context *txc;
    557 	struct vioif_rx_context *rxc;
    558 	char qname[32];
    559 	int r, dir;
    560 
    561 	txc = NULL;
    562 	rxc = NULL;
    563 	netq = &sc->sc_netqs[qid];
    564 	vq = &sc->sc_vqs[qid];
    565 	dir = VIOIF_NETQ_DIR(qid);
    566 
    567 	netq->netq_vq = &sc->sc_vqs[qid];
    568 	netq->netq_stopping = false;
    569 	netq->netq_running_handle = false;
    570 
    571 	snprintf(qname, sizeof(qname), "%s%zu",
    572 	    params[dir].dirname, VIOIF_NETQ_PAIRIDX(qid));
    573 	snprintf(netq->netq_evgroup, sizeof(netq->netq_evgroup),
    574 	    "%s-%s", device_xname(sc->sc_dev), qname);
    575 
    576 	mutex_init(&netq->netq_lock, MUTEX_DEFAULT, IPL_NET);
    577 	r = virtio_alloc_vq(vsc, vq, qid,
    578 	    params[dir].segsize + sc->sc_hdr_size,
    579 	    params[dir].nsegs, qname);
    580 	if (r != 0)
    581 		goto err;
    582 	netq->netq_vq = vq;
    583 
    584 	netq->netq_vq->vq_intrhand = params[dir].intrhand;
    585 	netq->netq_vq->vq_intrhand_arg = netq;
    586 	netq->netq_softint = softint_establish(softint_flags,
    587 	    params[dir].sihand, netq);
    588 	if (netq->netq_softint == NULL) {
    589 		aprint_error_dev(sc->sc_dev,
    590 		    "couldn't establish %s softint\n",
    591 		    params[dir].dirname);
    592 		goto err;
    593 	}
    594 	vioif_work_set(&netq->netq_work, params[dir].sihand, netq);
    595 
    596 	switch (dir) {
    597 	case VIOIF_NETQ_RX:
    598 		rxc = kmem_zalloc(sizeof(*rxc), KM_SLEEP);
    599 		netq->netq_ctx = rxc;
    600 		/* nothing to do */
    601 		break;
    602 	case VIOIF_NETQ_TX:
    603 		txc = kmem_zalloc(sizeof(*txc), KM_SLEEP);
    604 		netq->netq_ctx = (void *)txc;
    605 		txc->txc_deferred_transmit = softint_establish(softint_flags,
    606 		    vioif_deferred_transmit, netq);
    607 		if (txc->txc_deferred_transmit == NULL) {
    608 			aprint_error_dev(sc->sc_dev,
    609 			    "couldn't establish softint for "
    610 			    "tx deferred transmit\n");
    611 			goto err;
    612 		}
    613 		txc->txc_link_active = VIOIF_IS_LINK_ACTIVE(sc);
    614 		txc->txc_intrq = pcq_create(vq->vq_num, KM_SLEEP);
    615 		break;
    616 	}
    617 
    618 	return 0;
    619 
    620 err:
    621 	netq->netq_ctx = NULL;
    622 
    623 	if (rxc != NULL) {
    624 		kmem_free(rxc, sizeof(*rxc));
    625 	}
    626 
    627 	if (txc != NULL) {
    628 		if (txc->txc_deferred_transmit != NULL)
    629 			softint_disestablish(txc->txc_deferred_transmit);
    630 		if (txc->txc_intrq != NULL)
    631 			pcq_destroy(txc->txc_intrq);
    632 		kmem_free(txc, sizeof(txc));
    633 	}
    634 
    635 	vioif_work_set(&netq->netq_work, NULL, NULL);
    636 	if (netq->netq_softint != NULL) {
    637 		softint_disestablish(netq->netq_softint);
    638 		netq->netq_softint = NULL;
    639 	}
    640 	netq->netq_vq->vq_intrhand = NULL;
    641 	netq->netq_vq->vq_intrhand_arg = NULL;
    642 
    643 	virtio_free_vq(vsc, vq);
    644 	mutex_destroy(&netq->netq_lock);
    645 	netq->netq_vq = NULL;
    646 
    647 	return -1;
    648 }
    649 
    650 static void
    651 vioif_netqueue_teardown(struct vioif_softc *sc, struct virtio_softc *vsc,
    652     size_t qid)
    653 {
    654 	struct vioif_netqueue *netq;
    655 	struct vioif_rx_context *rxc;
    656 	struct vioif_tx_context *txc;
    657 	int dir;
    658 
    659 	netq = &sc->sc_netqs[qid];
    660 
    661 	if (netq->netq_vq == NULL)
    662 		return;
    663 
    664 	netq = &sc->sc_netqs[qid];
    665 	dir = VIOIF_NETQ_DIR(qid);
    666 	switch (dir) {
    667 	case VIOIF_NETQ_RX:
    668 		rxc = netq->netq_ctx;
    669 		netq->netq_ctx = NULL;
    670 		kmem_free(rxc, sizeof(*rxc));
    671 		break;
    672 	case VIOIF_NETQ_TX:
    673 		txc = netq->netq_ctx;
    674 		netq->netq_ctx = NULL;
    675 		softint_disestablish(txc->txc_deferred_transmit);
    676 		pcq_destroy(txc->txc_intrq);
    677 		kmem_free(txc, sizeof(*txc));
    678 		break;
    679 	}
    680 
    681 	softint_disestablish(netq->netq_softint);
    682 	virtio_free_vq(vsc, netq->netq_vq);
    683 	mutex_destroy(&netq->netq_lock);
    684 	netq->netq_vq = NULL;
    685 }
    686 
    687 /* allocate memory */
    688 /*
    689  * dma memory is used for:
    690  *   netq_maps_kva:	 metadata array for received frames (READ) and
    691  *			 sent frames (WRITE)
    692  *   ctrlq_cmd:		 command to be sent via ctrl vq (WRITE)
    693  *   ctrlq_status:	 return value for a command via ctrl vq (READ)
    694  *   ctrlq_rx:		 parameter for a VIRTIO_NET_CTRL_RX class command
    695  *			 (WRITE)
    696  *   ctrlq_mac_tbl_uc:	 unicast MAC address filter for a VIRTIO_NET_CTRL_MAC
    697  *			 class command (WRITE)
    698  *   ctrlq_mac_tbl_mc:	 multicast MAC address filter for a VIRTIO_NET_CTRL_MAC
    699  *			 class command (WRITE)
    700  * ctrlq_* structures are allocated only one each; they are protected by
    701  * ctrlq_inuse variable and ctrlq_wait condvar.
    702  */
    703 static int
    704 vioif_alloc_mems(struct vioif_softc *sc)
    705 {
    706 	struct virtio_softc *vsc = sc->sc_virtio;
    707 	struct vioif_netqueue *netq;
    708 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
    709 	struct vioif_net_map *maps;
    710 	unsigned int vq_num;
    711 	int r, rsegs;
    712 	bus_size_t dmamemsize;
    713 	size_t qid, i, netq_num, kmemsize;
    714 	void *vaddr;
    715 	intptr_t p;
    716 
    717 	netq_num = sc->sc_max_nvq_pairs * 2;
    718 
    719 	/* allocate DMA memory */
    720 	dmamemsize = 0;
    721 
    722 	for (qid = 0; qid < netq_num; qid++) {
    723 		maps = sc->sc_netqs[qid].netq_maps;
    724 		vq_num = sc->sc_netqs[qid].netq_vq->vq_num;
    725 		dmamemsize += sizeof(*maps[0].vnm_hdr) * vq_num;
    726 	}
    727 
    728 	if (sc->sc_has_ctrl) {
    729 		dmamemsize += sizeof(struct virtio_net_ctrl_cmd);
    730 		dmamemsize += sizeof(struct virtio_net_ctrl_status);
    731 		dmamemsize += sizeof(struct virtio_net_ctrl_rx);
    732 		dmamemsize += sizeof(struct virtio_net_ctrl_mac_tbl)
    733 		    + ETHER_ADDR_LEN;
    734 		dmamemsize += sizeof(struct virtio_net_ctrl_mac_tbl)
    735 		    + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES;
    736 		dmamemsize += sizeof(struct virtio_net_ctrl_mac_addr);
    737 		dmamemsize += sizeof(struct virtio_net_ctrl_mq);
    738 	}
    739 
    740 	r = bus_dmamem_alloc(virtio_dmat(vsc), dmamemsize, 0, 0,
    741 	    &sc->sc_hdr_segs[0], 1, &rsegs, BUS_DMA_NOWAIT);
    742 	if (r != 0) {
    743 		aprint_error_dev(sc->sc_dev,
    744 		    "DMA memory allocation failed, size %zu, "
    745 		    "error code %d\n", dmamemsize, r);
    746 		goto err_none;
    747 	}
    748 	r = bus_dmamem_map(virtio_dmat(vsc),&sc->sc_hdr_segs[0], 1,
    749 	    dmamemsize, &vaddr, BUS_DMA_NOWAIT);
    750 	if (r != 0) {
    751 		aprint_error_dev(sc->sc_dev,
    752 		    "DMA memory map failed, error code %d\n", r);
    753 		goto err_dmamem_alloc;
    754 	}
    755 
    756 	/* assign DMA memory */
    757 	memset(vaddr, 0, dmamemsize);
    758 	sc->sc_dmamem = vaddr;
    759 	p = (intptr_t) vaddr;
    760 
    761 	for (qid = 0; qid < netq_num; qid++) {
    762 		netq = &sc->sc_netqs[qid];
    763 		maps = netq->netq_maps;
    764 		vq_num = netq->netq_vq->vq_num;
    765 
    766 		netq->netq_maps_kva = vioif_assign_mem(&p,
    767 		    sizeof(*maps[0].vnm_hdr) * vq_num);
    768 	}
    769 
    770 	if (sc->sc_has_ctrl) {
    771 		ctrlq->ctrlq_cmd = vioif_assign_mem(&p,
    772 		    sizeof(*ctrlq->ctrlq_cmd));
    773 		ctrlq->ctrlq_status = vioif_assign_mem(&p,
    774 		    sizeof(*ctrlq->ctrlq_status));
    775 		ctrlq->ctrlq_rx = vioif_assign_mem(&p,
    776 		    sizeof(*ctrlq->ctrlq_rx));
    777 		ctrlq->ctrlq_mac_tbl_uc = vioif_assign_mem(&p,
    778 		    sizeof(*ctrlq->ctrlq_mac_tbl_uc)
    779 		    + ETHER_ADDR_LEN);
    780 		ctrlq->ctrlq_mac_tbl_mc = vioif_assign_mem(&p,
    781 		    sizeof(*ctrlq->ctrlq_mac_tbl_mc)
    782 		    + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES);
    783 		ctrlq->ctrlq_mac_addr = vioif_assign_mem(&p,
    784 		    sizeof(*ctrlq->ctrlq_mac_addr));
    785 		ctrlq->ctrlq_mq = vioif_assign_mem(&p, sizeof(*ctrlq->ctrlq_mq));
    786 	}
    787 
    788 	/* allocate kmem */
    789 	kmemsize = 0;
    790 
    791 	for (qid = 0; qid < netq_num; qid++) {
    792 		netq = &sc->sc_netqs[qid];
    793 		vq_num = netq->netq_vq->vq_num;
    794 
    795 		kmemsize += sizeof(netq->netq_maps[0]) * vq_num;
    796 	}
    797 
    798 	vaddr = kmem_zalloc(kmemsize, KM_SLEEP);
    799 	sc->sc_kmem = vaddr;
    800 
    801 	/* assign allocated kmem */
    802 	p = (intptr_t) vaddr;
    803 
    804 	for (qid = 0; qid < netq_num; qid++) {
    805 		netq = &sc->sc_netqs[qid];
    806 		vq_num = netq->netq_vq->vq_num;
    807 
    808 		netq->netq_maps = vioif_assign_mem(&p,
    809 		    sizeof(netq->netq_maps[0]) * vq_num);
    810 	}
    811 
    812 	/* prepare dmamaps */
    813 	for (qid = 0; qid < netq_num; qid++) {
    814 		static const struct {
    815 			const char	*msg_hdr;
    816 			const char	*msg_payload;
    817 			int		 dma_flag;
    818 			bus_size_t	 dma_size;
    819 			int		 dma_nsegs;
    820 		} dmaparams[VIOIF_NETQ_IDX] = {
    821 			[VIOIF_NETQ_RX] = {
    822 				.msg_hdr	= "rx header",
    823 				.msg_payload	= "rx payload",
    824 				.dma_flag	= BUS_DMA_READ,
    825 				.dma_size	= MCLBYTES - ETHER_ALIGN,
    826 				.dma_nsegs	= 1,
    827 			},
    828 			[VIOIF_NETQ_TX] = {
    829 				.msg_hdr	= "tx header",
    830 				.msg_payload	= "tx payload",
    831 				.dma_flag	= BUS_DMA_WRITE,
    832 				.dma_size	= ETHER_MAX_LEN,
    833 				.dma_nsegs	= VIRTIO_NET_TX_MAXNSEGS,
    834 			}
    835 		};
    836 
    837 		struct virtio_net_hdr *hdrs;
    838 		int dir;
    839 
    840 		dir = VIOIF_NETQ_DIR(qid);
    841 		netq = &sc->sc_netqs[qid];
    842 		vq_num = netq->netq_vq->vq_num;
    843 		maps = netq->netq_maps;
    844 		hdrs = netq->netq_maps_kva;
    845 
    846 		for (i = 0; i < vq_num; i++) {
    847 			maps[i].vnm_hdr = &hdrs[i];
    848 
    849 			r = vioif_dmamap_create_load(sc, &maps[i].vnm_hdr_map,
    850 			    maps[i].vnm_hdr, sc->sc_hdr_size, 1,
    851 			    dmaparams[dir].dma_flag, dmaparams[dir].msg_hdr);
    852 			if (r != 0)
    853 				goto err_reqs;
    854 
    855 			r = vioif_dmamap_create(sc, &maps[i].vnm_mbuf_map,
    856 			    dmaparams[dir].dma_size, dmaparams[dir].dma_nsegs,
    857 			    dmaparams[dir].msg_payload);
    858 			if (r != 0)
    859 				goto err_reqs;
    860 		}
    861 	}
    862 
    863 	if (sc->sc_has_ctrl) {
    864 		/* control vq class & command */
    865 		r = vioif_dmamap_create_load(sc, &ctrlq->ctrlq_cmd_dmamap,
    866 		    ctrlq->ctrlq_cmd, sizeof(*ctrlq->ctrlq_cmd), 1,
    867 		    BUS_DMA_WRITE, "control command");
    868 		if (r != 0)
    869 			goto err_reqs;
    870 
    871 		r = vioif_dmamap_create_load(sc, &ctrlq->ctrlq_status_dmamap,
    872 		    ctrlq->ctrlq_status, sizeof(*ctrlq->ctrlq_status), 1,
    873 		    BUS_DMA_READ, "control status");
    874 		if (r != 0)
    875 			goto err_reqs;
    876 
    877 		/* control vq rx mode command parameter */
    878 		r = vioif_dmamap_create_load(sc, &ctrlq->ctrlq_rx_dmamap,
    879 		    ctrlq->ctrlq_rx, sizeof(*ctrlq->ctrlq_rx), 1,
    880 		    BUS_DMA_WRITE, "rx mode control command");
    881 		if (r != 0)
    882 			goto err_reqs;
    883 
    884 		/* multiqueue set command */
    885 		r = vioif_dmamap_create_load(sc, &ctrlq->ctrlq_mq_dmamap,
    886 		    ctrlq->ctrlq_mq, sizeof(*ctrlq->ctrlq_mq), 1,
    887 		    BUS_DMA_WRITE, "multiqueue set command");
    888 		if (r != 0)
    889 			goto err_reqs;
    890 
    891 		/* control vq MAC filter table for unicast */
    892 		/* do not load now since its length is variable */
    893 		r = vioif_dmamap_create(sc, &ctrlq->ctrlq_tbl_uc_dmamap,
    894 		    sizeof(*ctrlq->ctrlq_mac_tbl_uc)
    895 		    + ETHER_ADDR_LEN, 1,
    896 		    "unicast MAC address filter command");
    897 		if (r != 0)
    898 			goto err_reqs;
    899 
    900 		/* control vq MAC filter table for multicast */
    901 		r = vioif_dmamap_create(sc, &ctrlq->ctrlq_tbl_mc_dmamap,
    902 		    sizeof(*ctrlq->ctrlq_mac_tbl_mc)
    903 		    + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES, 1,
    904 		    "multicast MAC address filter command");
    905 		if (r != 0)
    906 			goto err_reqs;
    907 
    908 		/* control vq MAC address set command */
    909 		r = vioif_dmamap_create_load(sc,
    910 		    &ctrlq->ctrlq_mac_addr_dmamap,
    911 		    ctrlq->ctrlq_mac_addr,
    912 		    sizeof(*ctrlq->ctrlq_mac_addr), 1,
    913 		    BUS_DMA_WRITE, "mac addr set command");
    914 		if (r != 0)
    915 			goto err_reqs;
    916 	}
    917 
    918 	return 0;
    919 
    920 err_reqs:
    921 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_tbl_mc_dmamap);
    922 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_tbl_uc_dmamap);
    923 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_rx_dmamap);
    924 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_status_dmamap);
    925 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_cmd_dmamap);
    926 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_mac_addr_dmamap);
    927 	for (qid = 0; qid < netq_num; qid++) {
    928 		vq_num = sc->sc_netqs[qid].netq_vq->vq_num;
    929 		maps = sc->sc_netqs[qid].netq_maps;
    930 
    931 		for (i = 0; i < vq_num; i++) {
    932 			vioif_dmamap_destroy(sc, &maps[i].vnm_mbuf_map);
    933 			vioif_dmamap_destroy(sc, &maps[i].vnm_hdr_map);
    934 		}
    935 	}
    936 	if (sc->sc_kmem) {
    937 		kmem_free(sc->sc_kmem, kmemsize);
    938 		sc->sc_kmem = NULL;
    939 	}
    940 	bus_dmamem_unmap(virtio_dmat(vsc), sc->sc_dmamem, dmamemsize);
    941 err_dmamem_alloc:
    942 	bus_dmamem_free(virtio_dmat(vsc), &sc->sc_hdr_segs[0], 1);
    943 err_none:
    944 	return -1;
    945 }
    946 
    947 static void
    948 vioif_attach(device_t parent, device_t self, void *aux)
    949 {
    950 	struct vioif_softc *sc = device_private(self);
    951 	struct virtio_softc *vsc = device_private(parent);
    952 	struct vioif_netqueue *txq0;
    953 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
    954 	uint64_t features, req_features;
    955 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    956 	u_int softint_flags;
    957 	int r, i, req_flags;
    958 	char xnamebuf[MAXCOMLEN];
    959 	size_t netq_num;
    960 
    961 	if (virtio_child(vsc) != NULL) {
    962 		aprint_normal(": child already attached for %s; "
    963 		    "something wrong...\n", device_xname(parent));
    964 		return;
    965 	}
    966 
    967 	sc->sc_dev = self;
    968 	sc->sc_virtio = vsc;
    969 	sc->sc_link_state = LINK_STATE_UNKNOWN;
    970 
    971 	sc->sc_max_nvq_pairs = 1;
    972 	sc->sc_req_nvq_pairs = 1;
    973 	sc->sc_act_nvq_pairs = 1;
    974 	sc->sc_txrx_workqueue_sysctl = true;
    975 	sc->sc_tx_intr_process_limit = VIOIF_TX_INTR_PROCESS_LIMIT;
    976 	sc->sc_tx_process_limit = VIOIF_TX_PROCESS_LIMIT;
    977 	sc->sc_rx_intr_process_limit = VIOIF_RX_INTR_PROCESS_LIMIT;
    978 	sc->sc_rx_process_limit = VIOIF_RX_PROCESS_LIMIT;
    979 
    980 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    981 
    982 	snprintf(xnamebuf, sizeof(xnamebuf), "%s_txrx", device_xname(self));
    983 	sc->sc_txrx_workqueue = vioif_workq_create(xnamebuf, VIOIF_WORKQUEUE_PRI,
    984 	    IPL_NET, WQ_PERCPU | WQ_MPSAFE);
    985 	if (sc->sc_txrx_workqueue == NULL)
    986 		goto err;
    987 
    988 	req_flags = 0;
    989 
    990 #ifdef VIOIF_MPSAFE
    991 	req_flags |= VIRTIO_F_INTR_MPSAFE;
    992 #endif
    993 	req_flags |= VIRTIO_F_INTR_MSIX;
    994 
    995 	req_features =
    996 	    VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_NET_F_CTRL_VQ |
    997 	    VIRTIO_NET_F_CTRL_RX | VIRTIO_F_NOTIFY_ON_EMPTY;
    998 	req_features |= VIRTIO_F_RING_EVENT_IDX;
    999 	req_features |= VIRTIO_NET_F_CTRL_MAC_ADDR;
   1000 #ifdef VIOIF_MULTIQ
   1001 	req_features |= VIRTIO_NET_F_MQ;
   1002 #endif
   1003 	virtio_child_attach_start(vsc, self, IPL_NET, NULL,
   1004 	    vioif_config_change, virtio_vq_intrhand, req_flags,
   1005 	    req_features, VIRTIO_NET_FLAG_BITS);
   1006 
   1007 	features = virtio_features(vsc);
   1008 	if (features == 0)
   1009 		goto err;
   1010 
   1011 	if (features & VIRTIO_NET_F_MAC) {
   1012 		for (i = 0; i < __arraycount(sc->sc_mac); i++) {
   1013 			sc->sc_mac[i] = virtio_read_device_config_1(vsc,
   1014 			    VIRTIO_NET_CONFIG_MAC + i);
   1015 		}
   1016 	} else {
   1017 		/* code stolen from sys/net/if_tap.c */
   1018 		struct timeval tv;
   1019 		uint32_t ui;
   1020 		getmicrouptime(&tv);
   1021 		ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff;
   1022 		memcpy(sc->sc_mac+3, (uint8_t *)&ui, 3);
   1023 		for (i = 0; i < __arraycount(sc->sc_mac); i++) {
   1024 			virtio_write_device_config_1(vsc,
   1025 			    VIRTIO_NET_CONFIG_MAC + i, sc->sc_mac[i]);
   1026 		}
   1027 	}
   1028 
   1029 	/* 'Ethernet' with capital follows other ethernet driver attachment */
   1030 	aprint_normal_dev(self, "Ethernet address %s\n",
   1031 	    ether_sprintf(sc->sc_mac));
   1032 
   1033 	if (features & (VIRTIO_NET_F_MRG_RXBUF | VIRTIO_F_VERSION_1)) {
   1034 		sc->sc_hdr_size = sizeof(struct virtio_net_hdr);
   1035 	} else {
   1036 		sc->sc_hdr_size = offsetof(struct virtio_net_hdr, num_buffers);
   1037 	}
   1038 
   1039 	if ((features & VIRTIO_NET_F_CTRL_VQ) &&
   1040 	    (features & VIRTIO_NET_F_CTRL_RX)) {
   1041 		sc->sc_has_ctrl = true;
   1042 
   1043 		cv_init(&ctrlq->ctrlq_wait, "ctrl_vq");
   1044 		mutex_init(&ctrlq->ctrlq_wait_lock, MUTEX_DEFAULT, IPL_NET);
   1045 		ctrlq->ctrlq_inuse = FREE;
   1046 	} else {
   1047 		sc->sc_has_ctrl = false;
   1048 	}
   1049 
   1050 	if (sc->sc_has_ctrl && (features & VIRTIO_NET_F_MQ)) {
   1051 		sc->sc_max_nvq_pairs = virtio_read_device_config_2(vsc,
   1052 		    VIRTIO_NET_CONFIG_MAX_VQ_PAIRS);
   1053 
   1054 		if (sc->sc_max_nvq_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX)
   1055 			goto err;
   1056 
   1057 		/* Limit the number of queue pairs to use */
   1058 		sc->sc_req_nvq_pairs = MIN(sc->sc_max_nvq_pairs, ncpu);
   1059 	}
   1060 
   1061 	vioif_alloc_queues(sc);
   1062 	virtio_child_attach_set_vqs(vsc, sc->sc_vqs, sc->sc_req_nvq_pairs);
   1063 
   1064 #ifdef VIOIF_MPSAFE
   1065 	softint_flags = SOFTINT_NET | SOFTINT_MPSAFE;
   1066 #else
   1067 	softint_flags = SOFTINT_NET;
   1068 #endif
   1069 
   1070 	/*
   1071 	 * Initialize network queues
   1072 	 */
   1073 	netq_num = sc->sc_max_nvq_pairs * 2;
   1074 	for (i = 0; i < netq_num; i++) {
   1075 		r = vioif_netqueue_init(sc, vsc, i, softint_flags);
   1076 		if (r != 0)
   1077 			goto err;
   1078 	}
   1079 
   1080 	if (sc->sc_has_ctrl) {
   1081 		int ctrlq_idx = sc->sc_max_nvq_pairs * 2;
   1082 		/*
   1083 		 * Allocating a virtqueue for control channel
   1084 		 */
   1085 		sc->sc_ctrlq.ctrlq_vq = &sc->sc_vqs[ctrlq_idx];
   1086 		r = virtio_alloc_vq(vsc, ctrlq->ctrlq_vq, ctrlq_idx,
   1087 		    NBPG, 1, "control");
   1088 		if (r != 0) {
   1089 			aprint_error_dev(self, "failed to allocate "
   1090 			    "a virtqueue for control channel, error code %d\n",
   1091 			    r);
   1092 
   1093 			sc->sc_has_ctrl = false;
   1094 			cv_destroy(&ctrlq->ctrlq_wait);
   1095 			mutex_destroy(&ctrlq->ctrlq_wait_lock);
   1096 		} else {
   1097 			ctrlq->ctrlq_vq->vq_intrhand = vioif_ctrl_intr;
   1098 			ctrlq->ctrlq_vq->vq_intrhand_arg = (void *) ctrlq;
   1099 		}
   1100 	}
   1101 
   1102 	sc->sc_ctl_softint = softint_establish(softint_flags,
   1103 	    vioif_ctl_softint, sc);
   1104 	if (sc->sc_ctl_softint == NULL) {
   1105 		aprint_error_dev(self, "cannot establish ctl softint\n");
   1106 		goto err;
   1107 	}
   1108 
   1109 	if (vioif_alloc_mems(sc) < 0)
   1110 		goto err;
   1111 
   1112 	if (virtio_child_attach_finish(vsc) != 0)
   1113 		goto err;
   1114 
   1115 	if (vioif_setup_sysctl(sc) != 0) {
   1116 		aprint_error_dev(self, "unable to create sysctl node\n");
   1117 		/* continue */
   1118 	}
   1119 
   1120 	vioif_setup_stats(sc);
   1121 
   1122 	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
   1123 	ifp->if_softc = sc;
   1124 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
   1125 #ifdef VIOIF_MPSAFE
   1126 	ifp->if_extflags = IFEF_MPSAFE;
   1127 #endif
   1128 	ifp->if_start = vioif_start;
   1129 	if (sc->sc_req_nvq_pairs > 1)
   1130 		ifp->if_transmit = vioif_transmit;
   1131 	ifp->if_ioctl = vioif_ioctl;
   1132 	ifp->if_init = vioif_init;
   1133 	ifp->if_stop = vioif_stop;
   1134 	ifp->if_capabilities = 0;
   1135 	ifp->if_watchdog = vioif_watchdog;
   1136 	txq0 = &sc->sc_netqs[VIOIF_NETQ_TXQID(0)];
   1137 	IFQ_SET_MAXLEN(&ifp->if_snd, MAX(txq0->netq_vq->vq_num, IFQ_MAXLEN));
   1138 	IFQ_SET_READY(&ifp->if_snd);
   1139 
   1140 	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
   1141 
   1142 	if_attach(ifp);
   1143 	if_deferred_start_init(ifp, NULL);
   1144 	ether_ifattach(ifp, sc->sc_mac);
   1145 	ether_set_ifflags_cb(&sc->sc_ethercom, vioif_ifflags_cb);
   1146 
   1147 	return;
   1148 
   1149 err:
   1150 	netq_num = sc->sc_max_nvq_pairs * 2;
   1151 	for (i = 0; i < netq_num; i++) {
   1152 		vioif_netqueue_teardown(sc, vsc, i);
   1153 	}
   1154 
   1155 	if (sc->sc_has_ctrl) {
   1156 		cv_destroy(&ctrlq->ctrlq_wait);
   1157 		mutex_destroy(&ctrlq->ctrlq_wait_lock);
   1158 		virtio_free_vq(vsc, ctrlq->ctrlq_vq);
   1159 		ctrlq->ctrlq_vq = NULL;
   1160 	}
   1161 
   1162 	vioif_free_queues(sc);
   1163 	mutex_destroy(&sc->sc_lock);
   1164 	virtio_child_attach_failed(vsc);
   1165 	config_finalize_register(self, vioif_finalize_teardown);
   1166 
   1167 	return;
   1168 }
   1169 
   1170 static int
   1171 vioif_finalize_teardown(device_t self)
   1172 {
   1173 	struct vioif_softc *sc = device_private(self);
   1174 
   1175 	if (sc->sc_txrx_workqueue != NULL) {
   1176 		vioif_workq_destroy(sc->sc_txrx_workqueue);
   1177 		sc->sc_txrx_workqueue = NULL;
   1178 	}
   1179 
   1180 	return 0;
   1181 }
   1182 
   1183 static void
   1184 vioif_enable_interrupt_vqpairs(struct vioif_softc *sc)
   1185 {
   1186 	struct virtio_softc *vsc = sc->sc_virtio;
   1187 	struct vioif_netqueue *netq;
   1188 	size_t i, netq_act_num;
   1189 
   1190 	netq_act_num = sc->sc_act_nvq_pairs * 2;
   1191 	for (i = 0; i < netq_act_num; i++) {
   1192 		netq = &sc->sc_netqs[i];
   1193 		virtio_start_vq_intr(vsc, netq->netq_vq);
   1194 	}
   1195 }
   1196 
   1197 static void
   1198 vioif_disable_interrupt_vqpairs(struct vioif_softc *sc)
   1199 {
   1200 	struct virtio_softc *vsc = sc->sc_virtio;
   1201 	struct vioif_netqueue *netq;
   1202 	size_t i, netq_act_num;
   1203 
   1204 	netq_act_num = sc->sc_act_nvq_pairs * 2;
   1205 	for (i = 0; i < netq_act_num; i++) {
   1206 		netq = &sc->sc_netqs[i];
   1207 		virtio_stop_vq_intr(vsc, netq->netq_vq);
   1208 	}
   1209 }
   1210 
   1211 /*
   1212  * Interface functions for ifnet
   1213  */
   1214 static int
   1215 vioif_init(struct ifnet *ifp)
   1216 {
   1217 	struct vioif_softc *sc = ifp->if_softc;
   1218 	struct virtio_softc *vsc = sc->sc_virtio;
   1219 	struct vioif_netqueue *netq;
   1220 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
   1221 	int r, i;
   1222 
   1223 	vioif_stop(ifp, 0);
   1224 
   1225 	r = virtio_reinit_start(vsc);
   1226 	if (r != 0) {
   1227 		log(LOG_ERR, "%s: reset failed\n", ifp->if_xname);
   1228 		return EIO;
   1229 	}
   1230 
   1231 	virtio_negotiate_features(vsc, virtio_features(vsc));
   1232 
   1233 	for (i = 0; i < sc->sc_req_nvq_pairs; i++) {
   1234 		netq = &sc->sc_netqs[VIOIF_NETQ_RXQID(i)];
   1235 
   1236 		mutex_enter(&netq->netq_lock);
   1237 		vioif_populate_rx_mbufs_locked(sc, netq);
   1238 		mutex_exit(&netq->netq_lock);
   1239 	}
   1240 
   1241 	virtio_reinit_end(vsc);
   1242 
   1243 	if (sc->sc_has_ctrl)
   1244 		virtio_start_vq_intr(vsc, ctrlq->ctrlq_vq);
   1245 
   1246 	r = vioif_ctrl_mq_vq_pairs_set(sc, sc->sc_req_nvq_pairs);
   1247 	if (r == 0)
   1248 		sc->sc_act_nvq_pairs = sc->sc_req_nvq_pairs;
   1249 	else
   1250 		sc->sc_act_nvq_pairs = 1;
   1251 
   1252 	SET(ifp->if_flags, IFF_RUNNING);
   1253 	CLR(ifp->if_flags, IFF_OACTIVE);
   1254 
   1255 	vioif_enable_interrupt_vqpairs(sc);
   1256 
   1257 	vioif_update_link_status(sc);
   1258 	r = vioif_rx_filter(sc);
   1259 
   1260 	return r;
   1261 }
   1262 
   1263 static void
   1264 vioif_stop(struct ifnet *ifp, int disable)
   1265 {
   1266 	struct vioif_softc *sc = ifp->if_softc;
   1267 	struct virtio_softc *vsc = sc->sc_virtio;
   1268 	struct vioif_netqueue *netq;
   1269 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
   1270 	size_t i, netq_act_num;
   1271 
   1272 	netq_act_num = sc->sc_act_nvq_pairs * 2;
   1273 
   1274 	CLR(ifp->if_flags, IFF_RUNNING);
   1275 	for (i = 0; i < netq_act_num; i++) {
   1276 		netq = &sc->sc_netqs[i];
   1277 
   1278 		mutex_enter(&netq->netq_lock);
   1279 		netq->netq_stopping = true;
   1280 		mutex_exit(&netq->netq_lock);
   1281 	}
   1282 
   1283 	/* disable interrupts */
   1284 	vioif_disable_interrupt_vqpairs(sc);
   1285 	if (sc->sc_has_ctrl)
   1286 		virtio_stop_vq_intr(vsc, ctrlq->ctrlq_vq);
   1287 
   1288 	/*
   1289 	 * only way to stop interrupt, I/O and DMA is resetting...
   1290 	 *
   1291 	 * NOTE: Devices based on VirtIO draft specification can not
   1292 	 * stop interrupt completely even if virtio_stop_vq_intr() is called.
   1293 	 */
   1294 	virtio_reset(vsc);
   1295 
   1296 	vioif_intr_barrier();
   1297 
   1298 	for (i = 0; i < netq_act_num; i++) {
   1299 		netq = &sc->sc_netqs[i];
   1300 		vioif_work_wait(sc->sc_txrx_workqueue, &netq->netq_work);
   1301 	}
   1302 
   1303 	for (i = 0; i < sc->sc_act_nvq_pairs; i++) {
   1304 		netq = &sc->sc_netqs[VIOIF_NETQ_RXQID(i)];
   1305 		vioif_rx_queue_clear(sc, vsc, netq);
   1306 
   1307 		netq = &sc->sc_netqs[VIOIF_NETQ_TXQID(i)];
   1308 		vioif_tx_queue_clear(sc, vsc, netq);
   1309 	}
   1310 
   1311 	/* all packet processing is stopped */
   1312 	for (i = 0; i < netq_act_num; i++) {
   1313 		netq = &sc->sc_netqs[i];
   1314 
   1315 		mutex_enter(&netq->netq_lock);
   1316 		netq->netq_stopping = false;
   1317 		mutex_exit(&netq->netq_lock);
   1318 	}
   1319 }
   1320 
   1321 static void
   1322 vioif_send_common_locked(struct ifnet *ifp, struct vioif_netqueue *netq,
   1323     bool is_transmit)
   1324 {
   1325 	struct vioif_softc *sc = ifp->if_softc;
   1326 	struct virtio_softc *vsc = sc->sc_virtio;
   1327 	struct virtqueue *vq = netq->netq_vq;
   1328 	struct vioif_tx_context *txc;
   1329 	struct vioif_net_map *map;
   1330 	struct virtio_net_hdr *hdr;
   1331 	struct mbuf *m;
   1332 	int queued = 0;
   1333 
   1334 	KASSERT(mutex_owned(&netq->netq_lock));
   1335 
   1336 	if (netq->netq_stopping ||
   1337 	    !ISSET(ifp->if_flags, IFF_RUNNING))
   1338 		return;
   1339 
   1340 	txc = netq->netq_ctx;
   1341 
   1342 	if (!txc->txc_link_active)
   1343 		return;
   1344 
   1345 	if (!is_transmit &&
   1346 	    ISSET(ifp->if_flags, IFF_OACTIVE))
   1347 		return;
   1348 
   1349 	for (;;) {
   1350 		int slot, r;
   1351 		r = virtio_enqueue_prep(vsc, vq, &slot);
   1352 		if (r == EAGAIN)
   1353 			break;
   1354 		if (__predict_false(r != 0))
   1355 			panic("enqueue_prep for tx buffers");
   1356 
   1357 		if (is_transmit)
   1358 			m = pcq_get(txc->txc_intrq);
   1359 		else
   1360 			IFQ_DEQUEUE(&ifp->if_snd, m);
   1361 
   1362 		if (m == NULL) {
   1363 			virtio_enqueue_abort(vsc, vq, slot);
   1364 			break;
   1365 		}
   1366 
   1367 		map = &netq->netq_maps[slot];
   1368 		KASSERT(map->vnm_mbuf == NULL);
   1369 
   1370 		r = bus_dmamap_load_mbuf(virtio_dmat(vsc),
   1371 		    map->vnm_mbuf_map, m, BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   1372 		if (r != 0) {
   1373 			/* maybe just too fragmented */
   1374 			struct mbuf *newm;
   1375 
   1376 			newm = m_defrag(m, M_NOWAIT);
   1377 			if (newm == NULL) {
   1378 				txc->txc_defrag_failed.ev_count++;
   1379 				goto skip;
   1380 			}
   1381 
   1382 			m = newm;
   1383 			r = bus_dmamap_load_mbuf(virtio_dmat(vsc),
   1384 			    map->vnm_mbuf_map, m,
   1385 			    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   1386 			if (r != 0) {
   1387 				netq->netq_mbuf_load_failed.ev_count++;
   1388 skip:
   1389 				m_freem(m);
   1390 				if_statinc(ifp, if_oerrors);
   1391 				virtio_enqueue_abort(vsc, vq, slot);
   1392 				continue;
   1393 			}
   1394 		}
   1395 
   1396 		/* This should actually never fail */
   1397 		r = virtio_enqueue_reserve(vsc, vq, slot,
   1398 		    map->vnm_mbuf_map->dm_nsegs + 1);
   1399 		if (r != 0) {
   1400 			netq->netq_enqueue_reserve_failed.ev_count++;
   1401 			bus_dmamap_unload(virtio_dmat(vsc),
   1402 			     map->vnm_mbuf_map);
   1403 			/* slot already freed by virtio_enqueue_reserve */
   1404 			m_freem(m);
   1405 			if_statinc(ifp, if_oerrors);
   1406 			continue;
   1407 		}
   1408 
   1409 		map->vnm_mbuf = m;
   1410 		hdr = map->vnm_hdr;
   1411 		memset(hdr, 0, sc->sc_hdr_size);
   1412 		bus_dmamap_sync(virtio_dmat(vsc), map->vnm_mbuf_map,
   1413 		    0, map->vnm_mbuf_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
   1414 		bus_dmamap_sync(virtio_dmat(vsc), map->vnm_hdr_map,
   1415 		    0, map->vnm_hdr_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
   1416 		virtio_enqueue(vsc, vq, slot, map->vnm_hdr_map, true);
   1417 		virtio_enqueue(vsc, vq, slot, map->vnm_mbuf_map, true);
   1418 		virtio_enqueue_commit(vsc, vq, slot, false);
   1419 
   1420 		queued++;
   1421 		bpf_mtap(ifp, m, BPF_D_OUT);
   1422 	}
   1423 
   1424 	if (queued > 0) {
   1425 		virtio_enqueue_commit(vsc, vq, -1, true);
   1426 		ifp->if_timer = 5;
   1427 	}
   1428 }
   1429 
   1430 static void
   1431 vioif_start_locked(struct ifnet *ifp, struct vioif_netqueue *netq)
   1432 {
   1433 
   1434 	/*
   1435 	 * ifp->if_obytes and ifp->if_omcasts are added in if_transmit()@if.c.
   1436 	 */
   1437 	vioif_send_common_locked(ifp, netq, false);
   1438 
   1439 }
   1440 
   1441 static void
   1442 vioif_start(struct ifnet *ifp)
   1443 {
   1444 	struct vioif_softc *sc = ifp->if_softc;
   1445 	struct vioif_netqueue *txq0 = &sc->sc_netqs[VIOIF_NETQ_TXQID(0)];
   1446 
   1447 #ifdef VIOIF_MPSAFE
   1448 	KASSERT(if_is_mpsafe(ifp));
   1449 #endif
   1450 
   1451 	mutex_enter(&txq0->netq_lock);
   1452 	vioif_start_locked(ifp, txq0);
   1453 	mutex_exit(&txq0->netq_lock);
   1454 }
   1455 
   1456 static inline int
   1457 vioif_select_txqueue(struct ifnet *ifp, struct mbuf *m)
   1458 {
   1459 	struct vioif_softc *sc = ifp->if_softc;
   1460 	u_int cpuid = cpu_index(curcpu());
   1461 
   1462 	return VIOIF_NETQ_TXQID(cpuid % sc->sc_act_nvq_pairs);
   1463 }
   1464 
   1465 static void
   1466 vioif_transmit_locked(struct ifnet *ifp, struct vioif_netqueue *netq)
   1467 {
   1468 
   1469 	vioif_send_common_locked(ifp, netq, true);
   1470 }
   1471 
   1472 static int
   1473 vioif_transmit(struct ifnet *ifp, struct mbuf *m)
   1474 {
   1475 	struct vioif_softc *sc = ifp->if_softc;
   1476 	struct vioif_netqueue *netq;
   1477 	struct vioif_tx_context *txc;
   1478 	int qid;
   1479 
   1480 	qid = vioif_select_txqueue(ifp, m);
   1481 	netq = &sc->sc_netqs[qid];
   1482 	txc = netq->netq_ctx;
   1483 
   1484 	if (__predict_false(!pcq_put(txc->txc_intrq, m))) {
   1485 		m_freem(m);
   1486 		return ENOBUFS;
   1487 	}
   1488 
   1489 	net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
   1490 	if_statadd_ref(nsr, if_obytes, m->m_pkthdr.len);
   1491 	if (m->m_flags & M_MCAST)
   1492 		if_statinc_ref(nsr, if_omcasts);
   1493 	IF_STAT_PUTREF(ifp);
   1494 
   1495 	if (mutex_tryenter(&netq->netq_lock)) {
   1496 		vioif_transmit_locked(ifp, netq);
   1497 		mutex_exit(&netq->netq_lock);
   1498 	}
   1499 
   1500 	return 0;
   1501 }
   1502 
   1503 static void
   1504 vioif_deferred_transmit(void *arg)
   1505 {
   1506 	struct vioif_netqueue *netq = arg;
   1507 	struct virtio_softc *vsc = netq->netq_vq->vq_owner;
   1508 	struct vioif_softc *sc = device_private(virtio_child(vsc));
   1509 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1510 
   1511 	mutex_enter(&netq->netq_lock);
   1512 	vioif_send_common_locked(ifp, netq, true);
   1513 	mutex_exit(&netq->netq_lock);
   1514 }
   1515 
   1516 static int
   1517 vioif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   1518 {
   1519 	int s, r;
   1520 
   1521 	s = splnet();
   1522 
   1523 	r = ether_ioctl(ifp, cmd, data);
   1524 	if (r == ENETRESET && (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI)) {
   1525 		if (ifp->if_flags & IFF_RUNNING) {
   1526 			r = vioif_rx_filter(ifp->if_softc);
   1527 		} else {
   1528 			r = 0;
   1529 		}
   1530 	}
   1531 
   1532 	splx(s);
   1533 
   1534 	return r;
   1535 }
   1536 
   1537 void
   1538 vioif_watchdog(struct ifnet *ifp)
   1539 {
   1540 	struct vioif_softc *sc = ifp->if_softc;
   1541 	struct vioif_netqueue *netq;
   1542 	int i;
   1543 
   1544 	if (ifp->if_flags & IFF_RUNNING) {
   1545 		for (i = 0; i < sc->sc_act_nvq_pairs; i++) {
   1546 			netq = &sc->sc_netqs[VIOIF_NETQ_TXQID(i)];
   1547 
   1548 			mutex_enter(&netq->netq_lock);
   1549 			if (!netq->netq_running_handle) {
   1550 				netq->netq_running_handle = true;
   1551 				vioif_net_sched_handle(sc, netq);
   1552 			}
   1553 			mutex_exit(&netq->netq_lock);
   1554 		}
   1555 	}
   1556 }
   1557 
   1558 static void
   1559 vioif_net_sched_handle(struct vioif_softc *sc, struct vioif_netqueue *netq)
   1560 {
   1561 
   1562 	KASSERT(mutex_owned(&netq->netq_lock));
   1563 	KASSERT(!netq->netq_stopping);
   1564 
   1565 	if (netq->netq_workqueue) {
   1566 		vioif_work_add(sc->sc_txrx_workqueue, &netq->netq_work);
   1567 	} else {
   1568 		softint_schedule(netq->netq_softint);
   1569 	}
   1570 }
   1571 
   1572 /*
   1573  * Receive implementation
   1574  */
   1575 /* add mbufs for all the empty receive slots */
   1576 static void
   1577 vioif_populate_rx_mbufs_locked(struct vioif_softc *sc, struct vioif_netqueue *netq)
   1578 {
   1579 	struct virtqueue *vq = netq->netq_vq;
   1580 	struct virtio_softc *vsc = vq->vq_owner;
   1581 	struct vioif_rx_context *rxc;
   1582 	struct vioif_net_map *map;
   1583 	struct mbuf *m;
   1584 	int i, r, ndone = 0;
   1585 
   1586 	KASSERT(mutex_owned(&netq->netq_lock));
   1587 
   1588 	rxc = netq->netq_ctx;
   1589 
   1590 	for (i = 0; i < vq->vq_num; i++) {
   1591 		int slot;
   1592 		r = virtio_enqueue_prep(vsc, vq, &slot);
   1593 		if (r == EAGAIN)
   1594 			break;
   1595 		if (__predict_false(r != 0))
   1596 			panic("enqueue_prep for rx buffers");
   1597 
   1598 		map = &netq->netq_maps[slot];
   1599 		KASSERT(map->vnm_mbuf == NULL);
   1600 
   1601 		MGETHDR(m, M_DONTWAIT, MT_DATA);
   1602 		if (m == NULL) {
   1603 			virtio_enqueue_abort(vsc, vq, slot);
   1604 			rxc->rxc_mbuf_enobufs.ev_count++;
   1605 			break;
   1606 		}
   1607 		MCLGET(m, M_DONTWAIT);
   1608 		if ((m->m_flags & M_EXT) == 0) {
   1609 			virtio_enqueue_abort(vsc, vq, slot);
   1610 			m_freem(m);
   1611 			rxc->rxc_mbuf_enobufs.ev_count++;
   1612 			break;
   1613 		}
   1614 
   1615 		m->m_len = m->m_pkthdr.len = MCLBYTES;
   1616 		m_adj(m, ETHER_ALIGN);
   1617 
   1618 		r = bus_dmamap_load_mbuf(virtio_dmat(vsc),
   1619 		    map->vnm_mbuf_map, m, BUS_DMA_READ | BUS_DMA_NOWAIT);
   1620 
   1621 		if (r != 0) {
   1622 			virtio_enqueue_abort(vsc, vq, slot);
   1623 			m_freem(m);
   1624 			netq->netq_mbuf_load_failed.ev_count++;
   1625 			break;
   1626 		}
   1627 
   1628 		r = virtio_enqueue_reserve(vsc, vq, slot,
   1629 		    map->vnm_mbuf_map->dm_nsegs + 1);
   1630 		if (r != 0) {
   1631 			netq->netq_enqueue_reserve_failed.ev_count++;
   1632 			bus_dmamap_unload(virtio_dmat(vsc), map->vnm_mbuf_map);
   1633 			m_freem(m);
   1634 			/* slot already freed by virtio_enqueue_reserve */
   1635 			break;
   1636 		}
   1637 
   1638 		map->vnm_mbuf = m;
   1639 		bus_dmamap_sync(virtio_dmat(vsc), map->vnm_hdr_map,
   1640 		    0, sc->sc_hdr_size, BUS_DMASYNC_PREREAD);
   1641 		bus_dmamap_sync(virtio_dmat(vsc), map->vnm_mbuf_map,
   1642 		    0, map->vnm_mbuf_map->dm_mapsize, BUS_DMASYNC_PREREAD);
   1643 		virtio_enqueue(vsc, vq, slot, map->vnm_hdr_map, false);
   1644 		virtio_enqueue(vsc, vq, slot, map->vnm_mbuf_map, false);
   1645 		virtio_enqueue_commit(vsc, vq, slot, false);
   1646 		ndone++;
   1647 	}
   1648 	if (ndone > 0)
   1649 		virtio_enqueue_commit(vsc, vq, -1, true);
   1650 }
   1651 
   1652 static void
   1653 vioif_rx_queue_clear(struct vioif_softc *sc, struct virtio_softc *vsc,
   1654     struct vioif_netqueue *netq)
   1655 {
   1656 	struct vioif_net_map *map;
   1657 	unsigned int i, vq_num;
   1658 	bool more;
   1659 
   1660 	mutex_enter(&netq->netq_lock);
   1661 	vq_num = netq->netq_vq->vq_num;
   1662 
   1663 	for (;;) {
   1664 		more = vioif_rx_deq_locked(sc, vsc, netq, vq_num, NULL);
   1665 		if (more == false)
   1666 			break;
   1667 	}
   1668 
   1669 	for (i = 0; i < vq_num; i++) {
   1670 		map = &netq->netq_maps[i];
   1671 
   1672 		if (map->vnm_mbuf == NULL)
   1673 			continue;
   1674 
   1675 		bus_dmamap_unload(virtio_dmat(vsc), map->vnm_mbuf_map);
   1676 		m_freem(map->vnm_mbuf);
   1677 		map->vnm_mbuf = NULL;
   1678 	}
   1679 	mutex_exit(&netq->netq_lock);
   1680 }
   1681 
   1682 /* dequeue received packets */
   1683 static bool
   1684 vioif_rx_deq_locked(struct vioif_softc *sc, struct virtio_softc *vsc,
   1685     struct vioif_netqueue *netq, u_int limit, size_t *ndeqp)
   1686 {
   1687 	struct virtqueue *vq = netq->netq_vq;
   1688 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1689 	struct vioif_net_map *map;
   1690 	struct mbuf *m;
   1691 	int slot, len;
   1692 	bool more;
   1693 	size_t ndeq;
   1694 
   1695 	KASSERT(mutex_owned(&netq->netq_lock));
   1696 
   1697 	more = false;
   1698 	ndeq = 0;
   1699 
   1700 	if (virtio_vq_is_enqueued(vsc, vq) == false)
   1701 		goto done;
   1702 
   1703 	for (;;ndeq++) {
   1704 		if (ndeq >= limit) {
   1705 			more = true;
   1706 			break;
   1707 		}
   1708 
   1709 		if (virtio_dequeue(vsc, vq, &slot, &len) != 0)
   1710 			break;
   1711 
   1712 		map = &netq->netq_maps[slot];
   1713 		KASSERT(map->vnm_mbuf != NULL);
   1714 
   1715 		bus_dmamap_sync(virtio_dmat(vsc), map->vnm_hdr_map,
   1716 		    0, sc->sc_hdr_size, BUS_DMASYNC_POSTREAD);
   1717 		bus_dmamap_sync(virtio_dmat(vsc), map->vnm_mbuf_map,
   1718 		    0, map->vnm_mbuf_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1719 
   1720 		bus_dmamap_unload(virtio_dmat(vsc), map->vnm_mbuf_map);
   1721 		m = map->vnm_mbuf;
   1722 		map->vnm_mbuf = NULL;
   1723 		virtio_dequeue_commit(vsc, vq, slot);
   1724 
   1725 		m->m_len = m->m_pkthdr.len = len - sc->sc_hdr_size;
   1726 		m_set_rcvif(m, ifp);
   1727 		if_percpuq_enqueue(ifp->if_percpuq, m);
   1728 	}
   1729 
   1730 done:
   1731 	if (ndeqp != NULL)
   1732 		*ndeqp = ndeq;
   1733 
   1734 	return more;
   1735 }
   1736 
   1737 /* rx interrupt; call _dequeue above and schedule a softint */
   1738 
   1739 static void
   1740 vioif_rx_handle_locked(void *xnetq, u_int limit)
   1741 {
   1742 	struct vioif_netqueue *netq = xnetq;
   1743 	struct virtqueue *vq = netq->netq_vq;
   1744 	struct virtio_softc *vsc = vq->vq_owner;
   1745 	struct vioif_softc *sc = device_private(virtio_child(vsc));
   1746 	bool more;
   1747 	int enqueued;
   1748 	size_t ndeq;
   1749 
   1750 	KASSERT(mutex_owned(&netq->netq_lock));
   1751 	KASSERT(!netq->netq_stopping);
   1752 
   1753 	more = vioif_rx_deq_locked(sc, vsc, netq, limit, &ndeq);
   1754 	if (ndeq > 0)
   1755 		vioif_populate_rx_mbufs_locked(sc, netq);
   1756 
   1757 	if (more) {
   1758 		vioif_net_sched_handle(sc, netq);
   1759 		return;
   1760 	}
   1761 
   1762 	enqueued = virtio_start_vq_intr(vsc, netq->netq_vq);
   1763 	if (enqueued != 0) {
   1764 		virtio_stop_vq_intr(vsc, netq->netq_vq);
   1765 		vioif_net_sched_handle(sc, netq);
   1766 		return;
   1767 	}
   1768 
   1769 	netq->netq_running_handle = false;
   1770 }
   1771 
   1772 static int
   1773 vioif_rx_intr(void *arg)
   1774 {
   1775 	struct vioif_netqueue *netq = arg;
   1776 	struct virtqueue *vq = netq->netq_vq;
   1777 	struct virtio_softc *vsc = vq->vq_owner;
   1778 	struct vioif_softc *sc = device_private(virtio_child(vsc));
   1779 	u_int limit;
   1780 
   1781 	mutex_enter(&netq->netq_lock);
   1782 
   1783 	/* handler is already running in softint/workqueue */
   1784 	if (netq->netq_running_handle)
   1785 		goto done;
   1786 
   1787 	netq->netq_running_handle = true;
   1788 
   1789 	limit = sc->sc_rx_intr_process_limit;
   1790 	virtio_stop_vq_intr(vsc, vq);
   1791 	vioif_rx_handle_locked(netq, limit);
   1792 
   1793 done:
   1794 	mutex_exit(&netq->netq_lock);
   1795 	return 1;
   1796 }
   1797 
   1798 static void
   1799 vioif_rx_handle(void *xnetq)
   1800 {
   1801 	struct vioif_netqueue *netq = xnetq;
   1802 	struct virtqueue *vq = netq->netq_vq;
   1803 	struct virtio_softc *vsc = vq->vq_owner;
   1804 	struct vioif_softc *sc = device_private(virtio_child(vsc));
   1805 	u_int limit;
   1806 
   1807 	mutex_enter(&netq->netq_lock);
   1808 
   1809 	KASSERT(netq->netq_running_handle);
   1810 
   1811 	if (netq->netq_stopping) {
   1812 		netq->netq_running_handle = false;
   1813 		goto done;
   1814 	}
   1815 
   1816 	limit = sc->sc_rx_process_limit;
   1817 	vioif_rx_handle_locked(netq, limit);
   1818 
   1819 done:
   1820 	mutex_exit(&netq->netq_lock);
   1821 }
   1822 
   1823 /*
   1824  * Transmition implementation
   1825  */
   1826 /* actual transmission is done in if_start */
   1827 /* tx interrupt; dequeue and free mbufs */
   1828 /*
   1829  * tx interrupt is actually disabled; this should be called upon
   1830  * tx vq full and watchdog
   1831  */
   1832 
   1833 static void
   1834 vioif_tx_handle_locked(struct vioif_netqueue *netq, u_int limit)
   1835 {
   1836 	struct virtqueue *vq = netq->netq_vq;
   1837 	struct vioif_tx_context *txc = netq->netq_ctx;
   1838 	struct virtio_softc *vsc = vq->vq_owner;
   1839 	struct vioif_softc *sc = device_private(virtio_child(vsc));
   1840 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1841 	bool more;
   1842 	int enqueued;
   1843 
   1844 	KASSERT(mutex_owned(&netq->netq_lock));
   1845 	KASSERT(!netq->netq_stopping);
   1846 
   1847 	more = vioif_tx_deq_locked(sc, vsc, netq, limit);
   1848 	if (more) {
   1849 		vioif_net_sched_handle(sc, netq);
   1850 		return;
   1851 	}
   1852 
   1853 	enqueued = (virtio_features(vsc) & VIRTIO_F_RING_EVENT_IDX) ?
   1854 	    virtio_postpone_intr_smart(vsc, vq):
   1855 	    virtio_start_vq_intr(vsc, vq);
   1856 	if (enqueued != 0) {
   1857 		virtio_stop_vq_intr(vsc, vq);
   1858 		vioif_net_sched_handle(sc, netq);
   1859 		return;
   1860 	}
   1861 
   1862 	netq->netq_running_handle = false;
   1863 
   1864 	/* for ALTQ */
   1865 	if (netq == &sc->sc_netqs[VIOIF_NETQ_TXQID(0)]) {
   1866 		if_schedule_deferred_start(ifp);
   1867 		ifp->if_flags &= ~IFF_OACTIVE;
   1868 	}
   1869 	softint_schedule(txc->txc_deferred_transmit);
   1870 }
   1871 
   1872 static int
   1873 vioif_tx_intr(void *arg)
   1874 {
   1875 	struct vioif_netqueue *netq = arg;
   1876 	struct virtqueue *vq = netq->netq_vq;
   1877 	struct virtio_softc *vsc = vq->vq_owner;
   1878 	struct vioif_softc *sc = device_private(virtio_child(vsc));
   1879 	u_int limit;
   1880 
   1881 	mutex_enter(&netq->netq_lock);
   1882 
   1883 	/* tx handler is already running in softint/workqueue */
   1884 	if (netq->netq_running_handle)
   1885 		goto done;
   1886 
   1887 	if (netq->netq_stopping)
   1888 		goto done;
   1889 
   1890 	netq->netq_running_handle = true;
   1891 
   1892 	virtio_stop_vq_intr(vsc, vq);
   1893 	netq->netq_workqueue = sc->sc_txrx_workqueue_sysctl;
   1894 	limit = sc->sc_tx_intr_process_limit;
   1895 	vioif_tx_handle_locked(netq, limit);
   1896 
   1897 done:
   1898 	mutex_exit(&netq->netq_lock);
   1899 	return 1;
   1900 }
   1901 
   1902 static void
   1903 vioif_tx_handle(void *xnetq)
   1904 {
   1905 	struct vioif_netqueue *netq = xnetq;
   1906 	struct virtqueue *vq = netq->netq_vq;
   1907 	struct virtio_softc *vsc = vq->vq_owner;
   1908 	struct vioif_softc *sc = device_private(virtio_child(vsc));
   1909 	u_int limit;
   1910 
   1911 	mutex_enter(&netq->netq_lock);
   1912 
   1913 	KASSERT(netq->netq_running_handle);
   1914 
   1915 	if (netq->netq_stopping) {
   1916 		netq->netq_running_handle = false;
   1917 		goto done;
   1918 	}
   1919 
   1920 	limit = sc->sc_tx_process_limit;
   1921 	vioif_tx_handle_locked(netq, limit);
   1922 
   1923 done:
   1924 	mutex_exit(&netq->netq_lock);
   1925 }
   1926 
   1927 static void
   1928 vioif_tx_queue_clear(struct vioif_softc *sc, struct virtio_softc *vsc,
   1929     struct vioif_netqueue *netq)
   1930 {
   1931 	struct vioif_net_map *map;
   1932 	unsigned int i, vq_num;
   1933 	bool more;
   1934 
   1935 	mutex_enter(&netq->netq_lock);
   1936 
   1937 	vq_num = netq->netq_vq->vq_num;
   1938 	for (;;) {
   1939 		more = vioif_tx_deq_locked(sc, vsc, netq, vq_num);
   1940 		if (more == false)
   1941 			break;
   1942 	}
   1943 
   1944 	for (i = 0; i < vq_num; i++) {
   1945 		map = &netq->netq_maps[i];
   1946 		if (map->vnm_mbuf == NULL)
   1947 			continue;
   1948 
   1949 		bus_dmamap_unload(virtio_dmat(vsc), map->vnm_mbuf_map);
   1950 		m_freem(map->vnm_mbuf);
   1951 		map->vnm_mbuf = NULL;
   1952 	}
   1953 	mutex_exit(&netq->netq_lock);
   1954 }
   1955 
   1956 static bool
   1957 vioif_tx_deq_locked(struct vioif_softc *sc, struct virtio_softc *vsc,
   1958     struct vioif_netqueue *netq, u_int limit)
   1959 {
   1960 	struct virtqueue *vq = netq->netq_vq;
   1961 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1962 	struct vioif_net_map *map;
   1963 	struct mbuf *m;
   1964 	int slot, len;
   1965 	bool more = false;
   1966 
   1967 	KASSERT(mutex_owned(&netq->netq_lock));
   1968 
   1969 	if (virtio_vq_is_enqueued(vsc, vq) == false)
   1970 		return false;
   1971 
   1972 	for (;;) {
   1973 		if (limit-- == 0) {
   1974 			more = true;
   1975 			break;
   1976 		}
   1977 
   1978 		if (virtio_dequeue(vsc, vq, &slot, &len) != 0)
   1979 			break;
   1980 
   1981 		map = &netq->netq_maps[slot];
   1982 		KASSERT(map->vnm_mbuf != NULL);
   1983 
   1984 		bus_dmamap_sync(virtio_dmat(vsc), map->vnm_hdr_map,
   1985 		    0, sc->sc_hdr_size, BUS_DMASYNC_POSTWRITE);
   1986 		bus_dmamap_sync(virtio_dmat(vsc), map->vnm_mbuf_map,
   1987 		    0, map->vnm_mbuf_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1988 
   1989 		bus_dmamap_unload(virtio_dmat(vsc), map->vnm_mbuf_map);
   1990 		m = map->vnm_mbuf;
   1991 		map->vnm_mbuf = NULL;
   1992 		virtio_dequeue_commit(vsc, vq, slot);
   1993 
   1994 		if_statinc(ifp, if_opackets);
   1995 		m_freem(m);
   1996 	}
   1997 
   1998 	return more;
   1999 }
   2000 
   2001 /*
   2002  * Control vq
   2003  */
   2004 /* issue a VIRTIO_NET_CTRL_RX class command and wait for completion */
   2005 static void
   2006 vioif_ctrl_acquire(struct vioif_softc *sc)
   2007 {
   2008 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
   2009 
   2010 	mutex_enter(&ctrlq->ctrlq_wait_lock);
   2011 	while (ctrlq->ctrlq_inuse != FREE)
   2012 		cv_wait(&ctrlq->ctrlq_wait, &ctrlq->ctrlq_wait_lock);
   2013 	ctrlq->ctrlq_inuse = INUSE;
   2014 	ctrlq->ctrlq_owner = curlwp;
   2015 	mutex_exit(&ctrlq->ctrlq_wait_lock);
   2016 }
   2017 
   2018 static void
   2019 vioif_ctrl_release(struct vioif_softc *sc)
   2020 {
   2021 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
   2022 
   2023 	KASSERT(ctrlq->ctrlq_inuse != FREE);
   2024 	KASSERT(ctrlq->ctrlq_owner == curlwp);
   2025 
   2026 	mutex_enter(&ctrlq->ctrlq_wait_lock);
   2027 	ctrlq->ctrlq_inuse = FREE;
   2028 	ctrlq->ctrlq_owner = NULL;
   2029 	cv_signal(&ctrlq->ctrlq_wait);
   2030 	mutex_exit(&ctrlq->ctrlq_wait_lock);
   2031 }
   2032 
   2033 static int
   2034 vioif_ctrl_load_cmdspec(struct vioif_softc *sc,
   2035     struct vioif_ctrl_cmdspec *specs, int nspecs)
   2036 {
   2037 	struct virtio_softc *vsc = sc->sc_virtio;
   2038 	int i, r, loaded;
   2039 
   2040 	loaded = 0;
   2041 	for (i = 0; i < nspecs; i++) {
   2042 		r = bus_dmamap_load(virtio_dmat(vsc),
   2043 		    specs[i].dmamap, specs[i].buf, specs[i].bufsize,
   2044 		    NULL, BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   2045 		if (r) {
   2046 			sc->sc_ctrlq.ctrlq_cmd_load_failed.ev_count++;
   2047 			goto err;
   2048 		}
   2049 		loaded++;
   2050 
   2051 	}
   2052 
   2053 	return r;
   2054 
   2055 err:
   2056 	for (i = 0; i < loaded; i++) {
   2057 		bus_dmamap_unload(virtio_dmat(vsc), specs[i].dmamap);
   2058 	}
   2059 
   2060 	return r;
   2061 }
   2062 
   2063 static void
   2064 vioif_ctrl_unload_cmdspec(struct vioif_softc *sc,
   2065     struct vioif_ctrl_cmdspec *specs, int nspecs)
   2066 {
   2067 	struct virtio_softc *vsc = sc->sc_virtio;
   2068 	int i;
   2069 
   2070 	for (i = 0; i < nspecs; i++) {
   2071 		bus_dmamap_unload(virtio_dmat(vsc), specs[i].dmamap);
   2072 	}
   2073 }
   2074 
   2075 static int
   2076 vioif_ctrl_send_command(struct vioif_softc *sc, uint8_t class, uint8_t cmd,
   2077     struct vioif_ctrl_cmdspec *specs, int nspecs)
   2078 {
   2079 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
   2080 	struct virtqueue *vq = ctrlq->ctrlq_vq;
   2081 	struct virtio_softc *vsc = sc->sc_virtio;
   2082 	int i, r, slot;
   2083 
   2084 	ctrlq->ctrlq_cmd->class = class;
   2085 	ctrlq->ctrlq_cmd->command = cmd;
   2086 
   2087 	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap,
   2088 	    0, sizeof(struct virtio_net_ctrl_cmd), BUS_DMASYNC_PREWRITE);
   2089 	for (i = 0; i < nspecs; i++) {
   2090 		bus_dmamap_sync(virtio_dmat(vsc), specs[i].dmamap,
   2091 		    0, specs[i].bufsize, BUS_DMASYNC_PREWRITE);
   2092 	}
   2093 	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap,
   2094 	    0, sizeof(struct virtio_net_ctrl_status), BUS_DMASYNC_PREREAD);
   2095 
   2096 	/* we need to explicitly (re)start vq intr when using RING EVENT IDX */
   2097 	if (virtio_features(vsc) & VIRTIO_F_RING_EVENT_IDX)
   2098 		virtio_start_vq_intr(vsc, ctrlq->ctrlq_vq);
   2099 
   2100 	r = virtio_enqueue_prep(vsc, vq, &slot);
   2101 	if (r != 0)
   2102 		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
   2103 	r = virtio_enqueue_reserve(vsc, vq, slot, nspecs + 2);
   2104 	if (r != 0)
   2105 		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
   2106 	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_cmd_dmamap, true);
   2107 	for (i = 0; i < nspecs; i++) {
   2108 		virtio_enqueue(vsc, vq, slot, specs[i].dmamap, true);
   2109 	}
   2110 	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_status_dmamap, false);
   2111 	virtio_enqueue_commit(vsc, vq, slot, true);
   2112 
   2113 	/* wait for done */
   2114 	mutex_enter(&ctrlq->ctrlq_wait_lock);
   2115 	while (ctrlq->ctrlq_inuse != DONE)
   2116 		cv_wait(&ctrlq->ctrlq_wait, &ctrlq->ctrlq_wait_lock);
   2117 	mutex_exit(&ctrlq->ctrlq_wait_lock);
   2118 	/* already dequeueued */
   2119 
   2120 	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap, 0,
   2121 	    sizeof(struct virtio_net_ctrl_cmd), BUS_DMASYNC_POSTWRITE);
   2122 	for (i = 0; i < nspecs; i++) {
   2123 		bus_dmamap_sync(virtio_dmat(vsc), specs[i].dmamap, 0,
   2124 		    specs[i].bufsize, BUS_DMASYNC_POSTWRITE);
   2125 	}
   2126 	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap, 0,
   2127 	    sizeof(struct virtio_net_ctrl_status), BUS_DMASYNC_POSTREAD);
   2128 
   2129 	if (ctrlq->ctrlq_status->ack == VIRTIO_NET_OK)
   2130 		r = 0;
   2131 	else {
   2132 		device_printf(sc->sc_dev, "failed setting rx mode\n");
   2133 		sc->sc_ctrlq.ctrlq_cmd_failed.ev_count++;
   2134 		r = EIO;
   2135 	}
   2136 
   2137 	return r;
   2138 }
   2139 
   2140 static int
   2141 vioif_ctrl_rx(struct vioif_softc *sc, int cmd, bool onoff)
   2142 {
   2143 	struct virtio_net_ctrl_rx *rx = sc->sc_ctrlq.ctrlq_rx;
   2144 	struct vioif_ctrl_cmdspec specs[1];
   2145 	int r;
   2146 
   2147 	if (!sc->sc_has_ctrl)
   2148 		return ENOTSUP;
   2149 
   2150 	vioif_ctrl_acquire(sc);
   2151 
   2152 	rx->onoff = onoff;
   2153 	specs[0].dmamap = sc->sc_ctrlq.ctrlq_rx_dmamap;
   2154 	specs[0].buf = rx;
   2155 	specs[0].bufsize = sizeof(*rx);
   2156 
   2157 	r = vioif_ctrl_send_command(sc, VIRTIO_NET_CTRL_RX, cmd,
   2158 	    specs, __arraycount(specs));
   2159 
   2160 	vioif_ctrl_release(sc);
   2161 	return r;
   2162 }
   2163 
   2164 static int
   2165 vioif_set_promisc(struct vioif_softc *sc, bool onoff)
   2166 {
   2167 	return vioif_ctrl_rx(sc, VIRTIO_NET_CTRL_RX_PROMISC, onoff);
   2168 }
   2169 
   2170 static int
   2171 vioif_set_allmulti(struct vioif_softc *sc, bool onoff)
   2172 {
   2173 	return vioif_ctrl_rx(sc, VIRTIO_NET_CTRL_RX_ALLMULTI, onoff);
   2174 }
   2175 
   2176 /* issue VIRTIO_NET_CTRL_MAC_TABLE_SET command and wait for completion */
   2177 static int
   2178 vioif_set_rx_filter(struct vioif_softc *sc)
   2179 {
   2180 	/* filter already set in ctrlq->ctrlq_mac_tbl */
   2181 	struct virtio_softc *vsc = sc->sc_virtio;
   2182 	struct virtio_net_ctrl_mac_tbl *mac_tbl_uc, *mac_tbl_mc;
   2183 	struct vioif_ctrl_cmdspec specs[2];
   2184 	int nspecs = __arraycount(specs);
   2185 	int r;
   2186 
   2187 	mac_tbl_uc = sc->sc_ctrlq.ctrlq_mac_tbl_uc;
   2188 	mac_tbl_mc = sc->sc_ctrlq.ctrlq_mac_tbl_mc;
   2189 
   2190 	if (!sc->sc_has_ctrl)
   2191 		return ENOTSUP;
   2192 
   2193 	vioif_ctrl_acquire(sc);
   2194 
   2195 	specs[0].dmamap = sc->sc_ctrlq.ctrlq_tbl_uc_dmamap;
   2196 	specs[0].buf = mac_tbl_uc;
   2197 	specs[0].bufsize = sizeof(*mac_tbl_uc)
   2198 	    + (ETHER_ADDR_LEN * virtio_rw32(vsc, mac_tbl_uc->nentries));
   2199 
   2200 	specs[1].dmamap = sc->sc_ctrlq.ctrlq_tbl_mc_dmamap;
   2201 	specs[1].buf = mac_tbl_mc;
   2202 	specs[1].bufsize = sizeof(*mac_tbl_mc)
   2203 	    + (ETHER_ADDR_LEN * virtio_rw32(vsc, mac_tbl_mc->nentries));
   2204 
   2205 	r = vioif_ctrl_load_cmdspec(sc, specs, nspecs);
   2206 	if (r != 0)
   2207 		goto out;
   2208 
   2209 	r = vioif_ctrl_send_command(sc,
   2210 	    VIRTIO_NET_CTRL_MAC, VIRTIO_NET_CTRL_MAC_TABLE_SET,
   2211 	    specs, nspecs);
   2212 
   2213 	vioif_ctrl_unload_cmdspec(sc, specs, nspecs);
   2214 
   2215 out:
   2216 	vioif_ctrl_release(sc);
   2217 
   2218 	return r;
   2219 }
   2220 
   2221 static int
   2222 vioif_set_mac_addr(struct vioif_softc *sc)
   2223 {
   2224 	struct virtio_net_ctrl_mac_addr *ma =
   2225 	    sc->sc_ctrlq.ctrlq_mac_addr;
   2226 	struct vioif_ctrl_cmdspec specs[1];
   2227 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   2228 	int nspecs = __arraycount(specs);
   2229 	uint64_t features;
   2230 	int r;
   2231 	size_t i;
   2232 
   2233 	if (!sc->sc_has_ctrl)
   2234 		return ENOTSUP;
   2235 
   2236 	if (memcmp(CLLADDR(ifp->if_sadl), sc->sc_mac,
   2237 	    ETHER_ADDR_LEN) == 0) {
   2238 		return 0;
   2239 	}
   2240 
   2241 	memcpy(sc->sc_mac, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
   2242 
   2243 	features = virtio_features(sc->sc_virtio);
   2244 	if (features & VIRTIO_NET_F_CTRL_MAC_ADDR) {
   2245 		vioif_ctrl_acquire(sc);
   2246 
   2247 		memcpy(ma->mac, sc->sc_mac, ETHER_ADDR_LEN);
   2248 		specs[0].dmamap = sc->sc_ctrlq.ctrlq_mac_addr_dmamap;
   2249 		specs[0].buf = ma;
   2250 		specs[0].bufsize = sizeof(*ma);
   2251 
   2252 		r = vioif_ctrl_send_command(sc,
   2253 		    VIRTIO_NET_CTRL_MAC, VIRTIO_NET_CTRL_MAC_ADDR_SET,
   2254 		    specs, nspecs);
   2255 
   2256 		vioif_ctrl_release(sc);
   2257 	} else {
   2258 		for (i = 0; i < __arraycount(sc->sc_mac); i++) {
   2259 			virtio_write_device_config_1(sc->sc_virtio,
   2260 			    VIRTIO_NET_CONFIG_MAC + i, sc->sc_mac[i]);
   2261 		}
   2262 		r = 0;
   2263 	}
   2264 
   2265 	return r;
   2266 }
   2267 
   2268 static int
   2269 vioif_ctrl_mq_vq_pairs_set(struct vioif_softc *sc, int nvq_pairs)
   2270 {
   2271 	struct virtio_net_ctrl_mq *mq = sc->sc_ctrlq.ctrlq_mq;
   2272 	struct vioif_ctrl_cmdspec specs[1];
   2273 	int r;
   2274 
   2275 	if (!sc->sc_has_ctrl)
   2276 		return ENOTSUP;
   2277 
   2278 	if (nvq_pairs <= 1)
   2279 		return EINVAL;
   2280 
   2281 	vioif_ctrl_acquire(sc);
   2282 
   2283 	mq->virtqueue_pairs = virtio_rw16(sc->sc_virtio, nvq_pairs);
   2284 	specs[0].dmamap = sc->sc_ctrlq.ctrlq_mq_dmamap;
   2285 	specs[0].buf = mq;
   2286 	specs[0].bufsize = sizeof(*mq);
   2287 
   2288 	r = vioif_ctrl_send_command(sc,
   2289 	    VIRTIO_NET_CTRL_MQ, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET,
   2290 	    specs, __arraycount(specs));
   2291 
   2292 	vioif_ctrl_release(sc);
   2293 
   2294 	return r;
   2295 }
   2296 
   2297 /* ctrl vq interrupt; wake up the command issuer */
   2298 static int
   2299 vioif_ctrl_intr(void *arg)
   2300 {
   2301 	struct vioif_ctrlqueue *ctrlq = arg;
   2302 	struct virtqueue *vq = ctrlq->ctrlq_vq;
   2303 	struct virtio_softc *vsc = vq->vq_owner;
   2304 	int r, slot;
   2305 
   2306 	if (virtio_vq_is_enqueued(vsc, vq) == false)
   2307 		return 0;
   2308 
   2309 	r = virtio_dequeue(vsc, vq, &slot, NULL);
   2310 	if (r == ENOENT)
   2311 		return 0;
   2312 	virtio_dequeue_commit(vsc, vq, slot);
   2313 
   2314 	mutex_enter(&ctrlq->ctrlq_wait_lock);
   2315 	ctrlq->ctrlq_inuse = DONE;
   2316 	cv_signal(&ctrlq->ctrlq_wait);
   2317 	mutex_exit(&ctrlq->ctrlq_wait_lock);
   2318 
   2319 	return 1;
   2320 }
   2321 
   2322 static int
   2323 vioif_ifflags(struct vioif_softc *sc)
   2324 {
   2325 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   2326 	bool onoff;
   2327 	int r;
   2328 
   2329 	if (!sc->sc_has_ctrl) {
   2330 		/* no ctrl vq; always promisc and allmulti */
   2331 		ifp->if_flags |= (IFF_PROMISC | IFF_ALLMULTI);
   2332 		return 0;
   2333 	}
   2334 
   2335 	onoff = ifp->if_flags & IFF_ALLMULTI ? true : false;
   2336 	r = vioif_set_allmulti(sc, onoff);
   2337 	if (r != 0) {
   2338 		log(LOG_WARNING,
   2339 		    "%s: couldn't %sable ALLMULTI\n",
   2340 		    ifp->if_xname, onoff ? "en" : "dis");
   2341 		if (onoff == false) {
   2342 			ifp->if_flags |= IFF_ALLMULTI;
   2343 		}
   2344 	}
   2345 
   2346 	onoff = ifp->if_flags & IFF_PROMISC ? true : false;
   2347 	r = vioif_set_promisc(sc, onoff);
   2348 	if (r != 0) {
   2349 		log(LOG_WARNING,
   2350 		    "%s: couldn't %sable PROMISC\n",
   2351 		    ifp->if_xname, onoff ? "en" : "dis");
   2352 		if (onoff == false) {
   2353 			ifp->if_flags |= IFF_PROMISC;
   2354 		}
   2355 	}
   2356 
   2357 	return 0;
   2358 }
   2359 
   2360 static int
   2361 vioif_ifflags_cb(struct ethercom *ec)
   2362 {
   2363 	struct ifnet *ifp = &ec->ec_if;
   2364 	struct vioif_softc *sc = ifp->if_softc;
   2365 
   2366 	return vioif_ifflags(sc);
   2367 }
   2368 
   2369 /*
   2370  * If multicast filter small enough (<=MAXENTRIES) set rx filter
   2371  * If large multicast filter exist use ALLMULTI
   2372  * If setting rx filter fails fall back to ALLMULTI
   2373  */
   2374 static int
   2375 vioif_rx_filter(struct vioif_softc *sc)
   2376 {
   2377 	struct virtio_softc *vsc = sc->sc_virtio;
   2378 	struct ethercom *ec = &sc->sc_ethercom;
   2379 	struct ifnet *ifp = &ec->ec_if;
   2380 	struct ether_multi *enm;
   2381 	struct ether_multistep step;
   2382 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
   2383 	int nentries;
   2384 	bool allmulti = 0;
   2385 	int r;
   2386 
   2387 	if (!sc->sc_has_ctrl) {
   2388 		goto set_ifflags;
   2389 	}
   2390 
   2391 	memcpy(ctrlq->ctrlq_mac_tbl_uc->macs[0],
   2392 	    CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
   2393 
   2394 	nentries = 0;
   2395 	allmulti = false;
   2396 
   2397 	ETHER_LOCK(ec);
   2398 	for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   2399 	    ETHER_NEXT_MULTI(step, enm)) {
   2400 		if (nentries >= VIRTIO_NET_CTRL_MAC_MAXENTRIES) {
   2401 			allmulti = true;
   2402 			break;
   2403 		}
   2404 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
   2405 			allmulti = true;
   2406 			break;
   2407 		}
   2408 
   2409 		memcpy(ctrlq->ctrlq_mac_tbl_mc->macs[nentries],
   2410 		    enm->enm_addrlo, ETHER_ADDR_LEN);
   2411 		nentries++;
   2412 	}
   2413 	ETHER_UNLOCK(ec);
   2414 
   2415 	r = vioif_set_mac_addr(sc);
   2416 	if (r != 0) {
   2417 		log(LOG_WARNING, "%s: couldn't set MAC address\n",
   2418 		    ifp->if_xname);
   2419 	}
   2420 
   2421 	if (!allmulti) {
   2422 		ctrlq->ctrlq_mac_tbl_uc->nentries = virtio_rw32(vsc, 1);
   2423 		ctrlq->ctrlq_mac_tbl_mc->nentries = virtio_rw32(vsc, nentries);
   2424 		r = vioif_set_rx_filter(sc);
   2425 		if (r != 0) {
   2426 			allmulti = true; /* fallback */
   2427 		}
   2428 	}
   2429 
   2430 	if (allmulti) {
   2431 		ctrlq->ctrlq_mac_tbl_uc->nentries = virtio_rw32(vsc, 0);
   2432 		ctrlq->ctrlq_mac_tbl_mc->nentries = virtio_rw32(vsc, 0);
   2433 		r = vioif_set_rx_filter(sc);
   2434 		if (r != 0) {
   2435 			log(LOG_DEBUG, "%s: couldn't clear RX filter\n",
   2436 			    ifp->if_xname);
   2437 			/* what to do on failure? */
   2438 		}
   2439 
   2440 		ifp->if_flags |= IFF_ALLMULTI;
   2441 	}
   2442 
   2443 set_ifflags:
   2444 	r = vioif_ifflags(sc);
   2445 
   2446 	return r;
   2447 }
   2448 
   2449 static int
   2450 vioif_get_link_status(struct vioif_softc *sc)
   2451 {
   2452 	struct virtio_softc *vsc = sc->sc_virtio;
   2453 	uint16_t status;
   2454 
   2455 	if (virtio_features(vsc) & VIRTIO_NET_F_STATUS)
   2456 		status = virtio_read_device_config_2(vsc,
   2457 		    VIRTIO_NET_CONFIG_STATUS);
   2458 	else
   2459 		status = VIRTIO_NET_S_LINK_UP;
   2460 
   2461 	if ((status & VIRTIO_NET_S_LINK_UP) != 0)
   2462 		return LINK_STATE_UP;
   2463 
   2464 	return LINK_STATE_DOWN;
   2465 }
   2466 
   2467 /* change link status */
   2468 static void
   2469 vioif_update_link_status(struct vioif_softc *sc)
   2470 {
   2471 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   2472 	struct vioif_netqueue *netq;
   2473 	struct vioif_tx_context *txc;
   2474 	bool active;
   2475 	int link, i;
   2476 
   2477 	mutex_enter(&sc->sc_lock);
   2478 
   2479 	link = vioif_get_link_status(sc);
   2480 
   2481 	if (link == sc->sc_link_state)
   2482 		goto done;
   2483 
   2484 	sc->sc_link_state = link;
   2485 
   2486 	active = VIOIF_IS_LINK_ACTIVE(sc);
   2487 	for (i = 0; i < sc->sc_act_nvq_pairs; i++) {
   2488 		netq = &sc->sc_netqs[VIOIF_NETQ_TXQID(i)];
   2489 
   2490 		mutex_enter(&netq->netq_lock);
   2491 		txc = netq->netq_ctx;
   2492 		txc->txc_link_active = active;
   2493 		mutex_exit(&netq->netq_lock);
   2494 	}
   2495 
   2496 	if_link_state_change(ifp, sc->sc_link_state);
   2497 
   2498 done:
   2499 	mutex_exit(&sc->sc_lock);
   2500 }
   2501 
   2502 static int
   2503 vioif_config_change(struct virtio_softc *vsc)
   2504 {
   2505 	struct vioif_softc *sc = device_private(virtio_child(vsc));
   2506 
   2507 	softint_schedule(sc->sc_ctl_softint);
   2508 	return 0;
   2509 }
   2510 
   2511 static void
   2512 vioif_ctl_softint(void *arg)
   2513 {
   2514 	struct vioif_softc *sc = arg;
   2515 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   2516 
   2517 	vioif_update_link_status(sc);
   2518 	vioif_start(ifp);
   2519 }
   2520 
   2521 static struct workqueue *
   2522 vioif_workq_create(const char *name, pri_t prio, int ipl, int flags)
   2523 {
   2524 	struct workqueue *wq;
   2525 	int error;
   2526 
   2527 	error = workqueue_create(&wq, name, vioif_workq_work, NULL,
   2528 	    prio, ipl, flags);
   2529 
   2530 	if (error)
   2531 		return NULL;
   2532 
   2533 	return wq;
   2534 }
   2535 
   2536 static void
   2537 vioif_workq_destroy(struct workqueue *wq)
   2538 {
   2539 
   2540 	workqueue_destroy(wq);
   2541 }
   2542 
   2543 static void
   2544 vioif_workq_work(struct work *wk, void *context)
   2545 {
   2546 	struct vioif_work *work;
   2547 
   2548 	work = container_of(wk, struct vioif_work, cookie);
   2549 
   2550 	atomic_store_relaxed(&work->added, 0);
   2551 	work->func(work->arg);
   2552 }
   2553 
   2554 static void
   2555 vioif_work_set(struct vioif_work *work, void (*func)(void *), void *arg)
   2556 {
   2557 
   2558 	memset(work, 0, sizeof(*work));
   2559 	work->func = func;
   2560 	work->arg = arg;
   2561 }
   2562 
   2563 static void
   2564 vioif_work_add(struct workqueue *wq, struct vioif_work *work)
   2565 {
   2566 
   2567 	if (atomic_load_relaxed(&work->added) != 0)
   2568 		return;
   2569 
   2570 	atomic_store_relaxed(&work->added, 1);
   2571 	kpreempt_disable();
   2572 	workqueue_enqueue(wq, &work->cookie, NULL);
   2573 	kpreempt_enable();
   2574 }
   2575 
   2576 static void
   2577 vioif_work_wait(struct workqueue *wq, struct vioif_work *work)
   2578 {
   2579 
   2580 	workqueue_wait(wq, &work->cookie);
   2581 }
   2582 
   2583 static int
   2584 vioif_setup_sysctl(struct vioif_softc *sc)
   2585 {
   2586 	const char *devname;
   2587 	struct sysctllog **log;
   2588 	const struct sysctlnode *rnode, *rxnode, *txnode;
   2589 	int error;
   2590 
   2591 	log = &sc->sc_sysctllog;
   2592 	devname = device_xname(sc->sc_dev);
   2593 
   2594 	error = sysctl_createv(log, 0, NULL, &rnode,
   2595 	    0, CTLTYPE_NODE, devname,
   2596 	    SYSCTL_DESCR("virtio-net information and settings"),
   2597 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
   2598 	if (error)
   2599 		goto out;
   2600 
   2601 	error = sysctl_createv(log, 0, &rnode, NULL,
   2602 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "txrx_workqueue",
   2603 	    SYSCTL_DESCR("Use workqueue for packet processing"),
   2604 	    NULL, 0, &sc->sc_txrx_workqueue_sysctl, 0, CTL_CREATE, CTL_EOL);
   2605 	if (error)
   2606 		goto out;
   2607 
   2608 	error = sysctl_createv(log, 0, &rnode, &rxnode,
   2609 	    0, CTLTYPE_NODE, "rx",
   2610 	    SYSCTL_DESCR("virtio-net information and settings for Rx"),
   2611 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
   2612 	if (error)
   2613 		goto out;
   2614 
   2615 	error = sysctl_createv(log, 0, &rxnode, NULL,
   2616 	    CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit",
   2617 	    SYSCTL_DESCR("max number of Rx packets to process for interrupt processing"),
   2618 	    NULL, 0, &sc->sc_rx_intr_process_limit, 0, CTL_CREATE, CTL_EOL);
   2619 	if (error)
   2620 		goto out;
   2621 
   2622 	error = sysctl_createv(log, 0, &rxnode, NULL,
   2623 	    CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit",
   2624 	    SYSCTL_DESCR("max number of Rx packets to process for deferred processing"),
   2625 	    NULL, 0, &sc->sc_rx_process_limit, 0, CTL_CREATE, CTL_EOL);
   2626 	if (error)
   2627 		goto out;
   2628 
   2629 	error = sysctl_createv(log, 0, &rnode, &txnode,
   2630 	    0, CTLTYPE_NODE, "tx",
   2631 	    SYSCTL_DESCR("virtio-net information and settings for Tx"),
   2632 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
   2633 	if (error)
   2634 		goto out;
   2635 
   2636 	error = sysctl_createv(log, 0, &txnode, NULL,
   2637 	    CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit",
   2638 	    SYSCTL_DESCR("max number of Tx packets to process for interrupt processing"),
   2639 	    NULL, 0, &sc->sc_tx_intr_process_limit, 0, CTL_CREATE, CTL_EOL);
   2640 	if (error)
   2641 		goto out;
   2642 
   2643 	error = sysctl_createv(log, 0, &txnode, NULL,
   2644 	    CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit",
   2645 	    SYSCTL_DESCR("max number of Tx packets to process for deferred processing"),
   2646 	    NULL, 0, &sc->sc_tx_process_limit, 0, CTL_CREATE, CTL_EOL);
   2647 
   2648 out:
   2649 	if (error)
   2650 		sysctl_teardown(log);
   2651 
   2652 	return error;
   2653 }
   2654 
   2655 static void
   2656 vioif_setup_stats(struct vioif_softc *sc)
   2657 {
   2658 	struct vioif_netqueue *netq;
   2659 	struct vioif_tx_context *txc;
   2660 	struct vioif_rx_context *rxc;
   2661 	size_t i, netq_num;
   2662 
   2663 	netq_num = sc->sc_max_nvq_pairs * 2;
   2664 	for (i = 0; i < netq_num; i++) {
   2665 		netq = &sc->sc_netqs[i];
   2666 		evcnt_attach_dynamic(&netq->netq_mbuf_load_failed, EVCNT_TYPE_MISC,
   2667 		    NULL, netq->netq_evgroup, "failed to load mbuf to DMA");
   2668 		evcnt_attach_dynamic(&netq->netq_enqueue_reserve_failed,
   2669 		    EVCNT_TYPE_MISC, NULL, netq->netq_evgroup,
   2670 		    "virtio_enqueue_reserve failed");
   2671 
   2672 		switch (VIOIF_NETQ_DIR(i)) {
   2673 		case VIOIF_NETQ_RX:
   2674 			rxc = netq->netq_ctx;
   2675 			evcnt_attach_dynamic(&rxc->rxc_mbuf_enobufs,
   2676 			    EVCNT_TYPE_MISC, NULL, netq->netq_evgroup,
   2677 			    "no receive buffer");
   2678 			break;
   2679 		case VIOIF_NETQ_TX:
   2680 			txc = netq->netq_ctx;
   2681 			evcnt_attach_dynamic(&txc->txc_defrag_failed,
   2682 			    EVCNT_TYPE_MISC, NULL, netq->netq_evgroup,
   2683 			    "m_defrag() failed");
   2684 			break;
   2685 		}
   2686 	}
   2687 
   2688 	evcnt_attach_dynamic(&sc->sc_ctrlq.ctrlq_cmd_load_failed, EVCNT_TYPE_MISC,
   2689 	    NULL, device_xname(sc->sc_dev), "control command dmamap load failed");
   2690 	evcnt_attach_dynamic(&sc->sc_ctrlq.ctrlq_cmd_failed, EVCNT_TYPE_MISC,
   2691 	    NULL, device_xname(sc->sc_dev), "control command failed");
   2692 }
   2693 
   2694 static void
   2695 vioif_intr_barrier(void)
   2696 {
   2697 
   2698 	/* wait for finish all interrupt handler */
   2699 	xc_barrier(0);
   2700 }
   2701 
   2702 MODULE(MODULE_CLASS_DRIVER, if_vioif, "virtio");
   2703 
   2704 #ifdef _MODULE
   2705 #include "ioconf.c"
   2706 #endif
   2707 
   2708 static int
   2709 if_vioif_modcmd(modcmd_t cmd, void *opaque)
   2710 {
   2711 	int error = 0;
   2712 
   2713 #ifdef _MODULE
   2714 	switch (cmd) {
   2715 	case MODULE_CMD_INIT:
   2716 		error = config_init_component(cfdriver_ioconf_if_vioif,
   2717 		    cfattach_ioconf_if_vioif, cfdata_ioconf_if_vioif);
   2718 		break;
   2719 	case MODULE_CMD_FINI:
   2720 		error = config_fini_component(cfdriver_ioconf_if_vioif,
   2721 		    cfattach_ioconf_if_vioif, cfdata_ioconf_if_vioif);
   2722 		break;
   2723 	default:
   2724 		error = ENOTTY;
   2725 		break;
   2726 	}
   2727 #endif
   2728 
   2729 	return error;
   2730 }
   2731