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 ch_dev_rdbuf ch_dev_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 *, const struct vmbus_chanpkt_hdr *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 const struct vmbus_chanpkt_hdr *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 = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
156 PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma,
157 BUS_DMA_WAITOK | BUS_DMA_ZERO);
158 if (net_dev->rx_buf == NULL) {
159 device_printf(sc->hn_dev, "allocate rxbuf failed\n");
164 * Connect the RXBUF GPADL to the primary channel.
167 * Only primary channel has RXBUF connected to it. Sub-channels
168 * just share this RXBUF.
170 ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
171 net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size,
172 &net_dev->rx_buf_gpadl_handle);
174 device_printf(sc->hn_dev, "rxbuf gpadl connect failed: %d\n",
179 /* sema_wait(&ext->channel_init_sema); KYS CHECK */
181 /* Notify the NetVsp of the gpadl handle */
182 init_pkt = &net_dev->channel_init_packet;
184 memset(init_pkt, 0, sizeof(nvsp_msg));
186 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
187 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
188 net_dev->rx_buf_gpadl_handle;
189 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
190 NETVSC_RECEIVE_BUFFER_ID;
192 /* Send the gpadl notification request */
194 ret = vmbus_chan_send(sc->hn_prichan,
195 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
196 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
201 sema_wait(&net_dev->channel_init_sema);
203 /* Check the response */
204 if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
205 != nvsp_status_success) {
210 net_dev->rx_section_count =
211 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
213 net_dev->rx_sections = malloc(net_dev->rx_section_count *
214 sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
215 memcpy(net_dev->rx_sections,
216 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
217 net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));
221 * For first release, there should only be 1 section that represents
222 * the entire receive buffer
224 if (net_dev->rx_section_count != 1
225 || net_dev->rx_sections->offset != 0) {
233 hv_nv_destroy_rx_buffer(net_dev);
240 * Net VSC initialize send buffer with net VSP
243 hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
249 net_dev = hv_nv_get_outbound_net_device(sc);
254 net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
255 PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma,
256 BUS_DMA_WAITOK | BUS_DMA_ZERO);
257 if (net_dev->send_buf == NULL) {
258 device_printf(sc->hn_dev, "allocate chimney txbuf failed\n");
263 * Connect chimney sending buffer GPADL to the primary channel.
266 * Only primary channel has chimney sending buffer connected to it.
267 * Sub-channels just share this chimney sending buffer.
269 ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
270 net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size,
271 &net_dev->send_buf_gpadl_handle);
273 device_printf(sc->hn_dev, "chimney sending buffer gpadl "
274 "connect failed: %d\n", ret);
278 /* Notify the NetVsp of the gpadl handle */
280 init_pkt = &net_dev->channel_init_packet;
282 memset(init_pkt, 0, sizeof(nvsp_msg));
284 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
285 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
286 net_dev->send_buf_gpadl_handle;
287 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
288 NETVSC_SEND_BUFFER_ID;
290 /* Send the gpadl notification request */
292 ret = vmbus_chan_send(sc->hn_prichan,
293 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
294 init_pkt, sizeof(nvsp_msg), (uint64_t)init_pkt);
299 sema_wait(&net_dev->channel_init_sema);
301 /* Check the response */
302 if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
303 != nvsp_status_success) {
308 net_dev->send_section_size =
309 init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
310 net_dev->send_section_count =
311 net_dev->send_buf_size / net_dev->send_section_size;
312 net_dev->bitsmap_words = howmany(net_dev->send_section_count,
314 net_dev->send_section_bitsmap =
315 malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
321 hv_nv_destroy_send_buffer(net_dev);
328 * Net VSC destroy receive buffer
331 hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
333 nvsp_msg *revoke_pkt;
337 * If we got a section count, it means we received a
338 * send_rx_buf_complete msg
339 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
340 * we need to send a revoke msg here
342 if (net_dev->rx_section_count) {
343 /* Send the revoke receive buffer */
344 revoke_pkt = &net_dev->revoke_packet;
345 memset(revoke_pkt, 0, sizeof(nvsp_msg));
347 revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf;
348 revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
349 NETVSC_RECEIVE_BUFFER_ID;
351 ret = vmbus_chan_send(net_dev->sc->hn_prichan,
352 VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
353 (uint64_t)(uintptr_t)revoke_pkt);
356 * If we failed here, we might as well return and have a leak
357 * rather than continue and a bugchk
364 /* Tear down the gpadl on the vsp end */
365 if (net_dev->rx_buf_gpadl_handle) {
366 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
367 net_dev->rx_buf_gpadl_handle);
369 * If we failed here, we might as well return and have a leak
370 * rather than continue and a bugchk
375 net_dev->rx_buf_gpadl_handle = 0;
378 if (net_dev->rx_buf) {
379 /* Free up the receive buffer */
380 hyperv_dmamem_free(&net_dev->rxbuf_dma, net_dev->rx_buf);
381 net_dev->rx_buf = NULL;
384 if (net_dev->rx_sections) {
385 free(net_dev->rx_sections, M_NETVSC);
386 net_dev->rx_sections = NULL;
387 net_dev->rx_section_count = 0;
394 * Net VSC destroy send buffer
397 hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
399 nvsp_msg *revoke_pkt;
403 * If we got a section count, it means we received a
404 * send_rx_buf_complete msg
405 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
406 * we need to send a revoke msg here
408 if (net_dev->send_section_size) {
409 /* Send the revoke send buffer */
410 revoke_pkt = &net_dev->revoke_packet;
411 memset(revoke_pkt, 0, sizeof(nvsp_msg));
413 revoke_pkt->hdr.msg_type =
414 nvsp_msg_1_type_revoke_send_buf;
415 revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id =
416 NETVSC_SEND_BUFFER_ID;
418 ret = vmbus_chan_send(net_dev->sc->hn_prichan,
419 VMBUS_CHANPKT_TYPE_INBAND, 0,
420 revoke_pkt, sizeof(nvsp_msg),
421 (uint64_t)(uintptr_t)revoke_pkt);
423 * If we failed here, we might as well return and have a leak
424 * rather than continue and a bugchk
431 /* Tear down the gpadl on the vsp end */
432 if (net_dev->send_buf_gpadl_handle) {
433 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
434 net_dev->send_buf_gpadl_handle);
437 * If we failed here, we might as well return and have a leak
438 * rather than continue and a bugchk
443 net_dev->send_buf_gpadl_handle = 0;
446 if (net_dev->send_buf) {
447 /* Free up the receive buffer */
448 hyperv_dmamem_free(&net_dev->txbuf_dma, net_dev->send_buf);
449 net_dev->send_buf = NULL;
452 if (net_dev->send_section_bitsmap) {
453 free(net_dev->send_section_bitsmap, M_NETVSC);
461 * Attempt to negotiate the caller-specified NVSP version
463 * For NVSP v2, Server 2008 R2 does not set
464 * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
465 * to the negotiated version, so we cannot rely on that.
468 hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
474 init_pkt = &net_dev->channel_init_packet;
475 memset(init_pkt, 0, sizeof(nvsp_msg));
476 init_pkt->hdr.msg_type = nvsp_msg_type_init;
479 * Specify parameter as the only acceptable protocol version
481 init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver;
482 init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
484 /* Send the init request */
485 ret = vmbus_chan_send(sc->hn_prichan,
486 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
487 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
491 sema_wait(&net_dev->channel_init_sema);
493 if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success)
500 * Send NDIS version 2 config packet containing MTU.
502 * Not valid for NDIS version 1.
505 hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
511 net_dev = hv_nv_get_outbound_net_device(sc);
516 * Set up configuration packet, write MTU
517 * Indicate we are capable of handling VLAN tags
519 init_pkt = &net_dev->channel_init_packet;
520 memset(init_pkt, 0, sizeof(nvsp_msg));
521 init_pkt->hdr.msg_type = nvsp_msg_2_type_send_ndis_config;
522 init_pkt->msgs.vers_2_msgs.send_ndis_config.mtu = mtu;
524 msgs.vers_2_msgs.send_ndis_config.capabilities.u1.u2.ieee8021q
527 /* Send the configuration packet */
528 ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
529 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
537 * Net VSC connect to VSP
540 hv_nv_connect_to_vsp(struct hn_softc *sc)
544 uint32_t ndis_version;
545 uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
546 NVSP_PROTOCOL_VERSION_2,
547 NVSP_PROTOCOL_VERSION_4,
548 NVSP_PROTOCOL_VERSION_5 };
550 int protocol_number = nitems(protocol_list);
552 device_t dev = sc->hn_dev;
553 struct ifnet *ifp = sc->hn_ifp;
555 net_dev = hv_nv_get_outbound_net_device(sc);
558 * Negotiate the NVSP version. Try the latest NVSP first.
560 for (i = protocol_number - 1; i >= 0; i--) {
561 if (hv_nv_negotiate_nvsp_protocol(sc, net_dev,
562 protocol_list[i]) == 0) {
563 net_dev->nvsp_version = protocol_list[i];
565 device_printf(dev, "Netvsc: got version 0x%x\n",
566 net_dev->nvsp_version);
573 device_printf(dev, "failed to negotiate a valid "
579 * Set the MTU if supported by this NVSP protocol version
580 * This needs to be right after the NVSP init message per Haiyang
582 if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
583 ret = hv_nv_send_ndis_config(sc, ifp->if_mtu);
586 * Send the NDIS version
588 init_pkt = &net_dev->channel_init_packet;
590 memset(init_pkt, 0, sizeof(nvsp_msg));
592 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) {
593 ndis_version = NDIS_VERSION_6_1;
595 ndis_version = NDIS_VERSION_6_30;
598 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers;
599 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers =
600 (ndis_version & 0xFFFF0000) >> 16;
601 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_minor_vers =
602 ndis_version & 0xFFFF;
604 /* Send the init request */
606 ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
607 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
612 * TODO: BUGBUG - We have to wait for the above msg since the netvsp
613 * uses KMCL which acknowledges packet (completion packet)
614 * since our Vmbus always set the VMBUS_CHANPKT_FLAG_RC flag
616 /* sema_wait(&NetVscChannel->channel_init_sema); */
618 /* Post the big receive buffer to NetVSP */
619 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
620 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
622 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
623 net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
625 ret = hv_nv_init_rx_buffer_with_net_vsp(sc);
627 ret = hv_nv_init_send_buffer_with_net_vsp(sc);
634 * Net VSC disconnect from VSP
637 hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
639 hv_nv_destroy_rx_buffer(net_dev);
640 hv_nv_destroy_send_buffer(net_dev);
644 hv_nv_subchan_attach(struct hv_vmbus_channel *chan)
647 chan->ch_dev_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK);
648 vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
649 NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0,
650 hv_nv_on_channel_callback, chan);
654 * Net VSC on device add
656 * Callback when the device belonging to this driver is added
659 hv_nv_on_device_add(struct hn_softc *sc, void *additional_info)
661 struct hv_vmbus_channel *chan = sc->hn_prichan;
665 net_dev = hv_nv_alloc_net_device(sc);
669 /* Initialize the NetVSC channel extension */
671 sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
673 chan->ch_dev_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK);
678 ret = vmbus_chan_open(chan,
679 NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
680 NULL, 0, hv_nv_on_channel_callback, chan);
682 free(chan->ch_dev_rdbuf, M_NETVSC);
687 * Connect with the NetVsp
689 ret = hv_nv_connect_to_vsp(sc);
696 /* Now, we can close the channel safely */
697 free(chan->ch_dev_rdbuf, M_NETVSC);
698 vmbus_chan_close(chan);
702 * Free the packet buffers on the netvsc device packet queue.
703 * Release other resources.
705 sema_destroy(&net_dev->channel_init_sema);
706 free(net_dev, M_NETVSC);
712 * Net VSC on device remove
715 hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
717 netvsc_dev *net_dev = sc->net_dev;;
719 /* Stop outbound traffic ie sends and receives completions */
720 net_dev->destroy = TRUE;
722 hv_nv_disconnect_from_vsp(net_dev);
724 /* At this point, no one should be accessing net_dev except in here */
726 /* Now, we can close the channel safely */
728 free(sc->hn_prichan->ch_dev_rdbuf, M_NETVSC);
729 vmbus_chan_close(sc->hn_prichan);
731 sema_destroy(&net_dev->channel_init_sema);
732 free(net_dev, M_NETVSC);
738 * Net VSC on send completion
741 hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan,
742 const struct vmbus_chanpkt_hdr *pkt)
744 const nvsp_msg *nvsp_msg_pkt;
745 netvsc_packet *net_vsc_pkt;
747 nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
749 if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete
750 || nvsp_msg_pkt->hdr.msg_type
751 == nvsp_msg_1_type_send_rx_buf_complete
752 || nvsp_msg_pkt->hdr.msg_type
753 == nvsp_msg_1_type_send_send_buf_complete
754 || nvsp_msg_pkt->hdr.msg_type
755 == nvsp_msg5_type_subchannel) {
756 /* Copy the response back */
757 memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt,
759 sema_post(&net_dev->channel_init_sema);
760 } else if (nvsp_msg_pkt->hdr.msg_type ==
761 nvsp_msg_1_type_send_rndis_pkt_complete) {
762 /* Get the send context */
764 (netvsc_packet *)(unsigned long)pkt->cph_xactid;
765 if (NULL != net_vsc_pkt) {
766 if (net_vsc_pkt->send_buf_section_idx !=
767 NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
771 idx = net_vsc_pkt->send_buf_section_idx /
773 KASSERT(idx < net_dev->bitsmap_words,
774 ("invalid section index %u",
775 net_vsc_pkt->send_buf_section_idx));
777 (net_vsc_pkt->send_buf_section_idx %
780 KASSERT(net_dev->send_section_bitsmap[idx] &
782 ("index bitmap 0x%lx, section index %u, "
783 "bitmap idx %d, bitmask 0x%lx",
784 net_dev->send_section_bitsmap[idx],
785 net_vsc_pkt->send_buf_section_idx,
788 &net_dev->send_section_bitsmap[idx], mask);
791 /* Notify the layer above us */
792 net_vsc_pkt->compl.send.on_send_completion(chan,
793 net_vsc_pkt->compl.send.send_completion_context);
801 * Sends a packet on the specified Hyper-V device.
802 * Returns 0 on success, non-zero on failure.
805 hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt)
810 send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
811 if (pkt->is_data_pkt) {
813 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
815 /* 1 is RMC_CONTROL */
816 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
819 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
820 pkt->send_buf_section_idx;
821 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
822 pkt->send_buf_section_size;
825 ret = vmbus_chan_send_sglist(chan, pkt->gpa, pkt->gpa_cnt,
826 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
828 ret = vmbus_chan_send(chan,
829 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
830 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
839 * In the FreeBSD Hyper-V virtual world, this function deals exclusively
840 * with virtual addresses.
843 hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc,
844 struct hv_vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
846 const struct vmbus_chanpkt_rxbuf *pkt;
847 const nvsp_msg *nvsp_msg_pkt;
848 netvsc_packet vsc_pkt;
849 netvsc_packet *net_vsc_pkt = &vsc_pkt;
850 device_t dev = sc->hn_dev;
853 int status = nvsp_status_success;
855 nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);
857 /* Make sure this is a valid nvsp packet */
858 if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
859 device_printf(dev, "packet hdr type %u is invalid!\n",
860 nvsp_msg_pkt->hdr.msg_type);
864 pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
866 if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
867 device_printf(dev, "rxbuf_id %d is invalid!\n",
872 count = pkt->cp_rxbuf_cnt;
874 /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
875 for (i = 0; i < count; i++) {
876 net_vsc_pkt->status = nvsp_status_success;
877 net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
878 pkt->cp_rxbuf[i].rb_ofs);
879 net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
881 hv_rf_on_receive(net_dev, chan, net_vsc_pkt);
882 if (net_vsc_pkt->status != nvsp_status_success) {
883 status = nvsp_status_failure;
888 * Moved completion call back here so that all received
889 * messages (not just data messages) will trigger a response
890 * message back to the host.
892 hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
896 * Net VSC on receive completion
898 * Send a receive completion packet to RNDIS device (ie NetVsp)
901 hv_nv_on_receive_completion(struct hv_vmbus_channel *chan, uint64_t tid,
904 nvsp_msg rx_comp_msg;
908 rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete;
910 /* Pass in the status */
911 rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
915 /* Send the completion */
916 ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, 0,
917 &rx_comp_msg, sizeof(nvsp_msg), tid);
921 } else if (ret == EAGAIN) {
922 /* no more room... wait a bit and attempt to retry 3 times */
927 goto retry_send_cmplt;
933 * Net VSC receiving vRSS send table from VSP
936 hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
939 const nvsp_msg *nvsp_msg_pkt;
942 const uint32_t *table;
944 net_dev = hv_nv_get_inbound_net_device(sc);
948 nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
950 if (nvsp_msg_pkt->hdr.msg_type !=
951 nvsp_msg5_type_send_indirection_table) {
952 printf("Netvsc: !Warning! receive msg type not "
953 "send_indirection_table. type = %d\n",
954 nvsp_msg_pkt->hdr.msg_type);
958 count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count;
959 if (count != VRSS_SEND_TABLE_SIZE) {
960 printf("Netvsc: Received wrong send table size: %u\n", count);
964 table = (const uint32_t *)
965 ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
966 nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);
968 for (i = 0; i < count; i++)
969 net_dev->vrss_send_table[i] = table[i];
973 * Net VSC on channel callback
976 hv_nv_on_channel_callback(void *xchan)
978 struct hv_vmbus_channel *chan = xchan;
979 device_t dev = chan->ch_dev;
980 struct hn_softc *sc = device_get_softc(dev);
983 int bufferlen = NETVSC_PACKET_SIZE;
985 net_dev = hv_nv_get_inbound_net_device(sc);
989 buffer = chan->ch_dev_rdbuf;
991 struct vmbus_chanpkt_hdr *pkt = buffer;
995 bytes_rxed = bufferlen;
996 ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
998 if (bytes_rxed > 0) {
999 switch (pkt->cph_type) {
1000 case VMBUS_CHANPKT_TYPE_COMP:
1001 hv_nv_on_send_completion(net_dev, chan,
1004 case VMBUS_CHANPKT_TYPE_RXBUF:
1005 hv_nv_on_receive(net_dev, sc, chan, pkt);
1007 case VMBUS_CHANPKT_TYPE_INBAND:
1008 hv_nv_send_table(sc, pkt);
1012 "unknown chan pkt %u\n",
1017 } else if (ret == ENOBUFS) {
1018 /* Handle large packet */
1019 if (bufferlen > NETVSC_PACKET_SIZE) {
1020 free(buffer, M_NETVSC);
1024 /* alloc new buffer */
1025 buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
1026 if (buffer == NULL) {
1028 "hv_cb malloc buffer failed, len=%u\n",
1033 bufferlen = bytes_rxed;
1035 /* No more packets */
1040 if (bufferlen > NETVSC_PACKET_SIZE)
1041 free(buffer, M_NETVSC);
1043 hv_rf_channel_rollup(chan);