]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/hyperv/netvsc/hv_net_vsc.c
MFC 303867,303901
[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 "hv_net_vsc.h"
48 #include "hv_rndis.h"
49 #include "hv_rndis_filter.h"
50
51 MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
52
53 /*
54  * Forward declarations
55  */
56 static void hv_nv_on_channel_callback(struct vmbus_channel *chan,
57     void *xrxr);
58 static int  hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc);
59 static int  hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *);
60 static int  hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
61 static int  hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
62 static int  hv_nv_connect_to_vsp(struct hn_softc *sc);
63 static void hv_nv_on_send_completion(netvsc_dev *net_dev,
64     struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt);
65 static void hv_nv_on_receive_completion(struct vmbus_channel *chan,
66     uint64_t tid, uint32_t status);
67 static void hv_nv_on_receive(netvsc_dev *net_dev,
68     struct hn_rx_ring *rxr, struct vmbus_channel *chan,
69     const struct vmbus_chanpkt_hdr *pkt);
70 static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
71     struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
72     const struct nvsp_msg_ *msg);
73
74 static struct hn_send_ctx       hn_send_ctx_none =
75     HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
76
77 /*
78  *
79  */
80 static inline netvsc_dev *
81 hv_nv_alloc_net_device(struct hn_softc *sc)
82 {
83         netvsc_dev *net_dev;
84
85         net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
86
87         net_dev->sc = sc;
88         net_dev->destroy = FALSE;
89         sc->net_dev = net_dev;
90
91         return (net_dev);
92 }
93
94 /*
95  * XXX unnecessary; nuke it.
96  */
97 static inline netvsc_dev *
98 hv_nv_get_outbound_net_device(struct hn_softc *sc)
99 {
100         return sc->net_dev;
101 }
102
103 /*
104  * XXX unnecessary; nuke it.
105  */
106 static inline netvsc_dev *
107 hv_nv_get_inbound_net_device(struct hn_softc *sc)
108 {
109         return sc->net_dev;
110 }
111
112 int
113 hv_nv_get_next_send_section(netvsc_dev *net_dev)
114 {
115         unsigned long bitsmap_words = net_dev->bitsmap_words;
116         unsigned long *bitsmap = net_dev->send_section_bitsmap;
117         unsigned long idx;
118         int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
119         int i;
120
121         for (i = 0; i < bitsmap_words; i++) {
122                 idx = ffsl(~bitsmap[i]);
123                 if (0 == idx)
124                         continue;
125
126                 idx--;
127                 KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count,
128                     ("invalid i %d and idx %lu", i, idx));
129
130                 if (atomic_testandset_long(&bitsmap[i], idx))
131                         continue;
132
133                 ret = i * BITS_PER_LONG + idx;
134                 break;
135         }
136
137         return (ret);
138 }
139
140 /*
141  * Net VSC initialize receive buffer with net VSP
142  * 
143  * Net VSP:  Network virtual services client, also known as the
144  *     Hyper-V extensible switch and the synthetic data path.
145  */
146 static int 
147 hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
148 {
149         struct hn_send_ctx sndc;
150         netvsc_dev *net_dev;
151         nvsp_msg *init_pkt;
152         int ret = 0;
153
154         net_dev = hv_nv_get_outbound_net_device(sc);
155         if (!net_dev) {
156                 return (ENODEV);
157         }
158
159         net_dev->rx_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
160             PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma,
161             BUS_DMA_WAITOK | BUS_DMA_ZERO);
162         if (net_dev->rx_buf == NULL) {
163                 device_printf(sc->hn_dev, "allocate rxbuf failed\n");
164                 return ENOMEM;
165         }
166
167         /*
168          * Connect the RXBUF GPADL to the primary channel.
169          *
170          * NOTE:
171          * Only primary channel has RXBUF connected to it.  Sub-channels
172          * just share this RXBUF.
173          */
174         ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
175             net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size,
176             &net_dev->rx_buf_gpadl_handle);
177         if (ret != 0) {
178                 device_printf(sc->hn_dev, "rxbuf gpadl connect failed: %d\n",
179                     ret);
180                 goto cleanup;
181         }
182         
183         /* sema_wait(&ext->channel_init_sema); KYS CHECK */
184
185         /* Notify the NetVsp of the gpadl handle */
186         init_pkt = &net_dev->channel_init_packet;
187
188         memset(init_pkt, 0, sizeof(nvsp_msg));
189
190         init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
191         init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
192             net_dev->rx_buf_gpadl_handle;
193         init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
194             NETVSC_RECEIVE_BUFFER_ID;
195
196         /* Send the gpadl notification request */
197
198         hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
199         ret = vmbus_chan_send(sc->hn_prichan,
200             VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
201             init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
202         if (ret != 0) {
203                 goto cleanup;
204         }
205
206         sema_wait(&net_dev->channel_init_sema);
207
208         /* Check the response */
209         if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
210             != nvsp_status_success) {
211                 ret = EINVAL;
212                 goto cleanup;
213         }
214
215         net_dev->rx_section_count =
216             init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
217
218         net_dev->rx_sections = malloc(net_dev->rx_section_count *
219             sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
220         memcpy(net_dev->rx_sections, 
221             init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
222             net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));
223
224
225         /*
226          * For first release, there should only be 1 section that represents
227          * the entire receive buffer
228          */
229         if (net_dev->rx_section_count != 1
230             || net_dev->rx_sections->offset != 0) {
231                 ret = EINVAL;
232                 goto cleanup;
233         }
234
235         goto exit;
236
237 cleanup:
238         hv_nv_destroy_rx_buffer(net_dev);
239         
240 exit:
241         return (ret);
242 }
243
244 /*
245  * Net VSC initialize send buffer with net VSP
246  */
247 static int 
248 hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
249 {
250         struct hn_send_ctx sndc;
251         netvsc_dev *net_dev;
252         nvsp_msg *init_pkt;
253         int ret = 0;
254
255         net_dev = hv_nv_get_outbound_net_device(sc);
256         if (!net_dev) {
257                 return (ENODEV);
258         }
259
260         net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
261             PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma,
262             BUS_DMA_WAITOK | BUS_DMA_ZERO);
263         if (net_dev->send_buf == NULL) {
264                 device_printf(sc->hn_dev, "allocate chimney txbuf failed\n");
265                 return ENOMEM;
266         }
267
268         /*
269          * Connect chimney sending buffer GPADL to the primary channel.
270          *
271          * NOTE:
272          * Only primary channel has chimney sending buffer connected to it.
273          * Sub-channels just share this chimney sending buffer.
274          */
275         ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
276             net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size,
277             &net_dev->send_buf_gpadl_handle);
278         if (ret != 0) {
279                 device_printf(sc->hn_dev, "chimney sending buffer gpadl "
280                     "connect failed: %d\n", ret);
281                 goto cleanup;
282         }
283
284         /* Notify the NetVsp of the gpadl handle */
285
286         init_pkt = &net_dev->channel_init_packet;
287
288         memset(init_pkt, 0, sizeof(nvsp_msg));
289
290         init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
291         init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
292             net_dev->send_buf_gpadl_handle;
293         init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
294             NETVSC_SEND_BUFFER_ID;
295
296         /* Send the gpadl notification request */
297
298         hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
299         ret = vmbus_chan_send(sc->hn_prichan,
300             VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
301             init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
302         if (ret != 0) {
303                 goto cleanup;
304         }
305
306         sema_wait(&net_dev->channel_init_sema);
307
308         /* Check the response */
309         if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
310             != nvsp_status_success) {
311                 ret = EINVAL;
312                 goto cleanup;
313         }
314
315         net_dev->send_section_size =
316             init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
317         net_dev->send_section_count =
318             net_dev->send_buf_size / net_dev->send_section_size;
319         net_dev->bitsmap_words = howmany(net_dev->send_section_count,
320             BITS_PER_LONG);
321         net_dev->send_section_bitsmap =
322             malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
323             M_WAITOK | M_ZERO);
324
325         goto exit;
326
327 cleanup:
328         hv_nv_destroy_send_buffer(net_dev);
329         
330 exit:
331         return (ret);
332 }
333
334 /*
335  * Net VSC destroy receive buffer
336  */
337 static int
338 hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
339 {
340         nvsp_msg *revoke_pkt;
341         int ret = 0;
342
343         /*
344          * If we got a section count, it means we received a
345          * send_rx_buf_complete msg 
346          * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
347          * we need to send a revoke msg here
348          */
349         if (net_dev->rx_section_count) {
350                 /* Send the revoke receive buffer */
351                 revoke_pkt = &net_dev->revoke_packet;
352                 memset(revoke_pkt, 0, sizeof(nvsp_msg));
353
354                 revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf;
355                 revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
356                     NETVSC_RECEIVE_BUFFER_ID;
357
358                 ret = vmbus_chan_send(net_dev->sc->hn_prichan,
359                     VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
360                     (uint64_t)(uintptr_t)&hn_send_ctx_none);
361                 /*
362                  * If we failed here, we might as well return and have a leak 
363                  * rather than continue and a bugchk
364                  */
365                 if (ret != 0) {
366                         return (ret);
367                 }
368         }
369                 
370         /* Tear down the gpadl on the vsp end */
371         if (net_dev->rx_buf_gpadl_handle) {
372                 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
373                     net_dev->rx_buf_gpadl_handle);
374                 /*
375                  * If we failed here, we might as well return and have a leak 
376                  * rather than continue and a bugchk
377                  */
378                 if (ret != 0) {
379                         return (ret);
380                 }
381                 net_dev->rx_buf_gpadl_handle = 0;
382         }
383
384         if (net_dev->rx_buf) {
385                 /* Free up the receive buffer */
386                 hyperv_dmamem_free(&net_dev->rxbuf_dma, net_dev->rx_buf);
387                 net_dev->rx_buf = NULL;
388         }
389
390         if (net_dev->rx_sections) {
391                 free(net_dev->rx_sections, M_NETVSC);
392                 net_dev->rx_sections = NULL;
393                 net_dev->rx_section_count = 0;
394         }
395
396         return (ret);
397 }
398
399 /*
400  * Net VSC destroy send buffer
401  */
402 static int
403 hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
404 {
405         nvsp_msg *revoke_pkt;
406         int ret = 0;
407
408         /*
409          * If we got a section count, it means we received a
410          * send_rx_buf_complete msg 
411          * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
412          * we need to send a revoke msg here
413          */
414         if (net_dev->send_section_size) {
415                 /* Send the revoke send buffer */
416                 revoke_pkt = &net_dev->revoke_packet;
417                 memset(revoke_pkt, 0, sizeof(nvsp_msg));
418
419                 revoke_pkt->hdr.msg_type =
420                     nvsp_msg_1_type_revoke_send_buf;
421                 revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id =
422                     NETVSC_SEND_BUFFER_ID;
423
424                 ret = vmbus_chan_send(net_dev->sc->hn_prichan,
425                     VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
426                     (uint64_t)(uintptr_t)&hn_send_ctx_none);
427                 /*
428                  * If we failed here, we might as well return and have a leak 
429                  * rather than continue and a bugchk
430                  */
431                 if (ret != 0) {
432                         return (ret);
433                 }
434         }
435                 
436         /* Tear down the gpadl on the vsp end */
437         if (net_dev->send_buf_gpadl_handle) {
438                 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
439                     net_dev->send_buf_gpadl_handle);
440
441                 /*
442                  * If we failed here, we might as well return and have a leak 
443                  * rather than continue and a bugchk
444                  */
445                 if (ret != 0) {
446                         return (ret);
447                 }
448                 net_dev->send_buf_gpadl_handle = 0;
449         }
450
451         if (net_dev->send_buf) {
452                 /* Free up the receive buffer */
453                 hyperv_dmamem_free(&net_dev->txbuf_dma, net_dev->send_buf);
454                 net_dev->send_buf = NULL;
455         }
456
457         if (net_dev->send_section_bitsmap) {
458                 free(net_dev->send_section_bitsmap, M_NETVSC);
459         }
460
461         return (ret);
462 }
463
464
465 /*
466  * Attempt to negotiate the caller-specified NVSP version
467  *
468  * For NVSP v2, Server 2008 R2 does not set
469  * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
470  * to the negotiated version, so we cannot rely on that.
471  */
472 static int
473 hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
474     uint32_t nvsp_ver)
475 {
476         struct hn_send_ctx sndc;
477         nvsp_msg *init_pkt;
478         int ret;
479
480         init_pkt = &net_dev->channel_init_packet;
481         memset(init_pkt, 0, sizeof(nvsp_msg));
482         init_pkt->hdr.msg_type = nvsp_msg_type_init;
483
484         /*
485          * Specify parameter as the only acceptable protocol version
486          */
487         init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver;
488         init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
489
490         /* Send the init request */
491         hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
492         ret = vmbus_chan_send(sc->hn_prichan,
493             VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
494             init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
495         if (ret != 0)
496                 return (-1);
497
498         sema_wait(&net_dev->channel_init_sema);
499
500         if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success)
501                 return (EINVAL);
502
503         return (0);
504 }
505
506 /*
507  * Send NDIS version 2 config packet containing MTU.
508  *
509  * Not valid for NDIS version 1.
510  */
511 static int
512 hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
513 {
514         netvsc_dev *net_dev;
515         nvsp_msg *init_pkt;
516         int ret;
517
518         net_dev = hv_nv_get_outbound_net_device(sc);
519         if (!net_dev)
520                 return (-ENODEV);
521
522         /*
523          * Set up configuration packet, write MTU
524          * Indicate we are capable of handling VLAN tags
525          */
526         init_pkt = &net_dev->channel_init_packet;
527         memset(init_pkt, 0, sizeof(nvsp_msg));
528         init_pkt->hdr.msg_type = nvsp_msg_2_type_send_ndis_config;
529         init_pkt->msgs.vers_2_msgs.send_ndis_config.mtu = mtu;
530         init_pkt->
531                 msgs.vers_2_msgs.send_ndis_config.capabilities.u1.u2.ieee8021q
532                 = 1;
533
534         /* Send the configuration packet */
535         ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
536             init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none);
537         if (ret != 0)
538                 return (-EINVAL);
539
540         return (0);
541 }
542
543 /*
544  * Net VSC connect to VSP
545  */
546 static int
547 hv_nv_connect_to_vsp(struct hn_softc *sc)
548 {
549         netvsc_dev *net_dev;
550         nvsp_msg *init_pkt;
551         uint32_t ndis_version;
552         uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
553             NVSP_PROTOCOL_VERSION_2,
554             NVSP_PROTOCOL_VERSION_4,
555             NVSP_PROTOCOL_VERSION_5 };
556         int i;
557         int protocol_number = nitems(protocol_list);
558         int ret = 0;
559         device_t dev = sc->hn_dev;
560         struct ifnet *ifp = sc->arpcom.ac_ifp;
561
562         net_dev = hv_nv_get_outbound_net_device(sc);
563
564         /*
565          * Negotiate the NVSP version.  Try the latest NVSP first.
566          */
567         for (i = protocol_number - 1; i >= 0; i--) {
568                 if (hv_nv_negotiate_nvsp_protocol(sc, net_dev,
569                     protocol_list[i]) == 0) {
570                         net_dev->nvsp_version = protocol_list[i];
571                         if (bootverbose)
572                                 device_printf(dev, "Netvsc: got version 0x%x\n",
573                                     net_dev->nvsp_version);
574                         break;
575                 }
576         }
577
578         if (i < 0) {
579                 if (bootverbose)
580                         device_printf(dev, "failed to negotiate a valid "
581                             "protocol.\n");
582                 return (EPROTO);
583         }
584
585         /*
586          * Set the MTU if supported by this NVSP protocol version
587          * This needs to be right after the NVSP init message per Haiyang
588          */
589         if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
590                 ret = hv_nv_send_ndis_config(sc, ifp->if_mtu);
591
592         /*
593          * Send the NDIS version
594          */
595         init_pkt = &net_dev->channel_init_packet;
596
597         memset(init_pkt, 0, sizeof(nvsp_msg));
598
599         if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) {
600                 ndis_version = NDIS_VERSION_6_1;
601         } else {
602                 ndis_version = NDIS_VERSION_6_30;
603         }
604
605         init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers;
606         init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers =
607             (ndis_version & 0xFFFF0000) >> 16;
608         init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_minor_vers =
609             ndis_version & 0xFFFF;
610
611         /* Send the init request */
612
613         ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
614             init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none);
615         if (ret != 0) {
616                 goto cleanup;
617         }
618         /*
619          * TODO:  BUGBUG - We have to wait for the above msg since the netvsp
620          * uses KMCL which acknowledges packet (completion packet) 
621          * since our Vmbus always set the VMBUS_CHANPKT_FLAG_RC flag
622          */
623         /* sema_wait(&NetVscChannel->channel_init_sema); */
624
625         /* Post the big receive buffer to NetVSP */
626         if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
627                 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
628         else
629                 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
630         net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
631
632         ret = hv_nv_init_rx_buffer_with_net_vsp(sc);
633         if (ret == 0)
634                 ret = hv_nv_init_send_buffer_with_net_vsp(sc);
635
636 cleanup:
637         return (ret);
638 }
639
640 /*
641  * Net VSC disconnect from VSP
642  */
643 static void
644 hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
645 {
646         hv_nv_destroy_rx_buffer(net_dev);
647         hv_nv_destroy_send_buffer(net_dev);
648 }
649
650 void
651 hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr)
652 {
653         KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan),
654             ("chan%u subidx %u, rxr%d mismatch",
655              vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx));
656         vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
657             NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0,
658             hv_nv_on_channel_callback, rxr);
659 }
660
661 /*
662  * Net VSC on device add
663  * 
664  * Callback when the device belonging to this driver is added
665  */
666 netvsc_dev *
667 hv_nv_on_device_add(struct hn_softc *sc, void *additional_info,
668     struct hn_rx_ring *rxr)
669 {
670         struct vmbus_channel *chan = sc->hn_prichan;
671         netvsc_dev *net_dev;
672         int ret = 0;
673
674         net_dev = hv_nv_alloc_net_device(sc);
675         if (net_dev == NULL)
676                 return NULL;
677
678         /* Initialize the NetVSC channel extension */
679
680         sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
681
682         /*
683          * Open the channel
684          */
685         KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan),
686             ("chan%u subidx %u, rxr%d mismatch",
687              vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx));
688         ret = vmbus_chan_open(chan,
689             NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
690             NULL, 0, hv_nv_on_channel_callback, rxr);
691         if (ret != 0)
692                 goto cleanup;
693
694         /*
695          * Connect with the NetVsp
696          */
697         ret = hv_nv_connect_to_vsp(sc);
698         if (ret != 0)
699                 goto close;
700
701         return (net_dev);
702
703 close:
704         /* Now, we can close the channel safely */
705         vmbus_chan_close(chan);
706
707 cleanup:
708         /*
709          * Free the packet buffers on the netvsc device packet queue.
710          * Release other resources.
711          */
712         sema_destroy(&net_dev->channel_init_sema);
713         free(net_dev, M_NETVSC);
714
715         return (NULL);
716 }
717
718 /*
719  * Net VSC on device remove
720  */
721 int
722 hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
723 {
724         netvsc_dev *net_dev = sc->net_dev;;
725         
726         /* Stop outbound traffic ie sends and receives completions */
727         net_dev->destroy = TRUE;
728
729         hv_nv_disconnect_from_vsp(net_dev);
730
731         /* At this point, no one should be accessing net_dev except in here */
732
733         /* Now, we can close the channel safely */
734
735         vmbus_chan_close(sc->hn_prichan);
736
737         sema_destroy(&net_dev->channel_init_sema);
738         free(net_dev, M_NETVSC);
739
740         return (0);
741 }
742
743 void
744 hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused,
745     struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused,
746     const struct nvsp_msg_ *msg)
747 {
748         /* Copy the response back */
749         memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg));
750         sema_post(&net_dev->channel_init_sema);
751 }
752
753 static void
754 hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
755     struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
756     const struct nvsp_msg_ *msg __unused)
757 {
758         /* EMPTY */
759 }
760
761 void
762 hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx)
763 {
764         u_long mask;
765         uint32_t idx;
766
767         idx = chim_idx / BITS_PER_LONG;
768         KASSERT(idx < net_dev->bitsmap_words,
769             ("invalid chimney index 0x%x", chim_idx));
770
771         mask = 1UL << (chim_idx % BITS_PER_LONG);
772         KASSERT(net_dev->send_section_bitsmap[idx] & mask,
773             ("index bitmap 0x%lx, chimney index %u, "
774              "bitmap idx %d, bitmask 0x%lx",
775              net_dev->send_section_bitsmap[idx], chim_idx, idx, mask));
776
777         atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask);
778 }
779
780 /*
781  * Net VSC on send completion
782  */
783 static void
784 hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
785     const struct vmbus_chanpkt_hdr *pkt)
786 {
787         struct hn_send_ctx *sndc;
788
789         sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
790         sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt));
791         /*
792          * NOTE:
793          * 'sndc' CAN NOT be accessed anymore, since it can be freed by
794          * its callback.
795          */
796 }
797
798 /*
799  * Net VSC on send
800  * Sends a packet on the specified Hyper-V device.
801  * Returns 0 on success, non-zero on failure.
802  */
803 int
804 hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
805     struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
806 {
807         nvsp_msg send_msg;
808         int ret;
809
810         send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
811         if (is_data_pkt) {
812                 /* 0 is RMC_DATA */
813                 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
814         } else {
815                 /* 1 is RMC_CONTROL */
816                 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
817         }
818
819         send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
820             sndc->hn_chim_idx;
821         send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
822             sndc->hn_chim_sz;
823
824         if (gpa_cnt) {
825                 ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt,
826                     &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
827         } else {
828                 ret = vmbus_chan_send(chan,
829                     VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
830                     &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
831         }
832
833         return (ret);
834 }
835
836 /*
837  * Net VSC on receive
838  *
839  * In the FreeBSD Hyper-V virtual world, this function deals exclusively
840  * with virtual addresses.
841  */
842 static void
843 hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
844     struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
845 {
846         const struct vmbus_chanpkt_rxbuf *pkt;
847         const nvsp_msg *nvsp_msg_pkt;
848         netvsc_packet vsc_pkt;
849         netvsc_packet *net_vsc_pkt = &vsc_pkt;
850         int count = 0;
851         int i = 0;
852         int status = nvsp_status_success;
853
854         nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);
855
856         /* Make sure this is a valid nvsp packet */
857         if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
858                 if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n",
859                     nvsp_msg_pkt->hdr.msg_type);
860                 return;
861         }
862         
863         pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
864
865         if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
866                 if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n",
867                     pkt->cp_rxbuf_id);
868                 return;
869         }
870
871         count = pkt->cp_rxbuf_cnt;
872
873         /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
874         for (i = 0; i < count; i++) {
875                 net_vsc_pkt->status = nvsp_status_success;
876                 net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
877                     pkt->cp_rxbuf[i].rb_ofs);
878                 net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
879
880                 hv_rf_on_receive(net_dev, rxr, net_vsc_pkt);
881                 if (net_vsc_pkt->status != nvsp_status_success) {
882                         status = nvsp_status_failure;
883                 }
884         }
885         
886         /*
887          * Moved completion call back here so that all received 
888          * messages (not just data messages) will trigger a response
889          * message back to the host.
890          */
891         hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
892 }
893
894 /*
895  * Net VSC on receive completion
896  *
897  * Send a receive completion packet to RNDIS device (ie NetVsp)
898  */
899 static void
900 hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid,
901     uint32_t status)
902 {
903         nvsp_msg rx_comp_msg;
904         int retries = 0;
905         int ret = 0;
906         
907         rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete;
908
909         /* Pass in the status */
910         rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
911             status;
912
913 retry_send_cmplt:
914         /* Send the completion */
915         ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, 0,
916             &rx_comp_msg, sizeof(nvsp_msg), tid);
917         if (ret == 0) {
918                 /* success */
919                 /* no-op */
920         } else if (ret == EAGAIN) {
921                 /* no more room... wait a bit and attempt to retry 3 times */
922                 retries++;
923
924                 if (retries < 4) {
925                         DELAY(100);
926                         goto retry_send_cmplt;
927                 }
928         }
929 }
930
931 /*
932  * Net VSC receiving vRSS send table from VSP
933  */
934 static void
935 hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
936 {
937         netvsc_dev *net_dev;
938         const nvsp_msg *nvsp_msg_pkt;
939         int i;
940         uint32_t count;
941         const uint32_t *table;
942
943         net_dev = hv_nv_get_inbound_net_device(sc);
944         if (!net_dev)
945                 return;
946
947         nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
948
949         if (nvsp_msg_pkt->hdr.msg_type !=
950             nvsp_msg5_type_send_indirection_table) {
951                 printf("Netvsc: !Warning! receive msg type not "
952                         "send_indirection_table. type = %d\n",
953                         nvsp_msg_pkt->hdr.msg_type);
954                 return;
955         }
956
957         count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count;
958         if (count != VRSS_SEND_TABLE_SIZE) {
959                 printf("Netvsc: Received wrong send table size: %u\n", count);
960                 return;
961         }
962
963         table = (const uint32_t *)
964             ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
965              nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);
966
967         for (i = 0; i < count; i++)
968                 net_dev->vrss_send_table[i] = table[i];
969 }
970
971 /*
972  * Net VSC on channel callback
973  */
974 static void
975 hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr)
976 {
977         struct hn_rx_ring *rxr = xrxr;
978         struct hn_softc *sc = rxr->hn_ifp->if_softc;
979         netvsc_dev *net_dev;
980         void *buffer;
981         int bufferlen = NETVSC_PACKET_SIZE;
982
983         net_dev = hv_nv_get_inbound_net_device(sc);
984         if (net_dev == NULL)
985                 return;
986
987         buffer = rxr->hn_rdbuf;
988         do {
989                 struct vmbus_chanpkt_hdr *pkt = buffer;
990                 uint32_t bytes_rxed;
991                 int ret;
992
993                 bytes_rxed = bufferlen;
994                 ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
995                 if (ret == 0) {
996                         if (bytes_rxed > 0) {
997                                 switch (pkt->cph_type) {
998                                 case VMBUS_CHANPKT_TYPE_COMP:
999                                         hv_nv_on_send_completion(net_dev, chan,
1000                                             pkt);
1001                                         break;
1002                                 case VMBUS_CHANPKT_TYPE_RXBUF:
1003                                         hv_nv_on_receive(net_dev, rxr, chan, pkt);
1004                                         break;
1005                                 case VMBUS_CHANPKT_TYPE_INBAND:
1006                                         hv_nv_send_table(sc, pkt);
1007                                         break;
1008                                 default:
1009                                         if_printf(rxr->hn_ifp,
1010                                             "unknown chan pkt %u\n",
1011                                             pkt->cph_type);
1012                                         break;
1013                                 }
1014                         }
1015                 } else if (ret == ENOBUFS) {
1016                         /* Handle large packet */
1017                         if (bufferlen > NETVSC_PACKET_SIZE) {
1018                                 free(buffer, M_NETVSC);
1019                                 buffer = NULL;
1020                         }
1021
1022                         /* alloc new buffer */
1023                         buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
1024                         if (buffer == NULL) {
1025                                 if_printf(rxr->hn_ifp,
1026                                     "hv_cb malloc buffer failed, len=%u\n",
1027                                     bytes_rxed);
1028                                 bufferlen = 0;
1029                                 break;
1030                         }
1031                         bufferlen = bytes_rxed;
1032                 } else {
1033                         /* No more packets */
1034                         break;
1035                 }
1036         } while (1);
1037
1038         if (bufferlen > NETVSC_PACKET_SIZE)
1039                 free(buffer, M_NETVSC);
1040
1041         hv_rf_channel_rollup(rxr, rxr->hn_txr);
1042 }