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