if_vioif.c revision 1.43
1/*	$NetBSD: if_vioif.c,v 1.43 2019/01/14 14:35:52 yamaguchi 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.43 2019/01/14 14:35:52 yamaguchi Exp $");
30
31#ifdef _KERNEL_OPT
32#include "opt_net_mpsafe.h"
33#endif
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38#include <sys/bus.h>
39#include <sys/condvar.h>
40#include <sys/device.h>
41#include <sys/intr.h>
42#include <sys/kmem.h>
43#include <sys/mbuf.h>
44#include <sys/mutex.h>
45#include <sys/sockio.h>
46#include <sys/cpu.h>
47#include <sys/module.h>
48
49#include <dev/pci/virtioreg.h>
50#include <dev/pci/virtiovar.h>
51
52#include <net/if.h>
53#include <net/if_media.h>
54#include <net/if_ether.h>
55
56#include <net/bpf.h>
57
58#include "ioconf.h"
59
60#ifdef NET_MPSAFE
61#define VIOIF_MPSAFE	1
62#endif
63
64#ifdef SOFTINT_INTR
65#define VIOIF_SOFTINT_INTR	1
66#endif
67
68/*
69 * if_vioifreg.h:
70 */
71/* Configuration registers */
72#define VIRTIO_NET_CONFIG_MAC		0 /* 8bit x 6byte */
73#define VIRTIO_NET_CONFIG_STATUS	6 /* 16bit */
74
75/* Feature bits */
76#define VIRTIO_NET_F_CSUM	(1<<0)
77#define VIRTIO_NET_F_GUEST_CSUM	(1<<1)
78#define VIRTIO_NET_F_MAC	(1<<5)
79#define VIRTIO_NET_F_GSO	(1<<6)
80#define VIRTIO_NET_F_GUEST_TSO4	(1<<7)
81#define VIRTIO_NET_F_GUEST_TSO6	(1<<8)
82#define VIRTIO_NET_F_GUEST_ECN	(1<<9)
83#define VIRTIO_NET_F_GUEST_UFO	(1<<10)
84#define VIRTIO_NET_F_HOST_TSO4	(1<<11)
85#define VIRTIO_NET_F_HOST_TSO6	(1<<12)
86#define VIRTIO_NET_F_HOST_ECN	(1<<13)
87#define VIRTIO_NET_F_HOST_UFO	(1<<14)
88#define VIRTIO_NET_F_MRG_RXBUF	(1<<15)
89#define VIRTIO_NET_F_STATUS	(1<<16)
90#define VIRTIO_NET_F_CTRL_VQ	(1<<17)
91#define VIRTIO_NET_F_CTRL_RX	(1<<18)
92#define VIRTIO_NET_F_CTRL_VLAN	(1<<19)
93
94#define VIRTIO_NET_FLAG_BITS \
95	VIRTIO_COMMON_FLAG_BITS \
96	"\x14""CTRL_VLAN" \
97	"\x13""CTRL_RX" \
98	"\x12""CTRL_VQ" \
99	"\x11""STATUS" \
100	"\x10""MRG_RXBUF" \
101	"\x0f""HOST_UFO" \
102	"\x0e""HOST_ECN" \
103	"\x0d""HOST_TSO6" \
104	"\x0c""HOST_TSO4" \
105	"\x0b""GUEST_UFO" \
106	"\x0a""GUEST_ECN" \
107	"\x09""GUEST_TSO6" \
108	"\x08""GUEST_TSO4" \
109	"\x07""GSO" \
110	"\x06""MAC" \
111	"\x02""GUEST_CSUM" \
112	"\x01""CSUM"
113
114/* Status */
115#define VIRTIO_NET_S_LINK_UP	1
116
117/* Packet header structure */
118struct virtio_net_hdr {
119	uint8_t		flags;
120	uint8_t		gso_type;
121	uint16_t	hdr_len;
122	uint16_t	gso_size;
123	uint16_t	csum_start;
124	uint16_t	csum_offset;
125#if 0
126	uint16_t	num_buffers; /* if VIRTIO_NET_F_MRG_RXBUF enabled */
127#endif
128} __packed;
129
130#define VIRTIO_NET_HDR_F_NEEDS_CSUM	1 /* flags */
131#define VIRTIO_NET_HDR_GSO_NONE		0 /* gso_type */
132#define VIRTIO_NET_HDR_GSO_TCPV4	1 /* gso_type */
133#define VIRTIO_NET_HDR_GSO_UDP		3 /* gso_type */
134#define VIRTIO_NET_HDR_GSO_TCPV6	4 /* gso_type */
135#define VIRTIO_NET_HDR_GSO_ECN		0x80 /* gso_type, |'ed */
136
137#define VIRTIO_NET_MAX_GSO_LEN		(65536+ETHER_HDR_LEN)
138
139/* Control virtqueue */
140struct virtio_net_ctrl_cmd {
141	uint8_t	class;
142	uint8_t	command;
143} __packed;
144#define VIRTIO_NET_CTRL_RX		0
145# define VIRTIO_NET_CTRL_RX_PROMISC	0
146# define VIRTIO_NET_CTRL_RX_ALLMULTI	1
147
148#define VIRTIO_NET_CTRL_MAC		1
149# define VIRTIO_NET_CTRL_MAC_TABLE_SET	0
150
151#define VIRTIO_NET_CTRL_VLAN		2
152# define VIRTIO_NET_CTRL_VLAN_ADD	0
153# define VIRTIO_NET_CTRL_VLAN_DEL	1
154
155struct virtio_net_ctrl_status {
156	uint8_t	ack;
157} __packed;
158#define VIRTIO_NET_OK			0
159#define VIRTIO_NET_ERR			1
160
161struct virtio_net_ctrl_rx {
162	uint8_t	onoff;
163} __packed;
164
165struct virtio_net_ctrl_mac_tbl {
166	uint32_t nentries;
167	uint8_t macs[][ETHER_ADDR_LEN];
168} __packed;
169
170struct virtio_net_ctrl_vlan {
171	uint16_t id;
172} __packed;
173
174
175/*
176 * if_vioifvar.h:
177 */
178
179/*
180 * Locking notes:
181 * + a field in vioif_txqueue is protected by txq_lock (a spin mutex), and
182 *   a filds in vioif_rxqueue is protected by rxq_lock (a spin mutex).
183 *      - more than one lock cannot be held at onece
184 * + ctrlq_inuse is protected by ctrlq_wait_lock.
185 *      - other fields in vioif_ctrlqueue are protected by ctrlq_inuse
186 *      - txq_lock or rxq_lock cannot be held along with ctrlq_wait_lock
187 */
188
189struct vioif_txqueue {
190	kmutex_t		*txq_lock;	/* lock for tx operations */
191
192	struct virtqueue	*txq_vq;
193	bool			txq_stopping;
194	bool			txq_link_active;
195
196	struct virtio_net_hdr	*txq_hdrs;
197	bus_dmamap_t		*txq_hdr_dmamaps;
198
199	struct mbuf		**txq_mbufs;
200	bus_dmamap_t		*txq_dmamaps;
201};
202
203struct vioif_rxqueue {
204	kmutex_t		*rxq_lock;	/* lock for rx operations */
205
206	struct virtqueue	*rxq_vq;
207	bool			rxq_stopping;
208
209	struct virtio_net_hdr	*rxq_hdrs;
210	bus_dmamap_t		*rxq_hdr_dmamaps;
211
212	struct mbuf		**rxq_mbufs;
213	bus_dmamap_t		*rxq_dmamaps;
214
215	void			*rxq_softint;
216};
217
218struct vioif_ctrlqueue {
219	struct virtqueue		*ctrlq_vq;
220	enum {
221		FREE, INUSE, DONE
222	}				ctrlq_inuse;
223	kcondvar_t			ctrlq_wait;
224	kmutex_t			ctrlq_wait_lock;
225
226	struct virtio_net_ctrl_cmd	*ctrlq_cmd;
227	struct virtio_net_ctrl_status	*ctrlq_status;
228	struct virtio_net_ctrl_rx	*ctrlq_rx;
229	struct virtio_net_ctrl_mac_tbl	*ctrlq_mac_tbl_uc;
230	struct virtio_net_ctrl_mac_tbl	*ctrlq_mac_tbl_mc;
231
232	bus_dmamap_t			ctrlq_cmd_dmamap;
233	bus_dmamap_t			ctrlq_status_dmamap;
234	bus_dmamap_t			ctrlq_rx_dmamap;
235	bus_dmamap_t			ctrlq_tbl_uc_dmamap;
236	bus_dmamap_t			ctrlq_tbl_mc_dmamap;
237};
238
239struct vioif_softc {
240	device_t		sc_dev;
241
242	struct virtio_softc	*sc_virtio;
243	struct virtqueue	sc_vq[3];
244#define VQ_RX	0
245#define VQ_TX	1
246#define VQ_CTRL	2
247
248	uint8_t			sc_mac[ETHER_ADDR_LEN];
249	struct ethercom		sc_ethercom;
250	short			sc_deferred_init_done;
251	bool			sc_link_active;
252
253	struct vioif_txqueue	sc_txq;
254	struct vioif_rxqueue	sc_rxq;
255
256	bool			sc_has_ctrl;
257	struct vioif_ctrlqueue	sc_ctrlq;
258
259	bus_dma_segment_t	sc_hdr_segs[1];
260	void			*sc_dmamem;
261	void			*sc_kmem;
262
263	void			*sc_ctl_softint;
264};
265#define VIRTIO_NET_TX_MAXNSEGS		(16) /* XXX */
266#define VIRTIO_NET_CTRL_MAC_MAXENTRIES	(64) /* XXX */
267
268#define VIOIF_TXQ_LOCK(_q)	mutex_enter((_q)->txq_lock)
269#define VIOIF_TXQ_UNLOCK(_q)	mutex_exit((_q)->txq_lock)
270#define VIOIF_TXQ_LOCKED(_q)	mutex_owned((_q)->txq_lock)
271
272#define VIOIF_RXQ_LOCK(_q)	mutex_enter((_q)->rxq_lock)
273#define VIOIF_RXQ_UNLOCK(_q)	mutex_exit((_q)->rxq_lock)
274#define VIOIF_RXQ_LOCKED(_q)	mutex_owned((_q)->rxq_lock)
275
276/* cfattach interface functions */
277static int	vioif_match(device_t, cfdata_t, void *);
278static void	vioif_attach(device_t, device_t, void *);
279static void	vioif_deferred_init(device_t);
280
281/* ifnet interface functions */
282static int	vioif_init(struct ifnet *);
283static void	vioif_stop(struct ifnet *, int);
284static void	vioif_start(struct ifnet *);
285static int	vioif_ioctl(struct ifnet *, u_long, void *);
286static void	vioif_watchdog(struct ifnet *);
287
288/* rx */
289static int	vioif_add_rx_mbuf(struct vioif_softc *, int);
290static void	vioif_free_rx_mbuf(struct vioif_softc *, int);
291static void	vioif_populate_rx_mbufs(struct vioif_softc *);
292static void	vioif_populate_rx_mbufs_locked(struct vioif_softc *);
293static int	vioif_rx_deq(struct vioif_softc *);
294static int	vioif_rx_deq_locked(struct vioif_softc *);
295static int	vioif_rx_vq_done(struct virtqueue *);
296static void	vioif_rx_softint(void *);
297static void	vioif_rx_drain(struct vioif_softc *);
298
299/* tx */
300static int	vioif_tx_vq_done(struct virtqueue *);
301static int	vioif_tx_vq_done_locked(struct virtqueue *);
302static void	vioif_tx_drain(struct vioif_softc *);
303
304/* other control */
305static bool	vioif_is_link_up(struct vioif_softc *);
306static void	vioif_update_link_status(struct vioif_softc *);
307static int	vioif_ctrl_rx(struct vioif_softc *, int, bool);
308static int	vioif_set_promisc(struct vioif_softc *, bool);
309static int	vioif_set_allmulti(struct vioif_softc *, bool);
310static int	vioif_set_rx_filter(struct vioif_softc *);
311static int	vioif_rx_filter(struct vioif_softc *);
312static int	vioif_ctrl_vq_done(struct virtqueue *);
313static int	vioif_config_change(struct virtio_softc *);
314static void	vioif_ctl_softint(void *);
315
316CFATTACH_DECL_NEW(vioif, sizeof(struct vioif_softc),
317		  vioif_match, vioif_attach, NULL, NULL);
318
319static int
320vioif_match(device_t parent, cfdata_t match, void *aux)
321{
322	struct virtio_attach_args *va = aux;
323
324	if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_NETWORK)
325		return 1;
326
327	return 0;
328}
329
330/* allocate memory */
331/*
332 * dma memory is used for:
333 *   rxq_hdrs[slot]:	 metadata array for received frames (READ)
334 *   txq_hdrs[slot]:	 metadata array for frames to be sent (WRITE)
335 *   ctrlq_cmd:		 command to be sent via ctrl vq (WRITE)
336 *   ctrlq_status:	 return value for a command via ctrl vq (READ)
337 *   ctrlq_rx:		 parameter for a VIRTIO_NET_CTRL_RX class command
338 *			 (WRITE)
339 *   ctrlq_mac_tbl_uc:	 unicast MAC address filter for a VIRTIO_NET_CTRL_MAC
340 *			 class command (WRITE)
341 *   ctrlq_mac_tbl_mc:	 multicast MAC address filter for a VIRTIO_NET_CTRL_MAC
342 *			 class command (WRITE)
343 * ctrlq_* structures are allocated only one each; they are protected by
344 * ctrlq_inuse variable and ctrlq_wait condvar.
345 */
346/*
347 * dynamically allocated memory is used for:
348 *   rxq_hdr_dmamaps[slot]:	bus_dmamap_t array for sc_rx_hdrs[slot]
349 *   txq_hdr_dmamaps[slot]:	bus_dmamap_t array for sc_tx_hdrs[slot]
350 *   rxq_dmamaps[slot]:		bus_dmamap_t array for received payload
351 *   txq_dmamaps[slot]:		bus_dmamap_t array for sent payload
352 *   rxq_mbufs[slot]:		mbuf pointer array for received frames
353 *   txq_mbufs[slot]:		mbuf pointer array for sent frames
354 */
355static int
356vioif_alloc_mems(struct vioif_softc *sc)
357{
358	struct virtio_softc *vsc = sc->sc_virtio;
359	struct vioif_txqueue *txq = &sc->sc_txq;
360	struct vioif_rxqueue *rxq = &sc->sc_rxq;
361	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
362	int allocsize, allocsize2, r, rsegs, i;
363	void *vaddr;
364	intptr_t p;
365	int rxqsize, txqsize;
366
367	rxqsize = rxq->rxq_vq->vq_num;
368	txqsize = txq->txq_vq->vq_num;
369
370	allocsize = sizeof(struct virtio_net_hdr) * rxqsize;
371	allocsize += sizeof(struct virtio_net_hdr) * txqsize;
372	if (sc->sc_has_ctrl) {
373		allocsize += sizeof(struct virtio_net_ctrl_cmd) * 1;
374		allocsize += sizeof(struct virtio_net_ctrl_status) * 1;
375		allocsize += sizeof(struct virtio_net_ctrl_rx) * 1;
376		allocsize += sizeof(struct virtio_net_ctrl_mac_tbl)
377			+ sizeof(struct virtio_net_ctrl_mac_tbl)
378			+ ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES;
379	}
380	r = bus_dmamem_alloc(virtio_dmat(vsc), allocsize, 0, 0,
381			     &sc->sc_hdr_segs[0], 1, &rsegs, BUS_DMA_NOWAIT);
382	if (r != 0) {
383		aprint_error_dev(sc->sc_dev,
384				 "DMA memory allocation failed, size %d, "
385				 "error code %d\n", allocsize, r);
386		goto err_none;
387	}
388	r = bus_dmamem_map(virtio_dmat(vsc),
389			   &sc->sc_hdr_segs[0], 1, allocsize,
390			   &vaddr, BUS_DMA_NOWAIT);
391	if (r != 0) {
392		aprint_error_dev(sc->sc_dev,
393				 "DMA memory map failed, "
394				 "error code %d\n", r);
395		goto err_dmamem_alloc;
396	}
397
398#define P(p, p0, p0size)	do { p0 = (void *) p;		\
399				     p += p0size; } while (0)
400	memset(vaddr, 0, allocsize);
401	sc->sc_dmamem = vaddr;
402	p = (intptr_t) vaddr;
403
404	P(p, rxq->rxq_hdrs, sizeof(rxq->rxq_hdrs[0]) * rxqsize);
405	P(p, txq->txq_hdrs, sizeof(txq->txq_hdrs[0]) * txqsize);
406	if (sc->sc_has_ctrl) {
407		P(p, ctrlq->ctrlq_cmd, sizeof(*ctrlq->ctrlq_cmd));
408		P(p, ctrlq->ctrlq_status, sizeof(*ctrlq->ctrlq_status));
409		P(p, ctrlq->ctrlq_rx, sizeof(*ctrlq->ctrlq_rx));
410		P(p, ctrlq->ctrlq_mac_tbl_uc, sizeof(*ctrlq->ctrlq_mac_tbl_uc) + 0);
411		P(p, ctrlq->ctrlq_mac_tbl_mc,
412		    (sizeof(*ctrlq->ctrlq_mac_tbl_mc)
413		    + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES));
414	}
415
416	allocsize2 = sizeof(bus_dmamap_t) * (rxqsize + txqsize);
417	allocsize2 += sizeof(bus_dmamap_t) * (rxqsize + txqsize);
418	allocsize2 += sizeof(struct mbuf*) * (rxqsize + txqsize);
419	vaddr = kmem_zalloc(allocsize2, KM_SLEEP);
420	sc->sc_kmem = vaddr;
421	p = (intptr_t) vaddr;
422
423	P(p, rxq->rxq_hdr_dmamaps, sizeof(rxq->rxq_hdr_dmamaps[0]) * rxqsize);
424	P(p, txq->txq_hdr_dmamaps, sizeof(txq->txq_hdr_dmamaps[0]) * txqsize);
425	P(p, rxq->rxq_dmamaps, sizeof(rxq->rxq_dmamaps[0]) * rxqsize);
426	P(p, txq->txq_dmamaps, sizeof(txq->txq_dmamaps[0]) * txqsize);
427	P(p, rxq->rxq_mbufs, sizeof(rxq->rxq_mbufs[0]) * rxqsize);
428	P(p, txq->txq_mbufs, sizeof(txq->txq_mbufs[0]) * txqsize);
429#undef P
430
431#define C(map, size, nsegs, usage)						\
432	do {									\
433		r = bus_dmamap_create(virtio_dmat(vsc), size, nsegs, size, 0,	\
434				      BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,		\
435				      &map);					\
436		if (r != 0) {							\
437			aprint_error_dev(sc->sc_dev,				\
438			    "%s dmamap creation failed, "			\
439			    "error code %d\n", usage, r);			\
440			goto err_reqs;						\
441		}								\
442	} while (0)
443#define C_L(map, buf, size, nsegs, rw, usage)				\
444	C(map, size, nsegs, usage);					\
445	do {								\
446		r = bus_dmamap_load(virtio_dmat(vsc), map,		\
447				    buf, size, NULL,			\
448				    rw | BUS_DMA_NOWAIT);		\
449		if (r != 0) {						\
450			aprint_error_dev(sc->sc_dev,			\
451					 usage " dmamap load failed, "	\
452					 "error code %d\n", r);		\
453			goto err_reqs;					\
454		}							\
455	} while (0)
456	for (i = 0; i < rxqsize; i++) {
457		C_L(rxq->rxq_hdr_dmamaps[i], &rxq->rxq_hdrs[i], sizeof(rxq->rxq_hdrs[0]), 1,
458		    BUS_DMA_READ, "rx header");
459		C(rxq->rxq_dmamaps[i], MCLBYTES, 1, "rx payload");
460	}
461
462	for (i = 0; i < txqsize; i++) {
463		C_L(txq->txq_hdr_dmamaps[i], &txq->txq_hdrs[i], sizeof(txq->txq_hdrs[0]), 1,
464		    BUS_DMA_READ, "tx header");
465		C(txq->txq_dmamaps[i], ETHER_MAX_LEN, VIRTIO_NET_TX_MAXNSEGS, "tx payload");
466	}
467
468	if (sc->sc_has_ctrl) {
469		/* control vq class & command */
470		C_L(ctrlq->ctrlq_cmd_dmamap,
471		    ctrlq->ctrlq_cmd, sizeof(*ctrlq->ctrlq_cmd), 1,
472		    BUS_DMA_WRITE, "control command");
473		C_L(ctrlq->ctrlq_status_dmamap,
474		    ctrlq->ctrlq_status, sizeof(*ctrlq->ctrlq_status), 1,
475		    BUS_DMA_READ, "control status");
476
477		/* control vq rx mode command parameter */
478		C_L(ctrlq->ctrlq_rx_dmamap,
479		    ctrlq->ctrlq_rx, sizeof(*ctrlq->ctrlq_rx), 1,
480		    BUS_DMA_WRITE, "rx mode control command");
481
482		/* control vq MAC filter table for unicast */
483		/* do not load now since its length is variable */
484		C(ctrlq->ctrlq_tbl_uc_dmamap,
485		    sizeof(*ctrlq->ctrlq_mac_tbl_uc) + 0, 1,
486		    "unicast MAC address filter command");
487
488		/* control vq MAC filter table for multicast */
489		C(ctrlq->ctrlq_tbl_mc_dmamap,
490		    sizeof(*ctrlq->ctrlq_mac_tbl_mc)
491		    + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES, 1,
492		    "multicast MAC address filter command");
493	}
494#undef C_L
495#undef C
496
497	return 0;
498
499err_reqs:
500#define D(map)								\
501	do {								\
502		if (map) {						\
503			bus_dmamap_destroy(virtio_dmat(vsc), map);	\
504			map = NULL;					\
505		}							\
506	} while (0)
507	D(ctrlq->ctrlq_tbl_mc_dmamap);
508	D(ctrlq->ctrlq_tbl_uc_dmamap);
509	D(ctrlq->ctrlq_rx_dmamap);
510	D(ctrlq->ctrlq_status_dmamap);
511	D(ctrlq->ctrlq_cmd_dmamap);
512	for (i = 0; i < txqsize; i++) {
513		D(txq->txq_dmamaps[i]);
514		D(txq->txq_hdr_dmamaps[i]);
515	}
516	for (i = 0; i < rxqsize; i++) {
517		D(rxq->rxq_dmamaps[i]);
518		D(rxq->rxq_hdr_dmamaps[i]);
519	}
520#undef D
521	if (sc->sc_kmem) {
522		kmem_free(sc->sc_kmem, allocsize2);
523		sc->sc_kmem = NULL;
524	}
525	bus_dmamem_unmap(virtio_dmat(vsc), sc->sc_dmamem, allocsize);
526err_dmamem_alloc:
527	bus_dmamem_free(virtio_dmat(vsc), &sc->sc_hdr_segs[0], 1);
528err_none:
529	return -1;
530}
531
532static void
533vioif_attach(device_t parent, device_t self, void *aux)
534{
535	struct vioif_softc *sc = device_private(self);
536	struct virtio_softc *vsc = device_private(parent);
537	struct vioif_txqueue *txq = &sc->sc_txq;
538	struct vioif_rxqueue *rxq = &sc->sc_rxq;
539	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
540	uint32_t features;
541	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
542	u_int softint_flags;
543	int r, nvqs=0, req_flags;
544
545	if (virtio_child(vsc) != NULL) {
546		aprint_normal(": child already attached for %s; "
547			      "something wrong...\n",
548			      device_xname(parent));
549		return;
550	}
551
552	sc->sc_dev = self;
553	sc->sc_virtio = vsc;
554	sc->sc_link_active = false;
555
556	req_flags = 0;
557
558#ifdef VIOIF_MPSAFE
559	req_flags |= VIRTIO_F_PCI_INTR_MPSAFE;
560#endif
561#ifdef VIOIF_SOFTINT_INTR
562	req_flags |= VIRTIO_F_PCI_INTR_SOFTINT;
563#endif
564	req_flags |= VIRTIO_F_PCI_INTR_MSIX;
565
566	virtio_child_attach_start(vsc, self, IPL_NET, sc->sc_vq,
567	    vioif_config_change, virtio_vq_intr, req_flags,
568	    (VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_NET_F_CTRL_VQ |
569	     VIRTIO_NET_F_CTRL_RX | VIRTIO_F_NOTIFY_ON_EMPTY),
570	    VIRTIO_NET_FLAG_BITS);
571
572	features = virtio_features(vsc);
573
574	if (features & VIRTIO_NET_F_MAC) {
575		sc->sc_mac[0] = virtio_read_device_config_1(vsc,
576						    VIRTIO_NET_CONFIG_MAC+0);
577		sc->sc_mac[1] = virtio_read_device_config_1(vsc,
578						    VIRTIO_NET_CONFIG_MAC+1);
579		sc->sc_mac[2] = virtio_read_device_config_1(vsc,
580						    VIRTIO_NET_CONFIG_MAC+2);
581		sc->sc_mac[3] = virtio_read_device_config_1(vsc,
582						    VIRTIO_NET_CONFIG_MAC+3);
583		sc->sc_mac[4] = virtio_read_device_config_1(vsc,
584						    VIRTIO_NET_CONFIG_MAC+4);
585		sc->sc_mac[5] = virtio_read_device_config_1(vsc,
586						    VIRTIO_NET_CONFIG_MAC+5);
587	} else {
588		/* code stolen from sys/net/if_tap.c */
589		struct timeval tv;
590		uint32_t ui;
591		getmicrouptime(&tv);
592		ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff;
593		memcpy(sc->sc_mac+3, (uint8_t *)&ui, 3);
594		virtio_write_device_config_1(vsc,
595					     VIRTIO_NET_CONFIG_MAC+0,
596					     sc->sc_mac[0]);
597		virtio_write_device_config_1(vsc,
598					     VIRTIO_NET_CONFIG_MAC+1,
599					     sc->sc_mac[1]);
600		virtio_write_device_config_1(vsc,
601					     VIRTIO_NET_CONFIG_MAC+2,
602					     sc->sc_mac[2]);
603		virtio_write_device_config_1(vsc,
604					     VIRTIO_NET_CONFIG_MAC+3,
605					     sc->sc_mac[3]);
606		virtio_write_device_config_1(vsc,
607					     VIRTIO_NET_CONFIG_MAC+4,
608					     sc->sc_mac[4]);
609		virtio_write_device_config_1(vsc,
610					     VIRTIO_NET_CONFIG_MAC+5,
611					     sc->sc_mac[5]);
612	}
613
614	aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(sc->sc_mac));
615
616#ifdef VIOIF_MPSAFE
617	softint_flags = SOFTINT_NET | SOFTINT_MPSAFE;
618#else
619	softint_flags = SOFTINT_NET;
620#endif
621
622	/*
623	 * Allocating a virtqueue for Rx
624	 */
625	rxq->rxq_vq = &sc->sc_vq[VQ_RX];
626	rxq->rxq_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
627
628	rxq->rxq_softint = softint_establish(softint_flags, vioif_rx_softint, sc);
629	if (rxq->rxq_softint == NULL) {
630		aprint_error_dev(self, "cannot establish rx softint\n");
631		goto err;
632	}
633	r = virtio_alloc_vq(vsc, rxq->rxq_vq, VQ_RX,
634	    MCLBYTES+sizeof(struct virtio_net_hdr), 2, "rx");
635	if (r != 0)
636		goto err;
637	nvqs = 1;
638	rxq->rxq_vq->vq_done = vioif_rx_vq_done;
639	rxq->rxq_stopping = true;
640
641	/*
642	 * Allocating a virtqueue for Tx
643	 */
644	txq->txq_vq = &sc->sc_vq[VQ_TX];
645	txq->txq_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
646	r = virtio_alloc_vq(vsc, txq->txq_vq, VQ_TX,
647	    (sizeof(struct virtio_net_hdr) + (ETHER_MAX_LEN - ETHER_HDR_LEN)),
648	    VIRTIO_NET_TX_MAXNSEGS + 1, "tx");
649	if (r != 0)
650		goto err;
651	nvqs = 2;
652	txq->txq_vq->vq_done = vioif_tx_vq_done;
653	txq->txq_link_active = sc->sc_link_active;
654	txq->txq_stopping = false;
655
656	virtio_start_vq_intr(vsc, rxq->rxq_vq);
657	virtio_stop_vq_intr(vsc, txq->txq_vq); /* not urgent; do it later */
658
659	ctrlq->ctrlq_vq = &sc->sc_vq[VQ_CTRL];
660	if ((features & VIRTIO_NET_F_CTRL_VQ) &&
661	    (features & VIRTIO_NET_F_CTRL_RX)) {
662		/*
663		 * Allocating a virtqueue for control channel
664		 */
665		r = virtio_alloc_vq(vsc, ctrlq->ctrlq_vq, VQ_CTRL,
666		    NBPG, 1, "control");
667		if (r != 0) {
668			aprint_error_dev(self, "failed to allocate "
669			    "a virtqueue for control channel\n");
670			goto skip;
671		}
672
673		ctrlq->ctrlq_vq->vq_done = vioif_ctrl_vq_done;
674		cv_init(&ctrlq->ctrlq_wait, "ctrl_vq");
675		mutex_init(&ctrlq->ctrlq_wait_lock, MUTEX_DEFAULT, IPL_NET);
676		ctrlq->ctrlq_inuse = FREE;
677		virtio_start_vq_intr(vsc, ctrlq->ctrlq_vq);
678		sc->sc_has_ctrl = true;
679		nvqs = 3;
680	}
681skip:
682
683
684	sc->sc_ctl_softint = softint_establish(softint_flags, vioif_ctl_softint, sc);
685	if (sc->sc_ctl_softint == NULL) {
686		aprint_error_dev(self, "cannot establish ctl softint\n");
687		goto err;
688	}
689
690	if (vioif_alloc_mems(sc) < 0)
691		goto err;
692
693	if (virtio_child_attach_finish(vsc) != 0)
694		goto err;
695
696	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
697	ifp->if_softc = sc;
698	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
699	ifp->if_start = vioif_start;
700	ifp->if_ioctl = vioif_ioctl;
701	ifp->if_init = vioif_init;
702	ifp->if_stop = vioif_stop;
703	ifp->if_capabilities = 0;
704	ifp->if_watchdog = vioif_watchdog;
705	IFQ_SET_MAXLEN(&ifp->if_snd, MAX(txq->txq_vq->vq_num, IFQ_MAXLEN));
706	IFQ_SET_READY(&ifp->if_snd);
707
708	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
709
710	if_attach(ifp);
711	if_deferred_start_init(ifp, NULL);
712	ether_ifattach(ifp, sc->sc_mac);
713
714	return;
715
716err:
717	if (rxq->rxq_lock) {
718		mutex_obj_free(rxq->rxq_lock);
719		rxq->rxq_lock = NULL;
720	}
721
722	if (rxq->rxq_softint) {
723		softint_disestablish(rxq->rxq_softint);
724		rxq->rxq_softint = NULL;
725	}
726
727	if (txq->txq_lock) {
728		mutex_obj_free(txq->txq_lock);
729		txq->txq_lock = NULL;
730	}
731
732	if (sc->sc_has_ctrl) {
733		cv_destroy(&ctrlq->ctrlq_wait);
734		mutex_destroy(&ctrlq->ctrlq_wait_lock);
735	}
736
737	while (nvqs > 0)
738		virtio_free_vq(vsc, &sc->sc_vq[--nvqs]);
739
740	virtio_child_attach_failed(vsc);
741	return;
742}
743
744/* we need interrupts to make promiscuous mode off */
745static void
746vioif_deferred_init(device_t self)
747{
748	struct vioif_softc *sc = device_private(self);
749	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
750	int r;
751
752	if (ifp->if_flags & IFF_PROMISC)
753		return;
754
755	r =  vioif_set_promisc(sc, false);
756	if (r != 0)
757		aprint_error_dev(self, "resetting promisc mode failed, "
758				 "errror code %d\n", r);
759}
760
761/*
762 * Interface functions for ifnet
763 */
764static int
765vioif_init(struct ifnet *ifp)
766{
767	struct vioif_softc *sc = ifp->if_softc;
768	struct virtio_softc *vsc = sc->sc_virtio;
769	struct vioif_txqueue *txq = &sc->sc_txq;
770	struct vioif_rxqueue *rxq = &sc->sc_rxq;
771	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
772
773	vioif_stop(ifp, 0);
774
775	virtio_reinit_start(vsc);
776	virtio_negotiate_features(vsc, virtio_features(vsc));
777	virtio_start_vq_intr(vsc, rxq->rxq_vq);
778	virtio_stop_vq_intr(vsc, txq->txq_vq);
779	if (sc->sc_has_ctrl)
780		virtio_start_vq_intr(vsc, ctrlq->ctrlq_vq);
781	virtio_reinit_end(vsc);
782
783	if (!sc->sc_deferred_init_done) {
784		sc->sc_deferred_init_done = 1;
785		if (sc->sc_has_ctrl)
786			vioif_deferred_init(sc->sc_dev);
787	}
788
789	/* Have to set false before vioif_populate_rx_mbufs */
790	rxq->rxq_stopping = false;
791	txq->txq_stopping = false;
792
793	vioif_populate_rx_mbufs(sc);
794
795	vioif_update_link_status(sc);
796	ifp->if_flags |= IFF_RUNNING;
797	ifp->if_flags &= ~IFF_OACTIVE;
798	vioif_rx_filter(sc);
799
800	return 0;
801}
802
803static void
804vioif_stop(struct ifnet *ifp, int disable)
805{
806	struct vioif_softc *sc = ifp->if_softc;
807	struct virtio_softc *vsc = sc->sc_virtio;
808	struct vioif_txqueue *txq = &sc->sc_txq;
809	struct vioif_rxqueue *rxq = &sc->sc_rxq;
810	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
811
812	/* Take the locks to ensure that ongoing TX/RX finish */
813	VIOIF_TXQ_LOCK(txq);
814	txq->txq_stopping = true;
815	VIOIF_TXQ_UNLOCK(txq);
816
817	VIOIF_RXQ_LOCK(rxq);
818	rxq->rxq_stopping = true;
819	VIOIF_RXQ_UNLOCK(rxq);
820
821	/* disable interrupts */
822	virtio_stop_vq_intr(vsc, rxq->rxq_vq);
823	virtio_stop_vq_intr(vsc, txq->txq_vq);
824	if (sc->sc_has_ctrl)
825		virtio_stop_vq_intr(vsc, ctrlq->ctrlq_vq);
826
827	/* only way to stop I/O and DMA is resetting... */
828	virtio_reset(vsc);
829	vioif_rx_deq(sc);
830	vioif_tx_drain(sc);
831	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
832	sc->sc_link_active = false;
833	txq->txq_link_active = false;
834
835	if (disable)
836		vioif_rx_drain(sc);
837}
838
839static void
840vioif_start(struct ifnet *ifp)
841{
842	struct vioif_softc *sc = ifp->if_softc;
843	struct virtio_softc *vsc = sc->sc_virtio;
844	struct vioif_txqueue *txq = &sc->sc_txq;
845	struct virtqueue *vq = txq->txq_vq;
846	struct mbuf *m;
847	int queued = 0;
848
849	VIOIF_TXQ_LOCK(txq);
850
851	if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING ||
852	    !txq->txq_link_active)
853		goto out;
854
855	if (txq->txq_stopping)
856		goto out;
857
858	for (;;) {
859		int slot, r;
860
861		IFQ_DEQUEUE(&ifp->if_snd, m);
862		if (m == NULL)
863			break;
864
865		r = virtio_enqueue_prep(vsc, vq, &slot);
866		if (r == EAGAIN) {
867			ifp->if_flags |= IFF_OACTIVE;
868			m_freem(m);
869			break;
870		}
871		if (r != 0)
872			panic("enqueue_prep for a tx buffer");
873
874		r = bus_dmamap_load_mbuf(virtio_dmat(vsc),
875					 txq->txq_dmamaps[slot],
876					 m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
877		if (r != 0) {
878			/* maybe just too fragmented */
879			struct mbuf *newm;
880
881			newm = m_defrag(m, M_NOWAIT);
882			if (newm == NULL) {
883				aprint_error_dev(sc->sc_dev,
884				    "m_defrag() failed\n");
885				goto skip;
886			}
887
888			m = newm;
889			r = bus_dmamap_load_mbuf(virtio_dmat(vsc),
890					 txq->txq_dmamaps[slot],
891					 m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
892			if (r != 0) {
893				aprint_error_dev(sc->sc_dev,
894	   			    "tx dmamap load failed, error code %d\n",
895				    r);
896skip:
897				m_freem(m);
898				virtio_enqueue_abort(vsc, vq, slot);
899				continue;
900			}
901		}
902
903		/* This should actually never fail */
904		r = virtio_enqueue_reserve(vsc, vq, slot,
905					txq->txq_dmamaps[slot]->dm_nsegs + 1);
906		if (r != 0) {
907			aprint_error_dev(sc->sc_dev,
908	   		    "virtio_enqueue_reserve failed, error code %d\n",
909			    r);
910			bus_dmamap_unload(virtio_dmat(vsc),
911					  txq->txq_dmamaps[slot]);
912			/* slot already freed by virtio_enqueue_reserve */
913			m_freem(m);
914			continue;
915		}
916
917		txq->txq_mbufs[slot] = m;
918
919		memset(&txq->txq_hdrs[slot], 0, sizeof(struct virtio_net_hdr));
920		bus_dmamap_sync(virtio_dmat(vsc), txq->txq_dmamaps[slot],
921				0, txq->txq_dmamaps[slot]->dm_mapsize,
922				BUS_DMASYNC_PREWRITE);
923		bus_dmamap_sync(virtio_dmat(vsc), txq->txq_hdr_dmamaps[slot],
924				0, txq->txq_hdr_dmamaps[slot]->dm_mapsize,
925				BUS_DMASYNC_PREWRITE);
926		virtio_enqueue(vsc, vq, slot, txq->txq_hdr_dmamaps[slot], true);
927		virtio_enqueue(vsc, vq, slot, txq->txq_dmamaps[slot], true);
928		virtio_enqueue_commit(vsc, vq, slot, false);
929
930		queued++;
931		bpf_mtap(ifp, m, BPF_D_OUT);
932	}
933
934	if (queued > 0) {
935		virtio_enqueue_commit(vsc, vq, -1, true);
936		ifp->if_timer = 5;
937	}
938
939out:
940	VIOIF_TXQ_UNLOCK(txq);
941}
942
943static int
944vioif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
945{
946	int s, r;
947
948	s = splnet();
949
950	r = ether_ioctl(ifp, cmd, data);
951	if ((r == 0 && cmd == SIOCSIFFLAGS) ||
952	    (r == ENETRESET && (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI))) {
953		if (ifp->if_flags & IFF_RUNNING)
954			r = vioif_rx_filter(ifp->if_softc);
955		else
956			r = 0;
957	}
958
959	splx(s);
960
961	return r;
962}
963
964void
965vioif_watchdog(struct ifnet *ifp)
966{
967	struct vioif_softc *sc = ifp->if_softc;
968	struct vioif_txqueue *txq = &sc->sc_txq;
969
970	if (ifp->if_flags & IFF_RUNNING)
971		vioif_tx_vq_done(txq->txq_vq);
972}
973
974
975/*
976 * Receive implementation
977 */
978/* allocate and initialize a mbuf for receive */
979static int
980vioif_add_rx_mbuf(struct vioif_softc *sc, int i)
981{
982	struct vioif_rxqueue *rxq = &sc->sc_rxq;
983	struct mbuf *m;
984	int r;
985
986	MGETHDR(m, M_DONTWAIT, MT_DATA);
987	if (m == NULL)
988		return ENOBUFS;
989	MCLGET(m, M_DONTWAIT);
990	if ((m->m_flags & M_EXT) == 0) {
991		m_freem(m);
992		return ENOBUFS;
993	}
994	rxq->rxq_mbufs[i] = m;
995	m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
996	r = bus_dmamap_load_mbuf(virtio_dmat(sc->sc_virtio),
997				 rxq->rxq_dmamaps[i],
998				 m, BUS_DMA_READ|BUS_DMA_NOWAIT);
999	if (r) {
1000		m_freem(m);
1001		rxq->rxq_mbufs[i] = 0;
1002		return r;
1003	}
1004
1005	return 0;
1006}
1007
1008/* free a mbuf for receive */
1009static void
1010vioif_free_rx_mbuf(struct vioif_softc *sc, int i)
1011{
1012	struct vioif_rxqueue *rxq = &sc->sc_rxq;
1013
1014	bus_dmamap_unload(virtio_dmat(sc->sc_virtio), rxq->rxq_dmamaps[i]);
1015	m_freem(rxq->rxq_mbufs[i]);
1016	rxq->rxq_mbufs[i] = NULL;
1017}
1018
1019/* add mbufs for all the empty receive slots */
1020static void
1021vioif_populate_rx_mbufs(struct vioif_softc *sc)
1022{
1023	struct vioif_rxqueue *rxq = &sc->sc_rxq;
1024
1025	VIOIF_RXQ_LOCK(rxq);
1026	vioif_populate_rx_mbufs_locked(sc);
1027	VIOIF_RXQ_UNLOCK(rxq);
1028}
1029
1030static void
1031vioif_populate_rx_mbufs_locked(struct vioif_softc *sc)
1032{
1033	struct virtio_softc *vsc = sc->sc_virtio;
1034	struct vioif_rxqueue *rxq = &sc->sc_rxq;
1035	int i, r, ndone = 0;
1036	struct virtqueue *vq = rxq->rxq_vq;
1037
1038	KASSERT(VIOIF_RXQ_LOCKED(rxq));
1039
1040	if (rxq->rxq_stopping)
1041		return;
1042
1043	for (i = 0; i < vq->vq_num; i++) {
1044		int slot;
1045		r = virtio_enqueue_prep(vsc, vq, &slot);
1046		if (r == EAGAIN)
1047			break;
1048		if (r != 0)
1049			panic("enqueue_prep for rx buffers");
1050		if (rxq->rxq_mbufs[slot] == NULL) {
1051			r = vioif_add_rx_mbuf(sc, slot);
1052			if (r != 0) {
1053				printf("%s: rx mbuf allocation failed, "
1054				       "error code %d\n",
1055				       device_xname(sc->sc_dev), r);
1056				break;
1057			}
1058		}
1059		r = virtio_enqueue_reserve(vsc, vq, slot,
1060					rxq->rxq_dmamaps[slot]->dm_nsegs + 1);
1061		if (r != 0) {
1062			vioif_free_rx_mbuf(sc, slot);
1063			break;
1064		}
1065		bus_dmamap_sync(virtio_dmat(vsc), rxq->rxq_hdr_dmamaps[slot],
1066			0, sizeof(struct virtio_net_hdr), BUS_DMASYNC_PREREAD);
1067		bus_dmamap_sync(virtio_dmat(vsc), rxq->rxq_dmamaps[slot],
1068			0, MCLBYTES, BUS_DMASYNC_PREREAD);
1069		virtio_enqueue(vsc, vq, slot, rxq->rxq_hdr_dmamaps[slot], false);
1070		virtio_enqueue(vsc, vq, slot, rxq->rxq_dmamaps[slot], false);
1071		virtio_enqueue_commit(vsc, vq, slot, false);
1072		ndone++;
1073	}
1074	if (ndone > 0)
1075		virtio_enqueue_commit(vsc, vq, -1, true);
1076}
1077
1078/* dequeue received packets */
1079static int
1080vioif_rx_deq(struct vioif_softc *sc)
1081{
1082	struct vioif_rxqueue *rxq = &sc->sc_rxq;
1083	int r;
1084
1085	KASSERT(rxq->rxq_stopping);
1086
1087	VIOIF_RXQ_LOCK(rxq);
1088	r = vioif_rx_deq_locked(sc);
1089	VIOIF_RXQ_UNLOCK(rxq);
1090
1091	return r;
1092}
1093
1094/* dequeue received packets */
1095static int
1096vioif_rx_deq_locked(struct vioif_softc *sc)
1097{
1098	struct virtio_softc *vsc = sc->sc_virtio;
1099	struct vioif_rxqueue *rxq = &sc->sc_rxq;
1100	struct virtqueue *vq = rxq->rxq_vq;
1101	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1102	struct mbuf *m;
1103	int r = 0;
1104	int slot, len;
1105
1106	KASSERT(VIOIF_RXQ_LOCKED(rxq));
1107
1108	while (virtio_dequeue(vsc, vq, &slot, &len) == 0) {
1109		len -= sizeof(struct virtio_net_hdr);
1110		r = 1;
1111		bus_dmamap_sync(virtio_dmat(vsc), rxq->rxq_hdr_dmamaps[slot],
1112				0, sizeof(struct virtio_net_hdr),
1113				BUS_DMASYNC_POSTREAD);
1114		bus_dmamap_sync(virtio_dmat(vsc), rxq->rxq_dmamaps[slot],
1115				0, MCLBYTES,
1116				BUS_DMASYNC_POSTREAD);
1117		m = rxq->rxq_mbufs[slot];
1118		KASSERT(m != NULL);
1119		bus_dmamap_unload(virtio_dmat(vsc), rxq->rxq_dmamaps[slot]);
1120		rxq->rxq_mbufs[slot] = 0;
1121		virtio_dequeue_commit(vsc, vq, slot);
1122		m_set_rcvif(m, ifp);
1123		m->m_len = m->m_pkthdr.len = len;
1124
1125		VIOIF_RXQ_UNLOCK(rxq);
1126		if_percpuq_enqueue(ifp->if_percpuq, m);
1127		VIOIF_RXQ_LOCK(rxq);
1128
1129		if (rxq->rxq_stopping)
1130			break;
1131	}
1132
1133	return r;
1134}
1135
1136/* rx interrupt; call _dequeue above and schedule a softint */
1137static int
1138vioif_rx_vq_done(struct virtqueue *vq)
1139{
1140	struct virtio_softc *vsc = vq->vq_owner;
1141	struct vioif_softc *sc = device_private(virtio_child(vsc));
1142	struct vioif_rxqueue *rxq = &sc->sc_rxq;
1143	int r = 0;
1144
1145#ifdef VIOIF_SOFTINT_INTR
1146	KASSERT(!cpu_intr_p());
1147#endif
1148
1149	VIOIF_RXQ_LOCK(rxq);
1150
1151	if (rxq->rxq_stopping)
1152		goto out;
1153
1154	r = vioif_rx_deq_locked(sc);
1155	if (r)
1156#ifdef VIOIF_SOFTINT_INTR
1157		vioif_populate_rx_mbufs_locked(sc);
1158#else
1159		softint_schedule(rxq->rxq_softint);
1160#endif
1161
1162out:
1163	VIOIF_RXQ_UNLOCK(rxq);
1164	return r;
1165}
1166
1167/* softint: enqueue receive requests for new incoming packets */
1168static void
1169vioif_rx_softint(void *arg)
1170{
1171	struct vioif_softc *sc = arg;
1172
1173	vioif_populate_rx_mbufs(sc);
1174}
1175
1176/* free all the mbufs; called from if_stop(disable) */
1177static void
1178vioif_rx_drain(struct vioif_softc *sc)
1179{
1180	struct vioif_rxqueue *rxq = &sc->sc_rxq;
1181	struct virtqueue *vq = rxq->rxq_vq;
1182	int i;
1183
1184	for (i = 0; i < vq->vq_num; i++) {
1185		if (rxq->rxq_mbufs[i] == NULL)
1186			continue;
1187		vioif_free_rx_mbuf(sc, i);
1188	}
1189}
1190
1191
1192/*
1193 * Transmition implementation
1194 */
1195/* actual transmission is done in if_start */
1196/* tx interrupt; dequeue and free mbufs */
1197/*
1198 * tx interrupt is actually disabled; this should be called upon
1199 * tx vq full and watchdog
1200 */
1201static int
1202vioif_tx_vq_done(struct virtqueue *vq)
1203{
1204	struct virtio_softc *vsc = vq->vq_owner;
1205	struct vioif_softc *sc = device_private(virtio_child(vsc));
1206	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1207	struct vioif_txqueue *txq = &sc->sc_txq;
1208	int r = 0;
1209
1210	VIOIF_TXQ_LOCK(txq);
1211
1212	if (txq->txq_stopping)
1213		goto out;
1214
1215	r = vioif_tx_vq_done_locked(vq);
1216
1217out:
1218	VIOIF_TXQ_UNLOCK(txq);
1219	if (r)
1220		if_schedule_deferred_start(ifp);
1221	return r;
1222}
1223
1224static int
1225vioif_tx_vq_done_locked(struct virtqueue *vq)
1226{
1227	struct virtio_softc *vsc = vq->vq_owner;
1228	struct vioif_softc *sc = device_private(virtio_child(vsc));
1229	struct vioif_txqueue *txq = &sc->sc_txq;
1230	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1231	struct mbuf *m;
1232	int r = 0;
1233	int slot, len;
1234
1235	KASSERT(VIOIF_TXQ_LOCKED(txq));
1236
1237	while (virtio_dequeue(vsc, vq, &slot, &len) == 0) {
1238		r++;
1239		bus_dmamap_sync(virtio_dmat(vsc), txq->txq_hdr_dmamaps[slot],
1240				0, sizeof(struct virtio_net_hdr),
1241				BUS_DMASYNC_POSTWRITE);
1242		bus_dmamap_sync(virtio_dmat(vsc), txq->txq_dmamaps[slot],
1243				0, txq->txq_dmamaps[slot]->dm_mapsize,
1244				BUS_DMASYNC_POSTWRITE);
1245		m = txq->txq_mbufs[slot];
1246		bus_dmamap_unload(virtio_dmat(vsc), txq->txq_dmamaps[slot]);
1247		txq->txq_mbufs[slot] = 0;
1248		virtio_dequeue_commit(vsc, vq, slot);
1249		ifp->if_opackets++;
1250		m_freem(m);
1251	}
1252
1253	if (r)
1254		ifp->if_flags &= ~IFF_OACTIVE;
1255	return r;
1256}
1257
1258/* free all the mbufs already put on vq; called from if_stop(disable) */
1259static void
1260vioif_tx_drain(struct vioif_softc *sc)
1261{
1262	struct virtio_softc *vsc = sc->sc_virtio;
1263	struct vioif_txqueue *txq = &sc->sc_txq;
1264	struct virtqueue *vq = txq->txq_vq;
1265	int i;
1266
1267	KASSERT(txq->txq_stopping);
1268
1269	for (i = 0; i < vq->vq_num; i++) {
1270		if (txq->txq_mbufs[i] == NULL)
1271			continue;
1272		bus_dmamap_unload(virtio_dmat(vsc), txq->txq_dmamaps[i]);
1273		m_freem(txq->txq_mbufs[i]);
1274		txq->txq_mbufs[i] = NULL;
1275	}
1276}
1277
1278/*
1279 * Control vq
1280 */
1281/* issue a VIRTIO_NET_CTRL_RX class command and wait for completion */
1282static int
1283vioif_ctrl_rx(struct vioif_softc *sc, int cmd, bool onoff)
1284{
1285	struct virtio_softc *vsc = sc->sc_virtio;
1286	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
1287	struct virtqueue *vq = ctrlq->ctrlq_vq;
1288	int r, slot;
1289
1290	if (!sc->sc_has_ctrl)
1291		return ENOTSUP;
1292
1293	mutex_enter(&ctrlq->ctrlq_wait_lock);
1294	while (ctrlq->ctrlq_inuse != FREE)
1295		cv_wait(&ctrlq->ctrlq_wait, &ctrlq->ctrlq_wait_lock);
1296	ctrlq->ctrlq_inuse = INUSE;
1297	mutex_exit(&ctrlq->ctrlq_wait_lock);
1298
1299	ctrlq->ctrlq_cmd->class = VIRTIO_NET_CTRL_RX;
1300	ctrlq->ctrlq_cmd->command = cmd;
1301	ctrlq->ctrlq_rx->onoff = onoff;
1302
1303	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap,
1304			0, sizeof(struct virtio_net_ctrl_cmd),
1305			BUS_DMASYNC_PREWRITE);
1306	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_rx_dmamap,
1307			0, sizeof(struct virtio_net_ctrl_rx),
1308			BUS_DMASYNC_PREWRITE);
1309	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap,
1310			0, sizeof(struct virtio_net_ctrl_status),
1311			BUS_DMASYNC_PREREAD);
1312
1313	r = virtio_enqueue_prep(vsc, vq, &slot);
1314	if (r != 0)
1315		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
1316	r = virtio_enqueue_reserve(vsc, vq, slot, 3);
1317	if (r != 0)
1318		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
1319	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_cmd_dmamap, true);
1320	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_rx_dmamap, true);
1321	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_status_dmamap, false);
1322	virtio_enqueue_commit(vsc, vq, slot, true);
1323
1324	/* wait for done */
1325	mutex_enter(&ctrlq->ctrlq_wait_lock);
1326	while (ctrlq->ctrlq_inuse != DONE)
1327		cv_wait(&ctrlq->ctrlq_wait, &ctrlq->ctrlq_wait_lock);
1328	mutex_exit(&ctrlq->ctrlq_wait_lock);
1329	/* already dequeueued */
1330
1331	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap, 0,
1332			sizeof(struct virtio_net_ctrl_cmd),
1333			BUS_DMASYNC_POSTWRITE);
1334	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_rx_dmamap, 0,
1335			sizeof(struct virtio_net_ctrl_rx),
1336			BUS_DMASYNC_POSTWRITE);
1337	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap, 0,
1338			sizeof(struct virtio_net_ctrl_status),
1339			BUS_DMASYNC_POSTREAD);
1340
1341	if (ctrlq->ctrlq_status->ack == VIRTIO_NET_OK)
1342		r = 0;
1343	else {
1344		printf("%s: failed setting rx mode\n",
1345		       device_xname(sc->sc_dev));
1346		r = EIO;
1347	}
1348
1349	mutex_enter(&ctrlq->ctrlq_wait_lock);
1350	ctrlq->ctrlq_inuse = FREE;
1351	cv_signal(&ctrlq->ctrlq_wait);
1352	mutex_exit(&ctrlq->ctrlq_wait_lock);
1353
1354	return r;
1355}
1356
1357static int
1358vioif_set_promisc(struct vioif_softc *sc, bool onoff)
1359{
1360	int r;
1361
1362	r = vioif_ctrl_rx(sc, VIRTIO_NET_CTRL_RX_PROMISC, onoff);
1363
1364	return r;
1365}
1366
1367static int
1368vioif_set_allmulti(struct vioif_softc *sc, bool onoff)
1369{
1370	int r;
1371
1372	r = vioif_ctrl_rx(sc, VIRTIO_NET_CTRL_RX_ALLMULTI, onoff);
1373
1374	return r;
1375}
1376
1377/* issue VIRTIO_NET_CTRL_MAC_TABLE_SET command and wait for completion */
1378static int
1379vioif_set_rx_filter(struct vioif_softc *sc)
1380{
1381	/* filter already set in ctrlq->ctrlq_mac_tbl */
1382	struct virtio_softc *vsc = sc->sc_virtio;
1383	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
1384	struct virtqueue *vq = ctrlq->ctrlq_vq;
1385	int r, slot;
1386
1387	if (!sc->sc_has_ctrl)
1388		return ENOTSUP;
1389
1390	mutex_enter(&ctrlq->ctrlq_wait_lock);
1391	while (ctrlq->ctrlq_inuse != FREE)
1392		cv_wait(&ctrlq->ctrlq_wait, &ctrlq->ctrlq_wait_lock);
1393	ctrlq->ctrlq_inuse = INUSE;
1394	mutex_exit(&ctrlq->ctrlq_wait_lock);
1395
1396	ctrlq->ctrlq_cmd->class = VIRTIO_NET_CTRL_MAC;
1397	ctrlq->ctrlq_cmd->command = VIRTIO_NET_CTRL_MAC_TABLE_SET;
1398
1399	r = bus_dmamap_load(virtio_dmat(vsc), ctrlq->ctrlq_tbl_uc_dmamap,
1400			    ctrlq->ctrlq_mac_tbl_uc,
1401			    (sizeof(struct virtio_net_ctrl_mac_tbl)
1402			  + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_uc->nentries),
1403			    NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
1404	if (r) {
1405		printf("%s: control command dmamap load failed, "
1406		       "error code %d\n", device_xname(sc->sc_dev), r);
1407		goto out;
1408	}
1409	r = bus_dmamap_load(virtio_dmat(vsc), ctrlq->ctrlq_tbl_mc_dmamap,
1410			    ctrlq->ctrlq_mac_tbl_mc,
1411			    (sizeof(struct virtio_net_ctrl_mac_tbl)
1412			  + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_mc->nentries),
1413			    NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
1414	if (r) {
1415		printf("%s: control command dmamap load failed, "
1416		       "error code %d\n", device_xname(sc->sc_dev), r);
1417		bus_dmamap_unload(virtio_dmat(vsc), ctrlq->ctrlq_tbl_uc_dmamap);
1418		goto out;
1419	}
1420
1421	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap,
1422			0, sizeof(struct virtio_net_ctrl_cmd),
1423			BUS_DMASYNC_PREWRITE);
1424	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_tbl_uc_dmamap, 0,
1425			(sizeof(struct virtio_net_ctrl_mac_tbl)
1426			 + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_uc->nentries),
1427			BUS_DMASYNC_PREWRITE);
1428	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_tbl_mc_dmamap, 0,
1429			(sizeof(struct virtio_net_ctrl_mac_tbl)
1430			 + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_mc->nentries),
1431			BUS_DMASYNC_PREWRITE);
1432	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap,
1433			0, sizeof(struct virtio_net_ctrl_status),
1434			BUS_DMASYNC_PREREAD);
1435
1436	r = virtio_enqueue_prep(vsc, vq, &slot);
1437	if (r != 0)
1438		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
1439	r = virtio_enqueue_reserve(vsc, vq, slot, 4);
1440	if (r != 0)
1441		panic("%s: control vq busy!?", device_xname(sc->sc_dev));
1442	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_cmd_dmamap, true);
1443	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_tbl_uc_dmamap, true);
1444	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_tbl_mc_dmamap, true);
1445	virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_status_dmamap, false);
1446	virtio_enqueue_commit(vsc, vq, slot, true);
1447
1448	/* wait for done */
1449	mutex_enter(&ctrlq->ctrlq_wait_lock);
1450	while (ctrlq->ctrlq_inuse != DONE)
1451		cv_wait(&ctrlq->ctrlq_wait, &ctrlq->ctrlq_wait_lock);
1452	mutex_exit(&ctrlq->ctrlq_wait_lock);
1453	/* already dequeueued */
1454
1455	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap, 0,
1456			sizeof(struct virtio_net_ctrl_cmd),
1457			BUS_DMASYNC_POSTWRITE);
1458	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_tbl_uc_dmamap, 0,
1459			(sizeof(struct virtio_net_ctrl_mac_tbl)
1460			 + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_uc->nentries),
1461			BUS_DMASYNC_POSTWRITE);
1462	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_tbl_mc_dmamap, 0,
1463			(sizeof(struct virtio_net_ctrl_mac_tbl)
1464			 + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_mc->nentries),
1465			BUS_DMASYNC_POSTWRITE);
1466	bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap, 0,
1467			sizeof(struct virtio_net_ctrl_status),
1468			BUS_DMASYNC_POSTREAD);
1469	bus_dmamap_unload(virtio_dmat(vsc), ctrlq->ctrlq_tbl_uc_dmamap);
1470	bus_dmamap_unload(virtio_dmat(vsc), ctrlq->ctrlq_tbl_mc_dmamap);
1471
1472	if (ctrlq->ctrlq_status->ack == VIRTIO_NET_OK)
1473		r = 0;
1474	else {
1475		printf("%s: failed setting rx filter\n",
1476		       device_xname(sc->sc_dev));
1477		r = EIO;
1478	}
1479
1480out:
1481	mutex_enter(&ctrlq->ctrlq_wait_lock);
1482	ctrlq->ctrlq_inuse = FREE;
1483	cv_signal(&ctrlq->ctrlq_wait);
1484	mutex_exit(&ctrlq->ctrlq_wait_lock);
1485
1486	return r;
1487}
1488
1489/* ctrl vq interrupt; wake up the command issuer */
1490static int
1491vioif_ctrl_vq_done(struct virtqueue *vq)
1492{
1493	struct virtio_softc *vsc = vq->vq_owner;
1494	struct vioif_softc *sc = device_private(virtio_child(vsc));
1495	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
1496	int r, slot;
1497
1498	r = virtio_dequeue(vsc, vq, &slot, NULL);
1499	if (r == ENOENT)
1500		return 0;
1501	virtio_dequeue_commit(vsc, vq, slot);
1502
1503	mutex_enter(&ctrlq->ctrlq_wait_lock);
1504	ctrlq->ctrlq_inuse = DONE;
1505	cv_signal(&ctrlq->ctrlq_wait);
1506	mutex_exit(&ctrlq->ctrlq_wait_lock);
1507
1508	return 1;
1509}
1510
1511/*
1512 * If IFF_PROMISC requested,  set promiscuous
1513 * If multicast filter small enough (<=MAXENTRIES) set rx filter
1514 * If large multicast filter exist use ALLMULTI
1515 */
1516/*
1517 * If setting rx filter fails fall back to ALLMULTI
1518 * If ALLMULTI fails fall back to PROMISC
1519 */
1520static int
1521vioif_rx_filter(struct vioif_softc *sc)
1522{
1523	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1524	struct ether_multi *enm;
1525	struct ether_multistep step;
1526	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
1527	int nentries;
1528	int promisc = 0, allmulti = 0, rxfilter = 0;
1529	int r;
1530
1531	if (!sc->sc_has_ctrl) {	/* no ctrl vq; always promisc */
1532		ifp->if_flags |= IFF_PROMISC;
1533		return 0;
1534	}
1535
1536	if (ifp->if_flags & IFF_PROMISC) {
1537		promisc = 1;
1538		goto set;
1539	}
1540
1541	nentries = -1;
1542	ETHER_LOCK(&sc->sc_ethercom);
1543	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1544	while (nentries++, enm != NULL) {
1545		if (nentries >= VIRTIO_NET_CTRL_MAC_MAXENTRIES) {
1546			allmulti = 1;
1547			goto set_unlock;
1548		}
1549		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1550			   ETHER_ADDR_LEN)) {
1551			allmulti = 1;
1552			goto set_unlock;
1553		}
1554		memcpy(ctrlq->ctrlq_mac_tbl_mc->macs[nentries],
1555		       enm->enm_addrlo, ETHER_ADDR_LEN);
1556		ETHER_NEXT_MULTI(step, enm);
1557	}
1558	rxfilter = 1;
1559
1560set_unlock:
1561	ETHER_UNLOCK(&sc->sc_ethercom);
1562
1563set:
1564	if (rxfilter) {
1565		ctrlq->ctrlq_mac_tbl_uc->nentries = 0;
1566		ctrlq->ctrlq_mac_tbl_mc->nentries = nentries;
1567		r = vioif_set_rx_filter(sc);
1568		if (r != 0) {
1569			rxfilter = 0;
1570			allmulti = 1; /* fallback */
1571		}
1572	} else {
1573		/* remove rx filter */
1574		ctrlq->ctrlq_mac_tbl_uc->nentries = 0;
1575		ctrlq->ctrlq_mac_tbl_mc->nentries = 0;
1576		r = vioif_set_rx_filter(sc);
1577		/* what to do on failure? */
1578	}
1579	if (allmulti) {
1580		r = vioif_set_allmulti(sc, true);
1581		if (r != 0) {
1582			allmulti = 0;
1583			promisc = 1; /* fallback */
1584		}
1585	} else {
1586		r = vioif_set_allmulti(sc, false);
1587		/* what to do on failure? */
1588	}
1589	if (promisc) {
1590		r = vioif_set_promisc(sc, true);
1591	} else {
1592		r = vioif_set_promisc(sc, false);
1593	}
1594
1595	return r;
1596}
1597
1598static bool
1599vioif_is_link_up(struct vioif_softc *sc)
1600{
1601	struct virtio_softc *vsc = sc->sc_virtio;
1602	uint16_t status;
1603
1604	if (virtio_features(vsc) & VIRTIO_NET_F_STATUS)
1605		status = virtio_read_device_config_2(vsc,
1606		    VIRTIO_NET_CONFIG_STATUS);
1607	else
1608		status = VIRTIO_NET_S_LINK_UP;
1609
1610	return ((status & VIRTIO_NET_S_LINK_UP) != 0);
1611}
1612
1613/* change link status */
1614static void
1615vioif_update_link_status(struct vioif_softc *sc)
1616{
1617	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1618	struct vioif_txqueue *txq = &sc->sc_txq;
1619	bool active, changed;
1620	int link;
1621
1622	active = vioif_is_link_up(sc);
1623	changed = false;
1624
1625	if (active) {
1626		if (!sc->sc_link_active)
1627			changed = true;
1628
1629		link = LINK_STATE_UP;
1630		sc->sc_link_active = true;
1631	} else {
1632		if (sc->sc_link_active)
1633			changed = true;
1634
1635		link = LINK_STATE_DOWN;
1636		sc->sc_link_active = false;
1637	}
1638
1639	if (changed) {
1640		VIOIF_TXQ_LOCK(txq);
1641		txq->txq_link_active = sc->sc_link_active;
1642		VIOIF_TXQ_UNLOCK(txq);
1643
1644		if_link_state_change(ifp, link);
1645	}
1646}
1647
1648static int
1649vioif_config_change(struct virtio_softc *vsc)
1650{
1651	struct vioif_softc *sc = device_private(virtio_child(vsc));
1652
1653#ifdef VIOIF_SOFTINT_INTR
1654	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1655#endif
1656
1657#ifdef VIOIF_SOFTINT_INTR
1658	KASSERT(!cpu_intr_p());
1659	vioif_update_link_status(sc);
1660	vioif_start(ifp);
1661#else
1662	softint_schedule(sc->sc_ctl_softint);
1663#endif
1664
1665	return 0;
1666}
1667
1668static void
1669vioif_ctl_softint(void *arg)
1670{
1671	struct vioif_softc *sc = arg;
1672	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1673
1674	vioif_update_link_status(sc);
1675	vioif_start(ifp);
1676}
1677
1678MODULE(MODULE_CLASS_DRIVER, if_vioif, "virtio");
1679
1680#ifdef _MODULE
1681#include "ioconf.c"
1682#endif
1683
1684static int
1685if_vioif_modcmd(modcmd_t cmd, void *opaque)
1686{
1687	int error = 0;
1688
1689#ifdef _MODULE
1690	switch (cmd) {
1691	case MODULE_CMD_INIT:
1692		error = config_init_component(cfdriver_ioconf_if_vioif,
1693		    cfattach_ioconf_if_vioif, cfdata_ioconf_if_vioif);
1694		break;
1695	case MODULE_CMD_FINI:
1696		error = config_fini_component(cfdriver_ioconf_if_vioif,
1697		    cfattach_ioconf_if_vioif, cfdata_ioconf_if_vioif);
1698		break;
1699	default:
1700		error = ENOTTY;
1701		break;
1702	}
1703#endif
1704
1705	return error;
1706}
1707