2 * Copyright (c) 2009-2012,2016 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 /* priv1 and priv2 are consumed by the main driver */
53 #define hv_chan_rdbuf hv_chan_priv3
55 MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
58 * Forward declarations
60 static void hv_nv_on_channel_callback(void *xchan);
61 static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc);
62 static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *);
63 static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
64 static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
65 static int hv_nv_connect_to_vsp(struct hn_softc *sc);
66 static void hv_nv_on_send_completion(netvsc_dev *net_dev,
67 struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt);
68 static void hv_nv_on_receive_completion(struct hv_vmbus_channel *chan,
69 uint64_t tid, uint32_t status);
70 static void hv_nv_on_receive(netvsc_dev *net_dev,
71 struct hn_softc *sc, struct hv_vmbus_channel *chan,
72 hv_vm_packet_descriptor *pkt);
77 static inline netvsc_dev *
78 hv_nv_alloc_net_device(struct hn_softc *sc)
82 net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
85 net_dev->destroy = FALSE;
86 sc->net_dev = net_dev;
92 * XXX unnecessary; nuke it.
94 static inline netvsc_dev *
95 hv_nv_get_outbound_net_device(struct hn_softc *sc)
101 * XXX unnecessary; nuke it.
103 static inline netvsc_dev *
104 hv_nv_get_inbound_net_device(struct hn_softc *sc)
110 hv_nv_get_next_send_section(netvsc_dev *net_dev)
112 unsigned long bitsmap_words = net_dev->bitsmap_words;
113 unsigned long *bitsmap = net_dev->send_section_bitsmap;
115 int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
118 for (i = 0; i < bitsmap_words; i++) {
119 idx = ffsl(~bitsmap[i]);
124 KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count,
125 ("invalid i %d and idx %lu", i, idx));
127 if (atomic_testandset_long(&bitsmap[i], idx))
130 ret = i * BITS_PER_LONG + idx;
138 * Net VSC initialize receive buffer with net VSP
140 * Net VSP: Network virtual services client, also known as the
141 * Hyper-V extensible switch and the synthetic data path.
144 hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
150 net_dev = hv_nv_get_outbound_net_device(sc);
155 net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_NETVSC,
156 M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
159 * Establish the GPADL handle for this buffer on this channel.
160 * Note: This call uses the vmbus connection rather than the
161 * channel to establish the gpadl handle.
162 * GPADL: Guest physical address descriptor list.
164 ret = hv_vmbus_channel_establish_gpadl(
165 sc->hn_prichan, net_dev->rx_buf,
166 net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle);
171 /* sema_wait(&ext->channel_init_sema); KYS CHECK */
173 /* Notify the NetVsp of the gpadl handle */
174 init_pkt = &net_dev->channel_init_packet;
176 memset(init_pkt, 0, sizeof(nvsp_msg));
178 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
179 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
180 net_dev->rx_buf_gpadl_handle;
181 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
182 NETVSC_RECEIVE_BUFFER_ID;
184 /* Send the gpadl notification request */
186 ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
187 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
188 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC);
193 sema_wait(&net_dev->channel_init_sema);
195 /* Check the response */
196 if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
197 != nvsp_status_success) {
202 net_dev->rx_section_count =
203 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
205 net_dev->rx_sections = malloc(net_dev->rx_section_count *
206 sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
207 memcpy(net_dev->rx_sections,
208 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
209 net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));
213 * For first release, there should only be 1 section that represents
214 * the entire receive buffer
216 if (net_dev->rx_section_count != 1
217 || net_dev->rx_sections->offset != 0) {
225 hv_nv_destroy_rx_buffer(net_dev);
232 * Net VSC initialize send buffer with net VSP
235 hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
241 net_dev = hv_nv_get_outbound_net_device(sc);
246 net_dev->send_buf = contigmalloc(net_dev->send_buf_size, M_NETVSC,
247 M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
248 if (net_dev->send_buf == NULL) {
254 * Establish the gpadl handle for this buffer on this channel.
255 * Note: This call uses the vmbus connection rather than the
256 * channel to establish the gpadl handle.
258 ret = hv_vmbus_channel_establish_gpadl(sc->hn_prichan,
259 net_dev->send_buf, net_dev->send_buf_size,
260 &net_dev->send_buf_gpadl_handle);
265 /* Notify the NetVsp of the gpadl handle */
267 init_pkt = &net_dev->channel_init_packet;
269 memset(init_pkt, 0, sizeof(nvsp_msg));
271 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
272 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
273 net_dev->send_buf_gpadl_handle;
274 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
275 NETVSC_SEND_BUFFER_ID;
277 /* Send the gpadl notification request */
279 ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
280 sizeof(nvsp_msg), (uint64_t)init_pkt,
281 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC);
286 sema_wait(&net_dev->channel_init_sema);
288 /* Check the response */
289 if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
290 != nvsp_status_success) {
295 net_dev->send_section_size =
296 init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
297 net_dev->send_section_count =
298 net_dev->send_buf_size / net_dev->send_section_size;
299 net_dev->bitsmap_words = howmany(net_dev->send_section_count,
301 net_dev->send_section_bitsmap =
302 malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
308 hv_nv_destroy_send_buffer(net_dev);
315 * Net VSC destroy receive buffer
318 hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
320 nvsp_msg *revoke_pkt;
324 * If we got a section count, it means we received a
325 * send_rx_buf_complete msg
326 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
327 * we need to send a revoke msg here
329 if (net_dev->rx_section_count) {
330 /* Send the revoke receive buffer */
331 revoke_pkt = &net_dev->revoke_packet;
332 memset(revoke_pkt, 0, sizeof(nvsp_msg));
334 revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf;
335 revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
336 NETVSC_RECEIVE_BUFFER_ID;
338 ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan,
339 revoke_pkt, sizeof(nvsp_msg),
340 (uint64_t)(uintptr_t)revoke_pkt,
341 VMBUS_CHANPKT_TYPE_INBAND, 0);
344 * If we failed here, we might as well return and have a leak
345 * rather than continue and a bugchk
352 /* Tear down the gpadl on the vsp end */
353 if (net_dev->rx_buf_gpadl_handle) {
354 ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan,
355 net_dev->rx_buf_gpadl_handle);
357 * If we failed here, we might as well return and have a leak
358 * rather than continue and a bugchk
363 net_dev->rx_buf_gpadl_handle = 0;
366 if (net_dev->rx_buf) {
367 /* Free up the receive buffer */
368 contigfree(net_dev->rx_buf, net_dev->rx_buf_size, M_NETVSC);
369 net_dev->rx_buf = NULL;
372 if (net_dev->rx_sections) {
373 free(net_dev->rx_sections, M_NETVSC);
374 net_dev->rx_sections = NULL;
375 net_dev->rx_section_count = 0;
382 * Net VSC destroy send buffer
385 hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
387 nvsp_msg *revoke_pkt;
391 * If we got a section count, it means we received a
392 * send_rx_buf_complete msg
393 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
394 * we need to send a revoke msg here
396 if (net_dev->send_section_size) {
397 /* Send the revoke send buffer */
398 revoke_pkt = &net_dev->revoke_packet;
399 memset(revoke_pkt, 0, sizeof(nvsp_msg));
401 revoke_pkt->hdr.msg_type =
402 nvsp_msg_1_type_revoke_send_buf;
403 revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id =
404 NETVSC_SEND_BUFFER_ID;
406 ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan,
407 revoke_pkt, sizeof(nvsp_msg),
408 (uint64_t)(uintptr_t)revoke_pkt,
409 VMBUS_CHANPKT_TYPE_INBAND, 0);
411 * If we failed here, we might as well return and have a leak
412 * rather than continue and a bugchk
419 /* Tear down the gpadl on the vsp end */
420 if (net_dev->send_buf_gpadl_handle) {
421 ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan,
422 net_dev->send_buf_gpadl_handle);
425 * If we failed here, we might as well return and have a leak
426 * rather than continue and a bugchk
431 net_dev->send_buf_gpadl_handle = 0;
434 if (net_dev->send_buf) {
435 /* Free up the receive buffer */
436 contigfree(net_dev->send_buf, net_dev->send_buf_size, M_NETVSC);
437 net_dev->send_buf = NULL;
440 if (net_dev->send_section_bitsmap) {
441 free(net_dev->send_section_bitsmap, M_NETVSC);
449 * Attempt to negotiate the caller-specified NVSP version
451 * For NVSP v2, Server 2008 R2 does not set
452 * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
453 * to the negotiated version, so we cannot rely on that.
456 hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
462 init_pkt = &net_dev->channel_init_packet;
463 memset(init_pkt, 0, sizeof(nvsp_msg));
464 init_pkt->hdr.msg_type = nvsp_msg_type_init;
467 * Specify parameter as the only acceptable protocol version
469 init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver;
470 init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
472 /* Send the init request */
473 ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
474 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
475 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC);
479 sema_wait(&net_dev->channel_init_sema);
481 if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success)
488 * Send NDIS version 2 config packet containing MTU.
490 * Not valid for NDIS version 1.
493 hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
499 net_dev = hv_nv_get_outbound_net_device(sc);
504 * Set up configuration packet, write MTU
505 * Indicate we are capable of handling VLAN tags
507 init_pkt = &net_dev->channel_init_packet;
508 memset(init_pkt, 0, sizeof(nvsp_msg));
509 init_pkt->hdr.msg_type = nvsp_msg_2_type_send_ndis_config;
510 init_pkt->msgs.vers_2_msgs.send_ndis_config.mtu = mtu;
512 msgs.vers_2_msgs.send_ndis_config.capabilities.u1.u2.ieee8021q
515 /* Send the configuration packet */
516 ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
517 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
518 VMBUS_CHANPKT_TYPE_INBAND, 0);
526 * Net VSC connect to VSP
529 hv_nv_connect_to_vsp(struct hn_softc *sc)
533 uint32_t ndis_version;
534 uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
535 NVSP_PROTOCOL_VERSION_2,
536 NVSP_PROTOCOL_VERSION_4,
537 NVSP_PROTOCOL_VERSION_5 };
539 int protocol_number = nitems(protocol_list);
541 device_t dev = sc->hn_dev;
542 struct ifnet *ifp = sc->hn_ifp;
544 net_dev = hv_nv_get_outbound_net_device(sc);
547 * Negotiate the NVSP version. Try the latest NVSP first.
549 for (i = protocol_number - 1; i >= 0; i--) {
550 if (hv_nv_negotiate_nvsp_protocol(sc, net_dev,
551 protocol_list[i]) == 0) {
552 net_dev->nvsp_version = protocol_list[i];
554 device_printf(dev, "Netvsc: got version 0x%x\n",
555 net_dev->nvsp_version);
562 device_printf(dev, "failed to negotiate a valid "
568 * Set the MTU if supported by this NVSP protocol version
569 * This needs to be right after the NVSP init message per Haiyang
571 if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
572 ret = hv_nv_send_ndis_config(sc, ifp->if_mtu);
575 * Send the NDIS version
577 init_pkt = &net_dev->channel_init_packet;
579 memset(init_pkt, 0, sizeof(nvsp_msg));
581 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) {
582 ndis_version = NDIS_VERSION_6_1;
584 ndis_version = NDIS_VERSION_6_30;
587 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers;
588 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers =
589 (ndis_version & 0xFFFF0000) >> 16;
590 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_minor_vers =
591 ndis_version & 0xFFFF;
593 /* Send the init request */
595 ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
596 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
597 VMBUS_CHANPKT_TYPE_INBAND, 0);
602 * TODO: BUGBUG - We have to wait for the above msg since the netvsp
603 * uses KMCL which acknowledges packet (completion packet)
604 * since our Vmbus always set the VMBUS_CHANPKT_FLAG_RC flag
606 /* sema_wait(&NetVscChannel->channel_init_sema); */
608 /* Post the big receive buffer to NetVSP */
609 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
610 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
612 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
613 net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
615 ret = hv_nv_init_rx_buffer_with_net_vsp(sc);
617 ret = hv_nv_init_send_buffer_with_net_vsp(sc);
624 * Net VSC disconnect from VSP
627 hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
629 hv_nv_destroy_rx_buffer(net_dev);
630 hv_nv_destroy_send_buffer(net_dev);
634 hv_nv_subchan_attach(struct hv_vmbus_channel *chan)
637 chan->hv_chan_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK);
638 hv_vmbus_channel_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
639 NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0,
640 hv_nv_on_channel_callback, chan);
644 * Net VSC on device add
646 * Callback when the device belonging to this driver is added
649 hv_nv_on_device_add(struct hn_softc *sc, void *additional_info)
651 struct hv_vmbus_channel *chan = sc->hn_prichan;
655 net_dev = hv_nv_alloc_net_device(sc);
659 /* Initialize the NetVSC channel extension */
661 sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
663 chan->hv_chan_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK);
668 ret = hv_vmbus_channel_open(chan,
669 NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
670 NULL, 0, hv_nv_on_channel_callback, chan);
672 free(chan->hv_chan_rdbuf, M_NETVSC);
677 * Connect with the NetVsp
679 ret = hv_nv_connect_to_vsp(sc);
686 /* Now, we can close the channel safely */
687 free(chan->hv_chan_rdbuf, M_NETVSC);
688 hv_vmbus_channel_close(chan);
692 * Free the packet buffers on the netvsc device packet queue.
693 * Release other resources.
695 sema_destroy(&net_dev->channel_init_sema);
696 free(net_dev, M_NETVSC);
702 * Net VSC on device remove
705 hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
707 netvsc_dev *net_dev = sc->net_dev;;
709 /* Stop outbound traffic ie sends and receives completions */
710 net_dev->destroy = TRUE;
712 hv_nv_disconnect_from_vsp(net_dev);
714 /* At this point, no one should be accessing net_dev except in here */
716 /* Now, we can close the channel safely */
718 free(sc->hn_prichan->hv_chan_rdbuf, M_NETVSC);
719 hv_vmbus_channel_close(sc->hn_prichan);
721 sema_destroy(&net_dev->channel_init_sema);
722 free(net_dev, M_NETVSC);
728 * Net VSC on send completion
731 hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan,
732 hv_vm_packet_descriptor *pkt)
734 nvsp_msg *nvsp_msg_pkt;
735 netvsc_packet *net_vsc_pkt;
738 (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
740 if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete
741 || nvsp_msg_pkt->hdr.msg_type
742 == nvsp_msg_1_type_send_rx_buf_complete
743 || nvsp_msg_pkt->hdr.msg_type
744 == nvsp_msg_1_type_send_send_buf_complete
745 || nvsp_msg_pkt->hdr.msg_type
746 == nvsp_msg5_type_subchannel) {
747 /* Copy the response back */
748 memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt,
750 sema_post(&net_dev->channel_init_sema);
751 } else if (nvsp_msg_pkt->hdr.msg_type ==
752 nvsp_msg_1_type_send_rndis_pkt_complete) {
753 /* Get the send context */
755 (netvsc_packet *)(unsigned long)pkt->transaction_id;
756 if (NULL != net_vsc_pkt) {
757 if (net_vsc_pkt->send_buf_section_idx !=
758 NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
762 idx = net_vsc_pkt->send_buf_section_idx /
764 KASSERT(idx < net_dev->bitsmap_words,
765 ("invalid section index %u",
766 net_vsc_pkt->send_buf_section_idx));
768 (net_vsc_pkt->send_buf_section_idx %
771 KASSERT(net_dev->send_section_bitsmap[idx] &
773 ("index bitmap 0x%lx, section index %u, "
774 "bitmap idx %d, bitmask 0x%lx",
775 net_dev->send_section_bitsmap[idx],
776 net_vsc_pkt->send_buf_section_idx,
779 &net_dev->send_section_bitsmap[idx], mask);
782 /* Notify the layer above us */
783 net_vsc_pkt->compl.send.on_send_completion(chan,
784 net_vsc_pkt->compl.send.send_completion_context);
792 * Sends a packet on the specified Hyper-V device.
793 * Returns 0 on success, non-zero on failure.
796 hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt)
801 send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
802 if (pkt->is_data_pkt) {
804 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
806 /* 1 is RMC_CONTROL */
807 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
810 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
811 pkt->send_buf_section_idx;
812 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
813 pkt->send_buf_section_size;
816 ret = vmbus_chan_send_sglist(chan, pkt->gpa, pkt->gpa_cnt,
817 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
819 ret = hv_vmbus_channel_send_packet(chan,
820 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt,
821 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC);
830 * In the FreeBSD Hyper-V virtual world, this function deals exclusively
831 * with virtual addresses.
834 hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc,
835 struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt)
837 hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
838 nvsp_msg *nvsp_msg_pkt;
839 netvsc_packet vsc_pkt;
840 netvsc_packet *net_vsc_pkt = &vsc_pkt;
841 device_t dev = sc->hn_dev;
844 int status = nvsp_status_success;
847 * All inbound packets other than send completion should be
850 if (pkt->type != VMBUS_CHANPKT_TYPE_RXBUF) {
851 device_printf(dev, "packet type %d is invalid!\n", pkt->type);
855 nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt
856 + (pkt->data_offset8 << 3));
858 /* Make sure this is a valid nvsp packet */
859 if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
860 device_printf(dev, "packet hdr type %d is invalid!\n",
865 vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt;
867 if (vm_xfer_page_pkt->transfer_page_set_id !=
868 NETVSC_RECEIVE_BUFFER_ID) {
869 device_printf(dev, "transfer_page_set_id %d is invalid!\n",
870 vm_xfer_page_pkt->transfer_page_set_id);
874 count = vm_xfer_page_pkt->range_count;
876 /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
877 for (i = 0; i < count; i++) {
878 net_vsc_pkt->status = nvsp_status_success;
879 net_vsc_pkt->data = (void *)((unsigned long)net_dev->rx_buf +
880 vm_xfer_page_pkt->ranges[i].byte_offset);
881 net_vsc_pkt->tot_data_buf_len =
882 vm_xfer_page_pkt->ranges[i].byte_count;
884 hv_rf_on_receive(net_dev, chan, net_vsc_pkt);
885 if (net_vsc_pkt->status != nvsp_status_success) {
886 status = nvsp_status_failure;
891 * Moved completion call back here so that all received
892 * messages (not just data messages) will trigger a response
893 * message back to the host.
895 hv_nv_on_receive_completion(chan, vm_xfer_page_pkt->d.transaction_id,
900 * Net VSC on receive completion
902 * Send a receive completion packet to RNDIS device (ie NetVsp)
905 hv_nv_on_receive_completion(struct hv_vmbus_channel *chan, uint64_t tid,
908 nvsp_msg rx_comp_msg;
912 rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete;
914 /* Pass in the status */
915 rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
919 /* Send the completion */
920 ret = hv_vmbus_channel_send_packet(chan, &rx_comp_msg,
921 sizeof(nvsp_msg), tid, VMBUS_CHANPKT_TYPE_COMP, 0);
925 } else if (ret == EAGAIN) {
926 /* no more room... wait a bit and attempt to retry 3 times */
931 goto retry_send_cmplt;
937 * Net VSC receiving vRSS send table from VSP
940 hv_nv_send_table(struct hn_softc *sc, hv_vm_packet_descriptor *pkt)
943 nvsp_msg *nvsp_msg_pkt;
945 uint32_t count, *table;
947 net_dev = hv_nv_get_inbound_net_device(sc);
952 (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
954 if (nvsp_msg_pkt->hdr.msg_type !=
955 nvsp_msg5_type_send_indirection_table) {
956 printf("Netvsc: !Warning! receive msg type not "
957 "send_indirection_table. type = %d\n",
958 nvsp_msg_pkt->hdr.msg_type);
962 count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count;
963 if (count != VRSS_SEND_TABLE_SIZE) {
964 printf("Netvsc: Received wrong send table size: %u\n", count);
969 ((unsigned long)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
970 nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);
972 for (i = 0; i < count; i++)
973 net_dev->vrss_send_table[i] = table[i];
977 * Net VSC on channel callback
980 hv_nv_on_channel_callback(void *xchan)
982 struct hv_vmbus_channel *chan = xchan;
983 device_t dev = chan->ch_dev;
984 struct hn_softc *sc = device_get_softc(dev);
988 hv_vm_packet_descriptor *desc;
990 int bufferlen = NETVSC_PACKET_SIZE;
993 net_dev = hv_nv_get_inbound_net_device(sc);
997 buffer = chan->hv_chan_rdbuf;
1000 ret = hv_vmbus_channel_recv_packet_raw(chan,
1001 buffer, bufferlen, &bytes_rxed, &request_id);
1003 if (bytes_rxed > 0) {
1004 desc = (hv_vm_packet_descriptor *)buffer;
1005 switch (desc->type) {
1006 case VMBUS_CHANPKT_TYPE_COMP:
1007 hv_nv_on_send_completion(net_dev, chan,
1010 case VMBUS_CHANPKT_TYPE_RXBUF:
1011 hv_nv_on_receive(net_dev, sc, chan, desc);
1013 case VMBUS_CHANPKT_TYPE_INBAND:
1014 hv_nv_send_table(sc, desc);
1018 "hv_cb recv unknow type %d "
1019 " packet\n", desc->type);
1025 } else if (ret == ENOBUFS) {
1026 /* Handle large packet */
1027 if (bufferlen > NETVSC_PACKET_SIZE) {
1028 free(buffer, M_NETVSC);
1032 /* alloc new buffer */
1033 buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
1034 if (buffer == NULL) {
1036 "hv_cb malloc buffer failed, len=%u\n",
1041 bufferlen = bytes_rxed;
1045 if (bufferlen > NETVSC_PACKET_SIZE)
1046 free(buffer, M_NETVSC);
1048 hv_rf_channel_rollup(chan);