summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlucy wang - Sun Microsystems - Beijing China <xiuyan.wang@Sun.COM>2010-02-13 11:23:29 +0800
committerlucy wang - Sun Microsystems - Beijing China <xiuyan.wang@Sun.COM>2010-02-13 11:23:29 +0800
commit91e187871f25f5f4cebb89ca6783e31ac6e8a540 (patch)
tree06faad6ba3d70fc7dfaa42897d358de362d7bdd0
parentdf3cd224ef765c29101e4110546062199562f757 (diff)
downloadillumos-joyent-91e187871f25f5f4cebb89ca6783e31ac6e8a540.tar.gz
6925864 Should disable LRO capability by default
6925474 The IP checksum field of LSO packets need to be zero'ed in driver before it's passed to h/w Contributed by Myricom <gallatin@myri.com>
-rw-r--r--usr/src/uts/common/io/myri10ge/drv/myri10ge.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/usr/src/uts/common/io/myri10ge/drv/myri10ge.c b/usr/src/uts/common/io/myri10ge/drv/myri10ge.c
index 15f71beaa0..d2bda2311b 100644
--- a/usr/src/uts/common/io/myri10ge/drv/myri10ge.c
+++ b/usr/src/uts/common/io/myri10ge/drv/myri10ge.c
@@ -68,7 +68,7 @@ int myri10ge_force_firmware = 0;
static boolean_t myri10ge_use_lso = B_TRUE;
static int myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT;
static int myri10ge_tx_hash = 1;
-static int myri10ge_lro = 1;
+static int myri10ge_lro = 0;
static int myri10ge_lro_cnt = 8;
int myri10ge_lro_max_aggr = 2;
static int myri10ge_lso_copy = 0;
@@ -3059,7 +3059,7 @@ static int
myri10ge_lso_parse_header(mblk_t *mp, int off)
{
char buf[128];
- int seglen;
+ int seglen, sum_off;
struct ip *ip;
struct tcphdr *tcp;
@@ -3076,6 +3076,36 @@ myri10ge_lso_parse_header(mblk_t *mp, int off)
ip = (struct ip *)(void *)buf;
}
tcp = (struct tcphdr *)(void *)((char *)ip + (ip->ip_hl << 2));
+
+ /*
+ * NIC expects ip_sum to be zero. Recent changes to
+ * OpenSolaris leave the correct ip checksum there, rather
+ * than the required zero, so we need to zero it. Otherwise,
+ * the NIC will produce bad checksums when sending LSO packets.
+ */
+ if (ip->ip_sum != 0) {
+ if (((char *)ip) != buf) {
+ /* ip points into mblk, so just zero it */
+ ip->ip_sum = 0;
+ } else {
+ /*
+ * ip points into a copy, so walk the chain
+ * to find the ip_csum, then zero it
+ */
+ sum_off = off + _PTRDIFF(&ip->ip_sum, buf);
+ while (sum_off > (int)(MBLKL(mp) - 1)) {
+ sum_off -= MBLKL(mp);
+ mp = mp->b_cont;
+ }
+ mp->b_rptr[sum_off] = 0;
+ sum_off++;
+ while (sum_off > MBLKL(mp) - 1) {
+ sum_off -= MBLKL(mp);
+ mp = mp->b_cont;
+ }
+ mp->b_rptr[sum_off] = 0;
+ }
+ }
return (off + ((ip->ip_hl + tcp->th_off) << 2));
}