diff options
author | lucy wang - Sun Microsystems - Beijing China <xiuyan.wang@Sun.COM> | 2010-02-13 11:23:29 +0800 |
---|---|---|
committer | lucy wang - Sun Microsystems - Beijing China <xiuyan.wang@Sun.COM> | 2010-02-13 11:23:29 +0800 |
commit | 91e187871f25f5f4cebb89ca6783e31ac6e8a540 (patch) | |
tree | 06faad6ba3d70fc7dfaa42897d358de362d7bdd0 | |
parent | df3cd224ef765c29101e4110546062199562f757 (diff) | |
download | illumos-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.c | 34 |
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)); } |