Commit 11bc3088 authored by Steve Glendinning's avatar Steve Glendinning Committed by David S. Miller

smsc95xx: Fix tx checksum offload for small packets

TX checksum offload does not work properly when transmitting
UDP packets with 0, 1 or 2 bytes of data.  This patch works
around the problem by calculating checksums for these packets
in the driver.
Signed-off-by: default avatarSteve Glendinning <steve.glendinning@smsc.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0ecad5a2
...@@ -1189,10 +1189,22 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, ...@@ -1189,10 +1189,22 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
} }
if (csum) { if (csum) {
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); u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
skb_push(skb, 4); skb_push(skb, 4);
memcpy(skb->data, &csum_preamble, 4); memcpy(skb->data, &csum_preamble, 4);
} }
}
skb_push(skb, 4); skb_push(skb, 4);
tx_cmd_b = (u32)(skb->len - 4); tx_cmd_b = (u32)(skb->len - 4);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment