2 * Copyright (c) 2009-2012 Microsoft Corp.
3 * Copyright (c) 2010-2012 Citrix Inc.
4 * Copyright (c) 2012 NetApp Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice unmodified, this list of conditions, and the following
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.
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.
32 * HyperV vmbus network VSC (virtual services client) module
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/socket.h>
42 #include <net/if_arp.h>
43 #include <machine/bus.h>
44 #include <machine/atomic.h>
46 #include <dev/hyperv/include/hyperv.h>
47 #include "hv_net_vsc.h"
49 #include "hv_rndis_filter.h"
51 MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
54 * Forward declarations
56 static void hv_nv_on_channel_callback(void *context);
57 static int hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device);
58 static int hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device);
59 static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
60 static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
61 static int hv_nv_connect_to_vsp(struct hv_device *device);
62 static void hv_nv_on_send_completion(netvsc_dev *net_dev,
63 struct hv_device *device, hv_vm_packet_descriptor *pkt);
64 static void hv_nv_on_receive(netvsc_dev *net_dev,
65 struct hv_device *device, hv_vm_packet_descriptor *pkt);
70 static inline netvsc_dev *
71 hv_nv_alloc_net_device(struct hv_device *device)
74 hn_softc_t *sc = device_get_softc(device->device);
76 net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
78 net_dev->dev = device;
79 net_dev->destroy = FALSE;
80 sc->net_dev = net_dev;
88 static inline netvsc_dev *
89 hv_nv_get_outbound_net_device(struct hv_device *device)
91 hn_softc_t *sc = device_get_softc(device->device);
92 netvsc_dev *net_dev = sc->net_dev;;
94 if ((net_dev != NULL) && net_dev->destroy) {
104 static inline netvsc_dev *
105 hv_nv_get_inbound_net_device(struct hv_device *device)
107 hn_softc_t *sc = device_get_softc(device->device);
108 netvsc_dev *net_dev = sc->net_dev;;
110 if (net_dev == NULL) {
114 * When the device is being destroyed; we only
115 * permit incoming packets if and only if there
116 * are outstanding sends.
118 if (net_dev->destroy && net_dev->num_outstanding_sends == 0) {
126 hv_nv_get_next_send_section(netvsc_dev *net_dev)
128 unsigned long bitsmap_words = net_dev->bitsmap_words;
129 unsigned long *bitsmap = net_dev->send_section_bitsmap;
131 int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
134 for (i = 0; i < bitsmap_words; i++) {
135 idx = ffsl(~bitsmap[i]);
140 KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count,
141 ("invalid i %d and idx %lu", i, idx));
143 if (atomic_testandset_long(&bitsmap[i], idx))
146 ret = i * BITS_PER_LONG + idx;
154 * Net VSC initialize receive buffer with net VSP
156 * Net VSP: Network virtual services client, also known as the
157 * Hyper-V extensible switch and the synthetic data path.
160 hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
166 net_dev = hv_nv_get_outbound_net_device(device);
171 net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_NETVSC,
172 M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
175 * Establish the GPADL handle for this buffer on this channel.
176 * Note: This call uses the vmbus connection rather than the
177 * channel to establish the gpadl handle.
178 * GPADL: Guest physical address descriptor list.
180 ret = hv_vmbus_channel_establish_gpadl(
181 device->channel, net_dev->rx_buf,
182 net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle);
187 /* sema_wait(&ext->channel_init_sema); KYS CHECK */
189 /* Notify the NetVsp of the gpadl handle */
190 init_pkt = &net_dev->channel_init_packet;
192 memset(init_pkt, 0, sizeof(nvsp_msg));
194 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
195 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
196 net_dev->rx_buf_gpadl_handle;
197 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
198 NETVSC_RECEIVE_BUFFER_ID;
200 /* Send the gpadl notification request */
202 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
203 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
204 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
205 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
210 sema_wait(&net_dev->channel_init_sema);
212 /* Check the response */
213 if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
214 != nvsp_status_success) {
219 net_dev->rx_section_count =
220 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
222 net_dev->rx_sections = malloc(net_dev->rx_section_count *
223 sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
224 memcpy(net_dev->rx_sections,
225 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
226 net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));
230 * For first release, there should only be 1 section that represents
231 * the entire receive buffer
233 if (net_dev->rx_section_count != 1
234 || net_dev->rx_sections->offset != 0) {
242 hv_nv_destroy_rx_buffer(net_dev);
249 * Net VSC initialize send buffer with net VSP
252 hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
258 net_dev = hv_nv_get_outbound_net_device(device);
263 net_dev->send_buf = contigmalloc(net_dev->send_buf_size, M_NETVSC,
264 M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
265 if (net_dev->send_buf == NULL) {
271 * Establish the gpadl handle for this buffer on this channel.
272 * Note: This call uses the vmbus connection rather than the
273 * channel to establish the gpadl handle.
275 ret = hv_vmbus_channel_establish_gpadl(device->channel,
276 net_dev->send_buf, net_dev->send_buf_size,
277 &net_dev->send_buf_gpadl_handle);
282 /* Notify the NetVsp of the gpadl handle */
284 init_pkt = &net_dev->channel_init_packet;
286 memset(init_pkt, 0, sizeof(nvsp_msg));
288 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
289 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
290 net_dev->send_buf_gpadl_handle;
291 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
292 NETVSC_SEND_BUFFER_ID;
294 /* Send the gpadl notification request */
296 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
297 sizeof(nvsp_msg), (uint64_t)init_pkt,
298 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
299 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
304 sema_wait(&net_dev->channel_init_sema);
306 /* Check the response */
307 if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
308 != nvsp_status_success) {
313 net_dev->send_section_size =
314 init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
315 net_dev->send_section_count =
316 net_dev->send_buf_size / net_dev->send_section_size;
317 net_dev->bitsmap_words = howmany(net_dev->send_section_count,
319 net_dev->send_section_bitsmap =
320 malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
326 hv_nv_destroy_send_buffer(net_dev);
333 * Net VSC destroy receive buffer
336 hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
338 nvsp_msg *revoke_pkt;
342 * If we got a section count, it means we received a
343 * send_rx_buf_complete msg
344 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
345 * we need to send a revoke msg here
347 if (net_dev->rx_section_count) {
348 /* Send the revoke receive buffer */
349 revoke_pkt = &net_dev->revoke_packet;
350 memset(revoke_pkt, 0, sizeof(nvsp_msg));
352 revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf;
353 revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
354 NETVSC_RECEIVE_BUFFER_ID;
356 ret = hv_vmbus_channel_send_packet(net_dev->dev->channel,
357 revoke_pkt, sizeof(nvsp_msg),
358 (uint64_t)(uintptr_t)revoke_pkt,
359 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
362 * If we failed here, we might as well return and have a leak
363 * rather than continue and a bugchk
370 /* Tear down the gpadl on the vsp end */
371 if (net_dev->rx_buf_gpadl_handle) {
372 ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel,
373 net_dev->rx_buf_gpadl_handle);
375 * If we failed here, we might as well return and have a leak
376 * rather than continue and a bugchk
381 net_dev->rx_buf_gpadl_handle = 0;
384 if (net_dev->rx_buf) {
385 /* Free up the receive buffer */
386 contigfree(net_dev->rx_buf, net_dev->rx_buf_size, M_NETVSC);
387 net_dev->rx_buf = NULL;
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;
400 * Net VSC destroy send buffer
403 hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
405 nvsp_msg *revoke_pkt;
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
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));
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;
424 ret = hv_vmbus_channel_send_packet(net_dev->dev->channel,
425 revoke_pkt, sizeof(nvsp_msg),
426 (uint64_t)(uintptr_t)revoke_pkt,
427 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
429 * If we failed here, we might as well return and have a leak
430 * rather than continue and a bugchk
437 /* Tear down the gpadl on the vsp end */
438 if (net_dev->send_buf_gpadl_handle) {
439 ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel,
440 net_dev->send_buf_gpadl_handle);
443 * If we failed here, we might as well return and have a leak
444 * rather than continue and a bugchk
449 net_dev->send_buf_gpadl_handle = 0;
452 if (net_dev->send_buf) {
453 /* Free up the receive buffer */
454 contigfree(net_dev->send_buf, net_dev->send_buf_size, M_NETVSC);
455 net_dev->send_buf = NULL;
458 if (net_dev->send_section_bitsmap) {
459 free(net_dev->send_section_bitsmap, M_NETVSC);
467 * Attempt to negotiate the caller-specified NVSP version
469 * For NVSP v2, Server 2008 R2 does not set
470 * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
471 * to the negotiated version, so we cannot rely on that.
474 hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
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;
485 * Specify parameter as the only acceptable protocol version
487 init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver;
488 init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
490 /* Send the init request */
491 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
492 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
493 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
494 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
498 sema_wait(&net_dev->channel_init_sema);
500 if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success)
507 * Send NDIS version 2 config packet containing MTU.
509 * Not valid for NDIS version 1.
512 hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu)
518 net_dev = hv_nv_get_outbound_net_device(device);
523 * Set up configuration packet, write MTU
524 * Indicate we are capable of handling VLAN tags
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;
531 msgs.vers_2_msgs.send_ndis_config.capabilities.u1.u2.ieee8021q
534 /* Send the configuration packet */
535 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
536 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
537 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
545 * Net VSC connect to VSP
548 hv_nv_connect_to_vsp(struct hv_device *device)
552 uint32_t ndis_version;
553 uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
554 NVSP_PROTOCOL_VERSION_2,
555 NVSP_PROTOCOL_VERSION_4,
556 NVSP_PROTOCOL_VERSION_5 };
558 int protocol_number = nitems(protocol_list);
560 device_t dev = device->device;
561 hn_softc_t *sc = device_get_softc(dev);
562 struct ifnet *ifp = sc->arpcom.ac_ifp;
564 net_dev = hv_nv_get_outbound_net_device(device);
570 * Negotiate the NVSP version. Try the latest NVSP first.
572 for (i = protocol_number - 1; i >= 0; i--) {
573 if (hv_nv_negotiate_nvsp_protocol(device, net_dev,
574 protocol_list[i]) == 0) {
575 net_dev->nvsp_version = protocol_list[i];
577 device_printf(dev, "Netvsc: got version 0x%x\n",
578 net_dev->nvsp_version);
585 device_printf(dev, "failed to negotiate a valid "
591 * Set the MTU if supported by this NVSP protocol version
592 * This needs to be right after the NVSP init message per Haiyang
594 if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
595 ret = hv_nv_send_ndis_config(device, ifp->if_mtu);
598 * Send the NDIS version
600 init_pkt = &net_dev->channel_init_packet;
602 memset(init_pkt, 0, sizeof(nvsp_msg));
604 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) {
605 ndis_version = NDIS_VERSION_6_1;
607 ndis_version = NDIS_VERSION_6_30;
610 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers;
611 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers =
612 (ndis_version & 0xFFFF0000) >> 16;
613 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_minor_vers =
614 ndis_version & 0xFFFF;
616 /* Send the init request */
618 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
619 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
620 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
625 * TODO: BUGBUG - We have to wait for the above msg since the netvsp
626 * uses KMCL which acknowledges packet (completion packet)
627 * since our Vmbus always set the
628 * HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag
630 /* sema_wait(&NetVscChannel->channel_init_sema); */
632 /* Post the big receive buffer to NetVSP */
633 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
634 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
636 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
637 net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
639 ret = hv_nv_init_rx_buffer_with_net_vsp(device);
641 ret = hv_nv_init_send_buffer_with_net_vsp(device);
648 * Net VSC disconnect from VSP
651 hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
653 hv_nv_destroy_rx_buffer(net_dev);
654 hv_nv_destroy_send_buffer(net_dev);
658 * Net VSC on device add
660 * Callback when the device belonging to this driver is added
663 hv_nv_on_device_add(struct hv_device *device, void *additional_info)
668 net_dev = hv_nv_alloc_net_device(device);
672 /* Initialize the NetVSC channel extension */
674 sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
679 ret = hv_vmbus_channel_open(device->channel,
680 NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
681 NULL, 0, hv_nv_on_channel_callback, device);
686 * Connect with the NetVsp
688 ret = hv_nv_connect_to_vsp(device);
695 /* Now, we can close the channel safely */
697 hv_vmbus_channel_close(device->channel);
701 * Free the packet buffers on the netvsc device packet queue.
702 * Release other resources.
705 sema_destroy(&net_dev->channel_init_sema);
706 free(net_dev, M_NETVSC);
713 * Net VSC on device remove
716 hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
718 hn_softc_t *sc = device_get_softc(device->device);
719 netvsc_dev *net_dev = sc->net_dev;;
721 /* Stop outbound traffic ie sends and receives completions */
722 mtx_lock(&device->channel->inbound_lock);
723 net_dev->destroy = TRUE;
724 mtx_unlock(&device->channel->inbound_lock);
726 /* Wait for all send completions */
727 while (net_dev->num_outstanding_sends) {
731 hv_nv_disconnect_from_vsp(net_dev);
733 /* At this point, no one should be accessing net_dev except in here */
735 /* Now, we can close the channel safely */
737 if (!destroy_channel) {
738 device->channel->state =
739 HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE;
742 hv_vmbus_channel_close(device->channel);
744 sema_destroy(&net_dev->channel_init_sema);
745 free(net_dev, M_NETVSC);
751 * Net VSC on send completion
754 hv_nv_on_send_completion(netvsc_dev *net_dev,
755 struct hv_device *device, hv_vm_packet_descriptor *pkt)
757 nvsp_msg *nvsp_msg_pkt;
758 netvsc_packet *net_vsc_pkt;
761 (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
763 if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete
764 || nvsp_msg_pkt->hdr.msg_type
765 == nvsp_msg_1_type_send_rx_buf_complete
766 || nvsp_msg_pkt->hdr.msg_type
767 == nvsp_msg_1_type_send_send_buf_complete) {
768 /* Copy the response back */
769 memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt,
771 sema_post(&net_dev->channel_init_sema);
772 } else if (nvsp_msg_pkt->hdr.msg_type ==
773 nvsp_msg_1_type_send_rndis_pkt_complete) {
774 /* Get the send context */
776 (netvsc_packet *)(unsigned long)pkt->transaction_id;
777 if (NULL != net_vsc_pkt) {
778 if (net_vsc_pkt->send_buf_section_idx !=
779 NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
783 idx = net_vsc_pkt->send_buf_section_idx /
785 KASSERT(idx < net_dev->bitsmap_words,
786 ("invalid section index %u",
787 net_vsc_pkt->send_buf_section_idx));
789 (net_vsc_pkt->send_buf_section_idx %
792 KASSERT(net_dev->send_section_bitsmap[idx] &
794 ("index bitmap 0x%lx, section index %u, "
795 "bitmap idx %d, bitmask 0x%lx",
796 net_dev->send_section_bitsmap[idx],
797 net_vsc_pkt->send_buf_section_idx,
800 &net_dev->send_section_bitsmap[idx], mask);
803 /* Notify the layer above us */
804 net_vsc_pkt->compl.send.on_send_completion(
805 net_vsc_pkt->compl.send.send_completion_context);
809 atomic_subtract_int(&net_dev->num_outstanding_sends, 1);
815 * Sends a packet on the specified Hyper-V device.
816 * Returns 0 on success, non-zero on failure.
819 hv_nv_on_send(struct hv_device *device, netvsc_packet *pkt)
825 net_dev = hv_nv_get_outbound_net_device(device);
829 send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
830 if (pkt->is_data_pkt) {
832 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
834 /* 1 is RMC_CONTROL */
835 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
838 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
839 pkt->send_buf_section_idx;
840 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
841 pkt->send_buf_section_size;
843 if (pkt->page_buf_count) {
844 ret = hv_vmbus_channel_send_packet_pagebuffer(device->channel,
845 pkt->page_buffers, pkt->page_buf_count,
846 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
848 ret = hv_vmbus_channel_send_packet(device->channel,
849 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt,
850 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
851 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
854 /* Record outstanding send only if send_packet() succeeded */
856 atomic_add_int(&net_dev->num_outstanding_sends, 1);
864 * In the FreeBSD Hyper-V virtual world, this function deals exclusively
865 * with virtual addresses.
868 hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
869 hv_vm_packet_descriptor *pkt)
871 hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
872 nvsp_msg *nvsp_msg_pkt;
873 netvsc_packet vsc_pkt;
874 netvsc_packet *net_vsc_pkt = &vsc_pkt;
875 device_t dev = device->device;
878 int status = nvsp_status_success;
881 * All inbound packets other than send completion should be
884 if (pkt->type != HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES) {
885 device_printf(dev, "packet type %d is invalid!\n", pkt->type);
889 nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt
890 + (pkt->data_offset8 << 3));
892 /* Make sure this is a valid nvsp packet */
893 if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
894 device_printf(dev, "packet hdr type %d is invalid!\n",
899 vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt;
901 if (vm_xfer_page_pkt->transfer_page_set_id !=
902 NETVSC_RECEIVE_BUFFER_ID) {
903 device_printf(dev, "transfer_page_set_id %d is invalid!\n",
904 vm_xfer_page_pkt->transfer_page_set_id);
908 count = vm_xfer_page_pkt->range_count;
909 net_vsc_pkt->device = device;
911 /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
912 for (i = 0; i < count; i++) {
913 net_vsc_pkt->status = nvsp_status_success;
914 net_vsc_pkt->data = (void *)((unsigned long)net_dev->rx_buf +
915 vm_xfer_page_pkt->ranges[i].byte_offset);
916 net_vsc_pkt->tot_data_buf_len =
917 vm_xfer_page_pkt->ranges[i].byte_count;
919 hv_rf_on_receive(net_dev, device, net_vsc_pkt);
920 if (net_vsc_pkt->status != nvsp_status_success) {
921 status = nvsp_status_failure;
926 * Moved completion call back here so that all received
927 * messages (not just data messages) will trigger a response
928 * message back to the host.
930 hv_nv_on_receive_completion(device, vm_xfer_page_pkt->d.transaction_id,
932 hv_rf_receive_rollup(net_dev);
936 * Net VSC on receive completion
938 * Send a receive completion packet to RNDIS device (ie NetVsp)
941 hv_nv_on_receive_completion(struct hv_device *device, uint64_t tid,
944 nvsp_msg rx_comp_msg;
948 rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete;
950 /* Pass in the status */
951 rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
955 /* Send the completion */
956 ret = hv_vmbus_channel_send_packet(device->channel, &rx_comp_msg,
957 sizeof(nvsp_msg), tid, HV_VMBUS_PACKET_TYPE_COMPLETION, 0);
961 } else if (ret == EAGAIN) {
962 /* no more room... wait a bit and attempt to retry 3 times */
967 goto retry_send_cmplt;
973 * Net VSC on channel callback
976 hv_nv_on_channel_callback(void *context)
978 struct hv_device *device = (struct hv_device *)context;
980 device_t dev = device->device;
983 hv_vm_packet_descriptor *desc;
985 int bufferlen = NETVSC_PACKET_SIZE;
988 net_dev = hv_nv_get_inbound_net_device(device);
992 buffer = net_dev->callback_buf;
995 ret = hv_vmbus_channel_recv_packet_raw(device->channel,
996 buffer, bufferlen, &bytes_rxed, &request_id);
998 if (bytes_rxed > 0) {
999 desc = (hv_vm_packet_descriptor *)buffer;
1000 switch (desc->type) {
1001 case HV_VMBUS_PACKET_TYPE_COMPLETION:
1002 hv_nv_on_send_completion(net_dev, device, desc);
1004 case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES:
1005 hv_nv_on_receive(net_dev, device, desc);
1009 "hv_cb recv unknow type %d "
1010 " packet\n", desc->type);
1016 } else if (ret == ENOBUFS) {
1017 /* Handle large packet */
1018 if (bufferlen > NETVSC_PACKET_SIZE) {
1019 free(buffer, M_NETVSC);
1023 /* alloc new buffer */
1024 buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
1025 if (buffer == NULL) {
1027 "hv_cb malloc buffer failed, len=%u\n",
1032 bufferlen = bytes_rxed;
1036 if (bufferlen > NETVSC_PACKET_SIZE)
1037 free(buffer, M_NETVSC);
1039 hv_rf_channel_rollup(net_dev);