Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
Show First 20 Lines • Show All 545 Lines • ▼ Show 20 Lines | ifp->if_capenable |= | ||||
IFCAP_LRO; | IFCAP_LRO; | ||||
ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO; | ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO; | ||||
sc->hn_xact = vmbus_xact_ctx_create(bus_get_dma_tag(dev), | sc->hn_xact = vmbus_xact_ctx_create(bus_get_dma_tag(dev), | ||||
HN_XACT_REQ_SIZE, HN_XACT_RESP_SIZE, 0); | HN_XACT_REQ_SIZE, HN_XACT_RESP_SIZE, 0); | ||||
if (sc->hn_xact == NULL) | if (sc->hn_xact == NULL) | ||||
goto failed; | 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]); | &sc->hn_rx_ring[0]); | ||||
if (error) | if (error) | ||||
goto failed; | goto failed; | ||||
KASSERT(sc->net_dev->num_channel > 0 && | KASSERT(ring_cnt > 0 && ring_cnt <= sc->hn_rx_ring_inuse, | ||||
sc->net_dev->num_channel <= sc->hn_rx_ring_inuse, | ("invalid channel count %d, should be less than %d", | ||||
("invalid channel count %u, should be less than %d", | ring_cnt, sc->hn_rx_ring_inuse)); | ||||
sc->net_dev->num_channel, sc->hn_rx_ring_inuse)); | |||||
/* | /* | ||||
* Set the # of TX/RX rings that could be used according to | * Set the # of TX/RX rings that could be used according to | ||||
* the # of channels that host offered. | * the # of channels that host offered. | ||||
*/ | */ | ||||
if (sc->hn_tx_ring_inuse > sc->net_dev->num_channel) | if (sc->hn_tx_ring_inuse > ring_cnt) | ||||
sc->hn_tx_ring_inuse = sc->net_dev->num_channel; | sc->hn_tx_ring_inuse = ring_cnt; | ||||
sc->hn_rx_ring_inuse = sc->net_dev->num_channel; | sc->hn_rx_ring_inuse = ring_cnt; | ||||
device_printf(dev, "%d TX ring, %d RX ring\n", | device_printf(dev, "%d TX ring, %d RX ring\n", | ||||
sc->hn_tx_ring_inuse, sc->hn_rx_ring_inuse); | 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); | hn_subchan_setup(sc); | ||||
#if __FreeBSD_version >= 1100099 | #if __FreeBSD_version >= 1100099 | ||||
if (sc->hn_rx_ring_inuse > 1) { | if (sc->hn_rx_ring_inuse > 1) { | ||||
/* | /* | ||||
* Reduce TCP segment aggregation limit for multiple | * Reduce TCP segment aggregation limit for multiple | ||||
* RX rings to increase ACK timeliness. | * RX rings to increase ACK timeliness. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 924 Lines • ▼ Show 20 Lines | |||||
hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | ||||
{ | { | ||||
hn_softc_t *sc = ifp->if_softc; | hn_softc_t *sc = ifp->if_softc; | ||||
struct ifreq *ifr = (struct ifreq *)data; | struct ifreq *ifr = (struct ifreq *)data; | ||||
#ifdef INET | #ifdef INET | ||||
struct ifaddr *ifa = (struct ifaddr *)data; | struct ifaddr *ifa = (struct ifaddr *)data; | ||||
#endif | #endif | ||||
netvsc_device_info device_info; | netvsc_device_info device_info; | ||||
int mask, error = 0; | int mask, error = 0, ring_cnt; | ||||
int retry_cnt = 500; | int retry_cnt = 500; | ||||
switch(cmd) { | switch(cmd) { | ||||
case SIOCSIFADDR: | case SIOCSIFADDR: | ||||
#ifdef INET | #ifdef INET | ||||
if (ifa->ifa_addr->sa_family == AF_INET) { | if (ifa->ifa_addr->sa_family == AF_INET) { | ||||
ifp->if_flags |= IFF_UP; | ifp->if_flags |= IFF_UP; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if (error) { | ||||
sc->temp_unusable = FALSE; | sc->temp_unusable = FALSE; | ||||
NV_UNLOCK(sc); | NV_UNLOCK(sc); | ||||
break; | break; | ||||
} | } | ||||
/* Wait for subchannels to be destroyed */ | /* Wait for subchannels to be destroyed */ | ||||
vmbus_subchan_drain(sc->hn_prichan); | vmbus_subchan_drain(sc->hn_prichan); | ||||
error = hv_rf_on_device_add(sc, &device_info, | ring_cnt = sc->hn_rx_ring_inuse; | ||||
sc->hn_rx_ring_inuse, &sc->hn_rx_ring[0]); | error = hv_rf_on_device_add(sc, &device_info, &ring_cnt, | ||||
&sc->hn_rx_ring[0]); | |||||
if (error) { | if (error) { | ||||
NV_LOCK(sc); | NV_LOCK(sc); | ||||
sc->temp_unusable = FALSE; | sc->temp_unusable = FALSE; | ||||
NV_UNLOCK(sc); | NV_UNLOCK(sc); | ||||
break; | 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", | ("RX ring count %d and channel count %u mismatch", | ||||
sc->hn_rx_ring_cnt, sc->net_dev->num_channel)); | sc->hn_rx_ring_cnt, ring_cnt)); | ||||
if (sc->net_dev->num_channel > 1) { | if (sc->hn_rx_ring_inuse > 1) { | ||||
int r; | int r; | ||||
/* | /* | ||||
* Skip the rings on primary channel; they are | * Skip the rings on primary channel; they are | ||||
* handled by the hv_rf_on_device_add() above. | * handled by the hv_rf_on_device_add() above. | ||||
*/ | */ | ||||
for (r = 1; r < sc->hn_rx_ring_cnt; ++r) { | for (r = 1; r < sc->hn_rx_ring_cnt; ++r) { | ||||
sc->hn_rx_ring[r].hn_rx_flags &= | sc->hn_rx_ring[r].hn_rx_flags &= | ||||
▲ Show 20 Lines • Show All 1,353 Lines • ▼ Show 20 Lines | KASSERT(!vmbus_chan_is_primary(chan), | ||||
("subchannel callback on primary channel")); | ("subchannel callback on primary channel")); | ||||
hn_channel_attach(sc, chan); | hn_channel_attach(sc, chan); | ||||
} | } | ||||
static void | static void | ||||
hn_subchan_setup(struct hn_softc *sc) | hn_subchan_setup(struct hn_softc *sc) | ||||
{ | { | ||||
struct vmbus_channel **subchans; | struct vmbus_channel **subchans; | ||||
int subchan_cnt = sc->net_dev->num_channel - 1; | int subchan_cnt = sc->hn_rx_ring_inuse - 1; | ||||
int i; | int i; | ||||
/* Wait for sub-channels setup to complete. */ | /* Wait for sub-channels setup to complete. */ | ||||
subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); | subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); | ||||
/* Attach the sub-channels. */ | /* Attach the sub-channels. */ | ||||
for (i = 0; i < subchan_cnt; ++i) { | for (i = 0; i < subchan_cnt; ++i) { | ||||
struct vmbus_channel *subchan = subchans[i]; | struct vmbus_channel *subchan = subchans[i]; | ||||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |