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_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(struct vmbus_channel *chan,
58 static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc);
59 static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *);
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 hn_softc *sc);
63 static void hv_nv_on_send_completion(netvsc_dev *net_dev,
64 struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt);
65 static void hv_nv_on_receive_completion(struct vmbus_channel *chan,
66 uint64_t tid, uint32_t status);
67 static void hv_nv_on_receive(netvsc_dev *net_dev,
68 struct hn_rx_ring *rxr, struct vmbus_channel *chan,
69 const struct vmbus_chanpkt_hdr *pkt);
70 static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
71 struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
72 const struct nvsp_msg_ *msg);
74 static struct hn_send_ctx hn_send_ctx_none =
75 HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
80 static inline netvsc_dev *
81 hv_nv_alloc_net_device(struct hn_softc *sc)
85 net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
88 net_dev->destroy = FALSE;
89 sc->net_dev = net_dev;
95 * XXX unnecessary; nuke it.
97 static inline netvsc_dev *
98 hv_nv_get_outbound_net_device(struct hn_softc *sc)
104 * XXX unnecessary; nuke it.
106 static inline netvsc_dev *
107 hv_nv_get_inbound_net_device(struct hn_softc *sc)
113 hv_nv_get_next_send_section(netvsc_dev *net_dev)
115 unsigned long bitsmap_words = net_dev->bitsmap_words;
116 unsigned long *bitsmap = net_dev->send_section_bitsmap;
118 int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
121 for (i = 0; i < bitsmap_words; i++) {
122 idx = ffsl(~bitsmap[i]);
127 KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count,
128 ("invalid i %d and idx %lu", i, idx));
130 if (atomic_testandset_long(&bitsmap[i], idx))
133 ret = i * BITS_PER_LONG + idx;
141 * Net VSC initialize receive buffer with net VSP
143 * Net VSP: Network virtual services client, also known as the
144 * Hyper-V extensible switch and the synthetic data path.
147 hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
149 struct hn_send_ctx sndc;
154 net_dev = hv_nv_get_outbound_net_device(sc);
159 net_dev->rx_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
160 PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma,
161 BUS_DMA_WAITOK | BUS_DMA_ZERO);
162 if (net_dev->rx_buf == NULL) {
163 device_printf(sc->hn_dev, "allocate rxbuf failed\n");
168 * Connect the RXBUF GPADL to the primary channel.
171 * Only primary channel has RXBUF connected to it. Sub-channels
172 * just share this RXBUF.
174 ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
175 net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size,
176 &net_dev->rx_buf_gpadl_handle);
178 device_printf(sc->hn_dev, "rxbuf gpadl connect failed: %d\n",
183 /* sema_wait(&ext->channel_init_sema); KYS CHECK */
185 /* Notify the NetVsp of the gpadl handle */
186 init_pkt = &net_dev->channel_init_packet;
188 memset(init_pkt, 0, sizeof(nvsp_msg));
190 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
191 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
192 net_dev->rx_buf_gpadl_handle;
193 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
194 NETVSC_RECEIVE_BUFFER_ID;
196 /* Send the gpadl notification request */
198 hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
199 ret = vmbus_chan_send(sc->hn_prichan,
200 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
201 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
206 sema_wait(&net_dev->channel_init_sema);
208 /* Check the response */
209 if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
210 != nvsp_status_success) {
215 net_dev->rx_section_count =
216 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
218 net_dev->rx_sections = malloc(net_dev->rx_section_count *
219 sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
220 memcpy(net_dev->rx_sections,
221 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
222 net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));
226 * For first release, there should only be 1 section that represents
227 * the entire receive buffer
229 if (net_dev->rx_section_count != 1
230 || net_dev->rx_sections->offset != 0) {
238 hv_nv_destroy_rx_buffer(net_dev);
245 * Net VSC initialize send buffer with net VSP
248 hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
250 struct hn_send_ctx sndc;
255 net_dev = hv_nv_get_outbound_net_device(sc);
260 net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
261 PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma,
262 BUS_DMA_WAITOK | BUS_DMA_ZERO);
263 if (net_dev->send_buf == NULL) {
264 device_printf(sc->hn_dev, "allocate chimney txbuf failed\n");
269 * Connect chimney sending buffer GPADL to the primary channel.
272 * Only primary channel has chimney sending buffer connected to it.
273 * Sub-channels just share this chimney sending buffer.
275 ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
276 net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size,
277 &net_dev->send_buf_gpadl_handle);
279 device_printf(sc->hn_dev, "chimney sending buffer gpadl "
280 "connect failed: %d\n", ret);
284 /* Notify the NetVsp of the gpadl handle */
286 init_pkt = &net_dev->channel_init_packet;
288 memset(init_pkt, 0, sizeof(nvsp_msg));
290 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
291 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
292 net_dev->send_buf_gpadl_handle;
293 init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
294 NETVSC_SEND_BUFFER_ID;
296 /* Send the gpadl notification request */
298 hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
299 ret = vmbus_chan_send(sc->hn_prichan,
300 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
301 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
306 sema_wait(&net_dev->channel_init_sema);
308 /* Check the response */
309 if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
310 != nvsp_status_success) {
315 net_dev->send_section_size =
316 init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
317 net_dev->send_section_count =
318 net_dev->send_buf_size / net_dev->send_section_size;
319 net_dev->bitsmap_words = howmany(net_dev->send_section_count,
321 net_dev->send_section_bitsmap =
322 malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
328 hv_nv_destroy_send_buffer(net_dev);
335 * Net VSC destroy receive buffer
338 hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
340 nvsp_msg *revoke_pkt;
344 * If we got a section count, it means we received a
345 * send_rx_buf_complete msg
346 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
347 * we need to send a revoke msg here
349 if (net_dev->rx_section_count) {
350 /* Send the revoke receive buffer */
351 revoke_pkt = &net_dev->revoke_packet;
352 memset(revoke_pkt, 0, sizeof(nvsp_msg));
354 revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf;
355 revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
356 NETVSC_RECEIVE_BUFFER_ID;
358 ret = vmbus_chan_send(net_dev->sc->hn_prichan,
359 VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
360 (uint64_t)(uintptr_t)&hn_send_ctx_none);
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 = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
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 hyperv_dmamem_free(&net_dev->rxbuf_dma, net_dev->rx_buf);
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 = vmbus_chan_send(net_dev->sc->hn_prichan,
425 VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
426 (uint64_t)(uintptr_t)&hn_send_ctx_none);
428 * If we failed here, we might as well return and have a leak
429 * rather than continue and a bugchk
436 /* Tear down the gpadl on the vsp end */
437 if (net_dev->send_buf_gpadl_handle) {
438 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
439 net_dev->send_buf_gpadl_handle);
442 * If we failed here, we might as well return and have a leak
443 * rather than continue and a bugchk
448 net_dev->send_buf_gpadl_handle = 0;
451 if (net_dev->send_buf) {
452 /* Free up the receive buffer */
453 hyperv_dmamem_free(&net_dev->txbuf_dma, net_dev->send_buf);
454 net_dev->send_buf = NULL;
457 if (net_dev->send_section_bitsmap) {
458 free(net_dev->send_section_bitsmap, M_NETVSC);
466 * Attempt to negotiate the caller-specified NVSP version
468 * For NVSP v2, Server 2008 R2 does not set
469 * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
470 * to the negotiated version, so we cannot rely on that.
473 hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
476 struct hn_send_ctx sndc;
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 hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
492 ret = vmbus_chan_send(sc->hn_prichan,
493 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
494 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
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 hn_softc *sc, uint32_t mtu)
518 net_dev = hv_nv_get_outbound_net_device(sc);
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 = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
536 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none);
544 * Net VSC connect to VSP
547 hv_nv_connect_to_vsp(struct hn_softc *sc)
551 uint32_t ndis_version;
552 uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
553 NVSP_PROTOCOL_VERSION_2,
554 NVSP_PROTOCOL_VERSION_4,
555 NVSP_PROTOCOL_VERSION_5 };
557 int protocol_number = nitems(protocol_list);
559 device_t dev = sc->hn_dev;
560 struct ifnet *ifp = sc->arpcom.ac_ifp;
562 net_dev = hv_nv_get_outbound_net_device(sc);
565 * Negotiate the NVSP version. Try the latest NVSP first.
567 for (i = protocol_number - 1; i >= 0; i--) {
568 if (hv_nv_negotiate_nvsp_protocol(sc, net_dev,
569 protocol_list[i]) == 0) {
570 net_dev->nvsp_version = protocol_list[i];
572 device_printf(dev, "Netvsc: got version 0x%x\n",
573 net_dev->nvsp_version);
580 device_printf(dev, "failed to negotiate a valid "
586 * Set the MTU if supported by this NVSP protocol version
587 * This needs to be right after the NVSP init message per Haiyang
589 if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
590 ret = hv_nv_send_ndis_config(sc, ifp->if_mtu);
593 * Send the NDIS version
595 init_pkt = &net_dev->channel_init_packet;
597 memset(init_pkt, 0, sizeof(nvsp_msg));
599 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) {
600 ndis_version = NDIS_VERSION_6_1;
602 ndis_version = NDIS_VERSION_6_30;
605 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers;
606 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers =
607 (ndis_version & 0xFFFF0000) >> 16;
608 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_minor_vers =
609 ndis_version & 0xFFFF;
611 /* Send the init request */
613 ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
614 init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none);
619 * TODO: BUGBUG - We have to wait for the above msg since the netvsp
620 * uses KMCL which acknowledges packet (completion packet)
621 * since our Vmbus always set the VMBUS_CHANPKT_FLAG_RC flag
623 /* sema_wait(&NetVscChannel->channel_init_sema); */
625 /* Post the big receive buffer to NetVSP */
626 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
627 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
629 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
630 net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
632 ret = hv_nv_init_rx_buffer_with_net_vsp(sc);
634 ret = hv_nv_init_send_buffer_with_net_vsp(sc);
641 * Net VSC disconnect from VSP
644 hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
646 hv_nv_destroy_rx_buffer(net_dev);
647 hv_nv_destroy_send_buffer(net_dev);
651 hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr)
653 KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan),
654 ("chan%u subidx %u, rxr%d mismatch",
655 vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx));
656 vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
657 NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0,
658 hv_nv_on_channel_callback, rxr);
662 * Net VSC on device add
664 * Callback when the device belonging to this driver is added
667 hv_nv_on_device_add(struct hn_softc *sc, void *additional_info,
668 struct hn_rx_ring *rxr)
670 struct vmbus_channel *chan = sc->hn_prichan;
674 net_dev = hv_nv_alloc_net_device(sc);
678 /* Initialize the NetVSC channel extension */
680 sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
685 KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan),
686 ("chan%u subidx %u, rxr%d mismatch",
687 vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx));
688 ret = vmbus_chan_open(chan,
689 NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
690 NULL, 0, hv_nv_on_channel_callback, rxr);
695 * Connect with the NetVsp
697 ret = hv_nv_connect_to_vsp(sc);
704 /* Now, we can close the channel safely */
705 vmbus_chan_close(chan);
709 * Free the packet buffers on the netvsc device packet queue.
710 * Release other resources.
712 sema_destroy(&net_dev->channel_init_sema);
713 free(net_dev, M_NETVSC);
719 * Net VSC on device remove
722 hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
724 netvsc_dev *net_dev = sc->net_dev;;
726 /* Stop outbound traffic ie sends and receives completions */
727 net_dev->destroy = TRUE;
729 hv_nv_disconnect_from_vsp(net_dev);
731 /* At this point, no one should be accessing net_dev except in here */
733 /* Now, we can close the channel safely */
735 vmbus_chan_close(sc->hn_prichan);
737 sema_destroy(&net_dev->channel_init_sema);
738 free(net_dev, M_NETVSC);
744 hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused,
745 struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused,
746 const struct nvsp_msg_ *msg)
748 /* Copy the response back */
749 memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg));
750 sema_post(&net_dev->channel_init_sema);
754 hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
755 struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
756 const struct nvsp_msg_ *msg __unused)
762 hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx)
767 idx = chim_idx / BITS_PER_LONG;
768 KASSERT(idx < net_dev->bitsmap_words,
769 ("invalid chimney index 0x%x", chim_idx));
771 mask = 1UL << (chim_idx % BITS_PER_LONG);
772 KASSERT(net_dev->send_section_bitsmap[idx] & mask,
773 ("index bitmap 0x%lx, chimney index %u, "
774 "bitmap idx %d, bitmask 0x%lx",
775 net_dev->send_section_bitsmap[idx], chim_idx, idx, mask));
777 atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask);
781 * Net VSC on send completion
784 hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
785 const struct vmbus_chanpkt_hdr *pkt)
787 struct hn_send_ctx *sndc;
789 sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
790 sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt));
793 * 'sndc' CAN NOT be accessed anymore, since it can be freed by
800 * Sends a packet on the specified Hyper-V device.
801 * Returns 0 on success, non-zero on failure.
804 hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
805 struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
810 send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_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 =
821 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
825 ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt,
826 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
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)sndc);
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_rx_ring *rxr,
844 struct 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;
852 int status = nvsp_status_success;
854 nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);
856 /* Make sure this is a valid nvsp packet */
857 if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
858 if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n",
859 nvsp_msg_pkt->hdr.msg_type);
863 pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
865 if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
866 if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n",
871 count = pkt->cp_rxbuf_cnt;
873 /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
874 for (i = 0; i < count; i++) {
875 net_vsc_pkt->status = nvsp_status_success;
876 net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
877 pkt->cp_rxbuf[i].rb_ofs);
878 net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
880 hv_rf_on_receive(net_dev, rxr, net_vsc_pkt);
881 if (net_vsc_pkt->status != nvsp_status_success) {
882 status = nvsp_status_failure;
887 * Moved completion call back here so that all received
888 * messages (not just data messages) will trigger a response
889 * message back to the host.
891 hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
895 * Net VSC on receive completion
897 * Send a receive completion packet to RNDIS device (ie NetVsp)
900 hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid,
903 nvsp_msg rx_comp_msg;
907 rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete;
909 /* Pass in the status */
910 rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
914 /* Send the completion */
915 ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, 0,
916 &rx_comp_msg, sizeof(nvsp_msg), tid);
920 } else if (ret == EAGAIN) {
921 /* no more room... wait a bit and attempt to retry 3 times */
926 goto retry_send_cmplt;
932 * Net VSC receiving vRSS send table from VSP
935 hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
938 const nvsp_msg *nvsp_msg_pkt;
941 const uint32_t *table;
943 net_dev = hv_nv_get_inbound_net_device(sc);
947 nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
949 if (nvsp_msg_pkt->hdr.msg_type !=
950 nvsp_msg5_type_send_indirection_table) {
951 printf("Netvsc: !Warning! receive msg type not "
952 "send_indirection_table. type = %d\n",
953 nvsp_msg_pkt->hdr.msg_type);
957 count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count;
958 if (count != VRSS_SEND_TABLE_SIZE) {
959 printf("Netvsc: Received wrong send table size: %u\n", count);
963 table = (const uint32_t *)
964 ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
965 nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);
967 for (i = 0; i < count; i++)
968 net_dev->vrss_send_table[i] = table[i];
972 * Net VSC on channel callback
975 hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr)
977 struct hn_rx_ring *rxr = xrxr;
978 struct hn_softc *sc = rxr->hn_ifp->if_softc;
981 int bufferlen = NETVSC_PACKET_SIZE;
983 net_dev = hv_nv_get_inbound_net_device(sc);
987 buffer = rxr->hn_rdbuf;
989 struct vmbus_chanpkt_hdr *pkt = buffer;
993 bytes_rxed = bufferlen;
994 ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
996 if (bytes_rxed > 0) {
997 switch (pkt->cph_type) {
998 case VMBUS_CHANPKT_TYPE_COMP:
999 hv_nv_on_send_completion(net_dev, chan,
1002 case VMBUS_CHANPKT_TYPE_RXBUF:
1003 hv_nv_on_receive(net_dev, rxr, chan, pkt);
1005 case VMBUS_CHANPKT_TYPE_INBAND:
1006 hv_nv_send_table(sc, pkt);
1009 if_printf(rxr->hn_ifp,
1010 "unknown chan pkt %u\n",
1015 } else if (ret == ENOBUFS) {
1016 /* Handle large packet */
1017 if (bufferlen > NETVSC_PACKET_SIZE) {
1018 free(buffer, M_NETVSC);
1022 /* alloc new buffer */
1023 buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
1024 if (buffer == NULL) {
1025 if_printf(rxr->hn_ifp,
1026 "hv_cb malloc buffer failed, len=%u\n",
1031 bufferlen = bytes_rxed;
1033 /* No more packets */
1038 if (bufferlen > NETVSC_PACKET_SIZE)
1039 free(buffer, M_NETVSC);
1041 hv_rf_channel_rollup(rxr, rxr->hn_txr);