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_var.h>
43 #include <net/if_arp.h>
44 #include <machine/bus.h>
45 #include <machine/atomic.h>
47 #include <dev/hyperv/include/hyperv.h>
48 #include "hv_net_vsc.h"
50 #include "hv_rndis_filter.h"
52 MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
55 * Forward declarations
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, hv_vm_packet_descriptor *pkt);
71 static inline netvsc_dev *
72 hv_nv_alloc_net_device(struct hv_device *device)
75 hn_softc_t *sc = device_get_softc(device->device);
77 net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_NOWAIT | M_ZERO);
78 if (net_dev == NULL) {
82 net_dev->dev = device;
83 net_dev->destroy = FALSE;
84 sc->net_dev = net_dev;
92 static inline netvsc_dev *
93 hv_nv_get_outbound_net_device(struct hv_device *device)
95 hn_softc_t *sc = device_get_softc(device->device);
96 netvsc_dev *net_dev = sc->net_dev;;
98 if ((net_dev != NULL) && net_dev->destroy) {
108 static inline netvsc_dev *
109 hv_nv_get_inbound_net_device(struct hv_device *device)
111 hn_softc_t *sc = device_get_softc(device->device);
112 netvsc_dev *net_dev = sc->net_dev;;
114 if (net_dev == NULL) {
118 * When the device is being destroyed; we only
119 * permit incoming packets if and only if there
120 * are outstanding sends.
122 if (net_dev->destroy && net_dev->num_outstanding_sends == 0) {
130 hv_nv_get_next_send_section(netvsc_dev *net_dev)
132 unsigned long bitsmap_words = net_dev->bitsmap_words;
133 unsigned long *bitsmap = net_dev->send_section_bitsmap;
135 int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
138 for (i = 0; i < bitsmap_words; i++) {
139 idx = ffs(~bitsmap[i]);
144 if (i * BITS_PER_LONG + idx >= net_dev->send_section_count)
147 if (synch_test_and_set_bit(idx, &bitsmap[i]))
150 ret = i * BITS_PER_LONG + idx;
158 * Net VSC initialize receive buffer with net VSP
160 * Net VSP: Network virtual services client, also known as the
161 * Hyper-V extensible switch and the synthetic data path.
164 hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
170 net_dev = hv_nv_get_outbound_net_device(device);
175 net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_NETVSC,
176 M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
179 * Establish the GPADL handle for this buffer on this channel.
180 * Note: This call uses the vmbus connection rather than the
181 * channel to establish the gpadl handle.
182 * GPADL: Guest physical address descriptor list.
184 ret = hv_vmbus_channel_establish_gpadl(
185 device->channel, net_dev->rx_buf,
186 net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle);
191 /* sema_wait(&ext->channel_init_sema); KYS CHECK */
193 /* Notify the NetVsp of the gpadl handle */
194 init_pkt = &net_dev->channel_init_packet;
196 memset(init_pkt, 0, sizeof(nvsp_msg));
198 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
199 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
200 net_dev->rx_buf_gpadl_handle;
201 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
202 NETVSC_RECEIVE_BUFFER_ID;
204 /* Send the gpadl notification request */
206 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
207 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
208 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
209 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
214 sema_wait(&net_dev->channel_init_sema);
216 /* Check the response */
217 if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
218 != nvsp_status_success) {
223 net_dev->rx_section_count =
224 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
226 net_dev->rx_sections = malloc(net_dev->rx_section_count *
227 sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_NOWAIT);
228 if (net_dev->rx_sections == NULL) {
232 memcpy(net_dev->rx_sections,
233 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
234 net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));
238 * For first release, there should only be 1 section that represents
239 * the entire receive buffer
241 if (net_dev->rx_section_count != 1
242 || net_dev->rx_sections->offset != 0) {
250 hv_nv_destroy_rx_buffer(net_dev);
257 * Net VSC initialize send buffer with net VSP
260 hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
266 net_dev = hv_nv_get_outbound_net_device(device);
271 net_dev->send_buf = contigmalloc(net_dev->send_buf_size, M_NETVSC,
272 M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
273 if (net_dev->send_buf == NULL) {
279 * Establish the gpadl handle for this buffer on this channel.
280 * Note: This call uses the vmbus connection rather than the
281 * channel to establish the gpadl handle.
283 ret = hv_vmbus_channel_establish_gpadl(device->channel,
284 net_dev->send_buf, net_dev->send_buf_size,
285 &net_dev->send_buf_gpadl_handle);
290 /* Notify the NetVsp of the gpadl handle */
292 init_pkt = &net_dev->channel_init_packet;
294 memset(init_pkt, 0, sizeof(nvsp_msg));
296 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
297 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
298 net_dev->send_buf_gpadl_handle;
299 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
300 NETVSC_SEND_BUFFER_ID;
302 /* Send the gpadl notification request */
304 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
305 sizeof(nvsp_msg), (uint64_t)init_pkt,
306 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
307 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
312 sema_wait(&net_dev->channel_init_sema);
314 /* Check the response */
315 if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
316 != nvsp_status_success) {
321 net_dev->send_section_size =
322 init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
323 net_dev->send_section_count =
324 net_dev->send_buf_size / net_dev->send_section_size;
325 net_dev->bitsmap_words = howmany(net_dev->send_section_count,
327 net_dev->send_section_bitsmap =
328 malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
330 if (NULL == net_dev->send_section_bitsmap) {
338 hv_nv_destroy_send_buffer(net_dev);
345 * Net VSC destroy receive buffer
348 hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
350 nvsp_msg *revoke_pkt;
354 * If we got a section count, it means we received a
355 * send_rx_buf_complete msg
356 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
357 * we need to send a revoke msg here
359 if (net_dev->rx_section_count) {
360 /* Send the revoke receive buffer */
361 revoke_pkt = &net_dev->revoke_packet;
362 memset(revoke_pkt, 0, sizeof(nvsp_msg));
364 revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf;
365 revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
366 NETVSC_RECEIVE_BUFFER_ID;
368 ret = hv_vmbus_channel_send_packet(net_dev->dev->channel,
369 revoke_pkt, sizeof(nvsp_msg),
370 (uint64_t)(uintptr_t)revoke_pkt,
371 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
374 * If we failed here, we might as well return and have a leak
375 * rather than continue and a bugchk
382 /* Tear down the gpadl on the vsp end */
383 if (net_dev->rx_buf_gpadl_handle) {
384 ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel,
385 net_dev->rx_buf_gpadl_handle);
387 * If we failed here, we might as well return and have a leak
388 * rather than continue and a bugchk
393 net_dev->rx_buf_gpadl_handle = 0;
396 if (net_dev->rx_buf) {
397 /* Free up the receive buffer */
398 contigfree(net_dev->rx_buf, net_dev->rx_buf_size, M_NETVSC);
399 net_dev->rx_buf = NULL;
402 if (net_dev->rx_sections) {
403 free(net_dev->rx_sections, M_NETVSC);
404 net_dev->rx_sections = NULL;
405 net_dev->rx_section_count = 0;
412 * Net VSC destroy send buffer
415 hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
417 nvsp_msg *revoke_pkt;
421 * If we got a section count, it means we received a
422 * send_rx_buf_complete msg
423 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
424 * we need to send a revoke msg here
426 if (net_dev->send_section_size) {
427 /* Send the revoke send buffer */
428 revoke_pkt = &net_dev->revoke_packet;
429 memset(revoke_pkt, 0, sizeof(nvsp_msg));
431 revoke_pkt->hdr.msg_type =
432 nvsp_msg_1_type_revoke_send_buf;
433 revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id =
434 NETVSC_SEND_BUFFER_ID;
436 ret = hv_vmbus_channel_send_packet(net_dev->dev->channel,
437 revoke_pkt, sizeof(nvsp_msg),
438 (uint64_t)(uintptr_t)revoke_pkt,
439 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
441 * If we failed here, we might as well return and have a leak
442 * rather than continue and a bugchk
449 /* Tear down the gpadl on the vsp end */
450 if (net_dev->send_buf_gpadl_handle) {
451 ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel,
452 net_dev->send_buf_gpadl_handle);
455 * If we failed here, we might as well return and have a leak
456 * rather than continue and a bugchk
461 net_dev->send_buf_gpadl_handle = 0;
464 if (net_dev->send_buf) {
465 /* Free up the receive buffer */
466 contigfree(net_dev->send_buf, net_dev->send_buf_size, M_NETVSC);
467 net_dev->send_buf = NULL;
470 if (net_dev->send_section_bitsmap) {
471 free(net_dev->send_section_bitsmap, M_NETVSC);
479 * Attempt to negotiate the caller-specified NVSP version
481 * For NVSP v2, Server 2008 R2 does not set
482 * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
483 * to the negotiated version, so we cannot rely on that.
486 hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
492 init_pkt = &net_dev->channel_init_packet;
493 memset(init_pkt, 0, sizeof(nvsp_msg));
494 init_pkt->hdr.msg_type = nvsp_msg_type_init;
497 * Specify parameter as the only acceptable protocol version
499 init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver;
500 init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
502 /* Send the init request */
503 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
504 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
505 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
506 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
510 sema_wait(&net_dev->channel_init_sema);
512 if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success)
519 * Send NDIS version 2 config packet containing MTU.
521 * Not valid for NDIS version 1.
524 hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu)
530 net_dev = hv_nv_get_outbound_net_device(device);
535 * Set up configuration packet, write MTU
536 * Indicate we are capable of handling VLAN tags
538 init_pkt = &net_dev->channel_init_packet;
539 memset(init_pkt, 0, sizeof(nvsp_msg));
540 init_pkt->hdr.msg_type = nvsp_msg_2_type_send_ndis_config;
541 init_pkt->msgs.vers_2_msgs.send_ndis_config.mtu = mtu;
543 msgs.vers_2_msgs.send_ndis_config.capabilities.u1.u2.ieee8021q
546 /* Send the configuration packet */
547 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
548 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
549 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
557 * Net VSC connect to VSP
560 hv_nv_connect_to_vsp(struct hv_device *device)
564 uint32_t ndis_version;
565 uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
566 NVSP_PROTOCOL_VERSION_2,
567 NVSP_PROTOCOL_VERSION_4,
568 NVSP_PROTOCOL_VERSION_5 };
570 int protocol_number = nitems(protocol_list);
572 device_t dev = device->device;
573 hn_softc_t *sc = device_get_softc(dev);
574 struct ifnet *ifp = sc->hn_ifp;
576 net_dev = hv_nv_get_outbound_net_device(device);
582 * Negotiate the NVSP version. Try the latest NVSP first.
584 for (i = protocol_number - 1; i >= 0; i--) {
585 if (hv_nv_negotiate_nvsp_protocol(device, net_dev,
586 protocol_list[i]) == 0) {
587 net_dev->nvsp_version = protocol_list[i];
589 device_printf(dev, "Netvsc: got version 0x%x\n",
590 net_dev->nvsp_version);
597 device_printf(dev, "failed to negotiate a valid "
603 * Set the MTU if supported by this NVSP protocol version
604 * This needs to be right after the NVSP init message per Haiyang
606 if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
607 ret = hv_nv_send_ndis_config(device, ifp->if_mtu);
610 * Send the NDIS version
612 init_pkt = &net_dev->channel_init_packet;
614 memset(init_pkt, 0, sizeof(nvsp_msg));
616 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) {
617 ndis_version = NDIS_VERSION_6_1;
619 ndis_version = NDIS_VERSION_6_30;
622 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers;
623 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers =
624 (ndis_version & 0xFFFF0000) >> 16;
625 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_minor_vers =
626 ndis_version & 0xFFFF;
628 /* Send the init request */
630 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
631 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
632 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
637 * TODO: BUGBUG - We have to wait for the above msg since the netvsp
638 * uses KMCL which acknowledges packet (completion packet)
639 * since our Vmbus always set the
640 * HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag
642 /* sema_wait(&NetVscChannel->channel_init_sema); */
644 /* Post the big receive buffer to NetVSP */
645 ret = hv_nv_init_rx_buffer_with_net_vsp(device);
647 ret = hv_nv_init_send_buffer_with_net_vsp(device);
654 * Net VSC disconnect from VSP
657 hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
659 hv_nv_destroy_rx_buffer(net_dev);
660 hv_nv_destroy_send_buffer(net_dev);
664 * Net VSC on device add
666 * Callback when the device belonging to this driver is added
669 hv_nv_on_device_add(struct hv_device *device, void *additional_info)
674 net_dev = hv_nv_alloc_net_device(device);
678 /* Initialize the NetVSC channel extension */
679 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
681 net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
683 sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
688 ret = hv_vmbus_channel_open(device->channel,
689 NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
690 NULL, 0, hv_nv_on_channel_callback, device);
695 * Connect with the NetVsp
697 ret = hv_nv_connect_to_vsp(device);
704 /* Now, we can close the channel safely */
706 hv_vmbus_channel_close(device->channel);
710 * Free the packet buffers on the netvsc device packet queue.
711 * Release other resources.
714 sema_destroy(&net_dev->channel_init_sema);
715 free(net_dev, M_NETVSC);
722 * Net VSC on device remove
725 hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
727 hn_softc_t *sc = device_get_softc(device->device);
728 netvsc_dev *net_dev = sc->net_dev;;
730 /* Stop outbound traffic ie sends and receives completions */
731 mtx_lock(&device->channel->inbound_lock);
732 net_dev->destroy = TRUE;
733 mtx_unlock(&device->channel->inbound_lock);
735 /* Wait for all send completions */
736 while (net_dev->num_outstanding_sends) {
740 hv_nv_disconnect_from_vsp(net_dev);
742 /* At this point, no one should be accessing net_dev except in here */
744 /* Now, we can close the channel safely */
746 if (!destroy_channel) {
747 device->channel->state =
748 HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE;
751 hv_vmbus_channel_close(device->channel);
753 sema_destroy(&net_dev->channel_init_sema);
754 free(net_dev, M_NETVSC);
760 * Net VSC on send completion
763 hv_nv_on_send_completion(netvsc_dev *net_dev,
764 struct hv_device *device, hv_vm_packet_descriptor *pkt)
766 nvsp_msg *nvsp_msg_pkt;
767 netvsc_packet *net_vsc_pkt;
770 (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
772 if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete
773 || nvsp_msg_pkt->hdr.msg_type
774 == nvsp_msg_1_type_send_rx_buf_complete
775 || nvsp_msg_pkt->hdr.msg_type
776 == nvsp_msg_1_type_send_send_buf_complete) {
777 /* Copy the response back */
778 memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt,
780 sema_post(&net_dev->channel_init_sema);
781 } else if (nvsp_msg_pkt->hdr.msg_type ==
782 nvsp_msg_1_type_send_rndis_pkt_complete) {
783 /* Get the send context */
785 (netvsc_packet *)(unsigned long)pkt->transaction_id;
786 if (NULL != net_vsc_pkt) {
787 if (net_vsc_pkt->send_buf_section_idx !=
788 NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
789 synch_change_bit(net_vsc_pkt->send_buf_section_idx,
790 net_dev->send_section_bitsmap);
793 /* Notify the layer above us */
794 net_vsc_pkt->compl.send.on_send_completion(
795 net_vsc_pkt->compl.send.send_completion_context);
799 atomic_subtract_int(&net_dev->num_outstanding_sends, 1);
805 * Sends a packet on the specified Hyper-V device.
806 * Returns 0 on success, non-zero on failure.
809 hv_nv_on_send(struct hv_device *device, netvsc_packet *pkt)
815 net_dev = hv_nv_get_outbound_net_device(device);
819 send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
820 if (pkt->is_data_pkt) {
822 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
824 /* 1 is RMC_CONTROL */
825 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
828 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
829 pkt->send_buf_section_idx;
830 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
831 pkt->send_buf_section_size;
833 if (pkt->page_buf_count) {
834 ret = hv_vmbus_channel_send_packet_pagebuffer(device->channel,
835 pkt->page_buffers, pkt->page_buf_count,
836 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
838 ret = hv_vmbus_channel_send_packet(device->channel,
839 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt,
840 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
841 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
844 /* Record outstanding send only if send_packet() succeeded */
846 atomic_add_int(&net_dev->num_outstanding_sends, 1);
854 * In the FreeBSD Hyper-V virtual world, this function deals exclusively
855 * with virtual addresses.
858 hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
859 hv_vm_packet_descriptor *pkt)
861 hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
862 nvsp_msg *nvsp_msg_pkt;
863 netvsc_packet vsc_pkt;
864 netvsc_packet *net_vsc_pkt = &vsc_pkt;
865 device_t dev = device->device;
868 int status = nvsp_status_success;
871 * All inbound packets other than send completion should be
874 if (pkt->type != HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES) {
875 device_printf(dev, "packet type %d is invalid!\n", pkt->type);
879 nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt
880 + (pkt->data_offset8 << 3));
882 /* Make sure this is a valid nvsp packet */
883 if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
884 device_printf(dev, "packet hdr type %d is invalid!\n",
889 vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt;
891 if (vm_xfer_page_pkt->transfer_page_set_id !=
892 NETVSC_RECEIVE_BUFFER_ID) {
893 device_printf(dev, "transfer_page_set_id %d is invalid!\n",
894 vm_xfer_page_pkt->transfer_page_set_id);
898 count = vm_xfer_page_pkt->range_count;
899 net_vsc_pkt->device = device;
901 /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
902 for (i = 0; i < count; i++) {
903 net_vsc_pkt->status = nvsp_status_success;
904 net_vsc_pkt->data = (void *)((unsigned long)net_dev->rx_buf +
905 vm_xfer_page_pkt->ranges[i].byte_offset);
906 net_vsc_pkt->tot_data_buf_len =
907 vm_xfer_page_pkt->ranges[i].byte_count;
909 hv_rf_on_receive(net_dev, device, net_vsc_pkt);
910 if (net_vsc_pkt->status != nvsp_status_success) {
911 status = nvsp_status_failure;
916 * Moved completion call back here so that all received
917 * messages (not just data messages) will trigger a response
918 * message back to the host.
920 hv_nv_on_receive_completion(device, vm_xfer_page_pkt->d.transaction_id,
922 hv_rf_receive_rollup(net_dev);
926 * Net VSC on receive completion
928 * Send a receive completion packet to RNDIS device (ie NetVsp)
931 hv_nv_on_receive_completion(struct hv_device *device, uint64_t tid,
934 nvsp_msg rx_comp_msg;
938 rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete;
940 /* Pass in the status */
941 rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
945 /* Send the completion */
946 ret = hv_vmbus_channel_send_packet(device->channel, &rx_comp_msg,
947 sizeof(nvsp_msg), tid, HV_VMBUS_PACKET_TYPE_COMPLETION, 0);
951 } else if (ret == EAGAIN) {
952 /* no more room... wait a bit and attempt to retry 3 times */
957 goto retry_send_cmplt;
963 * Net VSC on channel callback
966 hv_nv_on_channel_callback(void *context)
968 struct hv_device *device = (struct hv_device *)context;
970 device_t dev = device->device;
973 hv_vm_packet_descriptor *desc;
975 int bufferlen = NETVSC_PACKET_SIZE;
978 net_dev = hv_nv_get_inbound_net_device(device);
982 buffer = net_dev->callback_buf;
985 ret = hv_vmbus_channel_recv_packet_raw(device->channel,
986 buffer, bufferlen, &bytes_rxed, &request_id);
988 if (bytes_rxed > 0) {
989 desc = (hv_vm_packet_descriptor *)buffer;
990 switch (desc->type) {
991 case HV_VMBUS_PACKET_TYPE_COMPLETION:
992 hv_nv_on_send_completion(net_dev, device, desc);
994 case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES:
995 hv_nv_on_receive(net_dev, device, desc);
999 "hv_cb recv unknow type %d "
1000 " packet\n", desc->type);
1006 } else if (ret == ENOBUFS) {
1007 /* Handle large packet */
1008 if (bufferlen > NETVSC_PACKET_SIZE) {
1009 free(buffer, M_NETVSC);
1013 /* alloc new buffer */
1014 buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
1015 if (buffer == NULL) {
1017 "hv_cb malloc buffer failed, len=%u\n",
1022 bufferlen = bytes_rxed;
1026 if (bufferlen > NETVSC_PACKET_SIZE)
1027 free(buffer, M_NETVSC);