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 @@ -236,8 +236,6 @@ /* Holds rndis device info */ void *extension; - uint32_t num_channel; - struct hyperv_dma rxbuf_dma; struct hyperv_dma txbuf_dma; } netvsc_dev; 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 @@ -551,26 +551,25 @@ if (sc->hn_xact == NULL) goto failed; - error = hv_rf_on_device_add(sc, &device_info, ring_cnt, + error = hv_rf_on_device_add(sc, &device_info, &ring_cnt, &sc->hn_rx_ring[0]); if (error) goto failed; - KASSERT(sc->net_dev->num_channel > 0 && - sc->net_dev->num_channel <= sc->hn_rx_ring_inuse, - ("invalid channel count %u, should be less than %d", - sc->net_dev->num_channel, sc->hn_rx_ring_inuse)); + KASSERT(ring_cnt > 0 && ring_cnt <= sc->hn_rx_ring_inuse, + ("invalid channel count %d, should be less than %d", + ring_cnt, sc->hn_rx_ring_inuse)); /* * Set the # of TX/RX rings that could be used according to * the # of channels that host offered. */ - if (sc->hn_tx_ring_inuse > sc->net_dev->num_channel) - sc->hn_tx_ring_inuse = sc->net_dev->num_channel; - sc->hn_rx_ring_inuse = sc->net_dev->num_channel; + if (sc->hn_tx_ring_inuse > ring_cnt) + sc->hn_tx_ring_inuse = ring_cnt; + sc->hn_rx_ring_inuse = ring_cnt; device_printf(dev, "%d TX ring, %d RX ring\n", sc->hn_tx_ring_inuse, sc->hn_rx_ring_inuse); - if (sc->net_dev->num_channel > 1) + if (sc->hn_rx_ring_inuse > 1) hn_subchan_setup(sc); #if __FreeBSD_version >= 1100099 @@ -1511,7 +1510,7 @@ struct ifaddr *ifa = (struct ifaddr *)data; #endif netvsc_device_info device_info; - int mask, error = 0; + int mask, error = 0, ring_cnt; int retry_cnt = 500; switch(cmd) { @@ -1585,18 +1584,20 @@ /* Wait for subchannels to be destroyed */ vmbus_subchan_drain(sc->hn_prichan); - error = hv_rf_on_device_add(sc, &device_info, - sc->hn_rx_ring_inuse, &sc->hn_rx_ring[0]); + ring_cnt = sc->hn_rx_ring_inuse; + error = hv_rf_on_device_add(sc, &device_info, &ring_cnt, + &sc->hn_rx_ring[0]); if (error) { NV_LOCK(sc); sc->temp_unusable = FALSE; NV_UNLOCK(sc); break; } - KASSERT(sc->hn_rx_ring_cnt == sc->net_dev->num_channel, + /* # of channels can _not_ be changed */ + KASSERT(sc->hn_rx_ring_inuse == ring_cnt, ("RX ring count %d and channel count %u mismatch", - sc->hn_rx_ring_cnt, sc->net_dev->num_channel)); - if (sc->net_dev->num_channel > 1) { + sc->hn_rx_ring_cnt, ring_cnt)); + if (sc->hn_rx_ring_inuse > 1) { int r; /* @@ -2966,7 +2967,7 @@ hn_subchan_setup(struct hn_softc *sc) { struct vmbus_channel **subchans; - int subchan_cnt = sc->net_dev->num_channel - 1; + int subchan_cnt = sc->hn_rx_ring_inuse - 1; int i; /* Wait for sub-channels setup to complete. */ Index: head/sys/dev/hyperv/netvsc/hv_rndis_filter.h =================================================================== --- head/sys/dev/hyperv/netvsc/hv_rndis_filter.h +++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.h @@ -119,7 +119,7 @@ const void *data, int dlen); void hv_rf_receive_rollup(netvsc_dev *net_dev); void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); -int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int nchan, +int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int *nchan, struct hn_rx_ring *rxr); int hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel); int hv_rf_on_open(struct hn_softc *sc); Index: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c =================================================================== --- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -1035,7 +1035,7 @@ */ int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, - int nchan, struct hn_rx_ring *rxr) + int *nchan0, struct hn_rx_ring *rxr) { struct hn_send_ctx sndc; int ret; @@ -1051,6 +1051,7 @@ size_t resp_len; struct vmbus_xact *xact; uint32_t status, nsubch; + int nchan = *nchan0; rndis_dev = hv_get_rndis_device(); if (rndis_dev == NULL) { @@ -1114,7 +1115,6 @@ dev_info->link_state = rndis_dev->link_status; - net_dev->num_channel = 1; if (sc->hn_nvs_ver < NVSP_PROTOCOL_VERSION_5 || nchan == 1) return (0); @@ -1131,10 +1131,9 @@ rsscaps.num_recv_que, nchan); if (nchan > rsscaps.num_recv_que) nchan = rsscaps.num_recv_que; - net_dev->num_channel = nchan; - if (net_dev->num_channel == 1) { - device_printf(dev, "net_dev->num_channel == 1 under VRSS\n"); + if (nchan == 1) { + device_printf(dev, "only 1 channel is supported, no vRSS\n"); goto out; } @@ -1151,7 +1150,7 @@ req = vmbus_xact_req_data(xact); req->nvs_type = HN_NVS_TYPE_SUBCH_REQ; req->nvs_op = HN_NVS_SUBCH_OP_ALLOC; - req->nvs_nsubch = net_dev->num_channel - 1; + req->nvs_nsubch = nchan - 1; hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); vmbus_xact_activate(xact); @@ -1190,19 +1189,16 @@ ret = EIO; goto out; } - if (nsubch > net_dev->num_channel - 1) { + if (nsubch > nchan - 1) { if_printf(sc->hn_ifp, "%u subchans are allocated, requested %u\n", - nsubch, net_dev->num_channel - 1); - nsubch = net_dev->num_channel - 1; + nsubch, nchan - 1); + nsubch = nchan - 1; } - net_dev->num_channel = nsubch + 1; - - ret = hv_rf_set_rss_param(rndis_dev, net_dev->num_channel); + nchan = nsubch + 1; + ret = hv_rf_set_rss_param(rndis_dev, nchan); + *nchan0 = nchan; out: - if (ret) - net_dev->num_channel = 1; - return (ret); }