hn_nvs.c revision 307167
1/*-
2 * Copyright (c) 2009-2012,2016 Microsoft Corp.
3 * Copyright (c) 2010-2012 Citrix Inc.
4 * Copyright (c) 2012 NetApp Inc.
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 unmodified, this list of conditions, and the following
12 *    disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c 307167 2016-10-13 02:38:46Z sephe $
29 */
30
31/**
32 * HyperV vmbus network VSC (virtual services client) module
33 *
34 */
35
36
37#include <sys/param.h>
38#include <sys/kernel.h>
39#include <sys/socket.h>
40#include <sys/lock.h>
41#include <net/if.h>
42#include <net/if_arp.h>
43#include <machine/bus.h>
44#include <machine/atomic.h>
45
46#include <dev/hyperv/include/hyperv.h>
47#include <dev/hyperv/include/vmbus_xact.h>
48#include <dev/hyperv/netvsc/hv_net_vsc.h>
49#include <dev/hyperv/netvsc/hv_rndis.h>
50#include <dev/hyperv/netvsc/hv_rndis_filter.h>
51#include <dev/hyperv/netvsc/if_hnreg.h>
52
53MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
54
55/*
56 * Forward declarations
57 */
58static void hv_nv_on_channel_callback(struct vmbus_channel *chan,
59    void *xrxr);
60static int  hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc);
61static int  hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *);
62static int  hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
63static int  hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
64static int  hv_nv_connect_to_vsp(struct hn_softc *sc);
65static void hv_nv_on_send_completion(netvsc_dev *net_dev,
66    struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt);
67static void hv_nv_on_receive_completion(struct vmbus_channel *chan,
68    uint64_t tid, uint32_t status);
69static void hv_nv_on_receive(netvsc_dev *net_dev,
70    struct hn_rx_ring *rxr, struct vmbus_channel *chan,
71    const struct vmbus_chanpkt_hdr *pkt);
72static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
73    struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
74    const void *, int);
75
76static struct hn_send_ctx	hn_send_ctx_none =
77    HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
78
79/*
80 *
81 */
82static inline netvsc_dev *
83hv_nv_alloc_net_device(struct hn_softc *sc)
84{
85	netvsc_dev *net_dev;
86
87	net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
88
89	net_dev->sc = sc;
90	net_dev->destroy = FALSE;
91	sc->net_dev = net_dev;
92
93	return (net_dev);
94}
95
96/*
97 * XXX unnecessary; nuke it.
98 */
99static inline netvsc_dev *
100hv_nv_get_outbound_net_device(struct hn_softc *sc)
101{
102	return sc->net_dev;
103}
104
105/*
106 * XXX unnecessary; nuke it.
107 */
108static inline netvsc_dev *
109hv_nv_get_inbound_net_device(struct hn_softc *sc)
110{
111	return sc->net_dev;
112}
113
114int
115hv_nv_get_next_send_section(netvsc_dev *net_dev)
116{
117	unsigned long bitsmap_words = net_dev->bitsmap_words;
118	unsigned long *bitsmap = net_dev->send_section_bitsmap;
119	unsigned long idx;
120	int ret = HN_NVS_CHIM_IDX_INVALID;
121	int i;
122
123	for (i = 0; i < bitsmap_words; i++) {
124		idx = ffsl(~bitsmap[i]);
125		if (0 == idx)
126			continue;
127
128		idx--;
129		KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count,
130		    ("invalid i %d and idx %lu", i, idx));
131
132		if (atomic_testandset_long(&bitsmap[i], idx))
133			continue;
134
135		ret = i * BITS_PER_LONG + idx;
136		break;
137	}
138
139	return (ret);
140}
141
142/*
143 * Net VSC initialize receive buffer with net VSP
144 *
145 * Net VSP:  Network virtual services client, also known as the
146 *     Hyper-V extensible switch and the synthetic data path.
147 */
148static int
149hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
150{
151	struct vmbus_xact *xact;
152	struct hn_nvs_rxbuf_conn *conn;
153	const struct hn_nvs_rxbuf_connresp *resp;
154	size_t resp_len;
155	struct hn_send_ctx sndc;
156	netvsc_dev *net_dev;
157	uint32_t status;
158	int error;
159
160	net_dev = hv_nv_get_outbound_net_device(sc);
161	if (!net_dev) {
162		return (ENODEV);
163	}
164
165	net_dev->rx_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
166	    PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma,
167	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
168	if (net_dev->rx_buf == NULL) {
169		device_printf(sc->hn_dev, "allocate rxbuf failed\n");
170		return (ENOMEM);
171	}
172
173	/*
174	 * Connect the RXBUF GPADL to the primary channel.
175	 *
176	 * NOTE:
177	 * Only primary channel has RXBUF connected to it.  Sub-channels
178	 * just share this RXBUF.
179	 */
180	error = vmbus_chan_gpadl_connect(sc->hn_prichan,
181	    net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size,
182	    &net_dev->rx_buf_gpadl_handle);
183	if (error) {
184		if_printf(sc->hn_ifp, "rxbuf gpadl connect failed: %d\n",
185		    error);
186		goto cleanup;
187	}
188
189	/*
190	 * Connect RXBUF to NVS.
191	 */
192
193	xact = vmbus_xact_get(sc->hn_xact, sizeof(*conn));
194	if (xact == NULL) {
195		if_printf(sc->hn_ifp, "no xact for nvs rxbuf conn\n");
196		error = ENXIO;
197		goto cleanup;
198	}
199
200	conn = vmbus_xact_req_data(xact);
201	conn->nvs_type = HN_NVS_TYPE_RXBUF_CONN;
202	conn->nvs_gpadl = net_dev->rx_buf_gpadl_handle;
203	conn->nvs_sig = HN_NVS_RXBUF_SIG;
204
205	hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
206	vmbus_xact_activate(xact);
207
208	error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
209	    conn, sizeof(*conn), &sndc);
210	if (error != 0) {
211		if_printf(sc->hn_ifp, "send nvs rxbuf conn failed: %d\n",
212		    error);
213		vmbus_xact_deactivate(xact);
214		vmbus_xact_put(xact);
215		goto cleanup;
216	}
217
218	resp = vmbus_xact_wait(xact, &resp_len);
219	if (resp_len < sizeof(*resp)) {
220		if_printf(sc->hn_ifp, "invalid rxbuf conn resp length %zu\n",
221		    resp_len);
222		vmbus_xact_put(xact);
223		error = EINVAL;
224		goto cleanup;
225	}
226	if (resp->nvs_type != HN_NVS_TYPE_RXBUF_CONNRESP) {
227		if_printf(sc->hn_ifp, "not rxbuf conn resp, type %u\n",
228		    resp->nvs_type);
229		vmbus_xact_put(xact);
230		error = EINVAL;
231		goto cleanup;
232	}
233
234	status = resp->nvs_status;
235	vmbus_xact_put(xact);
236
237	if (status != HN_NVS_STATUS_OK) {
238		if_printf(sc->hn_ifp, "rxbuf conn failed: %x\n", status);
239		error = EIO;
240		goto cleanup;
241	}
242	net_dev->rx_section_count = 1;
243
244	return (0);
245
246cleanup:
247	hv_nv_destroy_rx_buffer(net_dev);
248	return (error);
249}
250
251/*
252 * Net VSC initialize send buffer with net VSP
253 */
254static int
255hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
256{
257	struct hn_send_ctx sndc;
258	struct vmbus_xact *xact;
259	struct hn_nvs_chim_conn *chim;
260	const struct hn_nvs_chim_connresp *resp;
261	size_t resp_len;
262	uint32_t status, sectsz;
263	netvsc_dev *net_dev;
264	int error;
265
266	net_dev = hv_nv_get_outbound_net_device(sc);
267	if (!net_dev) {
268		return (ENODEV);
269	}
270
271	net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
272	    PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma,
273	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
274	if (net_dev->send_buf == NULL) {
275		device_printf(sc->hn_dev, "allocate chimney txbuf failed\n");
276		return (ENOMEM);
277	}
278
279	/*
280	 * Connect chimney sending buffer GPADL to the primary channel.
281	 *
282	 * NOTE:
283	 * Only primary channel has chimney sending buffer connected to it.
284	 * Sub-channels just share this chimney sending buffer.
285	 */
286	error = vmbus_chan_gpadl_connect(sc->hn_prichan,
287  	    net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size,
288	    &net_dev->send_buf_gpadl_handle);
289	if (error) {
290		if_printf(sc->hn_ifp, "chimney sending buffer gpadl "
291		    "connect failed: %d\n", error);
292		goto cleanup;
293	}
294
295	/*
296	 * Connect chimney sending buffer to NVS
297	 */
298
299	xact = vmbus_xact_get(sc->hn_xact, sizeof(*chim));
300	if (xact == NULL) {
301		if_printf(sc->hn_ifp, "no xact for nvs chim conn\n");
302		error = ENXIO;
303		goto cleanup;
304	}
305
306	chim = vmbus_xact_req_data(xact);
307	chim->nvs_type = HN_NVS_TYPE_CHIM_CONN;
308	chim->nvs_gpadl = net_dev->send_buf_gpadl_handle;
309	chim->nvs_sig = HN_NVS_CHIM_SIG;
310
311	hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
312	vmbus_xact_activate(xact);
313
314	error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
315  	    chim, sizeof(*chim), &sndc);
316	if (error) {
317		if_printf(sc->hn_ifp, "send nvs chim conn failed: %d\n",
318		    error);
319		vmbus_xact_deactivate(xact);
320		vmbus_xact_put(xact);
321		goto cleanup;
322	}
323
324	resp = vmbus_xact_wait(xact, &resp_len);
325	if (resp_len < sizeof(*resp)) {
326		if_printf(sc->hn_ifp, "invalid chim conn resp length %zu\n",
327		    resp_len);
328		vmbus_xact_put(xact);
329		error = EINVAL;
330		goto cleanup;
331	}
332	if (resp->nvs_type != HN_NVS_TYPE_CHIM_CONNRESP) {
333		if_printf(sc->hn_ifp, "not chim conn resp, type %u\n",
334		    resp->nvs_type);
335		vmbus_xact_put(xact);
336		error = EINVAL;
337		goto cleanup;
338	}
339
340	status = resp->nvs_status;
341	sectsz = resp->nvs_sectsz;
342	vmbus_xact_put(xact);
343
344	if (status != HN_NVS_STATUS_OK) {
345		if_printf(sc->hn_ifp, "chim conn failed: %x\n", status);
346		error = EIO;
347		goto cleanup;
348	}
349	if (sectsz == 0) {
350		if_printf(sc->hn_ifp, "zero chimney sending buffer "
351		    "section size\n");
352		return 0;
353	}
354
355	net_dev->send_section_size = sectsz;
356	net_dev->send_section_count =
357	    net_dev->send_buf_size / net_dev->send_section_size;
358	net_dev->bitsmap_words = howmany(net_dev->send_section_count,
359	    BITS_PER_LONG);
360	net_dev->send_section_bitsmap =
361	    malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
362	    M_WAITOK | M_ZERO);
363
364	if (bootverbose) {
365		if_printf(sc->hn_ifp, "chimney sending buffer %u/%u\n",
366		    net_dev->send_section_size, net_dev->send_section_count);
367	}
368	return 0;
369
370cleanup:
371	hv_nv_destroy_send_buffer(net_dev);
372	return (error);
373}
374
375/*
376 * Net VSC destroy receive buffer
377 */
378static int
379hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
380{
381	int ret = 0;
382
383	if (net_dev->rx_section_count) {
384		struct hn_nvs_rxbuf_disconn disconn;
385
386		/*
387		 * Disconnect RXBUF from NVS.
388		 */
389		memset(&disconn, 0, sizeof(disconn));
390		disconn.nvs_type = HN_NVS_TYPE_RXBUF_DISCONN;
391		disconn.nvs_sig = HN_NVS_RXBUF_SIG;
392
393		/* NOTE: No response. */
394		ret = hn_nvs_send(net_dev->sc->hn_prichan,
395		    VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn),
396		    &hn_send_ctx_none);
397		if (ret != 0) {
398			if_printf(net_dev->sc->hn_ifp,
399			    "send rxbuf disconn failed: %d\n", ret);
400			return (ret);
401		}
402		net_dev->rx_section_count = 0;
403	}
404
405	/* Tear down the gpadl on the vsp end */
406	if (net_dev->rx_buf_gpadl_handle) {
407		ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
408		    net_dev->rx_buf_gpadl_handle);
409		/*
410		 * If we failed here, we might as well return and have a leak
411		 * rather than continue and a bugchk
412		 */
413		if (ret != 0) {
414			return (ret);
415		}
416		net_dev->rx_buf_gpadl_handle = 0;
417	}
418
419	if (net_dev->rx_buf) {
420		/* Free up the receive buffer */
421		hyperv_dmamem_free(&net_dev->rxbuf_dma, net_dev->rx_buf);
422		net_dev->rx_buf = NULL;
423	}
424
425	return (ret);
426}
427
428/*
429 * Net VSC destroy send buffer
430 */
431static int
432hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
433{
434	int ret = 0;
435
436	if (net_dev->send_section_size) {
437		struct hn_nvs_chim_disconn disconn;
438
439		/*
440		 * Disconnect chimney sending buffer from NVS.
441		 */
442		memset(&disconn, 0, sizeof(disconn));
443		disconn.nvs_type = HN_NVS_TYPE_CHIM_DISCONN;
444		disconn.nvs_sig = HN_NVS_CHIM_SIG;
445
446		/* NOTE: No response. */
447		ret = hn_nvs_send(net_dev->sc->hn_prichan,
448		    VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn),
449		    &hn_send_ctx_none);
450		if (ret != 0) {
451			if_printf(net_dev->sc->hn_ifp,
452			    "send chim disconn failed: %d\n", ret);
453			return (ret);
454		}
455	}
456
457	/* Tear down the gpadl on the vsp end */
458	if (net_dev->send_buf_gpadl_handle) {
459		ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
460		    net_dev->send_buf_gpadl_handle);
461
462		/*
463		 * If we failed here, we might as well return and have a leak
464		 * rather than continue and a bugchk
465		 */
466		if (ret != 0) {
467			return (ret);
468		}
469		net_dev->send_buf_gpadl_handle = 0;
470	}
471
472	if (net_dev->send_buf) {
473		/* Free up the receive buffer */
474		hyperv_dmamem_free(&net_dev->txbuf_dma, net_dev->send_buf);
475		net_dev->send_buf = NULL;
476	}
477
478	if (net_dev->send_section_bitsmap) {
479		free(net_dev->send_section_bitsmap, M_NETVSC);
480	}
481
482	return (ret);
483}
484
485static int
486hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
487    uint32_t nvs_ver)
488{
489	struct hn_send_ctx sndc;
490	struct vmbus_xact *xact;
491	struct hn_nvs_init *init;
492	const struct hn_nvs_init_resp *resp;
493	size_t resp_len;
494	uint32_t status;
495	int error;
496
497	xact = vmbus_xact_get(sc->hn_xact, sizeof(*init));
498	if (xact == NULL) {
499		if_printf(sc->hn_ifp, "no xact for nvs init\n");
500		return (ENXIO);
501	}
502
503	init = vmbus_xact_req_data(xact);
504	init->nvs_type = HN_NVS_TYPE_INIT;
505	init->nvs_ver_min = nvs_ver;
506	init->nvs_ver_max = nvs_ver;
507
508	vmbus_xact_activate(xact);
509	hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
510
511	error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
512	    init, sizeof(*init), &sndc);
513	if (error) {
514		if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error);
515		vmbus_xact_deactivate(xact);
516		vmbus_xact_put(xact);
517		return (error);
518	}
519
520	resp = vmbus_xact_wait(xact, &resp_len);
521	if (resp_len < sizeof(*resp)) {
522		if_printf(sc->hn_ifp, "invalid init resp length %zu\n",
523		    resp_len);
524		vmbus_xact_put(xact);
525		return (EINVAL);
526	}
527	if (resp->nvs_type != HN_NVS_TYPE_INIT_RESP) {
528		if_printf(sc->hn_ifp, "not init resp, type %u\n",
529		    resp->nvs_type);
530		vmbus_xact_put(xact);
531		return (EINVAL);
532	}
533
534	status = resp->nvs_status;
535	vmbus_xact_put(xact);
536
537	if (status != HN_NVS_STATUS_OK) {
538		if_printf(sc->hn_ifp, "nvs init failed for ver 0x%x\n",
539		    nvs_ver);
540		return (EINVAL);
541	}
542	return (0);
543}
544
545/*
546 * Send NDIS version 2 config packet containing MTU.
547 *
548 * Not valid for NDIS version 1.
549 */
550static int
551hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
552{
553	struct hn_nvs_ndis_conf conf;
554	int error;
555
556	memset(&conf, 0, sizeof(conf));
557	conf.nvs_type = HN_NVS_TYPE_NDIS_CONF;
558	conf.nvs_mtu = mtu;
559	conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN;
560
561	/* NOTE: No response. */
562	error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE,
563	    &conf, sizeof(conf), &hn_send_ctx_none);
564	if (error)
565		if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error);
566	return (error);
567}
568
569/*
570 * Net VSC connect to VSP
571 */
572static int
573hv_nv_connect_to_vsp(struct hn_softc *sc)
574{
575	netvsc_dev *net_dev;
576	uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
577	    NVSP_PROTOCOL_VERSION_2,
578	    NVSP_PROTOCOL_VERSION_4,
579	    NVSP_PROTOCOL_VERSION_5 };
580	int i;
581	int protocol_number = nitems(protocol_list);
582	int ret = 0;
583	device_t dev = sc->hn_dev;
584	struct ifnet *ifp = sc->arpcom.ac_ifp;
585	struct hn_nvs_ndis_init ndis;
586
587	net_dev = hv_nv_get_outbound_net_device(sc);
588
589	/*
590	 * Negotiate the NVSP version.  Try the latest NVSP first.
591	 */
592	for (i = protocol_number - 1; i >= 0; i--) {
593		if (hv_nv_negotiate_nvsp_protocol(sc, net_dev,
594		    protocol_list[i]) == 0) {
595			net_dev->nvsp_version = protocol_list[i];
596			if (bootverbose)
597				device_printf(dev, "Netvsc: got version 0x%x\n",
598				    net_dev->nvsp_version);
599			break;
600		}
601	}
602
603	if (i < 0) {
604		if (bootverbose)
605			device_printf(dev, "failed to negotiate a valid "
606			    "protocol.\n");
607		return (EPROTO);
608	}
609
610	/*
611	 * Set the MTU if supported by this NVSP protocol version
612	 * This needs to be right after the NVSP init message per Haiyang
613	 */
614	if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
615		ret = hv_nv_send_ndis_config(sc, ifp->if_mtu);
616
617	/*
618	 * Initialize NDIS.
619	 */
620
621	memset(&ndis, 0, sizeof(ndis));
622	ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT;
623	ndis.nvs_ndis_major = NDIS_VERSION_MAJOR_6;
624	if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4)
625		ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_1;
626	else
627		ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30;
628
629	/* NOTE: No response. */
630	ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE,
631	    &ndis, sizeof(ndis), &hn_send_ctx_none);
632	if (ret != 0) {
633		if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret);
634		goto cleanup;
635	}
636
637	/* Post the big receive buffer to NetVSP */
638	if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
639		net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
640	else
641		net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
642	net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
643
644	ret = hv_nv_init_rx_buffer_with_net_vsp(sc);
645	if (ret == 0)
646		ret = hv_nv_init_send_buffer_with_net_vsp(sc);
647
648cleanup:
649	return (ret);
650}
651
652/*
653 * Net VSC disconnect from VSP
654 */
655static void
656hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
657{
658	hv_nv_destroy_rx_buffer(net_dev);
659	hv_nv_destroy_send_buffer(net_dev);
660}
661
662void
663hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr)
664{
665	KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan),
666	    ("chan%u subidx %u, rxr%d mismatch",
667	     vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx));
668	vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
669	    NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0,
670	    hv_nv_on_channel_callback, rxr);
671}
672
673/*
674 * Net VSC on device add
675 *
676 * Callback when the device belonging to this driver is added
677 */
678netvsc_dev *
679hv_nv_on_device_add(struct hn_softc *sc, void *additional_info,
680    struct hn_rx_ring *rxr)
681{
682	struct vmbus_channel *chan = sc->hn_prichan;
683	netvsc_dev *net_dev;
684	int ret = 0;
685
686	net_dev = hv_nv_alloc_net_device(sc);
687	if (net_dev == NULL)
688		return NULL;
689
690	/* Initialize the NetVSC channel extension */
691
692	/*
693	 * Open the channel
694	 */
695	KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan),
696	    ("chan%u subidx %u, rxr%d mismatch",
697	     vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx));
698	ret = vmbus_chan_open(chan,
699	    NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
700	    NULL, 0, hv_nv_on_channel_callback, rxr);
701	if (ret != 0)
702		goto cleanup;
703
704	/*
705	 * Connect with the NetVsp
706	 */
707	ret = hv_nv_connect_to_vsp(sc);
708	if (ret != 0)
709		goto close;
710
711	return (net_dev);
712
713close:
714	/* Now, we can close the channel safely */
715	vmbus_chan_close(chan);
716
717cleanup:
718	/*
719	 * Free the packet buffers on the netvsc device packet queue.
720	 * Release other resources.
721	 */
722	free(net_dev, M_NETVSC);
723
724	return (NULL);
725}
726
727/*
728 * Net VSC on device remove
729 */
730int
731hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
732{
733	netvsc_dev *net_dev = sc->net_dev;;
734
735	/* Stop outbound traffic ie sends and receives completions */
736	net_dev->destroy = TRUE;
737
738	hv_nv_disconnect_from_vsp(net_dev);
739
740	/* At this point, no one should be accessing net_dev except in here */
741
742	/* Now, we can close the channel safely */
743
744	vmbus_chan_close(sc->hn_prichan);
745
746	free(net_dev, M_NETVSC);
747
748	return (0);
749}
750
751void
752hn_nvs_sent_xact(struct hn_send_ctx *sndc,
753    struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
754    const void *data, int dlen)
755{
756
757	vmbus_xact_wakeup(sndc->hn_cbarg, data, dlen);
758}
759
760static void
761hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
762    struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
763    const void *data __unused, int dlen __unused)
764{
765	/* EMPTY */
766}
767
768void
769hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx)
770{
771	u_long mask;
772	uint32_t idx;
773
774	idx = chim_idx / BITS_PER_LONG;
775	KASSERT(idx < net_dev->bitsmap_words,
776	    ("invalid chimney index 0x%x", chim_idx));
777
778	mask = 1UL << (chim_idx % BITS_PER_LONG);
779	KASSERT(net_dev->send_section_bitsmap[idx] & mask,
780	    ("index bitmap 0x%lx, chimney index %u, "
781	     "bitmap idx %d, bitmask 0x%lx",
782	     net_dev->send_section_bitsmap[idx], chim_idx, idx, mask));
783
784	atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask);
785}
786
787/*
788 * Net VSC on send completion
789 */
790static void
791hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
792    const struct vmbus_chanpkt_hdr *pkt)
793{
794	struct hn_send_ctx *sndc;
795
796	sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
797	sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt),
798	    VMBUS_CHANPKT_DATALEN(pkt));
799	/*
800	 * NOTE:
801	 * 'sndc' CAN NOT be accessed anymore, since it can be freed by
802	 * its callback.
803	 */
804}
805
806/*
807 * Net VSC on send
808 * Sends a packet on the specified Hyper-V device.
809 * Returns 0 on success, non-zero on failure.
810 */
811int
812hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
813    struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
814{
815	struct hn_nvs_rndis rndis;
816	int ret;
817
818	rndis.nvs_type = HN_NVS_TYPE_RNDIS;
819	rndis.nvs_rndis_mtype = rndis_mtype;
820	rndis.nvs_chim_idx = sndc->hn_chim_idx;
821	rndis.nvs_chim_sz = sndc->hn_chim_sz;
822
823	if (gpa_cnt) {
824		ret = hn_nvs_send_sglist(chan, gpa, gpa_cnt,
825		    &rndis, sizeof(rndis), sndc);
826	} else {
827		ret = hn_nvs_send(chan, VMBUS_CHANPKT_FLAG_RC,
828		    &rndis, sizeof(rndis), sndc);
829	}
830
831	return (ret);
832}
833
834/*
835 * Net VSC on receive
836 *
837 * In the FreeBSD Hyper-V virtual world, this function deals exclusively
838 * with virtual addresses.
839 */
840static void
841hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
842    struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
843{
844	const struct vmbus_chanpkt_rxbuf *pkt;
845	const struct hn_nvs_hdr *nvs_hdr;
846	netvsc_packet vsc_pkt;
847	netvsc_packet *net_vsc_pkt = &vsc_pkt;
848	int count = 0;
849	int i = 0;
850	int status = HN_NVS_STATUS_OK;
851
852	/* Make sure that this is a RNDIS message. */
853	nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr);
854	if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) {
855		if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n",
856		    nvs_hdr->nvs_type);
857		return;
858	}
859
860	pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
861
862	if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
863		if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n",
864		    pkt->cp_rxbuf_id);
865		return;
866	}
867
868	count = pkt->cp_rxbuf_cnt;
869
870	/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
871	for (i = 0; i < count; i++) {
872		net_vsc_pkt->status = HN_NVS_STATUS_OK;
873		net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
874		    pkt->cp_rxbuf[i].rb_ofs);
875		net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
876
877		hv_rf_on_receive(net_dev, rxr, net_vsc_pkt);
878
879		/* XXX pretty broken; whack it */
880		if (net_vsc_pkt->status != HN_NVS_STATUS_OK)
881			status = HN_NVS_STATUS_FAILED;
882	}
883
884	/*
885	 * Moved completion call back here so that all received
886	 * messages (not just data messages) will trigger a response
887	 * message back to the host.
888	 */
889	hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
890}
891
892/*
893 * Net VSC on receive completion
894 *
895 * Send a receive completion packet to RNDIS device (ie NetVsp)
896 */
897static void
898hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid,
899    uint32_t status)
900{
901	struct hn_nvs_rndis_ack ack;
902	int retries = 0;
903	int ret = 0;
904
905	ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK;
906	ack.nvs_status = status;
907
908retry_send_cmplt:
909	/* Send the completion */
910	ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP,
911	    VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid);
912	if (ret == 0) {
913		/* success */
914		/* no-op */
915	} else if (ret == EAGAIN) {
916		/* no more room... wait a bit and attempt to retry 3 times */
917		retries++;
918
919		if (retries < 4) {
920			DELAY(100);
921			goto retry_send_cmplt;
922		}
923	}
924}
925
926static void
927hn_proc_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
928{
929	const struct hn_nvs_hdr *hdr;
930
931	hdr = VMBUS_CHANPKT_CONST_DATA(pkt);
932	if (hdr->nvs_type == HN_NVS_TYPE_TXTBL_NOTE) {
933		/* Useless; ignore */
934		return;
935	}
936	if_printf(sc->hn_ifp, "got notify, nvs type %u\n", hdr->nvs_type);
937}
938
939/*
940 * Net VSC on channel callback
941 */
942static void
943hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr)
944{
945	struct hn_rx_ring *rxr = xrxr;
946	struct hn_softc *sc = rxr->hn_ifp->if_softc;
947	netvsc_dev *net_dev;
948	void *buffer;
949	int bufferlen = NETVSC_PACKET_SIZE;
950
951	net_dev = hv_nv_get_inbound_net_device(sc);
952	if (net_dev == NULL)
953		return;
954
955	buffer = rxr->hn_rdbuf;
956	do {
957		struct vmbus_chanpkt_hdr *pkt = buffer;
958		uint32_t bytes_rxed;
959		int ret;
960
961		bytes_rxed = bufferlen;
962		ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
963		if (ret == 0) {
964			if (bytes_rxed > 0) {
965				switch (pkt->cph_type) {
966				case VMBUS_CHANPKT_TYPE_COMP:
967					hv_nv_on_send_completion(net_dev, chan,
968					    pkt);
969					break;
970				case VMBUS_CHANPKT_TYPE_RXBUF:
971					hv_nv_on_receive(net_dev, rxr, chan, pkt);
972					break;
973				case VMBUS_CHANPKT_TYPE_INBAND:
974					hn_proc_notify(sc, pkt);
975					break;
976				default:
977					if_printf(rxr->hn_ifp,
978					    "unknown chan pkt %u\n",
979					    pkt->cph_type);
980					break;
981				}
982			}
983		} else if (ret == ENOBUFS) {
984			/* Handle large packet */
985			if (bufferlen > NETVSC_PACKET_SIZE) {
986				free(buffer, M_NETVSC);
987				buffer = NULL;
988			}
989
990			/* alloc new buffer */
991			buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
992			if (buffer == NULL) {
993				if_printf(rxr->hn_ifp,
994				    "hv_cb malloc buffer failed, len=%u\n",
995				    bytes_rxed);
996				bufferlen = 0;
997				break;
998			}
999			bufferlen = bytes_rxed;
1000		} else {
1001			/* No more packets */
1002			break;
1003		}
1004	} while (1);
1005
1006	if (bufferlen > NETVSC_PACKET_SIZE)
1007		free(buffer, M_NETVSC);
1008
1009	hv_rf_channel_rollup(rxr, rxr->hn_txr);
1010}
1011