]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/hyperv/netvsc/hv_net_vsc.c
MFC 304327,304329,304330
[FreeBSD/stable/10.git] / sys / dev / hyperv / netvsc / hv_net_vsc.c
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$
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
53 MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
54
55 /*
56  * Forward declarations
57  */
58 static void hv_nv_on_channel_callback(struct vmbus_channel *chan,
59     void *xrxr);
60 static int  hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc);
61 static int  hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *);
62 static int  hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
63 static int  hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
64 static int  hv_nv_connect_to_vsp(struct hn_softc *sc);
65 static void hv_nv_on_send_completion(netvsc_dev *net_dev,
66     struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt);
67 static void hv_nv_on_receive_completion(struct vmbus_channel *chan,
68     uint64_t tid);
69 static 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);
72 static 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
76 static struct hn_send_ctx       hn_send_ctx_none =
77     HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
78
79 /*
80  *
81  */
82 static inline netvsc_dev *
83 hv_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  */
99 static inline netvsc_dev *
100 hv_nv_get_outbound_net_device(struct hn_softc *sc)
101 {
102         return sc->net_dev;
103 }
104
105 /*
106  * XXX unnecessary; nuke it.
107  */
108 static inline netvsc_dev *
109 hv_nv_get_inbound_net_device(struct hn_softc *sc)
110 {
111         return sc->net_dev;
112 }
113
114 int
115 hv_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  */
148 static int 
149 hv_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
246 cleanup:
247         hv_nv_destroy_rx_buffer(net_dev);
248         return (error);
249 }
250
251 /*
252  * Net VSC initialize send buffer with net VSP
253  */
254 static int 
255 hv_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
370 cleanup:
371         hv_nv_destroy_send_buffer(net_dev);
372         return (error);
373 }
374
375 /*
376  * Net VSC destroy receive buffer
377  */
378 static int
379 hv_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  */
431 static int
432 hv_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
485 static int
486 hv_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  */
550 static int
551 hv_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  */
572 static int
573 hv_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
648 cleanup:
649         return (ret);
650 }
651
652 /*
653  * Net VSC disconnect from VSP
654  */
655 static void
656 hv_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
662 void
663 hv_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  */
678 netvsc_dev *
679 hv_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
713 close:
714         /* Now, we can close the channel safely */
715         vmbus_chan_close(chan);
716
717 cleanup:
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  */
730 int
731 hv_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
751 void
752 hn_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
760 static void
761 hn_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
768 void
769 hn_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  */
790 static void
791 hv_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  */
811 int
812 hv_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  */
840 static void
841 hv_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         int count = 0;
847         int i = 0;
848
849         /* Make sure that this is a RNDIS message. */
850         nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr);
851         if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) {
852                 if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n",
853                     nvs_hdr->nvs_type);
854                 return;
855         }
856         
857         pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
858
859         if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
860                 if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n",
861                     pkt->cp_rxbuf_id);
862                 return;
863         }
864
865         count = pkt->cp_rxbuf_cnt;
866
867         /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
868         for (i = 0; i < count; i++) {
869                 hv_rf_on_receive(net_dev, rxr,
870                     (const uint8_t *)net_dev->rx_buf + pkt->cp_rxbuf[i].rb_ofs,
871                     pkt->cp_rxbuf[i].rb_len);
872         }
873         
874         /*
875          * Moved completion call back here so that all received 
876          * messages (not just data messages) will trigger a response
877          * message back to the host.
878          */
879         hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid);
880 }
881
882 /*
883  * Net VSC on receive completion
884  *
885  * Send a receive completion packet to RNDIS device (ie NetVsp)
886  */
887 static void
888 hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid)
889 {
890         struct hn_nvs_rndis_ack ack;
891         int retries = 0;
892         int ret = 0;
893         
894         ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK;
895         ack.nvs_status = HN_NVS_STATUS_OK;
896
897 retry_send_cmplt:
898         /* Send the completion */
899         ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP,
900             VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid);
901         if (ret == 0) {
902                 /* success */
903                 /* no-op */
904         } else if (ret == EAGAIN) {
905                 /* no more room... wait a bit and attempt to retry 3 times */
906                 retries++;
907
908                 if (retries < 4) {
909                         DELAY(100);
910                         goto retry_send_cmplt;
911                 }
912         }
913 }
914
915 static void
916 hn_proc_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
917 {
918         const struct hn_nvs_hdr *hdr;
919
920         hdr = VMBUS_CHANPKT_CONST_DATA(pkt);
921         if (hdr->nvs_type == HN_NVS_TYPE_TXTBL_NOTE) {
922                 /* Useless; ignore */
923                 return;
924         }
925         if_printf(sc->hn_ifp, "got notify, nvs type %u\n", hdr->nvs_type);
926 }
927
928 /*
929  * Net VSC on channel callback
930  */
931 static void
932 hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr)
933 {
934         struct hn_rx_ring *rxr = xrxr;
935         struct hn_softc *sc = rxr->hn_ifp->if_softc;
936         netvsc_dev *net_dev;
937         void *buffer;
938         int bufferlen = NETVSC_PACKET_SIZE;
939
940         net_dev = hv_nv_get_inbound_net_device(sc);
941         if (net_dev == NULL)
942                 return;
943
944         buffer = rxr->hn_rdbuf;
945         do {
946                 struct vmbus_chanpkt_hdr *pkt = buffer;
947                 uint32_t bytes_rxed;
948                 int ret;
949
950                 bytes_rxed = bufferlen;
951                 ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
952                 if (ret == 0) {
953                         if (bytes_rxed > 0) {
954                                 switch (pkt->cph_type) {
955                                 case VMBUS_CHANPKT_TYPE_COMP:
956                                         hv_nv_on_send_completion(net_dev, chan,
957                                             pkt);
958                                         break;
959                                 case VMBUS_CHANPKT_TYPE_RXBUF:
960                                         hv_nv_on_receive(net_dev, rxr, chan, pkt);
961                                         break;
962                                 case VMBUS_CHANPKT_TYPE_INBAND:
963                                         hn_proc_notify(sc, pkt);
964                                         break;
965                                 default:
966                                         if_printf(rxr->hn_ifp,
967                                             "unknown chan pkt %u\n",
968                                             pkt->cph_type);
969                                         break;
970                                 }
971                         }
972                 } else if (ret == ENOBUFS) {
973                         /* Handle large packet */
974                         if (bufferlen > NETVSC_PACKET_SIZE) {
975                                 free(buffer, M_NETVSC);
976                                 buffer = NULL;
977                         }
978
979                         /* alloc new buffer */
980                         buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
981                         if (buffer == NULL) {
982                                 if_printf(rxr->hn_ifp,
983                                     "hv_cb malloc buffer failed, len=%u\n",
984                                     bytes_rxed);
985                                 bufferlen = 0;
986                                 break;
987                         }
988                         bufferlen = bytes_rxed;
989                 } else {
990                         /* No more packets */
991                         break;
992                 }
993         } while (1);
994
995         if (bufferlen > NETVSC_PACKET_SIZE)
996                 free(buffer, M_NETVSC);
997
998         hv_rf_channel_rollup(rxr, rxr->hn_txr);
999 }