Home | History | Annotate | Line # | Download | only in pci
if_vioif.c revision 1.2.6.3
      1 /*	$NetBSD: if_vioif.c,v 1.2.6.3 2013/06/09 11:51:40 msaitoh Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2010 Minoura Makoto.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.2.6.3 2013/06/09 11:51:40 msaitoh Exp $");
     30 
     31 #include "bpfilter.h"
     32 
     33 #include <sys/param.h>
     34 #include <sys/systm.h>
     35 #include <sys/kernel.h>
     36 #include <sys/bus.h>
     37 #include <sys/condvar.h>
     38 #include <sys/device.h>
     39 #include <sys/intr.h>
     40 #include <sys/kmem.h>
     41 #include <sys/mbuf.h>
     42 #include <sys/mutex.h>
     43 #include <sys/sockio.h>
     44 
     45 #include <dev/pci/pcidevs.h>
     46 #include <dev/pci/pcireg.h>
     47 #include <dev/pci/pcivar.h>
     48 #include <dev/pci/virtioreg.h>
     49 #include <dev/pci/virtiovar.h>
     50 
     51 #include <net/if.h>
     52 #include <net/if_media.h>
     53 #include <net/if_ether.h>
     54 
     55 #if NBPFILTER > 0
     56 #include <net/bpf.h>
     57 #endif
     58 
     59 
     60 /*
     61  * if_vioifreg.h:
     62  */
     63 /* Configuration registers */
     64 #define VIRTIO_NET_CONFIG_MAC		0 /* 8bit x 6byte */
     65 #define VIRTIO_NET_CONFIG_STATUS	6 /* 16bit */
     66 
     67 /* Feature bits */
     68 #define VIRTIO_NET_F_CSUM	(1<<0)
     69 #define VIRTIO_NET_F_GUEST_CSUM	(1<<1)
     70 #define VIRTIO_NET_F_MAC	(1<<5)
     71 #define VIRTIO_NET_F_GSO	(1<<6)
     72 #define VIRTIO_NET_F_GUEST_TSO4	(1<<7)
     73 #define VIRTIO_NET_F_GUEST_TSO6	(1<<8)
     74 #define VIRTIO_NET_F_GUEST_ECN	(1<<9)
     75 #define VIRTIO_NET_F_GUEST_UFO	(1<<10)
     76 #define VIRTIO_NET_F_HOST_TSO4	(1<<11)
     77 #define VIRTIO_NET_F_HOST_TSO6	(1<<12)
     78 #define VIRTIO_NET_F_HOST_ECN	(1<<13)
     79 #define VIRTIO_NET_F_HOST_UFO	(1<<14)
     80 #define VIRTIO_NET_F_MRG_RXBUF	(1<<15)
     81 #define VIRTIO_NET_F_STATUS	(1<<16)
     82 #define VIRTIO_NET_F_CTRL_VQ	(1<<17)
     83 #define VIRTIO_NET_F_CTRL_RX	(1<<18)
     84 #define VIRTIO_NET_F_CTRL_VLAN	(1<<19)
     85 
     86 /* Status */
     87 #define VIRTIO_NET_S_LINK_UP	1
     88 
     89 /* Packet header structure */
     90 struct virtio_net_hdr {
     91 	uint8_t		flags;
     92 	uint8_t		gso_type;
     93 	uint16_t	hdr_len;
     94 	uint16_t	gso_size;
     95 	uint16_t	csum_start;
     96 	uint16_t	csum_offset;
     97 #if 0
     98 	uint16_t	num_buffers; /* if VIRTIO_NET_F_MRG_RXBUF enabled */
     99 #endif
    100 } __packed;
    101 
    102 #define VIRTIO_NET_HDR_F_NEEDS_CSUM	1 /* flags */
    103 #define VIRTIO_NET_HDR_GSO_NONE		0 /* gso_type */
    104 #define VIRTIO_NET_HDR_GSO_TCPV4	1 /* gso_type */
    105 #define VIRTIO_NET_HDR_GSO_UDP		3 /* gso_type */
    106 #define VIRTIO_NET_HDR_GSO_TCPV6	4 /* gso_type */
    107 #define VIRTIO_NET_HDR_GSO_ECN		0x80 /* gso_type, |'ed */
    108 
    109 #define VIRTIO_NET_MAX_GSO_LEN		(65536+ETHER_HDR_LEN)
    110 
    111 /* Control virtqueue */
    112 struct virtio_net_ctrl_cmd {
    113 	uint8_t	class;
    114 	uint8_t	command;
    115 } __packed;
    116 #define VIRTIO_NET_CTRL_RX		0
    117 # define VIRTIO_NET_CTRL_RX_PROMISC	0
    118 # define VIRTIO_NET_CTRL_RX_ALLMULTI	1
    119 
    120 #define VIRTIO_NET_CTRL_MAC		1
    121 # define VIRTIO_NET_CTRL_MAC_TABLE_SET	0
    122 
    123 #define VIRTIO_NET_CTRL_VLAN		2
    124 # define VIRTIO_NET_CTRL_VLAN_ADD	0
    125 # define VIRTIO_NET_CTRL_VLAN_DEL	1
    126 
    127 struct virtio_net_ctrl_status {
    128 	uint8_t	ack;
    129 } __packed;
    130 #define VIRTIO_NET_OK			0
    131 #define VIRTIO_NET_ERR			1
    132 
    133 struct virtio_net_ctrl_rx {
    134 	uint8_t	onoff;
    135 } __packed;
    136 
    137 struct virtio_net_ctrl_mac_tbl {
    138 	uint32_t nentries;
    139 	uint8_t macs[][ETHER_ADDR_LEN];
    140 } __packed;
    141 
    142 struct virtio_net_ctrl_vlan {
    143 	uint16_t id;
    144 } __packed;
    145 
    146 
    147 /*
    148  * if_vioifvar.h:
    149  */
    150 struct vioif_softc {
    151 	device_t		sc_dev;
    152 
    153 	struct virtio_softc	*sc_virtio;
    154 	struct virtqueue	sc_vq[3];
    155 
    156 	uint8_t			sc_mac[ETHER_ADDR_LEN];
    157 	struct ethercom		sc_ethercom;
    158 	short			sc_ifflags;
    159 
    160 	/* bus_dmamem */
    161 	bus_dma_segment_t	sc_hdr_segs[1];
    162 	struct virtio_net_hdr	*sc_hdrs;
    163 #define sc_rx_hdrs	sc_hdrs
    164 	struct virtio_net_hdr	*sc_tx_hdrs;
    165 	struct virtio_net_ctrl_cmd *sc_ctrl_cmd;
    166 	struct virtio_net_ctrl_status *sc_ctrl_status;
    167 	struct virtio_net_ctrl_rx *sc_ctrl_rx;
    168 	struct virtio_net_ctrl_mac_tbl *sc_ctrl_mac_tbl_uc;
    169 	struct virtio_net_ctrl_mac_tbl *sc_ctrl_mac_tbl_mc;
    170 
    171 	/* kmem */
    172 	bus_dmamap_t		*sc_arrays;
    173 #define sc_rxhdr_dmamaps sc_arrays
    174 	bus_dmamap_t		*sc_txhdr_dmamaps;
    175 	bus_dmamap_t		*sc_rx_dmamaps;
    176 	bus_dmamap_t		*sc_tx_dmamaps;
    177 	struct mbuf		**sc_rx_mbufs;
    178 	struct mbuf		**sc_tx_mbufs;
    179 
    180 	bus_dmamap_t		sc_ctrl_cmd_dmamap;
    181 	bus_dmamap_t		sc_ctrl_status_dmamap;
    182 	bus_dmamap_t		sc_ctrl_rx_dmamap;
    183 	bus_dmamap_t		sc_ctrl_tbl_uc_dmamap;
    184 	bus_dmamap_t		sc_ctrl_tbl_mc_dmamap;
    185 
    186 	void			*sc_rx_softint;
    187 
    188 	enum {
    189 		FREE, INUSE, DONE
    190 	}			sc_ctrl_inuse;
    191 	kcondvar_t		sc_ctrl_wait;
    192 	kmutex_t		sc_ctrl_wait_lock;
    193 };
    194 #define VIRTIO_NET_TX_MAXNSEGS		(16) /* XXX */
    195 #define VIRTIO_NET_CTRL_MAC_MAXENTRIES	(64) /* XXX */
    196 
    197 /* cfattach interface functions */
    198 static int	vioif_match(device_t, cfdata_t, void *);
    199 static void	vioif_attach(device_t, device_t, void *);
    200 static void	vioif_deferred_init(device_t);
    201 
    202 /* ifnet interface functions */
    203 static int	vioif_init(struct ifnet *);
    204 static void	vioif_stop(struct ifnet *, int);
    205 static void	vioif_start(struct ifnet *);
    206 static int	vioif_ioctl(struct ifnet *, u_long, void *);
    207 static void	vioif_watchdog(struct ifnet *);
    208 
    209 /* rx */
    210 static int	vioif_add_rx_mbuf(struct vioif_softc *, int);
    211 static void	vioif_free_rx_mbuf(struct vioif_softc *, int);
    212 static void	vioif_populate_rx_mbufs(struct vioif_softc *);
    213 static int	vioif_rx_deq(struct vioif_softc *);
    214 static int	vioif_rx_vq_done(struct virtqueue *);
    215 static void	vioif_rx_softint(void *);
    216 static void	vioif_rx_drain(struct vioif_softc *);
    217 
    218 /* tx */
    219 static int	vioif_tx_vq_done(struct virtqueue *);
    220 static void	vioif_tx_drain(struct vioif_softc *);
    221 
    222 /* other control */
    223 static int	vioif_updown(struct vioif_softc *, bool);
    224 static int	vioif_ctrl_rx(struct vioif_softc *, int, bool);
    225 static int	vioif_set_promisc(struct vioif_softc *, bool);
    226 static int	vioif_set_allmulti(struct vioif_softc *, bool);
    227 static int	vioif_set_rx_filter(struct vioif_softc *);
    228 static int	vioif_rx_filter(struct vioif_softc *);
    229 static int	vioif_ctrl_vq_done(struct virtqueue *);
    230 
    231 CFATTACH_DECL_NEW(vioif, sizeof(struct vioif_softc),
    232 		  vioif_match, vioif_attach, NULL, NULL);
    233 
    234 static int
    235 vioif_match(device_t parent, cfdata_t match, void *aux)
    236 {
    237 	struct virtio_softc *va = aux;
    238 
    239 	if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_NETWORK)
    240 		return 1;
    241 
    242 	return 0;
    243 }
    244 
    245 /* allocate memory */
    246 /*
    247  * dma memory is used for:
    248  *   sc_rx_hdrs[slot]:	 metadata array for recieved frames (READ)
    249  *   sc_tx_hdrs[slot]:	 metadata array for frames to be sent (WRITE)
    250  *   sc_ctrl_cmd:	 command to be sent via ctrl vq (WRITE)
    251  *   sc_ctrl_status:	 return value for a command via ctrl vq (READ)
    252  *   sc_ctrl_rx:	 parameter for a VIRTIO_NET_CTRL_RX class command
    253  *			 (WRITE)
    254  *   sc_ctrl_mac_tbl_uc: unicast MAC address filter for a VIRTIO_NET_CTRL_MAC
    255  *			 class command (WRITE)
    256  *   sc_ctrl_mac_tbl_mc: multicast MAC address filter for a VIRTIO_NET_CTRL_MAC
    257  *			 class command (WRITE)
    258  * sc_ctrl_* structures are allocated only one each; they are protected by
    259  * sc_ctrl_inuse variable and sc_ctrl_wait condvar.
    260  */
    261 /*
    262  * dynamically allocated memory is used for:
    263  *   sc_rxhdr_dmamaps[slot]:	bus_dmamap_t array for sc_rx_hdrs[slot]
    264  *   sc_txhdr_dmamaps[slot]:	bus_dmamap_t array for sc_tx_hdrs[slot]
    265  *   sc_rx_dmamaps[slot]:	bus_dmamap_t array for recieved payload
    266  *   sc_tx_dmamaps[slot]:	bus_dmamap_t array for sent payload
    267  *   sc_rx_mbufs[slot]:		mbuf pointer array for recieved frames
    268  *   sc_tx_mbufs[slot]:		mbuf pointer array for sent frames
    269  */
    270 static int
    271 vioif_alloc_mems(struct vioif_softc *sc)
    272 {
    273 	struct virtio_softc *vsc = sc->sc_virtio;
    274 	int allocsize, allocsize2, r, rsegs, i;
    275 	void *vaddr;
    276 	intptr_t p;
    277 	int rxqsize, txqsize;
    278 
    279 	rxqsize = vsc->sc_vqs[0].vq_num;
    280 	txqsize = vsc->sc_vqs[1].vq_num;
    281 
    282 	allocsize = sizeof(struct virtio_net_hdr) * rxqsize;
    283 	allocsize += sizeof(struct virtio_net_hdr) * txqsize;
    284 	if (vsc->sc_nvqs == 3) {
    285 		allocsize += sizeof(struct virtio_net_ctrl_cmd) * 1;
    286 		allocsize += sizeof(struct virtio_net_ctrl_status) * 1;
    287 		allocsize += sizeof(struct virtio_net_ctrl_rx) * 1;
    288 		allocsize += sizeof(struct virtio_net_ctrl_mac_tbl)
    289 			+ sizeof(struct virtio_net_ctrl_mac_tbl)
    290 			+ ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES;
    291 	}
    292 	r = bus_dmamem_alloc(vsc->sc_dmat, allocsize, 0, 0,
    293 			     &sc->sc_hdr_segs[0], 1, &rsegs, BUS_DMA_NOWAIT);
    294 	if (r != 0) {
    295 		aprint_error_dev(sc->sc_dev,
    296 				 "DMA memory allocation failed, size %d, "
    297 				 "error code %d\n", allocsize, r);
    298 		goto err_none;
    299 	}
    300 	r = bus_dmamem_map(vsc->sc_dmat,
    301 			   &sc->sc_hdr_segs[0], 1, allocsize,
    302 			   &vaddr, BUS_DMA_NOWAIT);
    303 	if (r != 0) {
    304 		aprint_error_dev(sc->sc_dev,
    305 				 "DMA memory map failed, "
    306 				 "error code %d\n", r);
    307 		goto err_dmamem_alloc;
    308 	}
    309 	sc->sc_hdrs = vaddr;
    310 	memset(vaddr, 0, allocsize);
    311 	p = (intptr_t) vaddr;
    312 	p += sizeof(struct virtio_net_hdr) * rxqsize;
    313 #define P(name,size)	do { sc->sc_ ##name = (void*) p;	\
    314 			     p += size; } while (0)
    315 	P(tx_hdrs, sizeof(struct virtio_net_hdr) * txqsize);
    316 	if (vsc->sc_nvqs == 3) {
    317 		P(ctrl_cmd, sizeof(struct virtio_net_ctrl_cmd));
    318 		P(ctrl_status, sizeof(struct virtio_net_ctrl_status));
    319 		P(ctrl_rx, sizeof(struct virtio_net_ctrl_rx));
    320 		P(ctrl_mac_tbl_uc, sizeof(struct virtio_net_ctrl_mac_tbl));
    321 		P(ctrl_mac_tbl_mc,
    322 		  (sizeof(struct virtio_net_ctrl_mac_tbl)
    323 		   + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES));
    324 	}
    325 #undef P
    326 
    327 	allocsize2 = sizeof(bus_dmamap_t) * (rxqsize + txqsize);
    328 	allocsize2 += sizeof(bus_dmamap_t) * (rxqsize + txqsize);
    329 	allocsize2 += sizeof(struct mbuf*) * (rxqsize + txqsize);
    330 	sc->sc_arrays = kmem_zalloc(allocsize2, KM_SLEEP);
    331 	if (sc->sc_arrays == NULL)
    332 		goto err_dmamem_map;
    333 	sc->sc_txhdr_dmamaps = sc->sc_arrays + rxqsize;
    334 	sc->sc_rx_dmamaps = sc->sc_txhdr_dmamaps + txqsize;
    335 	sc->sc_tx_dmamaps = sc->sc_rx_dmamaps + rxqsize;
    336 	sc->sc_rx_mbufs = (void*) (sc->sc_tx_dmamaps + txqsize);
    337 	sc->sc_tx_mbufs = sc->sc_rx_mbufs + rxqsize;
    338 
    339 #define C(map, buf, size, nsegs, rw, usage)				\
    340 	do {								\
    341 		r = bus_dmamap_create(vsc->sc_dmat, size, nsegs, size, 0, \
    342 				      BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,	\
    343 				      &sc->sc_ ##map);			\
    344 		if (r != 0) {						\
    345 			aprint_error_dev(sc->sc_dev,			\
    346 					 usage " dmamap creation failed, " \
    347 					 "error code %d\n", r);		\
    348 					 goto err_reqs;			\
    349 		}							\
    350 	} while (0)
    351 #define C_L1(map, buf, size, nsegs, rw, usage)				\
    352 	C(map, buf, size, nsegs, rw, usage);				\
    353 	do {								\
    354 		r = bus_dmamap_load(vsc->sc_dmat, sc->sc_ ##map,	\
    355 				    &sc->sc_ ##buf, size, NULL,		\
    356 				    BUS_DMA_ ##rw | BUS_DMA_NOWAIT);	\
    357 		if (r != 0) {						\
    358 			aprint_error_dev(sc->sc_dev,			\
    359 					 usage " dmamap load failed, "	\
    360 					 "error code %d\n", r);		\
    361 			goto err_reqs;					\
    362 		}							\
    363 	} while (0)
    364 #define C_L2(map, buf, size, nsegs, rw, usage)				\
    365 	C(map, buf, size, nsegs, rw, usage);				\
    366 	do {								\
    367 		r = bus_dmamap_load(vsc->sc_dmat, sc->sc_ ##map,	\
    368 				    sc->sc_ ##buf, size, NULL,		\
    369 				    BUS_DMA_ ##rw | BUS_DMA_NOWAIT);	\
    370 		if (r != 0) {						\
    371 			aprint_error_dev(sc->sc_dev,			\
    372 					 usage " dmamap load failed, "	\
    373 					 "error code %d\n", r);		\
    374 			goto err_reqs;					\
    375 		}							\
    376 	} while (0)
    377 	for (i = 0; i < rxqsize; i++) {
    378 		C_L1(rxhdr_dmamaps[i], rx_hdrs[i],
    379 		    sizeof(struct virtio_net_hdr), 1,
    380 		    READ, "rx header");
    381 		C(rx_dmamaps[i], NULL, MCLBYTES, 1, 0, "rx payload");
    382 	}
    383 
    384 	for (i = 0; i < txqsize; i++) {
    385 		C_L1(txhdr_dmamaps[i], rx_hdrs[i],
    386 		    sizeof(struct virtio_net_hdr), 1,
    387 		    WRITE, "tx header");
    388 		C(tx_dmamaps[i], NULL, ETHER_MAX_LEN, 256 /* XXX */, 0,
    389 		  "tx payload");
    390 	}
    391 
    392 	if (vsc->sc_nvqs == 3) {
    393 		/* control vq class & command */
    394 		C_L2(ctrl_cmd_dmamap, ctrl_cmd,
    395 		    sizeof(struct virtio_net_ctrl_cmd), 1, WRITE,
    396 		    "control command");
    397 
    398 		/* control vq status */
    399 		C_L2(ctrl_status_dmamap, ctrl_status,
    400 		    sizeof(struct virtio_net_ctrl_status), 1, READ,
    401 		    "control status");
    402 
    403 		/* control vq rx mode command parameter */
    404 		C_L2(ctrl_rx_dmamap, ctrl_rx,
    405 		    sizeof(struct virtio_net_ctrl_rx), 1, WRITE,
    406 		    "rx mode control command");
    407 
    408 		/* control vq MAC filter table for unicast */
    409 		/* do not load now since its length is variable */
    410 		C(ctrl_tbl_uc_dmamap, NULL,
    411 		  sizeof(struct virtio_net_ctrl_mac_tbl) + 0, 1, WRITE,
    412 		  "unicast MAC address filter command");
    413 
    414 		/* control vq MAC filter table for multicast */
    415 		C(ctrl_tbl_mc_dmamap, NULL,
    416 		  (sizeof(struct virtio_net_ctrl_mac_tbl)
    417 		   + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES),
    418 		  1, WRITE, "multicast MAC address filter command");
    419 	}
    420 #undef C_L2
    421 #undef C_L1
    422 #undef C
    423 
    424 	return 0;
    425 
    426 err_reqs:
    427 #define D(map)								\
    428 	do {								\
    429 		if (sc->sc_ ##map) {					\
    430 			bus_dmamap_destroy(vsc->sc_dmat, sc->sc_ ##map); \
    431 			sc->sc_ ##map = NULL;				\
    432 		}							\
    433 	} while (0)
    434 	D(ctrl_tbl_mc_dmamap);
    435 	D(ctrl_tbl_uc_dmamap);
    436 	D(ctrl_rx_dmamap);
    437 	D(ctrl_status_dmamap);
    438 	D(ctrl_cmd_dmamap);
    439 	for (i = 0; i < txqsize; i++) {
    440 		D(tx_dmamaps[i]);
    441 		D(txhdr_dmamaps[i]);
    442 	}
    443 	for (i = 0; i < rxqsize; i++) {
    444 		D(rx_dmamaps[i]);
    445 		D(rxhdr_dmamaps[i]);
    446 	}
    447 #undef D
    448 	if (sc->sc_arrays) {
    449 		kmem_free(sc->sc_arrays, allocsize2);
    450 		sc->sc_arrays = 0;
    451 	}
    452 err_dmamem_map:
    453 	bus_dmamem_unmap(vsc->sc_dmat, sc->sc_hdrs, allocsize);
    454 err_dmamem_alloc:
    455 	bus_dmamem_free(vsc->sc_dmat, &sc->sc_hdr_segs[0], 1);
    456 err_none:
    457 	return -1;
    458 }
    459 
    460 static void
    461 vioif_attach(device_t parent, device_t self, void *aux)
    462 {
    463 	struct vioif_softc *sc = device_private(self);
    464 	struct virtio_softc *vsc = device_private(parent);
    465 	uint32_t features;
    466 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    467 
    468 	if (vsc->sc_child != NULL) {
    469 		aprint_normal(": child already attached for %s; "
    470 			      "something wrong...\n",
    471 			      device_xname(parent));
    472 		return;
    473 	}
    474 
    475 	sc->sc_dev = self;
    476 	sc->sc_virtio = vsc;
    477 
    478 	vsc->sc_child = self;
    479 	vsc->sc_ipl = IPL_NET;
    480 	vsc->sc_vqs = &sc->sc_vq[0];
    481 	vsc->sc_config_change = 0;
    482 	vsc->sc_intrhand = virtio_vq_intr;
    483 
    484 	features = virtio_negotiate_features(vsc,
    485 					     (VIRTIO_NET_F_MAC |
    486 					      VIRTIO_NET_F_STATUS |
    487 					      VIRTIO_NET_F_CTRL_VQ |
    488 					      VIRTIO_NET_F_CTRL_RX |
    489 					      VIRTIO_F_NOTIFY_ON_EMPTY));
    490 	if (features & VIRTIO_NET_F_MAC) {
    491 		sc->sc_mac[0] = virtio_read_device_config_1(vsc,
    492 						    VIRTIO_NET_CONFIG_MAC+0);
    493 		sc->sc_mac[1] = virtio_read_device_config_1(vsc,
    494 						    VIRTIO_NET_CONFIG_MAC+1);
    495 		sc->sc_mac[2] = virtio_read_device_config_1(vsc,
    496 						    VIRTIO_NET_CONFIG_MAC+2);
    497 		sc->sc_mac[3] = virtio_read_device_config_1(vsc,
    498 						    VIRTIO_NET_CONFIG_MAC+3);
    499 		sc->sc_mac[4] = virtio_read_device_config_1(vsc,
    500 						    VIRTIO_NET_CONFIG_MAC+4);
    501 		sc->sc_mac[5] = virtio_read_device_config_1(vsc,
    502 						    VIRTIO_NET_CONFIG_MAC+5);
    503 	} else {
    504 		/* code stolen from sys/net/if_tap.c */
    505 		struct timeval tv;
    506 		uint32_t ui;
    507 		getmicrouptime(&tv);
    508 		ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff;
    509 		memcpy(sc->sc_mac+3, (uint8_t *)&ui, 3);
    510 		virtio_write_device_config_1(vsc,
    511 					     VIRTIO_NET_CONFIG_MAC+0,
    512 					     sc->sc_mac[0]);
    513 		virtio_write_device_config_1(vsc,
    514 					     VIRTIO_NET_CONFIG_MAC+1,
    515 					     sc->sc_mac[1]);
    516 		virtio_write_device_config_1(vsc,
    517 					     VIRTIO_NET_CONFIG_MAC+2,
    518 					     sc->sc_mac[2]);
    519 		virtio_write_device_config_1(vsc,
    520 					     VIRTIO_NET_CONFIG_MAC+3,
    521 					     sc->sc_mac[3]);
    522 		virtio_write_device_config_1(vsc,
    523 					     VIRTIO_NET_CONFIG_MAC+4,
    524 					     sc->sc_mac[4]);
    525 		virtio_write_device_config_1(vsc,
    526 					     VIRTIO_NET_CONFIG_MAC+5,
    527 					     sc->sc_mac[5]);
    528 	}
    529 	aprint_normal(": Ethernet address %s\n", ether_sprintf(sc->sc_mac));
    530 	aprint_naive("\n");
    531 
    532 	if (virtio_alloc_vq(vsc, &sc->sc_vq[0], 0,
    533 			    MCLBYTES+sizeof(struct virtio_net_hdr), 2,
    534 			    "rx") != 0) {
    535 		goto err;
    536 	}
    537 	vsc->sc_nvqs = 1;
    538 	sc->sc_vq[0].vq_done = vioif_rx_vq_done;
    539 	if (virtio_alloc_vq(vsc, &sc->sc_vq[1], 1,
    540 			    (sizeof(struct virtio_net_hdr)
    541 			     + (ETHER_MAX_LEN - ETHER_HDR_LEN)),
    542 			    VIRTIO_NET_TX_MAXNSEGS + 1,
    543 			    "tx") != 0) {
    544 		goto err;
    545 	}
    546 	vsc->sc_nvqs = 2;
    547 	sc->sc_vq[1].vq_done = vioif_tx_vq_done;
    548 	virtio_start_vq_intr(vsc, &sc->sc_vq[0]);
    549 	virtio_stop_vq_intr(vsc, &sc->sc_vq[1]); /* not urgent; do it later */
    550 	if ((features & VIRTIO_NET_F_CTRL_VQ)
    551 	    && (features & VIRTIO_NET_F_CTRL_RX)) {
    552 		if (virtio_alloc_vq(vsc, &sc->sc_vq[2], 2,
    553 				    NBPG, 1, "control") == 0) {
    554 			sc->sc_vq[2].vq_done = vioif_ctrl_vq_done;
    555 			cv_init(&sc->sc_ctrl_wait, "ctrl_vq");
    556 			mutex_init(&sc->sc_ctrl_wait_lock,
    557 				   MUTEX_DEFAULT, IPL_NET);
    558 			sc->sc_ctrl_inuse = FREE;
    559 			virtio_start_vq_intr(vsc, &sc->sc_vq[2]);
    560 			vsc->sc_nvqs = 3;
    561 		}
    562 	}
    563 
    564 	sc->sc_rx_softint = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE,
    565 					      vioif_rx_softint, sc);
    566 	if (sc->sc_rx_softint == NULL) {
    567 		aprint_error_dev(self, "cannot establish softint\n");
    568 		goto err;
    569 	}
    570 
    571 	if (vioif_alloc_mems(sc) < 0)
    572 		goto err;
    573 	if (vsc->sc_nvqs == 3)
    574 		config_interrupts(self, vioif_deferred_init);
    575 
    576 	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
    577 	ifp->if_softc = sc;
    578 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    579 	ifp->if_start = vioif_start;
    580 	ifp->if_ioctl = vioif_ioctl;
    581 	ifp->if_init = vioif_init;
    582 	ifp->if_stop = vioif_stop;
    583 	ifp->if_capabilities = 0;
    584 	ifp->if_watchdog = vioif_watchdog;
    585 
    586 	if_attach(ifp);
    587 	ether_ifattach(ifp, sc->sc_mac);
    588 
    589 	return;
    590 
    591 err:
    592 	if (vsc->sc_nvqs == 3) {
    593 		virtio_free_vq(vsc, &sc->sc_vq[2]);
    594 		cv_destroy(&sc->sc_ctrl_wait);
    595 		mutex_destroy(&sc->sc_ctrl_wait_lock);
    596 		vsc->sc_nvqs = 2;
    597 	}
    598 	if (vsc->sc_nvqs == 2) {
    599 		virtio_free_vq(vsc, &sc->sc_vq[1]);
    600 		vsc->sc_nvqs = 1;
    601 	}
    602 	if (vsc->sc_nvqs == 1) {
    603 		virtio_free_vq(vsc, &sc->sc_vq[0]);
    604 		vsc->sc_nvqs = 0;
    605 	}
    606 	vsc->sc_child = (void*)1;
    607 	return;
    608 }
    609 
    610 /* we need interrupts to make promiscuous mode off */
    611 static void
    612 vioif_deferred_init(device_t self)
    613 {
    614 	struct vioif_softc *sc = device_private(self);
    615 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    616 	int r;
    617 
    618 	r =  vioif_set_promisc(sc, false);
    619 	if (r != 0)
    620 		aprint_error_dev(self, "resetting promisc mode failed, "
    621 				 "errror code %d\n", r);
    622 	else
    623 		ifp->if_flags &= ~IFF_PROMISC;
    624 }
    625 
    626 /*
    627  * Interface functions for ifnet
    628  */
    629 static int
    630 vioif_init(struct ifnet *ifp)
    631 {
    632 	struct vioif_softc *sc = ifp->if_softc;
    633 
    634 	vioif_stop(ifp, 0);
    635 	vioif_populate_rx_mbufs(sc);
    636 	vioif_updown(sc, true);
    637 	ifp->if_flags |= IFF_RUNNING;
    638 	ifp->if_flags &= ~IFF_OACTIVE;
    639 	vioif_rx_filter(sc);
    640 
    641 	return 0;
    642 }
    643 
    644 static void
    645 vioif_stop(struct ifnet *ifp, int disable)
    646 {
    647 	struct vioif_softc *sc = ifp->if_softc;
    648 	struct virtio_softc *vsc = sc->sc_virtio;
    649 
    650 	/* only way to stop I/O and DMA is resetting... */
    651 	virtio_reset(vsc);
    652 	vioif_rx_deq(sc);
    653 	vioif_tx_drain(sc);
    654 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
    655 
    656 	if (disable)
    657 		vioif_rx_drain(sc);
    658 
    659 	virtio_reinit_start(vsc);
    660 	virtio_negotiate_features(vsc, vsc->sc_features);
    661 	virtio_start_vq_intr(vsc, &sc->sc_vq[0]);
    662 	virtio_stop_vq_intr(vsc, &sc->sc_vq[1]);
    663 	if (vsc->sc_nvqs >= 3)
    664 		virtio_start_vq_intr(vsc, &sc->sc_vq[2]);
    665 	virtio_reinit_end(vsc);
    666 	vioif_updown(sc, false);
    667 }
    668 
    669 static void
    670 vioif_start(struct ifnet *ifp)
    671 {
    672 	struct vioif_softc *sc = ifp->if_softc;
    673 	struct virtio_softc *vsc = sc->sc_virtio;
    674 	struct virtqueue *vq = &sc->sc_vq[1]; /* tx vq */
    675 	struct mbuf *m;
    676 	int queued = 0, retry = 0;
    677 
    678 	if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
    679 		return;
    680 
    681 	for (;;) {
    682 		int slot, r;
    683 
    684 		IFQ_POLL(&ifp->if_snd, m);
    685 		if (m == NULL)
    686 			break;
    687 
    688 		r = virtio_enqueue_prep(vsc, vq, &slot);
    689 		if (r == EAGAIN) {
    690 			ifp->if_flags |= IFF_OACTIVE;
    691 			vioif_tx_vq_done(vq);
    692 			if (retry++ == 0)
    693 				continue;
    694 			else
    695 				break;
    696 		}
    697 		if (r != 0)
    698 			panic("enqueue_prep for a tx buffer");
    699 		r = bus_dmamap_load_mbuf(vsc->sc_dmat,
    700 					 sc->sc_tx_dmamaps[slot],
    701 					 m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
    702 		if (r != 0) {
    703 			virtio_enqueue_abort(vsc, vq, slot);
    704 			printf("%s: tx dmamap load failed, error code %d\n",
    705 			       device_xname(sc->sc_dev), r);
    706 			break;
    707 		}
    708 		r = virtio_enqueue_reserve(vsc, vq, slot,
    709 					sc->sc_tx_dmamaps[slot]->dm_nsegs + 1);
    710 		if (r != 0) {
    711 			bus_dmamap_unload(vsc->sc_dmat,
    712 					  sc->sc_tx_dmamaps[slot]);
    713 			ifp->if_flags |= IFF_OACTIVE;
    714 			vioif_tx_vq_done(vq);
    715 			if (retry++ == 0)
    716 				continue;
    717 			else
    718 				break;
    719 		}
    720 		IFQ_DEQUEUE(&ifp->if_snd, m);
    721 		sc->sc_tx_mbufs[slot] = m;
    722 
    723 		memset(&sc->sc_tx_hdrs[slot], 0, sizeof(struct virtio_net_hdr));
    724 		bus_dmamap_sync(vsc->sc_dmat, sc->sc_tx_dmamaps[slot],
    725 				0, sc->sc_tx_dmamaps[slot]->dm_mapsize,
    726 				BUS_DMASYNC_PREWRITE);
    727 		bus_dmamap_sync(vsc->sc_dmat, sc->sc_txhdr_dmamaps[slot],
    728 				0, sc->sc_txhdr_dmamaps[slot]->dm_mapsize,
    729 				BUS_DMASYNC_PREWRITE);
    730 		virtio_enqueue(vsc, vq, slot, sc->sc_txhdr_dmamaps[slot], true);
    731 		virtio_enqueue(vsc, vq, slot, sc->sc_tx_dmamaps[slot], true);
    732 		virtio_enqueue_commit(vsc, vq, slot, false);
    733 		queued++;
    734 #if NBPFILTER > 0
    735 		if (ifp->if_bpf)
    736 			bpf_mtap(ifp->if_bpf, m);
    737 #endif
    738 	}
    739 
    740 	if (queued > 0) {
    741 		virtio_enqueue_commit(vsc, vq, -1, true);
    742 		ifp->if_timer = 5;
    743 	}
    744 }
    745 
    746 static int
    747 vioif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
    748 {
    749 	int s, r;
    750 
    751 	s = splnet();
    752 
    753 	r = ether_ioctl(ifp, cmd, data);
    754 	if ((r == 0 && cmd == SIOCSIFFLAGS) ||
    755 	    (r == ENETRESET && (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI))) {
    756 		if (ifp->if_flags & IFF_RUNNING)
    757 			r = vioif_rx_filter(ifp->if_softc);
    758 		else
    759 			r = 0;
    760 	}
    761 
    762 	splx(s);
    763 
    764 	return r;
    765 }
    766 
    767 void
    768 vioif_watchdog(struct ifnet *ifp)
    769 {
    770 	struct vioif_softc *sc = ifp->if_softc;
    771 
    772 	if (ifp->if_flags & IFF_RUNNING)
    773 		vioif_tx_vq_done(&sc->sc_vq[1]);
    774 }
    775 
    776 
    777 /*
    778  * Recieve implementation
    779  */
    780 /* allocate and initialize a mbuf for recieve */
    781 static int
    782 vioif_add_rx_mbuf(struct vioif_softc *sc, int i)
    783 {
    784 	struct mbuf *m;
    785 	int r;
    786 
    787 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    788 	if (m == NULL)
    789 		return ENOBUFS;
    790 	MCLGET(m, M_DONTWAIT);
    791 	if ((m->m_flags & M_EXT) == 0) {
    792 		m_freem(m);
    793 		return ENOBUFS;
    794 	}
    795 	sc->sc_rx_mbufs[i] = m;
    796 	m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
    797 	r = bus_dmamap_load_mbuf(sc->sc_virtio->sc_dmat,
    798 				 sc->sc_rx_dmamaps[i],
    799 				 m, BUS_DMA_READ|BUS_DMA_NOWAIT);
    800 	if (r) {
    801 		m_freem(m);
    802 		sc->sc_rx_mbufs[i] = 0;
    803 		return r;
    804 	}
    805 
    806 	return 0;
    807 }
    808 
    809 /* free a mbuf for recieve */
    810 static void
    811 vioif_free_rx_mbuf(struct vioif_softc *sc, int i)
    812 {
    813 	bus_dmamap_unload(sc->sc_virtio->sc_dmat, sc->sc_rx_dmamaps[i]);
    814 	m_freem(sc->sc_rx_mbufs[i]);
    815 	sc->sc_rx_mbufs[i] = NULL;
    816 }
    817 
    818 /* add mbufs for all the empty recieve slots */
    819 static void
    820 vioif_populate_rx_mbufs(struct vioif_softc *sc)
    821 {
    822 	struct virtio_softc *vsc = sc->sc_virtio;
    823 	int i, r, ndone = 0;
    824 	struct virtqueue *vq = &sc->sc_vq[0]; /* rx vq */
    825 
    826 	for (i = 0; i < vq->vq_num; i++) {
    827 		int slot;
    828 		r = virtio_enqueue_prep(vsc, vq, &slot);
    829 		if (r == EAGAIN)
    830 			break;
    831 		if (r != 0)
    832 			panic("enqueue_prep for rx buffers");
    833 		if (sc->sc_rx_mbufs[slot] == NULL) {
    834 			r = vioif_add_rx_mbuf(sc, slot);
    835 			if (r != 0) {
    836 				printf("%s: rx mbuf allocation failed, "
    837 				       "error code %d\n",
    838 				       device_xname(sc->sc_dev), r);
    839 				break;
    840 			}
    841 		}
    842 		r = virtio_enqueue_reserve(vsc, vq, slot,
    843 					sc->sc_rx_dmamaps[slot]->dm_nsegs + 1);
    844 		if (r != 0) {
    845 			vioif_free_rx_mbuf(sc, slot);
    846 			break;
    847 		}
    848 		bus_dmamap_sync(vsc->sc_dmat, sc->sc_rxhdr_dmamaps[slot],
    849 			0, sizeof(struct virtio_net_hdr), BUS_DMASYNC_PREREAD);
    850 		bus_dmamap_sync(vsc->sc_dmat, sc->sc_rx_dmamaps[slot],
    851 			0, MCLBYTES, BUS_DMASYNC_PREREAD);
    852 		virtio_enqueue(vsc, vq, slot, sc->sc_rxhdr_dmamaps[slot], false);
    853 		virtio_enqueue(vsc, vq, slot, sc->sc_rx_dmamaps[slot], false);
    854 		virtio_enqueue_commit(vsc, vq, slot, false);
    855 		ndone++;
    856 	}
    857 	if (ndone > 0)
    858 		virtio_enqueue_commit(vsc, vq, -1, true);
    859 }
    860 
    861 /* dequeue recieved packets */
    862 static int
    863 vioif_rx_deq(struct vioif_softc *sc)
    864 {
    865 	struct virtio_softc *vsc = sc->sc_virtio;
    866 	struct virtqueue *vq = &sc->sc_vq[0];
    867 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    868 	struct mbuf *m;
    869 	int r = 0;
    870 	int slot, len;
    871 
    872 	while (virtio_dequeue(vsc, vq, &slot, &len) == 0) {
    873 		len -= sizeof(struct virtio_net_hdr);
    874 		r = 1;
    875 		bus_dmamap_sync(vsc->sc_dmat, sc->sc_rxhdr_dmamaps[slot],
    876 				0, sizeof(struct virtio_net_hdr),
    877 				BUS_DMASYNC_POSTREAD);
    878 		bus_dmamap_sync(vsc->sc_dmat, sc->sc_rx_dmamaps[slot],
    879 				0, MCLBYTES,
    880 				BUS_DMASYNC_POSTREAD);
    881 		m = sc->sc_rx_mbufs[slot];
    882 		KASSERT(m != NULL);
    883 		bus_dmamap_unload(vsc->sc_dmat, sc->sc_rx_dmamaps[slot]);
    884 		sc->sc_rx_mbufs[slot] = 0;
    885 		virtio_dequeue_commit(vsc, vq, slot);
    886 		m->m_pkthdr.rcvif = ifp;
    887 		m->m_len = m->m_pkthdr.len = len;
    888 		ifp->if_ipackets++;
    889 #if NBPFILTER > 0
    890 		if (ifp->if_bpf)
    891 			bpf_mtap(ifp->if_bpf, m);
    892 #endif
    893 		(*ifp->if_input)(ifp, m);
    894 	}
    895 
    896 	return r;
    897 }
    898 
    899 /* rx interrupt; call _dequeue above and schedule a softint */
    900 static int
    901 vioif_rx_vq_done(struct virtqueue *vq)
    902 {
    903 	struct virtio_softc *vsc = vq->vq_owner;
    904 	struct vioif_softc *sc = device_private(vsc->sc_child);
    905 	int r;
    906 
    907 	r = vioif_rx_deq(sc);
    908 	if (r)
    909 		softint_schedule(sc->sc_rx_softint);
    910 
    911 	return r;
    912 }
    913 
    914 /* softint: enqueue recieve requests for new incoming packets */
    915 static void
    916 vioif_rx_softint(void *arg)
    917 {
    918 	struct vioif_softc *sc = arg;
    919 
    920 	vioif_populate_rx_mbufs(sc);
    921 }
    922 
    923 /* free all the mbufs; called from if_stop(disable) */
    924 static void
    925 vioif_rx_drain(struct vioif_softc *sc)
    926 {
    927 	struct virtqueue *vq = &sc->sc_vq[0];
    928 	int i;
    929 
    930 	for (i = 0; i < vq->vq_num; i++) {
    931 		if (sc->sc_rx_mbufs[i] == NULL)
    932 			continue;
    933 		vioif_free_rx_mbuf(sc, i);
    934 	}
    935 }
    936 
    937 
    938 /*
    939  * Transmition implementation
    940  */
    941 /* actual transmission is done in if_start */
    942 /* tx interrupt; dequeue and free mbufs */
    943 /*
    944  * tx interrupt is actually disabled; this should be called upon
    945  * tx vq full and watchdog
    946  */
    947 static int
    948 vioif_tx_vq_done(struct virtqueue *vq)
    949 {
    950 	struct virtio_softc *vsc = vq->vq_owner;
    951 	struct vioif_softc *sc = device_private(vsc->sc_child);
    952 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    953 	struct mbuf *m;
    954 	int r = 0;
    955 	int slot, len;
    956 
    957 	while (virtio_dequeue(vsc, vq, &slot, &len) == 0) {
    958 		r++;
    959 		bus_dmamap_sync(vsc->sc_dmat, sc->sc_txhdr_dmamaps[slot],
    960 				0, sizeof(struct virtio_net_hdr),
    961 				BUS_DMASYNC_POSTWRITE);
    962 		bus_dmamap_sync(vsc->sc_dmat, sc->sc_tx_dmamaps[slot],
    963 				0, sc->sc_tx_dmamaps[slot]->dm_mapsize,
    964 				BUS_DMASYNC_POSTWRITE);
    965 		m = sc->sc_tx_mbufs[slot];
    966 		bus_dmamap_unload(vsc->sc_dmat, sc->sc_tx_dmamaps[slot]);
    967 		sc->sc_tx_mbufs[slot] = 0;
    968 		virtio_dequeue_commit(vsc, vq, slot);
    969 		ifp->if_opackets++;
    970 		m_freem(m);
    971 	}
    972 
    973 	if (r)
    974 		ifp->if_flags &= ~IFF_OACTIVE;
    975 	return r;
    976 }
    977 
    978 /* free all the mbufs already put on vq; called from if_stop(disable) */
    979 static void
    980 vioif_tx_drain(struct vioif_softc *sc)
    981 {
    982 	struct virtio_softc *vsc = sc->sc_virtio;
    983 	struct virtqueue *vq = &sc->sc_vq[1];
    984 	int i;
    985 
    986 	for (i = 0; i < vq->vq_num; i++) {
    987 		if (sc->sc_tx_mbufs[i] == NULL)
    988 			continue;
    989 		bus_dmamap_unload(vsc->sc_dmat, sc->sc_tx_dmamaps[i]);
    990 		m_freem(sc->sc_tx_mbufs[i]);
    991 		sc->sc_tx_mbufs[i] = NULL;
    992 	}
    993 }
    994 
    995 /*
    996  * Control vq
    997  */
    998 /* issue a VIRTIO_NET_CTRL_RX class command and wait for completion */
    999 static int
   1000 vioif_ctrl_rx(struct vioif_softc *sc, int cmd, bool onoff)
   1001 {
   1002 	struct virtio_softc *vsc = sc->sc_virtio;
   1003 	struct virtqueue *vq = &sc->sc_vq[2];
   1004 	int r, slot;
   1005 
   1006 	if (vsc->sc_nvqs < 3)
   1007 		return ENOTSUP;
   1008 
   1009 	mutex_enter(&sc->sc_ctrl_wait_lock);
   1010 	while (sc->sc_ctrl_inuse != FREE)
   1011 		cv_wait(&sc->sc_ctrl_wait, &sc->sc_ctrl_wait_lock);
   1012 	sc->sc_ctrl_inuse = INUSE;
   1013 	mutex_exit(&sc->sc_ctrl_wait_lock);
   1014 
   1015 	sc->sc_ctrl_cmd->class = VIRTIO_NET_CTRL_RX;
   1016 	sc->sc_ctrl_cmd->command = cmd;
   1017 	sc->sc_ctrl_rx->onoff = onoff;
   1018 
   1019 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_cmd_dmamap,
   1020 			0, sizeof(struct virtio_net_ctrl_cmd),
   1021 			BUS_DMASYNC_PREWRITE);
   1022 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_rx_dmamap,
   1023 			0, sizeof(struct virtio_net_ctrl_rx),
   1024 			BUS_DMASYNC_PREWRITE);
   1025 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_status_dmamap,
   1026 			0, sizeof(struct virtio_net_ctrl_status),
   1027 			BUS_DMASYNC_PREREAD);
   1028 
   1029 	r = virtio_enqueue_prep(vsc, vq, &slot);
   1030 	if (r != 0)
   1031 		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
   1032 	r = virtio_enqueue_reserve(vsc, vq, slot, 3);
   1033 	if (r != 0)
   1034 		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
   1035 	virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_cmd_dmamap, true);
   1036 	virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_rx_dmamap, true);
   1037 	virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_status_dmamap, false);
   1038 	virtio_enqueue_commit(vsc, vq, slot, true);
   1039 
   1040 	/* wait for done */
   1041 	mutex_enter(&sc->sc_ctrl_wait_lock);
   1042 	while (sc->sc_ctrl_inuse != DONE)
   1043 		cv_wait(&sc->sc_ctrl_wait, &sc->sc_ctrl_wait_lock);
   1044 	mutex_exit(&sc->sc_ctrl_wait_lock);
   1045 	/* already dequeueued */
   1046 
   1047 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_cmd_dmamap, 0,
   1048 			sizeof(struct virtio_net_ctrl_cmd),
   1049 			BUS_DMASYNC_POSTWRITE);
   1050 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_rx_dmamap, 0,
   1051 			sizeof(struct virtio_net_ctrl_rx),
   1052 			BUS_DMASYNC_POSTWRITE);
   1053 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_status_dmamap, 0,
   1054 			sizeof(struct virtio_net_ctrl_status),
   1055 			BUS_DMASYNC_POSTREAD);
   1056 
   1057 	if (sc->sc_ctrl_status->ack == VIRTIO_NET_OK)
   1058 		r = 0;
   1059 	else {
   1060 		printf("%s: failed setting rx mode\n",
   1061 		       device_xname(sc->sc_dev));
   1062 		r = EIO;
   1063 	}
   1064 
   1065 	mutex_enter(&sc->sc_ctrl_wait_lock);
   1066 	sc->sc_ctrl_inuse = FREE;
   1067 	cv_signal(&sc->sc_ctrl_wait);
   1068 	mutex_exit(&sc->sc_ctrl_wait_lock);
   1069 
   1070 	return r;
   1071 }
   1072 
   1073 static int
   1074 vioif_set_promisc(struct vioif_softc *sc, bool onoff)
   1075 {
   1076 	int r;
   1077 
   1078 	r = vioif_ctrl_rx(sc, VIRTIO_NET_CTRL_RX_PROMISC, onoff);
   1079 
   1080 	return r;
   1081 }
   1082 
   1083 static int
   1084 vioif_set_allmulti(struct vioif_softc *sc, bool onoff)
   1085 {
   1086 	int r;
   1087 
   1088 	r = vioif_ctrl_rx(sc, VIRTIO_NET_CTRL_RX_ALLMULTI, onoff);
   1089 
   1090 	return r;
   1091 }
   1092 
   1093 /* issue VIRTIO_NET_CTRL_MAC_TABLE_SET command and wait for completion */
   1094 static int
   1095 vioif_set_rx_filter(struct vioif_softc *sc)
   1096 {
   1097 	/* filter already set in sc_ctrl_mac_tbl */
   1098 	struct virtio_softc *vsc = sc->sc_virtio;
   1099 	struct virtqueue *vq = &sc->sc_vq[2];
   1100 	int r, slot;
   1101 
   1102 	if (vsc->sc_nvqs < 3)
   1103 		return ENOTSUP;
   1104 
   1105 	mutex_enter(&sc->sc_ctrl_wait_lock);
   1106 	while (sc->sc_ctrl_inuse != FREE)
   1107 		cv_wait(&sc->sc_ctrl_wait, &sc->sc_ctrl_wait_lock);
   1108 	sc->sc_ctrl_inuse = INUSE;
   1109 	mutex_exit(&sc->sc_ctrl_wait_lock);
   1110 
   1111 	sc->sc_ctrl_cmd->class = VIRTIO_NET_CTRL_MAC;
   1112 	sc->sc_ctrl_cmd->command = VIRTIO_NET_CTRL_MAC_TABLE_SET;
   1113 
   1114 	r = bus_dmamap_load(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap,
   1115 			    sc->sc_ctrl_mac_tbl_uc,
   1116 			    (sizeof(struct virtio_net_ctrl_mac_tbl)
   1117 			  + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_uc->nentries),
   1118 			    NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
   1119 	if (r) {
   1120 		printf("%s: control command dmamap load failed, "
   1121 		       "error code %d\n", device_xname(sc->sc_dev), r);
   1122 		goto out;
   1123 	}
   1124 	r = bus_dmamap_load(vsc->sc_dmat, sc->sc_ctrl_tbl_mc_dmamap,
   1125 			    sc->sc_ctrl_mac_tbl_mc,
   1126 			    (sizeof(struct virtio_net_ctrl_mac_tbl)
   1127 			  + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_mc->nentries),
   1128 			    NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
   1129 	if (r) {
   1130 		printf("%s: control command dmamap load failed, "
   1131 		       "error code %d\n", device_xname(sc->sc_dev), r);
   1132 		bus_dmamap_unload(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap);
   1133 		goto out;
   1134 	}
   1135 
   1136 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_cmd_dmamap,
   1137 			0, sizeof(struct virtio_net_ctrl_cmd),
   1138 			BUS_DMASYNC_PREWRITE);
   1139 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap, 0,
   1140 			(sizeof(struct virtio_net_ctrl_mac_tbl)
   1141 			 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_uc->nentries),
   1142 			BUS_DMASYNC_PREWRITE);
   1143 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_tbl_mc_dmamap, 0,
   1144 			(sizeof(struct virtio_net_ctrl_mac_tbl)
   1145 			 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_mc->nentries),
   1146 			BUS_DMASYNC_PREWRITE);
   1147 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_status_dmamap,
   1148 			0, sizeof(struct virtio_net_ctrl_status),
   1149 			BUS_DMASYNC_PREREAD);
   1150 
   1151 	r = virtio_enqueue_prep(vsc, vq, &slot);
   1152 	if (r != 0)
   1153 		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
   1154 	r = virtio_enqueue_reserve(vsc, vq, slot, 4);
   1155 	if (r != 0)
   1156 		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
   1157 	virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_cmd_dmamap, true);
   1158 	virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_tbl_uc_dmamap, true);
   1159 	virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_tbl_mc_dmamap, true);
   1160 	virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_status_dmamap, false);
   1161 	virtio_enqueue_commit(vsc, vq, slot, true);
   1162 
   1163 	/* wait for done */
   1164 	mutex_enter(&sc->sc_ctrl_wait_lock);
   1165 	while (sc->sc_ctrl_inuse != DONE)
   1166 		cv_wait(&sc->sc_ctrl_wait, &sc->sc_ctrl_wait_lock);
   1167 	mutex_exit(&sc->sc_ctrl_wait_lock);
   1168 	/* already dequeueued */
   1169 
   1170 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_cmd_dmamap, 0,
   1171 			sizeof(struct virtio_net_ctrl_cmd),
   1172 			BUS_DMASYNC_POSTWRITE);
   1173 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap, 0,
   1174 			(sizeof(struct virtio_net_ctrl_mac_tbl)
   1175 			 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_uc->nentries),
   1176 			BUS_DMASYNC_POSTWRITE);
   1177 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_tbl_mc_dmamap, 0,
   1178 			(sizeof(struct virtio_net_ctrl_mac_tbl)
   1179 			 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_mc->nentries),
   1180 			BUS_DMASYNC_POSTWRITE);
   1181 	bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_status_dmamap, 0,
   1182 			sizeof(struct virtio_net_ctrl_status),
   1183 			BUS_DMASYNC_POSTREAD);
   1184 	bus_dmamap_unload(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap);
   1185 	bus_dmamap_unload(vsc->sc_dmat, sc->sc_ctrl_tbl_mc_dmamap);
   1186 
   1187 	if (sc->sc_ctrl_status->ack == VIRTIO_NET_OK)
   1188 		r = 0;
   1189 	else {
   1190 		printf("%s: failed setting rx filter\n",
   1191 		       device_xname(sc->sc_dev));
   1192 		r = EIO;
   1193 	}
   1194 
   1195 out:
   1196 	mutex_enter(&sc->sc_ctrl_wait_lock);
   1197 	sc->sc_ctrl_inuse = FREE;
   1198 	cv_signal(&sc->sc_ctrl_wait);
   1199 	mutex_exit(&sc->sc_ctrl_wait_lock);
   1200 
   1201 	return r;
   1202 }
   1203 
   1204 /* ctrl vq interrupt; wake up the command issuer */
   1205 static int
   1206 vioif_ctrl_vq_done(struct virtqueue *vq)
   1207 {
   1208 	struct virtio_softc *vsc = vq->vq_owner;
   1209 	struct vioif_softc *sc = device_private(vsc->sc_child);
   1210 	int r, slot;
   1211 
   1212 	r = virtio_dequeue(vsc, vq, &slot, NULL);
   1213 	if (r == ENOENT)
   1214 		return 0;
   1215 	virtio_dequeue_commit(vsc, vq, slot);
   1216 
   1217 	mutex_enter(&sc->sc_ctrl_wait_lock);
   1218 	sc->sc_ctrl_inuse = DONE;
   1219 	cv_signal(&sc->sc_ctrl_wait);
   1220 	mutex_exit(&sc->sc_ctrl_wait_lock);
   1221 
   1222 	return 1;
   1223 }
   1224 
   1225 /*
   1226  * If IFF_PROMISC requested,  set promiscuous
   1227  * If multicast filter small enough (<=MAXENTRIES) set rx filter
   1228  * If large multicast filter exist use ALLMULTI
   1229  */
   1230 /*
   1231  * If setting rx filter fails fall back to ALLMULTI
   1232  * If ALLMULTI fails fall back to PROMISC
   1233  */
   1234 static int
   1235 vioif_rx_filter(struct vioif_softc *sc)
   1236 {
   1237 	struct virtio_softc *vsc = sc->sc_virtio;
   1238 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1239 	struct ether_multi *enm;
   1240 	struct ether_multistep step;
   1241 	int nentries;
   1242 	int promisc = 0, allmulti = 0, rxfilter = 0;
   1243 	int r;
   1244 
   1245 	if (vsc->sc_nvqs < 3) {	/* no ctrl vq; always promisc */
   1246 		ifp->if_flags |= IFF_PROMISC;
   1247 		return 0;
   1248 	}
   1249 
   1250 	if (ifp->if_flags & IFF_PROMISC) {
   1251 		promisc = 1;
   1252 		goto set;
   1253 	}
   1254 
   1255 	nentries = -1;
   1256 	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
   1257 	while (nentries++, enm != NULL) {
   1258 		if (nentries >= VIRTIO_NET_CTRL_MAC_MAXENTRIES) {
   1259 			allmulti = 1;
   1260 			goto set;
   1261 		}
   1262 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
   1263 			   ETHER_ADDR_LEN)) {
   1264 			allmulti = 1;
   1265 			goto set;
   1266 		}
   1267 		memcpy(sc->sc_ctrl_mac_tbl_mc->macs[nentries],
   1268 		       enm->enm_addrlo, ETHER_ADDR_LEN);
   1269 		ETHER_NEXT_MULTI(step, enm);
   1270 	}
   1271 	rxfilter = 1;
   1272 
   1273 set:
   1274 	if (rxfilter) {
   1275 		sc->sc_ctrl_mac_tbl_uc->nentries = 0;
   1276 		sc->sc_ctrl_mac_tbl_mc->nentries = nentries;
   1277 		r = vioif_set_rx_filter(sc);
   1278 		if (r != 0) {
   1279 			rxfilter = 0;
   1280 			allmulti = 1; /* fallback */
   1281 		}
   1282 	} else {
   1283 		/* remove rx filter */
   1284 		sc->sc_ctrl_mac_tbl_uc->nentries = 0;
   1285 		sc->sc_ctrl_mac_tbl_mc->nentries = 0;
   1286 		r = vioif_set_rx_filter(sc);
   1287 		/* what to do on failure? */
   1288 	}
   1289 	if (allmulti) {
   1290 		r = vioif_set_allmulti(sc, true);
   1291 		if (r != 0) {
   1292 			allmulti = 0;
   1293 			promisc = 1; /* fallback */
   1294 		}
   1295 	} else {
   1296 		r = vioif_set_allmulti(sc, false);
   1297 		/* what to do on failure? */
   1298 	}
   1299 	if (promisc) {
   1300 		r = vioif_set_promisc(sc, true);
   1301 	} else {
   1302 		r = vioif_set_promisc(sc, false);
   1303 	}
   1304 
   1305 	return r;
   1306 }
   1307 
   1308 /* change link status */
   1309 static int
   1310 vioif_updown(struct vioif_softc *sc, bool isup)
   1311 {
   1312 	struct virtio_softc *vsc = sc->sc_virtio;
   1313 
   1314 	if (!(vsc->sc_features & VIRTIO_NET_F_STATUS))
   1315 		return ENODEV;
   1316 	virtio_write_device_config_1(vsc,
   1317 				     VIRTIO_NET_CONFIG_STATUS,
   1318 				     isup?VIRTIO_NET_S_LINK_UP:0);
   1319 	return 0;
   1320 }
   1321