Skip to content

Commit 11bc308

Browse files
Steve Glendinningdavem330
authored andcommitted
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: Steve Glendinning <steve.glendinning@smsc.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0ecad5a commit 11bc308

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

drivers/net/usb/smsc95xx.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,9 +1189,21 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
11891189
}
11901190

11911191
if (csum) {
1192-
u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
1193-
skb_push(skb, 4);
1194-
memcpy(skb->data, &csum_preamble, 4);
1192+
if (skb->len <= 45) {
1193+
/* workaround - hardware tx checksum does not work
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+
}
11951207
}
11961208

11971209
skb_push(skb, 4);

0 commit comments

Comments
 (0)