summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-03-20 11:55:11 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-03-20 11:55:11 +0000
commit1ac443066cace32e20cc35cbbc3164263e117bb9 (patch)
tree7860cecad1d7226689ec403bcf9de35c5c8fcc82 /sys/dev
parent3431604482aebe678d10072551f483ee21d56cb4 (diff)
some re(4) chips can do jumbos, but none of them can checksum jumbo
packets. rather than disable cksum offload for all packets, this sets things up so we still advertise offload to the stack, but if the driver gets a large packet it does the checksum itself in software. small (normal sized) packets still get offloaded like now. if you're doing a jumbo you'll be doing the cksum in software, but will hopefully win overall cos you'll be doing a 6th of the work cos you're doing more data in every packet. diff from jim smith ok sthen@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/re.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c
index 51045cd3706..8ad15ce2d02 100644
--- a/sys/dev/ic/re.c
+++ b/sys/dev/ic/re.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: re.c,v 1.175 2015/02/09 03:09:57 dlg Exp $ */
+/* $OpenBSD: re.c,v 1.176 2015/03/20 11:55:10 dlg Exp $ */
/* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -128,6 +128,8 @@
#include <net/if_media.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
#include <netinet/if_ether.h>
#if NVLAN > 0
@@ -194,6 +196,8 @@ void re_setup_intr(struct rl_softc *, int, int);
int re_wol(struct ifnet*, int);
#endif
+void in_delayed_cksum(struct mbuf *);
+
struct cfdriver re_cd = {
0, "re", DV_IFNET
};
@@ -1601,7 +1605,10 @@ int
re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
{
bus_dmamap_t map;
+ struct mbuf *mp, mh;
int error, seg, nsegs, uidx, startidx, curidx, lastidx, pad;
+ int off;
+ struct ip *ip;
struct rl_desc *d;
u_int32_t cmdstat, vlanctl = 0, csum_flags = 0;
struct rl_txq *txq;
@@ -1619,6 +1626,27 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
* RL_TDESC_CMD_UDPCSUM does not take affect.
*/
+ if ((sc->rl_flags & RL_FLAG_JUMBOV2) &&
+ m->m_pkthdr.len > RL_MTU &&
+ (m->m_pkthdr.csum_flags &
+ (M_IPV4_CSUM_OUT|M_TCP_CSUM_OUT|M_UDP_CSUM_OUT)) != 0) {
+ mp = m_getptr(m, ETHER_HDR_LEN, &off);
+ mh.m_flags = 0;
+ mh.m_data = mtod(mp, caddr_t) + off;
+ mh.m_next = mp->m_next;
+ mh.m_pkthdr.len = mp->m_pkthdr.len - ETHER_HDR_LEN;
+ mh.m_len = mp->m_len - off;
+ ip = (struct ip *)mh.m_data;
+
+ if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
+ ip->ip_sum = in_cksum(&mh, sizeof(struct ip));
+ if (m->m_pkthdr.csum_flags & (M_TCP_CSUM_OUT|M_UDP_CSUM_OUT))
+ in_delayed_cksum(&mh);
+
+ m->m_pkthdr.csum_flags &=
+ ~(M_IPV4_CSUM_OUT|M_TCP_CSUM_OUT|M_UDP_CSUM_OUT);
+ }
+
if ((m->m_pkthdr.csum_flags &
(M_IPV4_CSUM_OUT|M_TCP_CSUM_OUT|M_UDP_CSUM_OUT)) != 0) {
if (sc->rl_flags & RL_FLAG_DESCV2) {