summaryrefslogtreecommitdiffstats
path: root/sys/dev/re
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2011-01-10 23:28:46 +0000
committeryongari <yongari@FreeBSD.org>2011-01-10 23:28:46 +0000
commiteddf4ff0094898fc3322a2f40652ad8d20d8b85b (patch)
tree90849b0083d19d6c73d3478fc6d00eb3d6d5cc48 /sys/dev/re
parent769825141b6c7597dfb600e8f59ad6edb68db052 (diff)
downloadFreeBSD-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.c40
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
OpenPOWER on IntegriCloud