Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.h =================================================================== --- head/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -136,6 +136,9 @@ /* Rarely used stuffs */ struct sysctl_oid *hn_rx_sysctl_tree; int hn_rx_flags; + + void *hn_br; /* TX/RX bufring */ + struct hyperv_dma hn_br_dma; } __aligned(CACHE_LINE_SIZE); #define HN_TRUST_HCSUM_IP 0x0001 Index: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c =================================================================== --- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -2372,6 +2372,16 @@ for (i = 0; i < sc->hn_rx_ring_cnt; ++i) { struct hn_rx_ring *rxr = &sc->hn_rx_ring[i]; + rxr->hn_br = hyperv_dmamem_alloc(bus_get_dma_tag(dev), + PAGE_SIZE, 0, + NETVSC_DEVICE_RING_BUFFER_SIZE + + NETVSC_DEVICE_RING_BUFFER_SIZE, + &rxr->hn_br_dma, BUS_DMA_WAITOK); + if (rxr->hn_br == NULL) { + device_printf(dev, "allocate bufring failed\n"); + return (ENOMEM); + } + if (hn_trust_hosttcp) rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_TCP; if (hn_trust_hostudp) @@ -2520,6 +2530,11 @@ for (i = 0; i < sc->hn_rx_ring_cnt; ++i) { struct hn_rx_ring *rxr = &sc->hn_rx_ring[i]; + if (rxr->hn_br == NULL) + continue; + hyperv_dmamem_free(&rxr->hn_br_dma, rxr->hn_br); + rxr->hn_br = NULL; + #if defined(INET) || defined(INET6) tcp_lro_free(&rxr->hn_lro); #endif @@ -3125,6 +3140,7 @@ static int hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan) { + struct vmbus_chan_br cbr; struct hn_rx_ring *rxr; struct hn_tx_ring *txr = NULL; int idx, error; @@ -3163,9 +3179,14 @@ /* Bind this channel to a proper CPU. */ vmbus_chan_cpu_set(chan, (sc->hn_cpu + idx) % mp_ncpus); - /* Open this channel */ - error = vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, - NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, hn_chan_callback, rxr); + /* + * Open this channel + */ + cbr.cbr = rxr->hn_br; + cbr.cbr_paddr = rxr->hn_br_dma.hv_paddr; + cbr.cbr_txsz = NETVSC_DEVICE_RING_BUFFER_SIZE; + cbr.cbr_rxsz = NETVSC_DEVICE_RING_BUFFER_SIZE; + error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr); if (error) { if_printf(sc->hn_ifp, "open chan%u failed: %d\n", vmbus_chan_id(chan), error);