xref: /openbsd-src/sys/dev/pv/if_hvn.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*-
2  * Copyright (c) 2009-2012 Microsoft Corp.
3  * Copyright (c) 2010-2012 Citrix Inc.
4  * Copyright (c) 2012 NetApp Inc.
5  * Copyright (c) 2016 Mike Belopuhov <mike@esdenera.com>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice unmodified, this list of conditions, and the following
13  *    disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * The OpenBSD port was done under funding by Esdenera Networks GmbH.
32  */
33 
34 #include "bpfilter.h"
35 #include "vlan.h"
36 #include "hyperv.h"
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/atomic.h>
41 #include <sys/device.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/pool.h>
46 #include <sys/queue.h>
47 #include <sys/socket.h>
48 #include <sys/sockio.h>
49 #include <sys/task.h>
50 #include <sys/timeout.h>
51 
52 #include <machine/bus.h>
53 
54 #include <uvm/uvm_extern.h>
55 
56 #include <dev/pv/hypervreg.h>
57 #include <dev/pv/hypervvar.h>
58 
59 #include <dev/rndis.h>
60 #include <dev/pv/ndis.h>
61 #include <dev/pv/if_hvnreg.h>
62 
63 #include <net/if.h>
64 #include <net/if_media.h>
65 
66 #include <netinet/in.h>
67 #include <netinet/if_ether.h>
68 
69 #ifdef INET6
70 #include <netinet/ip6.h>
71 #endif
72 
73 #if NBPFILTER > 0
74 #include <net/bpf.h>
75 #endif
76 
77 #define HVN_DEBUG			1
78 
79 #define HVN_NVS_BUFSIZE		  	PAGE_SIZE
80 #define HVN_NVS_MSGSIZE			32
81 
82 /*
83  * RNDIS control interface
84  */
85 #define HVN_RNDIS_CTLREQS		4
86 #define HVN_RNDIS_CMPBUFSZ		512
87 
88 #define HVN_RNDIS_MSG_LEN		\
89 	(sizeof(struct rndis_packet_msg) + NDIS_VLAN_INFO_SIZE + \
90 	 NDIS_RXCSUM_INFO_SIZE)
91 
92 struct rndis_cmd {
93 	uint32_t			 rc_id;
94 	struct hvn_nvs_rndis		 rc_msg;
95 	void				*rc_req;
96 	bus_dmamap_t			 rc_dmap;
97 	bus_dma_segment_t		 rc_segs;
98 	int				 rc_nsegs;
99 	uint64_t			 rc_gpa;
100 	struct rndis_packet_msg		 rc_cmp;
101 	uint32_t			 rc_cmplen;
102 	uint8_t				 rc_cmpbuf[HVN_RNDIS_CMPBUFSZ];
103 	struct mutex			 rc_mtx;
104 	TAILQ_ENTRY(rndis_cmd)		 rc_entry;
105 };
106 TAILQ_HEAD(rndis_queue, rndis_cmd);
107 
108 /*
109  * Tx ring
110  */
111 #define HVN_TX_DESC			128
112 #define HVN_TX_FRAGS			31
113 #define HVN_TX_FRAG_SIZE		PAGE_SIZE
114 #define HVN_TX_PKT_SIZE			16384
115 
116 struct hvn_tx_desc {
117 	uint32_t			 txd_id;
118 	int				 txd_ready;
119 	struct vmbus_gpa		 txd_sgl[HVN_TX_FRAGS + 1];
120 	int				 txd_nsge;
121 	struct mbuf			*txd_buf;
122 	bus_dmamap_t			 txd_dmap;
123 	struct vmbus_gpa		 txd_gpa;
124 	struct hvn_nvs_rndis		 txd_cmd;
125 	struct rndis_packet_msg		*txd_req;
126 };
127 
128 struct hvn_softc {
129 	struct device			 sc_dev;
130 	struct hv_softc			*sc_hvsc;
131 	struct hv_channel		*sc_chan;
132 	bus_dma_tag_t			 sc_dmat;
133 
134 	struct arpcom			 sc_ac;
135 	struct ifmedia			 sc_media;
136 	int				 sc_link_state;
137 	int				 sc_promisc;
138 
139 	/* NVS protocol */
140 	int				 sc_proto;
141 	uint32_t			 sc_nvstid;
142 	uint8_t				 sc_nvsrsp[HVN_NVS_MSGSIZE];
143 	uint8_t				*sc_nvsbuf;
144 	struct mutex			 sc_nvslck;
145 
146 	/* RNDIS protocol */
147 	int				 sc_ndisver;
148 	uint32_t			 sc_rndisrid;
149 	struct rndis_queue		 sc_cntl_sq; /* submission queue */
150 	struct mutex			 sc_cntl_sqlck;
151 	struct rndis_queue		 sc_cntl_cq; /* completion queue */
152 	struct mutex			 sc_cntl_cqlck;
153 	struct rndis_queue		 sc_cntl_fq; /* free queue */
154 	struct mutex			 sc_cntl_fqlck;
155 	struct rndis_cmd		 sc_cntl_msgs[HVN_RNDIS_CTLREQS];
156 
157 	/* Rx ring */
158 	void				*sc_rx_ring;
159 	int				 sc_rx_size;
160 	uint32_t			 sc_rx_hndl;
161 
162 	/* Tx ring */
163 	uint32_t			 sc_tx_next;
164 	uint32_t			 sc_tx_avail;
165 	struct hvn_tx_desc		 sc_tx_desc[HVN_TX_DESC];
166 	bus_dmamap_t			 sc_tx_rmap;
167 	void				*sc_tx_msgs;
168 	bus_dma_segment_t		 sc_tx_mseg;
169 };
170 
171 int	hvn_match(struct device *, void *, void *);
172 void	hvn_attach(struct device *, struct device *, void *);
173 int	hvn_ioctl(struct ifnet *, u_long, caddr_t);
174 int	hvn_media_change(struct ifnet *);
175 void	hvn_media_status(struct ifnet *, struct ifmediareq *);
176 int	hvn_iff(struct hvn_softc *);
177 void	hvn_init(struct hvn_softc *);
178 void	hvn_stop(struct hvn_softc *);
179 void	hvn_start(struct ifnet *);
180 int	hvn_encap(struct hvn_softc *, struct mbuf *, struct hvn_tx_desc **);
181 void	hvn_decap(struct hvn_softc *, struct hvn_tx_desc *);
182 void	hvn_txeof(struct hvn_softc *, uint64_t);
183 int	hvn_rx_ring_create(struct hvn_softc *);
184 int	hvn_rx_ring_destroy(struct hvn_softc *);
185 int	hvn_tx_ring_create(struct hvn_softc *);
186 void	hvn_tx_ring_destroy(struct hvn_softc *);
187 int	hvn_get_lladdr(struct hvn_softc *);
188 int	hvn_set_lladdr(struct hvn_softc *);
189 void	hvn_get_link_status(struct hvn_softc *);
190 void	hvn_link_status(struct hvn_softc *);
191 
192 /* NSVP */
193 int	hvn_nvs_attach(struct hvn_softc *);
194 void	hvn_nvs_intr(void *);
195 int	hvn_nvs_cmd(struct hvn_softc *, void *, size_t, uint64_t, int);
196 int	hvn_nvs_ack(struct hvn_softc *, uint64_t);
197 void	hvn_nvs_detach(struct hvn_softc *);
198 
199 /* RNDIS */
200 int	hvn_rndis_attach(struct hvn_softc *);
201 int	hvn_rndis_cmd(struct hvn_softc *, struct rndis_cmd *, int);
202 void	hvn_rndis_input(struct hvn_softc *, uint64_t, void *);
203 void	hvn_rxeof(struct hvn_softc *, caddr_t, uint32_t, struct mbuf_list *);
204 void	hvn_rndis_complete(struct hvn_softc *, caddr_t, uint32_t);
205 int	hvn_rndis_output(struct hvn_softc *, struct hvn_tx_desc *);
206 void	hvn_rndis_status(struct hvn_softc *, caddr_t, uint32_t);
207 int	hvn_rndis_query(struct hvn_softc *, uint32_t, void *, size_t *);
208 int	hvn_rndis_set(struct hvn_softc *, uint32_t, void *, size_t);
209 int	hvn_rndis_open(struct hvn_softc *);
210 int	hvn_rndis_close(struct hvn_softc *);
211 void	hvn_rndis_detach(struct hvn_softc *);
212 
213 struct cfdriver hvn_cd = {
214 	NULL, "hvn", DV_IFNET
215 };
216 
217 const struct cfattach hvn_ca = {
218 	sizeof(struct hvn_softc), hvn_match, hvn_attach
219 };
220 
221 int
222 hvn_match(struct device *parent, void *match, void *aux)
223 {
224 	struct hv_attach_args *aa = aux;
225 
226 	if (strcmp("network", aa->aa_ident))
227 		return (0);
228 
229 	return (1);
230 }
231 
232 void
233 hvn_attach(struct device *parent, struct device *self, void *aux)
234 {
235 	struct hv_attach_args *aa = aux;
236 	struct hvn_softc *sc = (struct hvn_softc *)self;
237 	struct ifnet *ifp = &sc->sc_ac.ac_if;
238 
239 	sc->sc_hvsc = (struct hv_softc *)parent;
240 	sc->sc_chan = aa->aa_chan;
241 	sc->sc_dmat = aa->aa_dmat;
242 
243 	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
244 
245 	DPRINTF("\n");
246 
247 	if (hvn_nvs_attach(sc)) {
248 		printf(": failed to init NVSP\n");
249 		return;
250 	}
251 
252 	if (hvn_rx_ring_create(sc)) {
253 		printf(": failed to create Rx ring\n");
254 		goto detach;
255 	}
256 
257 	if (hvn_tx_ring_create(sc)) {
258 		printf(": failed to create Tx ring\n");
259 		goto detach;
260 	}
261 
262 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
263 	ifp->if_xflags = IFXF_MPSAFE;
264 	ifp->if_ioctl = hvn_ioctl;
265 	ifp->if_start = hvn_start;
266 	ifp->if_softc = sc;
267 
268 #ifdef notyet
269 	ifp->if_capabilities = IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 |
270 	    IFCAP_CSUM_UDPv4;
271 #endif
272 #if NVLAN > 0
273 	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
274 #endif
275 
276 	IFQ_SET_MAXLEN(&ifp->if_snd, HVN_TX_DESC - 1);
277 
278 	ifmedia_init(&sc->sc_media, IFM_IMASK, hvn_media_change,
279 	    hvn_media_status);
280 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL);
281 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL);
282 
283 	if_attach(ifp);
284 
285 	if (hvn_rndis_attach(sc)) {
286 		printf(": failed to init RNDIS\n");
287 		goto detach;
288 	}
289 
290 	if (hvn_get_lladdr(sc)) {
291 		printf(": failed to obtain an ethernet address\n");
292 		hvn_rndis_detach(sc);
293 		goto detach;
294 	}
295 
296 	DPRINTF("%s:", sc->sc_dev.dv_xname);
297 	printf(" channel %u: NVS %u.%u NDIS %u.%u, address %s\n",
298 	    sc->sc_chan->ch_id, sc->sc_proto >> 16, sc->sc_proto & 0xffff,
299 	    sc->sc_ndisver >> 16 , sc->sc_ndisver & 0xffff,
300 	    ether_sprintf(sc->sc_ac.ac_enaddr));
301 
302 	ether_ifattach(ifp);
303 	return;
304 
305  detach:
306 	hvn_rx_ring_destroy(sc);
307 	hvn_tx_ring_destroy(sc);
308 	hvn_nvs_detach(sc);
309 	if (ifp->if_start)
310 		if_detach(ifp);
311 }
312 
313 int
314 hvn_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
315 {
316 	struct hvn_softc *sc = ifp->if_softc;
317 	struct ifreq *ifr = (struct ifreq *)data;
318 	int s, error = 0;
319 
320 	s = splnet();
321 
322 	switch (command) {
323 	case SIOCSIFADDR:
324 		ifp->if_flags |= IFF_UP;
325 		if (!(ifp->if_flags & IFF_RUNNING))
326 			hvn_init(sc);
327 		break;
328 	case SIOCSIFFLAGS:
329 		if (ifp->if_flags & IFF_UP) {
330 			if (ifp->if_flags & IFF_RUNNING)
331 				error = ENETRESET;
332 			else
333 				hvn_init(sc);
334 		} else {
335 			if (ifp->if_flags & IFF_RUNNING)
336 				hvn_stop(sc);
337 		}
338 		break;
339 	case SIOCGIFMEDIA:
340 	case SIOCSIFMEDIA:
341 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
342 		break;
343 	default:
344 		error = ether_ioctl(ifp, &sc->sc_ac, command, data);
345 	}
346 
347 	if (error == ENETRESET) {
348 		if (ifp->if_flags & IFF_RUNNING)
349 			hvn_iff(sc);
350 		error = 0;
351 	}
352 
353 	splx(s);
354 
355 	return (error);
356 }
357 
358 int
359 hvn_media_change(struct ifnet *ifp)
360 {
361 	return (0);
362 }
363 
364 void
365 hvn_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
366 {
367 	struct hvn_softc *sc = ifp->if_softc;
368 
369 	hvn_get_link_status(sc);
370 	hvn_link_status(sc);
371 
372 	ifmr->ifm_status = IFM_AVALID;
373 	ifmr->ifm_active = IFM_ETHER | IFM_MANUAL;
374 	if (sc->sc_link_state == LINK_STATE_UP)
375 		ifmr->ifm_status |= IFM_ACTIVE;
376 }
377 
378 void
379 hvn_link_status(struct hvn_softc *sc)
380 {
381 	struct ifnet *ifp = &sc->sc_ac.ac_if;
382 
383 	if (sc->sc_link_state != ifp->if_link_state) {
384 		ifp->if_link_state = sc->sc_link_state;
385 		if_link_state_change(ifp);
386 	}
387 }
388 
389 int
390 hvn_iff(struct hvn_softc *sc)
391 {
392 	/* XXX */
393 	sc->sc_promisc = 0;
394 
395 	return (0);
396 }
397 
398 void
399 hvn_init(struct hvn_softc *sc)
400 {
401 	struct ifnet *ifp = &sc->sc_ac.ac_if;
402 
403 	hvn_stop(sc);
404 
405 	hvn_iff(sc);
406 
407 	if (hvn_rndis_open(sc) == 0) {
408 		ifp->if_flags |= IFF_RUNNING;
409 		ifq_clr_oactive(&ifp->if_snd);
410 	}
411 }
412 
413 void
414 hvn_stop(struct hvn_softc *sc)
415 {
416 	struct ifnet *ifp = &sc->sc_ac.ac_if;
417 
418 	if (ifp->if_flags & IFF_RUNNING) {
419 		ifp->if_flags &= ~IFF_RUNNING;
420 		hvn_rndis_close(sc);
421 	}
422 
423 	ifq_barrier(&ifp->if_snd);
424 	intr_barrier(sc->sc_chan);
425 
426 	ifq_clr_oactive(&ifp->if_snd);
427 }
428 
429 void
430 hvn_start(struct ifnet *ifp)
431 {
432 	struct hvn_softc *sc = ifp->if_softc;
433 	struct hvn_tx_desc *txd;
434 	struct mbuf *m;
435 
436 	if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
437 		return;
438 
439 	for (;;) {
440 		if (!sc->sc_tx_avail) {
441 			/* transient */
442 			ifq_set_oactive(&ifp->if_snd);
443 			break;
444 		}
445 
446 		m = ifq_dequeue(&ifp->if_snd);
447 		if (m == NULL)
448 			break;
449 
450 		if (hvn_encap(sc, m, &txd)) {
451 			/* the chain is too large */
452 			ifp->if_oerrors++;
453 			m_freem(m);
454 			continue;
455 		}
456 
457 #if NBPFILTER > 0
458 		if (ifp->if_bpf)
459 			bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT);
460 #endif
461 
462 		if (hvn_rndis_output(sc, txd)) {
463 			hvn_decap(sc, txd);
464 			m_freem(m);
465 		}
466 
467 		sc->sc_tx_next++;
468 		sc->sc_tx_next %= HVN_TX_DESC;
469 
470 		atomic_dec_int(&sc->sc_tx_avail);
471 
472 		ifp->if_opackets++;
473 	}
474 }
475 
476 int
477 hvn_encap(struct hvn_softc *sc, struct mbuf *m, struct hvn_tx_desc **txd0)
478 {
479 	struct hvn_tx_desc *txd;
480 	bus_dma_segment_t *seg;
481 	size_t rlen;
482 	int i;
483 
484 	/* XXX use queues? */
485 	txd = &sc->sc_tx_desc[sc->sc_tx_next];
486 	while (!txd->txd_ready) {
487 		sc->sc_tx_next++;
488 		sc->sc_tx_next %= HVN_TX_DESC;
489 		txd = &sc->sc_tx_desc[sc->sc_tx_next];
490 	}
491 
492 	memset(txd->txd_req, 0, sizeof(*txd->txd_req));
493 	txd->txd_req->rm_type = REMOTE_NDIS_PACKET_MSG;
494 	txd->txd_req->rm_dataoffset = RNDIS_DATA_OFFSET;
495 	txd->txd_req->rm_datalen = m->m_pkthdr.len;
496 	txd->txd_req->rm_pktinfooffset = RNDIS_DATA_OFFSET;
497 	rlen = sizeof(struct rndis_packet_msg);
498 
499 	if (bus_dmamap_load_mbuf(sc->sc_dmat, txd->txd_dmap, m, BUS_DMA_READ |
500 	    BUS_DMA_NOWAIT)) {
501 		DPRINTF("%s: failed to load mbuf\n", sc->sc_dev.dv_xname);
502 		return (-1);
503 	}
504 	txd->txd_buf = m;
505 
506 	/* Per-packet info adjusts rlen */
507 
508 	/* Final length value for the RNDIS header and data */
509 	txd->txd_req->rm_len = txd->txd_req->rm_datalen + rlen;
510 
511 	/* Attach an RNDIS message into the first slot */
512 	txd->txd_sgl[0].gpa_page = txd->txd_gpa.gpa_page;
513 	txd->txd_sgl[0].gpa_ofs = txd->txd_gpa.gpa_ofs;
514 	txd->txd_sgl[0].gpa_len = rlen;
515 	txd->txd_nsge = txd->txd_dmap->dm_nsegs + 1;
516 
517 	for (i = 0; i < txd->txd_dmap->dm_nsegs; i++) {
518 		seg = &txd->txd_dmap->dm_segs[i];
519 		txd->txd_sgl[1 + i].gpa_page = atop(seg->ds_addr);
520 		txd->txd_sgl[1 + i].gpa_ofs = seg->ds_addr & PAGE_MASK;
521 		txd->txd_sgl[1 + i].gpa_len = seg->ds_len;
522 	}
523 
524 	*txd0 = txd;
525 	return (0);
526 }
527 
528 void
529 hvn_decap(struct hvn_softc *sc, struct hvn_tx_desc *txd)
530 {
531 	bus_dmamap_sync(sc->sc_dmat, txd->txd_dmap, 0, 0,
532 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
533 	bus_dmamap_unload(sc->sc_dmat, txd->txd_dmap);
534 	txd->txd_buf = NULL;
535 	txd->txd_nsge = 0;
536 }
537 
538 void
539 hvn_txeof(struct hvn_softc *sc, uint64_t tid)
540 {
541 	struct ifnet *ifp = &sc->sc_ac.ac_if;
542 	struct hvn_tx_desc *txd;
543 	struct mbuf *m;
544 	uint32_t id = tid >> 32;
545 
546 	if ((tid & 0xffffffff) != 0)
547 		return;
548 	if (id > HVN_TX_DESC)
549 		panic("tx packet index too large: %u", id);
550 
551 	txd = &sc->sc_tx_desc[id];
552 
553 	if ((m = txd->txd_buf) == NULL)
554 		panic("%s: no mbuf @%u\n", sc->sc_dev.dv_xname, id);
555 	txd->txd_buf = NULL;
556 
557 	bus_dmamap_sync(sc->sc_dmat, txd->txd_dmap, 0, 0,
558 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
559 	bus_dmamap_unload(sc->sc_dmat, txd->txd_dmap);
560 	m_freem(m);
561 
562 	txd->txd_ready = 1;
563 
564 	atomic_inc_int(&sc->sc_tx_avail);
565 
566 	if (ifq_is_oactive(&ifp->if_snd))
567 		ifq_restart(&ifp->if_snd);
568 }
569 
570 int
571 hvn_rx_ring_create(struct hvn_softc *sc)
572 {
573 	struct hvn_nvs_rxbuf_conn cmd;
574 	struct hvn_nvs_rxbuf_conn_resp *rsp;
575 	uint64_t tid;
576 
577 	if (sc->sc_proto <= HVN_NVS_PROTO_VERSION_2)
578 		sc->sc_rx_size = 15 * 1024 * 1024;	/* 15MB */
579 	else
580 		sc->sc_rx_size = 16 * 1024 * 1024; 	/* 16MB */
581 	sc->sc_rx_ring = km_alloc(sc->sc_rx_size, &kv_any, &kp_zero,
582 	    cold ? &kd_nowait : &kd_waitok);
583 	if (sc->sc_rx_ring == NULL) {
584 		DPRINTF("%s: failed to allocate Rx ring buffer\n",
585 		    sc->sc_dev.dv_xname);
586 		return (-1);
587 	}
588 	if (hv_handle_alloc(sc->sc_chan, sc->sc_rx_ring, sc->sc_rx_size,
589 	    &sc->sc_rx_hndl)) {
590 		DPRINTF("%s: failed to obtain a PA handle\n",
591 		    sc->sc_dev.dv_xname);
592 		goto errout;
593 	}
594 
595 	memset(&cmd, 0, sizeof(cmd));
596 	cmd.nvs_type = HVN_NVS_TYPE_RXBUF_CONN;
597 	cmd.nvs_gpadl = sc->sc_rx_hndl;
598 	cmd.nvs_sig = HVN_NVS_RXBUF_SIG;
599 
600 	tid = atomic_inc_int_nv(&sc->sc_nvstid);
601 	if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 100))
602 		goto errout;
603 
604 	rsp = (struct hvn_nvs_rxbuf_conn_resp *)&sc->sc_nvsrsp;
605 	if (rsp->nvs_status != HVN_NVS_STATUS_OK) {
606 		DPRINTF("%s: failed to set up the Rx ring\n",
607 		    sc->sc_dev.dv_xname);
608 		goto errout;
609 	}
610 	if (rsp->nvs_nsect > 1) {
611 		DPRINTF("%s: invalid number of Rx ring sections: %d\n",
612 		    sc->sc_dev.dv_xname, rsp->nvs_nsect);
613 		hvn_rx_ring_destroy(sc);
614 		return (-1);
615 	}
616 	return (0);
617 
618  errout:
619 	if (sc->sc_rx_hndl) {
620 		hv_handle_free(sc->sc_chan, sc->sc_rx_hndl);
621 		sc->sc_rx_hndl = 0;
622 	}
623 	if (sc->sc_rx_ring) {
624 		km_free(sc->sc_rx_ring, sc->sc_rx_size, &kv_any, &kp_zero);
625 		sc->sc_rx_ring = NULL;
626 	}
627 	return (-1);
628 }
629 
630 int
631 hvn_rx_ring_destroy(struct hvn_softc *sc)
632 {
633 	struct hvn_nvs_rxbuf_disconn cmd;
634 	uint64_t tid;
635 
636 	if (sc->sc_rx_ring == NULL)
637 		return (0);
638 
639 	memset(&cmd, 0, sizeof(cmd));
640 	cmd.nvs_type = HVN_NVS_TYPE_RXBUF_DISCONN;
641 	cmd.nvs_sig = HVN_NVS_RXBUF_SIG;
642 
643 	tid = atomic_inc_int_nv(&sc->sc_nvstid);
644 	if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0))
645 		return (-1);
646 
647 	delay(100);
648 
649 	hv_handle_free(sc->sc_chan, sc->sc_rx_hndl);
650 
651 	sc->sc_rx_hndl = 0;
652 
653 	km_free(sc->sc_rx_ring, sc->sc_rx_size, &kv_any, &kp_zero);
654 	sc->sc_rx_ring = NULL;
655 
656 	return (0);
657 }
658 
659 int
660 hvn_tx_ring_create(struct hvn_softc *sc)
661 {
662 	struct hvn_tx_desc *txd;
663 	bus_dma_segment_t *seg;
664 	size_t msgsize;
665 	int i, rsegs;
666 	paddr_t pa;
667 
668 	msgsize = roundup(HVN_RNDIS_MSG_LEN, 128);
669 
670 	/* Allocate memory to store RNDIS messages */
671 	if (bus_dmamem_alloc(sc->sc_dmat, msgsize * HVN_TX_DESC, PAGE_SIZE, 0,
672 	    &sc->sc_tx_mseg, 1, &rsegs, BUS_DMA_ZERO | BUS_DMA_WAITOK)) {
673 		DPRINTF("%s: failed to allocate memory for RDNIS messages\n",
674 		    sc->sc_dev.dv_xname);
675 		goto errout;
676 	}
677 	if (bus_dmamem_map(sc->sc_dmat, &sc->sc_tx_mseg, 1, msgsize *
678 	    HVN_TX_DESC, (caddr_t *)&sc->sc_tx_msgs, BUS_DMA_WAITOK)) {
679 		DPRINTF("%s: failed to establish mapping for RDNIS messages\n",
680 		    sc->sc_dev.dv_xname);
681 		goto errout;
682 	}
683 	if (bus_dmamap_create(sc->sc_dmat, msgsize * HVN_TX_DESC, 1,
684 	    msgsize * HVN_TX_DESC, 0, BUS_DMA_WAITOK, &sc->sc_tx_rmap)) {
685 		DPRINTF("%s: failed to create map for RDNIS messages\n",
686 		    sc->sc_dev.dv_xname);
687 		goto errout;
688 	}
689 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_tx_rmap, sc->sc_tx_msgs,
690 	    msgsize * HVN_TX_DESC, NULL, BUS_DMA_WAITOK)) {
691 		DPRINTF("%s: failed to create map for RDNIS messages\n",
692 		    sc->sc_dev.dv_xname);
693 		goto errout;
694 	}
695 
696 	for (i = 0; i < HVN_TX_DESC; i++) {
697 		txd = &sc->sc_tx_desc[i];
698 		if (bus_dmamap_create(sc->sc_dmat, HVN_TX_PKT_SIZE,
699 		    HVN_TX_FRAGS, HVN_TX_FRAG_SIZE, 0, BUS_DMA_WAITOK,
700 		    &txd->txd_dmap)) {
701 			DPRINTF("%s: failed to create map for TX descriptors\n",
702 			    sc->sc_dev.dv_xname);
703 			goto errout;
704 		}
705 		seg = &sc->sc_tx_rmap->dm_segs[0];
706 		pa = seg->ds_addr + (msgsize * i);
707 		txd->txd_gpa.gpa_page = atop(pa);
708 		txd->txd_gpa.gpa_ofs = pa & PAGE_MASK;
709 		txd->txd_gpa.gpa_len = msgsize;
710 		txd->txd_req = (void *)((caddr_t)sc->sc_tx_msgs +
711 		    (msgsize * i));
712 		txd->txd_id = i;
713 		txd->txd_ready = 1;
714 	}
715 	sc->sc_tx_avail = HVN_TX_DESC;
716 
717 	return (0);
718 
719  errout:
720 	hvn_tx_ring_destroy(sc);
721 	return (-1);
722 }
723 
724 void
725 hvn_tx_ring_destroy(struct hvn_softc *sc)
726 {
727 	struct hvn_tx_desc *txd;
728 	int i;
729 
730 	for (i = 0; i < HVN_TX_DESC; i++) {
731 		txd = &sc->sc_tx_desc[i];
732 		if (txd->txd_dmap == NULL)
733 			continue;
734 		bus_dmamap_sync(sc->sc_dmat, txd->txd_dmap, 0, 0,
735 		    BUS_DMASYNC_POSTWRITE);
736 		bus_dmamap_unload(sc->sc_dmat, txd->txd_dmap);
737 		bus_dmamap_destroy(sc->sc_dmat, txd->txd_dmap);
738 		txd->txd_dmap = NULL;
739 		if (txd->txd_buf == NULL)
740 			continue;
741 		m_free(txd->txd_buf);
742 		txd->txd_buf = NULL;
743 	}
744 	if (sc->sc_tx_rmap) {
745 		bus_dmamap_sync(sc->sc_dmat, sc->sc_tx_rmap, 0, 0,
746 		    BUS_DMASYNC_POSTWRITE);
747 		bus_dmamap_unload(sc->sc_dmat, sc->sc_tx_rmap);
748 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_tx_rmap);
749 	}
750 	if (sc->sc_tx_msgs) {
751 		size_t msgsize = roundup(HVN_RNDIS_MSG_LEN, 128);
752 
753 		bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_tx_msgs,
754 		    msgsize * HVN_TX_DESC);
755 		bus_dmamem_free(sc->sc_dmat, &sc->sc_tx_mseg, 1);
756 	}
757 	sc->sc_tx_rmap = NULL;
758 	sc->sc_tx_msgs = NULL;
759 }
760 
761 int
762 hvn_get_lladdr(struct hvn_softc *sc)
763 {
764 	char enaddr[ETHER_ADDR_LEN];
765 	size_t addrlen = ETHER_ADDR_LEN;
766 	int rv;
767 
768 	rv = hvn_rndis_query(sc, OID_802_3_PERMANENT_ADDRESS,
769 	    enaddr, &addrlen);
770 	if (rv == 0 && addrlen == ETHER_ADDR_LEN)
771 		memcpy(sc->sc_ac.ac_enaddr, enaddr, ETHER_ADDR_LEN);
772 	return (rv);
773 }
774 
775 int
776 hvn_set_lladdr(struct hvn_softc *sc)
777 {
778 	return (hvn_rndis_set(sc, OID_802_3_CURRENT_ADDRESS,
779 	    sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN));
780 }
781 
782 void
783 hvn_get_link_status(struct hvn_softc *sc)
784 {
785 	uint32_t state;
786 	size_t len = sizeof(state);
787 
788 	if (hvn_rndis_query(sc, OID_GEN_MEDIA_CONNECT_STATUS,
789 	    &state, &len) == 0)
790 		sc->sc_link_state = (state == NDIS_MEDIA_STATE_CONNECTED) ?
791 		    LINK_STATE_UP : LINK_STATE_DOWN;
792 }
793 
794 int
795 hvn_nvs_attach(struct hvn_softc *sc)
796 {
797 	const uint32_t protos[] = {
798 		HVN_NVS_PROTO_VERSION_5, HVN_NVS_PROTO_VERSION_4,
799 		HVN_NVS_PROTO_VERSION_2, HVN_NVS_PROTO_VERSION_1
800 	};
801 	struct hvn_nvs_init cmd;
802 	struct hvn_nvs_init_resp *rsp;
803 	struct hvn_nvs_ndis_init ncmd;
804 	uint64_t tid;
805 	uint32_t ndisver;
806 	int i;
807 
808 	/* 4 page sized buffer for channel messages */
809 	sc->sc_nvsbuf = km_alloc(HVN_NVS_BUFSIZE, &kv_any, &kp_zero,
810 	    (cold ? &kd_nowait : &kd_waitok));
811 	if (sc->sc_nvsbuf == NULL) {
812 		DPRINTF("%s: failed to allocate channel data buffer\n",
813 		    sc->sc_dev.dv_xname);
814 		return (-1);
815 	}
816 	sc->sc_chan->ch_buflen = PAGE_SIZE * 4;
817 
818 	/* Associate our interrupt handler with the channel */
819 	if (hv_channel_open(sc->sc_chan, NULL, 0, hvn_nvs_intr, sc)) {
820 		DPRINTF("%s: failed to open channel\n", sc->sc_dev.dv_xname);
821 		km_free(sc->sc_nvsbuf, HVN_NVS_BUFSIZE, &kv_any, &kp_zero);
822 		return (-1);
823 	}
824 
825 	hv_evcount_attach(sc->sc_chan, sc->sc_dev.dv_xname);
826 
827 	mtx_init(&sc->sc_nvslck, IPL_NET);
828 
829 	memset(&cmd, 0, sizeof(cmd));
830 	cmd.nvs_type = HVN_NVS_TYPE_INIT;
831 	for (i = 0; i < nitems(protos); i++) {
832 		cmd.nvs_ver_min = cmd.nvs_ver_max = protos[i];
833 		tid = atomic_inc_int_nv(&sc->sc_nvstid);
834 		if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 100))
835 			return (-1);
836 		rsp = (struct hvn_nvs_init_resp *)&sc->sc_nvsrsp;
837 		if (rsp->nvs_status == HVN_NVS_STATUS_OK) {
838 			sc->sc_proto = protos[i];
839 			break;
840 		}
841 	}
842 	if (!sc->sc_proto) {
843 		DPRINTF("%s: failed to negotiate NVSP version\n",
844 		    sc->sc_dev.dv_xname);
845 		return (-1);
846 	}
847 
848 	memset(&ncmd, 0, sizeof(ncmd));
849 	ncmd.nvs_type = HVN_NVS_TYPE_NDIS_INIT;
850 	if (sc->sc_proto <= HVN_NVS_PROTO_VERSION_4)
851 		ndisver = NDIS_VERSION_6_1;
852 	else
853 		ndisver = NDIS_VERSION_6_30;
854 	ncmd.nvs_ndis_major = (ndisver & 0xffff0000) >> 16;
855 	ncmd.nvs_ndis_minor = (ndisver & 0x0000ffff);
856 
857 	tid = atomic_inc_int_nv(&sc->sc_nvstid);
858 	if (hvn_nvs_cmd(sc, &ncmd, sizeof(ncmd), tid, 100))
859 		return (-1);
860 
861 	sc->sc_ndisver = ndisver;
862 
863 	return (0);
864 }
865 
866 void
867 hvn_nvs_intr(void *arg)
868 {
869 	struct hvn_softc *sc = arg;
870 	struct vmbus_chanpkt_hdr *cph;
871 	struct hvn_nvs_hdr *nvs;
872 	uint64_t rid;
873 	uint32_t rlen;
874 	int rv;
875 
876 	for (;;) {
877 		rv = hv_channel_recv(sc->sc_chan, sc->sc_nvsbuf,
878 		    HVN_NVS_BUFSIZE, &rlen, &rid, 1);
879 		if (rv != 0 || rlen == 0) {
880 			if (rv != EAGAIN)
881 				printf("%s: failed to receive an NVSP "
882 				    "packet\n", sc->sc_dev.dv_xname);
883 			break;
884 		}
885 		cph = (struct vmbus_chanpkt_hdr *)sc->sc_nvsbuf;
886 		nvs = (struct hvn_nvs_hdr *)VMBUS_CHANPKT_CONST_DATA(cph);
887 
888 		if (cph->cph_type == VMBUS_CHANPKT_TYPE_COMP) {
889 			switch (nvs->nvs_type) {
890 			case HVN_NVS_TYPE_INIT_RESP:
891 			case HVN_NVS_TYPE_RXBUF_CONNRESP:
892 			case HVN_NVS_TYPE_CHIM_CONNRESP:
893 			case HVN_NVS_TYPE_SUBCH_RESP:
894 				/* copy the response back */
895 				memcpy(&sc->sc_nvsrsp, nvs, HVN_NVS_MSGSIZE);
896 				wakeup_one(&sc->sc_nvsrsp);
897 				break;
898 			case HVN_NVS_TYPE_RNDIS_ACK:
899 				hvn_txeof(sc, cph->cph_tid);
900 				break;
901 			default:
902 				printf("%s: unhandled NVSP packet type %d "
903 				    "on completion\n", sc->sc_dev.dv_xname,
904 				    nvs->nvs_type);
905 			}
906 		} else if (cph->cph_type == VMBUS_CHANPKT_TYPE_RXBUF) {
907 			switch (nvs->nvs_type) {
908 			case HVN_NVS_TYPE_RNDIS:
909 				hvn_rndis_input(sc, cph->cph_tid, cph);
910 				break;
911 			default:
912 				printf("%s: unhandled NVSP packet type %d "
913 				    "on receive\n", sc->sc_dev.dv_xname,
914 				    nvs->nvs_type);
915 			}
916 		} else
917 			printf("%s: unknown NVSP packet type %u\n",
918 			    sc->sc_dev.dv_xname, cph->cph_type);
919 	}
920 }
921 
922 int
923 hvn_nvs_cmd(struct hvn_softc *sc, void *cmd, size_t cmdsize, uint64_t tid,
924     int timo)
925 {
926 	struct hvn_nvs_hdr *hdr = cmd;
927 	int tries = 10;
928 	int rv;
929 
930 	do {
931 		rv = hv_channel_send(sc->sc_chan, cmd, cmdsize,
932 		    tid, VMBUS_CHANPKT_TYPE_INBAND,
933 		    timo ? VMBUS_CHANPKT_FLAG_RC : 0);
934 		if (rv == EAGAIN) {
935 			if (timo)
936 				tsleep(cmd, PRIBIO, "hvnsend", timo / 10);
937 			else
938 				delay(100);
939 		} else if (rv) {
940 			DPRINTF("%s: NVSP operation %d send error %d\n",
941 			    sc->sc_dev.dv_xname, hdr->nvs_type, rv);
942 			return (rv);
943 		}
944 	} while (rv != 0 && --tries > 0);
945 
946 	if (timo) {
947 		mtx_enter(&sc->sc_nvslck);
948 		rv = msleep(&sc->sc_nvsrsp, &sc->sc_nvslck, PRIBIO, "hvnvsp",
949 		    timo);
950 		mtx_leave(&sc->sc_nvslck);
951 #ifdef HVN_DEBUG
952 		switch (rv) {
953 		case EINTR:
954 			rv = 0;
955 			break;
956 		case EWOULDBLOCK:
957 			printf("%s: NVSP opertaion %d timed out\n",
958 			    sc->sc_dev.dv_xname, hdr->nvs_type);
959 		}
960 	}
961 #endif
962 	return (rv);
963 }
964 
965 int
966 hvn_nvs_ack(struct hvn_softc *sc, uint64_t tid)
967 {
968 	struct hvn_nvs_rndis_ack cmd;
969 	int tries = 5;
970 	int rv;
971 
972 	cmd.nvs_type = HVN_NVS_TYPE_RNDIS_ACK;
973 	cmd.nvs_status = HVN_NVS_STATUS_OK;
974 	do {
975 		rv = hv_channel_send(sc->sc_chan, &cmd, sizeof(cmd),
976 		    tid, VMBUS_CHANPKT_TYPE_COMP, 0);
977 		if (rv == EAGAIN)
978 			delay(100);
979 		else if (rv) {
980 			DPRINTF("%s: NVSP acknowledgement error %d\n",
981 			    sc->sc_dev.dv_xname, rv);
982 			return (rv);
983 		}
984 	} while (rv != 0 && --tries > 0);
985 	return (rv);
986 }
987 
988 void
989 hvn_nvs_detach(struct hvn_softc *sc)
990 {
991 	if (hv_channel_close(sc->sc_chan) == 0) {
992 		km_free(sc->sc_nvsbuf, HVN_NVS_BUFSIZE, &kv_any, &kp_zero);
993 		sc->sc_nvsbuf = NULL;
994 	}
995 }
996 
997 static inline struct rndis_cmd *
998 hvn_alloc_cmd(struct hvn_softc *sc)
999 {
1000 	struct rndis_cmd *rc;
1001 
1002 	mtx_enter(&sc->sc_cntl_fqlck);
1003 	while ((rc = TAILQ_FIRST(&sc->sc_cntl_fq)) == NULL)
1004 		msleep(&sc->sc_cntl_fq, &sc->sc_cntl_fqlck,
1005 		    PRIBIO, "hvnrr", 1);
1006 	TAILQ_REMOVE(&sc->sc_cntl_fq, rc, rc_entry);
1007 	mtx_leave(&sc->sc_cntl_fqlck);
1008 	return (rc);
1009 }
1010 
1011 static inline void
1012 hvn_submit_cmd(struct hvn_softc *sc, struct rndis_cmd *rc)
1013 {
1014 	mtx_enter(&sc->sc_cntl_sqlck);
1015 	TAILQ_INSERT_TAIL(&sc->sc_cntl_sq, rc, rc_entry);
1016 	mtx_leave(&sc->sc_cntl_sqlck);
1017 }
1018 
1019 static inline struct rndis_cmd *
1020 hvn_complete_cmd(struct hvn_softc *sc, uint32_t id)
1021 {
1022 	struct rndis_cmd *rc;
1023 
1024 	mtx_enter(&sc->sc_cntl_sqlck);
1025 	TAILQ_FOREACH(rc, &sc->sc_cntl_sq, rc_entry) {
1026 		if (rc->rc_id == id) {
1027 			TAILQ_REMOVE(&sc->sc_cntl_sq, rc, rc_entry);
1028 			break;
1029 		}
1030 	}
1031 	mtx_leave(&sc->sc_cntl_sqlck);
1032 	if (rc != NULL) {
1033 		mtx_enter(&sc->sc_cntl_cqlck);
1034 		TAILQ_INSERT_TAIL(&sc->sc_cntl_cq, rc, rc_entry);
1035 		mtx_leave(&sc->sc_cntl_cqlck);
1036 	}
1037 	return (rc);
1038 }
1039 
1040 static inline int
1041 hvn_rollback_cmd(struct hvn_softc *sc, struct rndis_cmd *rc)
1042 {
1043 	struct rndis_cmd *rn;
1044 
1045 	mtx_enter(&sc->sc_cntl_sqlck);
1046 	TAILQ_FOREACH(rn, &sc->sc_cntl_sq, rc_entry) {
1047 		if (rn == rc) {
1048 			TAILQ_REMOVE(&sc->sc_cntl_sq, rc, rc_entry);
1049 			mtx_leave(&sc->sc_cntl_sqlck);
1050 			return (0);
1051 		}
1052 	}
1053 	mtx_leave(&sc->sc_cntl_sqlck);
1054 	return (-1);
1055 }
1056 
1057 static inline void
1058 hvn_free_cmd(struct hvn_softc *sc, struct rndis_cmd *rc)
1059 {
1060 	memset(rc->rc_req, 0, sizeof(struct rndis_packet_msg));
1061 	memset(&rc->rc_cmp, 0, sizeof(rc->rc_cmp));
1062 	memset(&rc->rc_msg, 0, sizeof(rc->rc_msg));
1063 	mtx_enter(&sc->sc_cntl_fqlck);
1064 	TAILQ_INSERT_TAIL(&sc->sc_cntl_fq, rc, rc_entry);
1065 	mtx_leave(&sc->sc_cntl_fqlck);
1066 	wakeup(&sc->sc_cntl_fq);
1067 }
1068 
1069 int
1070 hvn_rndis_attach(struct hvn_softc *sc)
1071 {
1072 	struct rndis_init_req *req;
1073 	struct rndis_init_comp *cmp;
1074 	struct rndis_cmd *rc;
1075 	int i, rv;
1076 
1077 	/* RNDIS control message queues */
1078 	TAILQ_INIT(&sc->sc_cntl_sq);
1079 	TAILQ_INIT(&sc->sc_cntl_cq);
1080 	TAILQ_INIT(&sc->sc_cntl_fq);
1081 	mtx_init(&sc->sc_cntl_sqlck, IPL_NET);
1082 	mtx_init(&sc->sc_cntl_cqlck, IPL_NET);
1083 	mtx_init(&sc->sc_cntl_fqlck, IPL_NET);
1084 
1085 	for (i = 0; i < HVN_RNDIS_CTLREQS; i++) {
1086 		rc = &sc->sc_cntl_msgs[i];
1087 		if (bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1,
1088 		    PAGE_SIZE, 0, BUS_DMA_WAITOK, &rc->rc_dmap)) {
1089 			DPRINTF("%s: failed to create RNDIS command map\n",
1090 			    sc->sc_dev.dv_xname);
1091 			goto errout;
1092 		}
1093 		if (bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
1094 		    0, &rc->rc_segs, 1, &rc->rc_nsegs, BUS_DMA_NOWAIT |
1095 		    BUS_DMA_ZERO)) {
1096 			DPRINTF("%s: failed to allocate RNDIS command\n",
1097 			    sc->sc_dev.dv_xname);
1098 			bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap);
1099 			goto errout;
1100 		}
1101 		if (bus_dmamem_map(sc->sc_dmat, &rc->rc_segs, rc->rc_nsegs,
1102 		    PAGE_SIZE, (caddr_t *)&rc->rc_req, BUS_DMA_NOWAIT)) {
1103 			DPRINTF("%s: failed to allocate RNDIS command\n",
1104 			    sc->sc_dev.dv_xname);
1105 			bus_dmamem_free(sc->sc_dmat, &rc->rc_segs,
1106 			    rc->rc_nsegs);
1107 			bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap);
1108 			goto errout;
1109 		}
1110 		if (bus_dmamap_load(sc->sc_dmat, rc->rc_dmap, rc->rc_req,
1111 		    PAGE_SIZE, NULL, BUS_DMA_WAITOK)) {
1112 			DPRINTF("%s: failed to load RNDIS command map\n",
1113 			    sc->sc_dev.dv_xname);
1114 			bus_dmamem_free(sc->sc_dmat, &rc->rc_segs,
1115 			    rc->rc_nsegs);
1116 			bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap);
1117 			goto errout;
1118 		}
1119 		rc->rc_gpa = atop(rc->rc_dmap->dm_segs[0].ds_addr);
1120 		mtx_init(&rc->rc_mtx, IPL_NET);
1121 		TAILQ_INSERT_TAIL(&sc->sc_cntl_fq, rc, rc_entry);
1122 	}
1123 
1124 	rc = hvn_alloc_cmd(sc);
1125 
1126 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1127 	    BUS_DMASYNC_PREREAD);
1128 
1129 	rc->rc_id = atomic_inc_int_nv(&sc->sc_rndisrid);
1130 
1131 	req = rc->rc_req;
1132 	req->rm_type = REMOTE_NDIS_INITIALIZE_MSG;
1133 	req->rm_len = sizeof(*req);
1134 	req->rm_rid = rc->rc_id;
1135 	req->rm_ver_major = RNDIS_VERSION_MAJOR;
1136 	req->rm_ver_minor = RNDIS_VERSION_MINOR;
1137 	req->rm_max_xfersz = 2048; /* XXX */
1138 
1139 	rc->rc_cmplen = sizeof(*cmp);
1140 
1141 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1142 	    BUS_DMASYNC_PREWRITE);
1143 
1144 	if ((rv = hvn_rndis_cmd(sc, rc, 500)) != 0) {
1145 		DPRINTF("%s: INITIALIZE_MSG failed, error %u\n",
1146 		    sc->sc_dev.dv_xname, rv);
1147 		hvn_free_cmd(sc, rc);
1148 		goto errout;
1149 	}
1150 	cmp = (struct rndis_init_comp *)&rc->rc_cmp;
1151 	if (cmp->rm_status != RNDIS_STATUS_SUCCESS) {
1152 		DPRINTF("%s: failed to init RNDIS, error %#x\n",
1153 		    sc->sc_dev.dv_xname, cmp->rm_status);
1154 		hvn_free_cmd(sc, rc);
1155 		goto errout;
1156 	}
1157 
1158 	hvn_free_cmd(sc, rc);
1159 
1160 	return (0);
1161 
1162 errout:
1163 	for (i = 0; i < HVN_RNDIS_CTLREQS; i++) {
1164 		rc = &sc->sc_cntl_msgs[i];
1165 		if (rc->rc_req == NULL)
1166 			continue;
1167 		TAILQ_REMOVE(&sc->sc_cntl_fq, rc, rc_entry);
1168 		bus_dmamem_free(sc->sc_dmat, &rc->rc_segs, rc->rc_nsegs);
1169 		rc->rc_req = NULL;
1170 		bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap);
1171 	}
1172 	return (-1);
1173 }
1174 
1175 int
1176 hvn_rndis_cmd(struct hvn_softc *sc, struct rndis_cmd *rc, int timo)
1177 {
1178 	struct hvn_nvs_rndis *msg = &rc->rc_msg;
1179 	struct rndis_msghdr *hdr = rc->rc_req;
1180 	struct vmbus_gpa sgl[1];
1181 	int tries = 10;
1182 	int rv;
1183 
1184 	KASSERT(timo > 0);
1185 
1186 	msg->nvs_type = HVN_NVS_TYPE_RNDIS;
1187 	msg->nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_CTRL;
1188 	msg->nvs_chim_idx = HVN_NVS_CHIM_IDX_INVALID;
1189 
1190 	sgl[0].gpa_page = rc->rc_gpa;
1191 	sgl[0].gpa_len = hdr->rm_len;
1192 	sgl[0].gpa_ofs = 0;
1193 
1194 	hvn_submit_cmd(sc, rc);
1195 
1196 	do {
1197 		rv = hv_channel_send_sgl(sc->sc_chan, sgl, 1, &rc->rc_msg,
1198 		    sizeof(*msg), rc->rc_id);
1199 		if (rv == EAGAIN)
1200 			tsleep(rc, PRIBIO, "hvnsendbuf", timo / 10);
1201 		else if (rv) {
1202 			DPRINTF("%s: RNDIS operation %d send error %d\n",
1203 			    sc->sc_dev.dv_xname, hdr->rm_type, rv);
1204 			return (rv);
1205 		}
1206 	} while (rv != 0 && --tries > 0);
1207 
1208 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1209 	    BUS_DMASYNC_POSTWRITE);
1210 
1211 	mtx_enter(&rc->rc_mtx);
1212 	rv = msleep(rc, &rc->rc_mtx, PRIBIO, "rndisctl", timo);
1213 	mtx_leave(&rc->rc_mtx);
1214 
1215 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1216 	    BUS_DMASYNC_POSTREAD);
1217 
1218 #ifdef HVN_DEBUG
1219 	switch (rv) {
1220 	case EINTR:
1221 		rv = 0;
1222 		break;
1223 	case EWOULDBLOCK:
1224 		if (hvn_rollback_cmd(sc, rc)) {
1225 			/* failed to rollback? go for one sleep cycle */
1226 			tsleep(rc, PRIBIO, "rndisctl2", 1);
1227 			rv = 0;
1228 			break;
1229 		}
1230 		printf("%s: RNDIS opertaion %d timed out\n", sc->sc_dev.dv_xname,
1231 		    hdr->rm_type);
1232 	}
1233 #endif
1234 	return (rv);
1235 }
1236 
1237 void
1238 hvn_rndis_input(struct hvn_softc *sc, uint64_t tid, void *arg)
1239 {
1240 	struct ifnet *ifp = &sc->sc_ac.ac_if;
1241 	struct mbuf_list ml = MBUF_LIST_INITIALIZER();
1242 	struct vmbus_chanpkt_prplist *cp = arg;
1243 	uint32_t off, len, type;
1244 	int i;
1245 
1246 	if (sc->sc_rx_ring == NULL) {
1247 		DPRINTF("%s: invalid rx ring\n", sc->sc_dev.dv_xname);
1248 		return;
1249 	}
1250 	for (i = 0; i < cp->cp_range_cnt; i++) {
1251 		off = cp->cp_range[i].gpa_ofs;
1252 		len = cp->cp_range[i].gpa_len;
1253 
1254 		KASSERT(off + len <= sc->sc_rx_size);
1255 		KASSERT(len >= RNDIS_HEADER_OFFSET + 4);
1256 
1257 		memcpy(&type, (caddr_t)sc->sc_rx_ring + off, sizeof(type));
1258 		switch (type) {
1259 		/* data message */
1260 		case REMOTE_NDIS_PACKET_MSG:
1261 			hvn_rxeof(sc, (caddr_t)sc->sc_rx_ring +
1262 			    off, len, &ml);
1263 			break;
1264 		/* completion messages */
1265 		case REMOTE_NDIS_INITIALIZE_CMPLT:
1266 		case REMOTE_NDIS_QUERY_CMPLT:
1267 		case REMOTE_NDIS_SET_CMPLT:
1268 		case REMOTE_NDIS_RESET_CMPLT:
1269 		case REMOTE_NDIS_KEEPALIVE_CMPLT:
1270 			hvn_rndis_complete(sc, (caddr_t)sc->sc_rx_ring +
1271 			    off, len);
1272 			break;
1273 		/* notification message */
1274 		case REMOTE_NDIS_INDICATE_STATUS_MSG:
1275 			hvn_rndis_status(sc, (caddr_t)sc->sc_rx_ring +
1276 			    off, len);
1277 			break;
1278 		default:
1279 			printf("%s: unhandled RNDIS message type %u\n",
1280 			    sc->sc_dev.dv_xname, type);
1281 		}
1282 	}
1283 	hvn_nvs_ack(sc, tid);
1284 
1285 	if (MBUF_LIST_FIRST(&ml))
1286 		if_input(ifp, &ml);
1287 }
1288 
1289 static inline struct mbuf *
1290 hvn_devget(struct hvn_softc *sc, caddr_t buf, uint32_t len)
1291 {
1292 	struct mbuf *m;
1293 
1294 	if (len + ETHER_ALIGN <= MHLEN)
1295 		MGETHDR(m, M_NOWAIT, MT_DATA);
1296 	else
1297 		m = MCLGETI(NULL, M_NOWAIT, NULL, len + ETHER_ALIGN);
1298 	if (m == NULL)
1299 		return (NULL);
1300 	m->m_len = m->m_pkthdr.len = len;
1301 	m_adj(m, ETHER_ALIGN);
1302 
1303 	if (m_copyback(m, 0, len, buf, M_NOWAIT)) {
1304 		m_freem(m);
1305 		return (NULL);
1306 	}
1307 
1308 	return (m);
1309 }
1310 
1311 void
1312 hvn_rxeof(struct hvn_softc *sc, caddr_t buf, uint32_t len,
1313     struct mbuf_list *ml)
1314 {
1315 	struct ifnet *ifp = &sc->sc_ac.ac_if;
1316 	struct rndis_packet_msg *pkt;
1317 	struct rndis_pktinfo *pi;
1318 	uint32_t csum, vlan;
1319 	struct mbuf *m;
1320 
1321 	if (!(ifp->if_flags & IFF_RUNNING))
1322 		return;
1323 
1324 	if (len < RNDIS_HEADER_OFFSET + sizeof(*pkt)) {
1325 		printf("%s: data packet too short: %u\n",
1326 		    sc->sc_dev.dv_xname, len);
1327 		return;
1328 	}
1329 
1330 	pkt = (struct rndis_packet_msg *)buf;
1331 
1332 	if (pkt->rm_dataoffset + pkt->rm_datalen > len) {
1333 		printf("%s: data packet out of bounds: %u@%u\n",
1334 		    sc->sc_dev.dv_xname, pkt->rm_dataoffset, pkt->rm_datalen);
1335 		return;
1336 	}
1337 
1338 	if ((m = hvn_devget(sc, buf + RNDIS_HEADER_OFFSET + pkt->rm_dataoffset,
1339 	    pkt->rm_datalen)) == NULL) {
1340 		ifp->if_ierrors++;
1341 		return;
1342 	}
1343 
1344 	pi = (struct rndis_pktinfo *)((caddr_t)pkt + RNDIS_HEADER_OFFSET +
1345 	    pkt->rm_pktinfooffset);
1346 	while (pkt->rm_pktinfolen > 0) {
1347 		if (pkt->rm_pktinfooffset + pkt->rm_pktinfolen > len) {
1348 			printf("%s: PI out of bounds: %u@%u\n",
1349 			    sc->sc_dev.dv_xname, pkt->rm_pktinfolen,
1350 			    pkt->rm_pktinfooffset);
1351 			break;
1352 		}
1353 		if (pi->rm_size > pkt->rm_pktinfolen) {
1354 			printf("%s: invalid PI size: %u/%u\n",
1355 			    sc->sc_dev.dv_xname, pi->rm_size,
1356 			    pkt->rm_pktinfolen);
1357 			break;
1358 		}
1359 		switch (pi->rm_type) {
1360 		case NDIS_PKTINFO_TYPE_CSUM:
1361 			memcpy(&csum, (caddr_t)pi + pi->rm_size, sizeof(csum));
1362 			if (csum & NDIS_RXCSUM_INFO_IPCS_OK)
1363 				m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
1364 			if (csum & NDIS_RXCSUM_INFO_TCPCS_OK)
1365 				m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK;
1366 			if (csum & NDIS_RXCSUM_INFO_UDPCS_OK)
1367 				m->m_pkthdr.csum_flags |= M_UDP_CSUM_IN_OK;
1368 			break;
1369 		case NDIS_PKTINFO_TYPE_VLAN:
1370 			memcpy(&vlan, (caddr_t)pi + pi->rm_size, sizeof(vlan));
1371 #if NVLAN > 0
1372 			m->m_pkthdr.ether_vtag = vlan & 0xffff;
1373 			m->m_flags |= M_VLANTAG;
1374 #endif
1375 			break;
1376 		default:
1377 			DPRINTF("%s: unhandled PI %u\n", sc->sc_dev.dv_xname,
1378 			    pi->rm_type);
1379 		}
1380 		pkt->rm_pktinfolen -= pi->rm_size;
1381 		pi = (struct rndis_pktinfo *)((caddr_t)pi + pi->rm_size);
1382 	}
1383 
1384 	ml_enqueue(ml, m);
1385 }
1386 
1387 void
1388 hvn_rndis_complete(struct hvn_softc *sc, caddr_t buf, uint32_t len)
1389 {
1390 	struct rndis_cmd *rc;
1391 	uint32_t id;
1392 
1393 	memcpy(&id, buf + RNDIS_HEADER_OFFSET, sizeof(id));
1394 	if ((rc = hvn_complete_cmd(sc, id)) != NULL) {
1395 		if (len < rc->rc_cmplen)
1396 			printf("%s: RNDIS response %u too short: %u\n",
1397 			    sc->sc_dev.dv_xname, id, len);
1398 		else
1399 			memcpy(&rc->rc_cmp, buf, rc->rc_cmplen);
1400 		if (len > rc->rc_cmplen &&
1401 		    len - rc->rc_cmplen > HVN_RNDIS_CMPBUFSZ)
1402 			printf("%s: RNDIS response %u too large: %u\n",
1403 			    sc->sc_dev.dv_xname, id, len);
1404 		else if (len > rc->rc_cmplen)
1405 			memcpy(&rc->rc_cmpbuf, buf + rc->rc_cmplen,
1406 			    len - rc->rc_cmplen);
1407 		wakeup_one(rc);
1408 	} else
1409 		DPRINTF("%s: failed to complete RNDIS request id %u\n",
1410 		    sc->sc_dev.dv_xname, id);
1411 }
1412 
1413 int
1414 hvn_rndis_output(struct hvn_softc *sc, struct hvn_tx_desc *txd)
1415 {
1416 	struct hvn_nvs_rndis *cmd = &txd->txd_cmd;
1417 	int rv;
1418 
1419 	cmd->nvs_type = HVN_NVS_TYPE_RNDIS;
1420 	cmd->nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_DATA;
1421 	cmd->nvs_chim_idx = HVN_NVS_CHIM_IDX_INVALID;
1422 
1423 	rv = hv_channel_send_sgl(sc->sc_chan, txd->txd_sgl, txd->txd_nsge,
1424 	    &txd->txd_cmd, sizeof(*cmd), (uint64_t)txd->txd_id << 32);
1425 	if (rv) {
1426 		DPRINTF("%s: RNDIS data send error %d\n",
1427 		    sc->sc_dev.dv_xname, rv);
1428 		return (rv);
1429 	}
1430 
1431 	return (0);
1432 }
1433 
1434 void
1435 hvn_rndis_status(struct hvn_softc *sc, caddr_t buf, uint32_t len)
1436 {
1437 	uint32_t sta;
1438 
1439 	memcpy(&sta, buf + RNDIS_HEADER_OFFSET, sizeof(sta));
1440 	switch (sta) {
1441 	case RNDIS_STATUS_MEDIA_CONNECT:
1442 		sc->sc_link_state = LINK_STATE_UP;
1443 		break;
1444 	case RNDIS_STATUS_MEDIA_DISCONNECT:
1445 		sc->sc_link_state = LINK_STATE_DOWN;
1446 		break;
1447 	/* Ignore these */
1448 	case RNDIS_STATUS_OFFLOAD_CURRENT_CONFIG:
1449 		return;
1450 	default:
1451 		DPRINTF("%s: unhandled status %#x\n", sc->sc_dev.dv_xname, sta);
1452 		return;
1453 	}
1454 	KERNEL_LOCK();
1455 	hvn_link_status(sc);
1456 	KERNEL_UNLOCK();
1457 }
1458 
1459 int
1460 hvn_rndis_query(struct hvn_softc *sc, uint32_t oid, void *res, size_t *length)
1461 {
1462 	struct rndis_cmd *rc;
1463 	struct rndis_query_req *req;
1464 	struct rndis_query_comp *cmp;
1465 	size_t olength = *length;
1466 	int rv;
1467 
1468 	rc = hvn_alloc_cmd(sc);
1469 
1470 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1471 	    BUS_DMASYNC_PREREAD);
1472 
1473 	rc->rc_id = atomic_inc_int_nv(&sc->sc_rndisrid);
1474 
1475 	req = rc->rc_req;
1476 	req->rm_type = REMOTE_NDIS_QUERY_MSG;
1477 	req->rm_len = sizeof(*req);
1478 	req->rm_rid = rc->rc_id;
1479 	req->rm_oid = oid;
1480 	req->rm_infobufoffset = sizeof(*req) - RNDIS_HEADER_OFFSET;
1481 
1482 	rc->rc_cmplen = sizeof(*cmp);
1483 
1484 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1485 	    BUS_DMASYNC_PREWRITE);
1486 
1487 	if ((rv = hvn_rndis_cmd(sc, rc, 500)) != 0) {
1488 		DPRINTF("%s: QUERY_MSG failed, error %d\n",
1489 		    sc->sc_dev.dv_xname, rv);
1490 		hvn_free_cmd(sc, rc);
1491 		return (rv);
1492 	}
1493 
1494 	cmp = (struct rndis_query_comp *)&rc->rc_cmp;
1495 	switch (cmp->rm_status) {
1496 	case RNDIS_STATUS_SUCCESS:
1497 		if (cmp->rm_infobuflen > olength) {
1498 			rv = EINVAL;
1499 			break;
1500 		}
1501 		memcpy(res, rc->rc_cmpbuf, cmp->rm_infobuflen);
1502 		*length = cmp->rm_infobuflen;
1503 		break;
1504 	default:
1505 		*length = 0;
1506 		rv = EIO;
1507 	}
1508 
1509 	hvn_free_cmd(sc, rc);
1510 
1511 	return (rv);
1512 }
1513 
1514 int
1515 hvn_rndis_set(struct hvn_softc *sc, uint32_t oid, void *data, size_t length)
1516 {
1517 	struct rndis_cmd *rc;
1518 	struct rndis_set_req *req;
1519 	struct rndis_set_comp *cmp;
1520 	int rv;
1521 
1522 	rc = hvn_alloc_cmd(sc);
1523 
1524 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1525 	    BUS_DMASYNC_PREREAD);
1526 
1527 	rc->rc_id = atomic_inc_int_nv(&sc->sc_rndisrid);
1528 
1529 	req = rc->rc_req;
1530 	req->rm_type = REMOTE_NDIS_SET_MSG;
1531 	req->rm_len = sizeof(*req) + length;
1532 	req->rm_rid = rc->rc_id;
1533 	req->rm_oid = oid;
1534 	req->rm_infobufoffset = sizeof(*req) - RNDIS_HEADER_OFFSET;
1535 
1536 	rc->rc_cmplen = sizeof(*cmp);
1537 
1538 	if (length > 0) {
1539 		KASSERT(sizeof(*req) + length < PAGE_SIZE);
1540 		req->rm_infobuflen = length;
1541 		memcpy((caddr_t)(req + 1), data, length);
1542 	}
1543 
1544 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1545 	    BUS_DMASYNC_PREWRITE);
1546 
1547 	if ((rv = hvn_rndis_cmd(sc, rc, 500)) != 0) {
1548 		DPRINTF("%s: SET_MSG failed, error %u\n",
1549 		    sc->sc_dev.dv_xname, rv);
1550 		hvn_free_cmd(sc, rc);
1551 		return (rv);
1552 	}
1553 
1554 	cmp = (struct rndis_set_comp *)&rc->rc_cmp;
1555 	if (cmp->rm_status != RNDIS_STATUS_SUCCESS)
1556 		rv = EIO;
1557 
1558 	hvn_free_cmd(sc, rc);
1559 
1560 	return (rv);
1561 }
1562 
1563 int
1564 hvn_rndis_open(struct hvn_softc *sc)
1565 {
1566 	uint32_t filter;
1567 	int rv;
1568 
1569 	if (sc->sc_promisc)
1570 		filter = NDIS_PACKET_TYPE_PROMISCUOUS;
1571 	else
1572 		filter = NDIS_PACKET_TYPE_BROADCAST |
1573 		    NDIS_PACKET_TYPE_ALL_MULTICAST |
1574 		    NDIS_PACKET_TYPE_DIRECTED;
1575 
1576 	rv = hvn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
1577 	    &filter, sizeof(filter));
1578 	if (rv)
1579 		DPRINTF("%s: failed to set RNDIS filter to %#x\n",
1580 		    sc->sc_dev.dv_xname, filter);
1581 	return (rv);
1582 }
1583 
1584 int
1585 hvn_rndis_close(struct hvn_softc *sc)
1586 {
1587 	uint32_t filter = 0;
1588 	int rv;
1589 
1590 	rv = hvn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
1591 	    &filter, sizeof(filter));
1592 	if (rv)
1593 		DPRINTF("%s: failed to clear RNDIS filter\n",
1594 		    sc->sc_dev.dv_xname);
1595 	return (rv);
1596 }
1597 
1598 void
1599 hvn_rndis_detach(struct hvn_softc *sc)
1600 {
1601 	struct rndis_cmd *rc;
1602 	struct rndis_halt_req *req;
1603 	int rv;
1604 
1605 	rc = hvn_alloc_cmd(sc);
1606 
1607 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1608 	    BUS_DMASYNC_PREREAD);
1609 
1610 	rc->rc_id = atomic_inc_int_nv(&sc->sc_rndisrid);
1611 
1612 	req = rc->rc_req;
1613 	req->rm_type = REMOTE_NDIS_HALT_MSG;
1614 	req->rm_len = sizeof(*req);
1615 	req->rm_rid = rc->rc_id;
1616 
1617 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
1618 	    BUS_DMASYNC_PREWRITE);
1619 
1620 	if ((rv = hvn_rndis_cmd(sc, rc, 500)) != 0)
1621 		DPRINTF("%s: HALT_MSG failed, error %u\n",
1622 		    sc->sc_dev.dv_xname, rv);
1623 
1624 	hvn_free_cmd(sc, rc);
1625 }
1626