diff options
-rw-r--r-- | sys/dev/mxge/if_mxge.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c index 27564d4..c6beb6f 100644 --- a/sys/dev/mxge/if_mxge.c +++ b/sys/dev/mxge/if_mxge.c @@ -95,6 +95,7 @@ static int mxge_intr_coal_delay = 30; static int mxge_deassert_wait = 1; static int mxge_flow_control = 1; static int mxge_verbose = 0; +static int mxge_lro_cnt = 8; static int mxge_ticks; static char *mxge_fw_unaligned = "mxge_ethp_z8e"; static char *mxge_fw_aligned = "mxge_eth_z8e"; @@ -1238,6 +1239,26 @@ mxge_change_flow_control(SYSCTL_HANDLER_ARGS) } static int +mxge_change_lro_locked(mxge_softc_t *sc, int lro_cnt) +{ + struct ifnet *ifp; + int err; + + ifp = sc->ifp; + if (lro_cnt == 0) + ifp->if_capenable &= ~IFCAP_LRO; + else + ifp->if_capenable |= IFCAP_LRO; + sc->lro_cnt = lro_cnt; + callout_stop(&sc->co_hdl); + mxge_close(sc); + err = mxge_open(sc); + if (err == 0) + callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc); + return err; +} + +static int mxge_change_lro(SYSCTL_HANDLER_ARGS) { mxge_softc_t *sc; @@ -1257,12 +1278,7 @@ mxge_change_lro(SYSCTL_HANDLER_ARGS) return EINVAL; mtx_lock(&sc->driver_mtx); - sc->lro_cnt = lro_cnt; - callout_stop(&sc->co_hdl); - mxge_close(sc); - err = mxge_open(sc); - if (err == 0) - callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc); + err = mxge_change_lro_locked(sc, lro_cnt); mtx_unlock(&sc->driver_mtx); return err; } @@ -3156,7 +3172,12 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) err = EINVAL; } } - + if (mask & IFCAP_LRO) { + if (IFCAP_LRO & ifp->if_capenable) + err = mxge_change_lro_locked(sc, 0); + else + err = mxge_change_lro_locked(sc, mxge_lro_cnt); + } if (mask & IFCAP_VLAN_HWTAGGING) ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; mtx_unlock(&sc->driver_mtx); @@ -3193,6 +3214,9 @@ mxge_fetch_tunables(mxge_softc_t *sc) &mxge_verbose); TUNABLE_INT_FETCH("hw.mxge.ticks", &mxge_ticks); TUNABLE_INT_FETCH("hw.mxge.lro_cnt", &sc->lro_cnt); + printf("%d %d\n", sc->lro_cnt, mxge_lro_cnt); + if (sc->lro_cnt != 0) + mxge_lro_cnt = sc->lro_cnt; if (bootverbose) mxge_verbose = 1; @@ -3350,7 +3374,8 @@ mxge_attach(device_t dev) if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_baudrate = 100000000; ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_TSO4 | - IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM; + IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | + IFCAP_VLAN_HWCSUM | IFCAP_LRO; sc->max_mtu = mxge_max_mtu(sc); if (sc->max_mtu >= 9000) @@ -3361,6 +3386,8 @@ mxge_attach(device_t dev) sc->max_mtu - ETHER_HDR_LEN); ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_TSO; ifp->if_capenable = ifp->if_capabilities; + if (sc->lro_cnt == 0) + ifp->if_capenable &= ~IFCAP_LRO; sc->csum_flag = 1; ifp->if_init = mxge_init; ifp->if_softc = sc; |