From 275c4147544d4ed4f05cee3a5dabf1e6efeeb371 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 18 Mar 2010 22:18:41 -0700 Subject: [PATCH] --- yaml --- r: 188861 b: refs/heads/master c: 11bc3088373e913f165a8652601c6f8b8dc4aea2 h: refs/heads/master i: 188859: b6c0b4d67a2e3aa4f375666e86358fa2642a5021 v: v3 --- [refs] | 2 +- trunk/drivers/net/usb/smsc95xx.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 5dec18311f50..15f603c8dc55 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0ecad5a262923967147e2d1725e277a2a5fbcdd4 +refs/heads/master: 11bc3088373e913f165a8652601c6f8b8dc4aea2 diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index d222d7e25273..73f9a31cf94d 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -1189,9 +1189,21 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, } if (csum) { - u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); - skb_push(skb, 4); - memcpy(skb->data, &csum_preamble, 4); + if (skb->len <= 45) { + /* workaround - hardware tx checksum does not work + * properly with extremely small packets */ + long csstart = skb->csum_start - skb_headroom(skb); + __wsum calc = csum_partial(skb->data + csstart, + skb->len - csstart, 0); + *((__sum16 *)(skb->data + csstart + + skb->csum_offset)) = csum_fold(calc); + + csum = false; + } else { + u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); + skb_push(skb, 4); + memcpy(skb->data, &csum_preamble, 4); + } } skb_push(skb, 4);