diff options
author | yongari <yongari@FreeBSD.org> | 2011-01-10 23:28:46 +0000 |
---|---|---|
committer | yongari <yongari@FreeBSD.org> | 2011-01-10 23:28:46 +0000 |
commit | eddf4ff0094898fc3322a2f40652ad8d20d8b85b (patch) | |
tree | 90849b0083d19d6c73d3478fc6d00eb3d6d5cc48 /sys/dev/re | |
parent | 769825141b6c7597dfb600e8f59ad6edb68db052 (diff) | |
download | FreeBSD-src-eddf4ff0094898fc3322a2f40652ad8d20d8b85b.zip FreeBSD-src-eddf4ff0094898fc3322a2f40652ad8d20d8b85b.tar.gz |
Implement TSO on RealTek RTL8168/8111 C or later controllers.
RealTek changed TX descriptor format for later controllers so these
controllers require MSS configuration in different location of TX
descriptor. TSO is enabled by default for controllers that use new
descriptor format.
For old controllers, TSO is still disabled by default due to broken
frames under certain conditions but users can enable it.
Special thanks to Hayes Wang at RealTek.
MFC after: 2 weeks
Diffstat (limited to 'sys/dev/re')
-rw-r--r-- | sys/dev/re/if_re.c | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 4df624b..e1cf2b0 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -1460,8 +1460,8 @@ re_attach(device_t dev) ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = re_ioctl; ifp->if_start = re_start; - ifp->if_hwassist = RE_CSUM_FEATURES; - ifp->if_capabilities = IFCAP_HWCSUM; + ifp->if_hwassist = RE_CSUM_FEATURES | CSUM_TSO; + ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4; ifp->if_capenable = ifp->if_capabilities; ifp->if_init = re_init; IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN); @@ -1472,16 +1472,6 @@ re_attach(device_t dev) TASK_INIT(&sc->rl_inttask, 0, re_int_task, sc); /* - * XXX - * Still have no idea how to make TSO work on 8168C, 8168CP, - * 8111C and 8111CP. - */ - if ((sc->rl_flags & RL_FLAG_DESCV2) == 0) { - ifp->if_hwassist |= CSUM_TSO; - ifp->if_capabilities |= IFCAP_TSO4 | IFCAP_VLAN_HWTSO; - } - - /* * Call MI attach routine. */ ether_ifattach(ifp, eaddr); @@ -1495,12 +1485,14 @@ re_attach(device_t dev) ifp->if_capabilities |= IFCAP_WOL; ifp->if_capenable = ifp->if_capabilities; /* - * Don't enable TSO by default. Under certain - * circumtances the controller generated corrupted + * Don't enable TSO by default for old controllers. Under + * certain circumtances the controller generated corrupted * packets in TSO size. */ - ifp->if_hwassist &= ~CSUM_TSO; - ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO); + if ((sc->rl_flags & RL_FLAG_DESCV2) == 0) { + ifp->if_hwassist &= ~CSUM_TSO; + ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO); + } #ifdef DEVICE_POLLING ifp->if_capabilities |= IFCAP_POLLING; #endif @@ -2413,11 +2405,17 @@ re_encap(struct rl_softc *sc, struct mbuf **m_head) */ vlanctl = 0; csum_flags = 0; - if (((*m_head)->m_pkthdr.csum_flags & CSUM_TSO) != 0) - csum_flags = RL_TDESC_CMD_LGSEND | - ((uint32_t)(*m_head)->m_pkthdr.tso_segsz << - RL_TDESC_CMD_MSSVAL_SHIFT); - else { + if (((*m_head)->m_pkthdr.csum_flags & CSUM_TSO) != 0) { + if ((sc->rl_flags & RL_FLAG_DESCV2) != 0) { + csum_flags |= RL_TDESC_CMD_LGSEND; + vlanctl |= ((uint32_t)(*m_head)->m_pkthdr.tso_segsz << + RL_TDESC_CMD_MSSVALV2_SHIFT); + } else { + csum_flags |= RL_TDESC_CMD_LGSEND | + ((uint32_t)(*m_head)->m_pkthdr.tso_segsz << + RL_TDESC_CMD_MSSVAL_SHIFT); + } + } else { /* * Unconditionally enable IP checksum if TCP or UDP * checksum is required. Otherwise, TCP/UDP checksum |