diff options
Diffstat (limited to 'sys/dev/xen/netfront/netfront.c')
-rw-r--r-- | sys/dev/xen/netfront/netfront.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index 317a339..3eac25d 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -285,6 +285,8 @@ struct netfront_info { multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1]; mmu_update_t rx_mmu[NET_RX_RING_SIZE]; struct ifmedia sc_media; + + bool xn_resume; }; #define rx_mbufs xn_cdata.xn_rx_chain @@ -500,6 +502,7 @@ netfront_resume(device_t dev) { struct netfront_info *info = device_get_softc(dev); + info->xn_resume = true; netif_disconnect_backend(info); return (0); } @@ -1982,18 +1985,33 @@ xn_query_features(struct netfront_info *np) static int xn_configure_features(struct netfront_info *np) { - int err; + int err, cap_enabled; err = 0; + + if (np->xn_resume && + ((np->xn_ifp->if_capenable & np->xn_ifp->if_capabilities) + == np->xn_ifp->if_capenable)) { + /* Current options are available, no need to do anything. */ + return (0); + } + + /* Try to preserve as many options as possible. */ + if (np->xn_resume) + cap_enabled = np->xn_ifp->if_capenable; + else + cap_enabled = UINT_MAX; + #if __FreeBSD_version >= 700000 && (defined(INET) || defined(INET6)) - if ((np->xn_ifp->if_capenable & IFCAP_LRO) != 0) + if ((np->xn_ifp->if_capenable & IFCAP_LRO) == (cap_enabled & IFCAP_LRO)) tcp_lro_free(&np->xn_lro); #endif np->xn_ifp->if_capenable = - np->xn_ifp->if_capabilities & ~(IFCAP_LRO|IFCAP_TSO4); + np->xn_ifp->if_capabilities & ~(IFCAP_LRO|IFCAP_TSO4) & cap_enabled; np->xn_ifp->if_hwassist &= ~CSUM_TSO; #if __FreeBSD_version >= 700000 && (defined(INET) || defined(INET6)) - if (xn_enable_lro && (np->xn_ifp->if_capabilities & IFCAP_LRO) != 0) { + if (xn_enable_lro && (np->xn_ifp->if_capabilities & IFCAP_LRO) == + (cap_enabled & IFCAP_LRO)) { err = tcp_lro_init(&np->xn_lro); if (err) { device_printf(np->xbdev, "LRO initialization failed\n"); @@ -2002,7 +2020,8 @@ xn_configure_features(struct netfront_info *np) np->xn_ifp->if_capenable |= IFCAP_LRO; } } - if ((np->xn_ifp->if_capabilities & IFCAP_TSO4) != 0) { + if ((np->xn_ifp->if_capabilities & IFCAP_TSO4) == + (cap_enabled & IFCAP_TSO4)) { np->xn_ifp->if_capenable |= IFCAP_TSO4; np->xn_ifp->if_hwassist |= CSUM_TSO; } |