summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--sys/dev/re/if_re.c40
-rw-r--r--sys/pci/if_rlreg.h2
2 files changed, 21 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
diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
index 9de7217..d7ffd40 100644
--- a/sys/pci/if_rlreg.h
+++ b/sys/pci/if_rlreg.h
@@ -657,6 +657,8 @@ struct rl_desc {
#define RL_TDESC_CMD_UDPCSUMV2 0x80000000
#define RL_TDESC_CMD_TCPCSUMV2 0x40000000
#define RL_TDESC_CMD_IPCSUMV2 0x20000000
+#define RL_TDESC_CMD_MSSVALV2 0x1FFC0000
+#define RL_TDESC_CMD_MSSVALV2_SHIFT 18
/*
* Error bits are valid only on the last descriptor of a frame
OpenPOWER on IntegriCloud