diff options
-rw-r--r-- | sys/dev/re/if_re.c | 18 | ||||
-rw-r--r-- | sys/pci/if_rlreg.h | 8 |
2 files changed, 26 insertions, 0 deletions
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index ce74b7a..f549bf5 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -2543,6 +2543,14 @@ re_init_locked(sc) } else cfg |= RL_CPLUSCMD_RXENB | RL_CPLUSCMD_TXENB; CSR_WRITE_2(sc, RL_CPLUS_CMD, cfg); + /* + * Disable TSO if interface MTU size is greater than MSS + * allowed in controller. + */ + if (ifp->if_mtu > RL_TSO_MTU && (ifp->if_capenable & IFCAP_TSO4) != 0) { + ifp->if_capenable &= ~IFCAP_TSO4; + ifp->if_hwassist &= ~CSUM_TSO; + } /* * Init our MAC address. Even though the chipset @@ -2754,6 +2762,11 @@ re_ioctl(ifp, command, data) RL_LOCK(sc); if (ifp->if_mtu != ifr->ifr_mtu) ifp->if_mtu = ifr->ifr_mtu; + if (ifp->if_mtu > RL_TSO_MTU && + (ifp->if_capenable & IFCAP_TSO4) != 0) { + ifp->if_capenable &= ~IFCAP_TSO4; + ifp->if_hwassist &= ~CSUM_TSO; + } RL_UNLOCK(sc); break; case SIOCSIFFLAGS: @@ -2829,6 +2842,11 @@ re_ioctl(ifp, command, data) ifp->if_hwassist |= CSUM_TSO; else ifp->if_hwassist &= ~CSUM_TSO; + if (ifp->if_mtu > RL_TSO_MTU && + (ifp->if_capenable & IFCAP_TSO4) != 0) { + ifp->if_capenable &= ~IFCAP_TSO4; + ifp->if_hwassist &= ~CSUM_TSO; + } } if ((mask & IFCAP_WOL) != 0 && (ifp->if_capabilities & IFCAP_WOL) != 0) { diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h index 9456433..a5e5f12 100644 --- a/sys/pci/if_rlreg.h +++ b/sys/pci/if_rlreg.h @@ -750,6 +750,14 @@ struct rl_stats { #define RL_ADDR_LO(y) ((uint64_t) (y) & 0xFFFFFFFF) #define RL_ADDR_HI(y) ((uint64_t) (y) >> 32) +/* + * The number of bits reserved for MSS in RealTek controllers is + * 11bits. This limits the maximum interface MTU size in TSO case + * as upper stack should not generate TCP segments with MSS greater + * than the limit. + */ +#define RL_TSO_MTU (2047 - ETHER_HDR_LEN - ETHER_CRC_LEN) + /* see comment in dev/re/if_re.c */ #define RL_JUMBO_FRAMELEN 7440 #define RL_JUMBO_MTU (RL_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN) |