aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/smsc95xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/smsc95xx.c')
-rw-r--r--drivers/net/usb/smsc95xx.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index d222d7e25273..73f9a31cf94d 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1189,9 +1189,21 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
1189 } 1189 }
1190 1190
1191 if (csum) { 1191 if (csum) {
1192 u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); 1192 if (skb->len <= 45) {
1193 skb_push(skb, 4); 1193 /* workaround - hardware tx checksum does not work
1194 memcpy(skb->data, &csum_preamble, 4); 1194 * properly with extremely small packets */
1195 long csstart = skb->csum_start - skb_headroom(skb);
1196 __wsum calc = csum_partial(skb->data + csstart,
1197 skb->len - csstart, 0);
1198 *((__sum16 *)(skb->data + csstart
1199 + skb->csum_offset)) = csum_fold(calc);
1200
1201 csum = false;
1202 } else {
1203 u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
1204 skb_push(skb, 4);
1205 memcpy(skb->data, &csum_preamble, 4);
1206 }
1195 } 1207 }
1196 1208
1197 skb_push(skb, 4); 1209 skb_push(skb, 4);