Skip to content

Commit

Permalink
USB: Fix CDC EEM host driver 'sentinel' CRC validation
Browse files Browse the repository at this point in the history
This is an alternate solution to the EEM 'sentinel' CRC valiation issue.

CDC EEM allows using a 'sentinel' ethernet frame CRC of 0xdeadbeef in
place of a real CRC.  The 'sentinel' value is transmitted in big-endian
order whereas the normal CRC is little-endian.  This patch handles both
cases appropriately.

Signed-off-by: Brian Niebuhr <bniebuhr@efjohnson.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Brian Niebuhr authored and Greg Kroah-Hartman committed Sep 23, 2009
1 parent 5429c73 commit 9ca33a0
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions drivers/net/usb/cdc_eem.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,20 +300,23 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 0;
}

crc = get_unaligned_le32(skb2->data
+ len - ETH_FCS_LEN);
skb_trim(skb2, len - ETH_FCS_LEN);

/*
* The bmCRC helps to denote when the CRC field in
* the Ethernet frame contains a calculated CRC:
* bmCRC = 1 : CRC is calculated
* bmCRC = 0 : CRC = 0xDEADBEEF
*/
if (header & BIT(14))
crc2 = ~crc32_le(~0, skb2->data, skb2->len);
else
if (header & BIT(14)) {
crc = get_unaligned_le32(skb2->data
+ len - ETH_FCS_LEN);
crc2 = ~crc32_le(~0, skb2->data, skb2->len
- ETH_FCS_LEN);
} else {
crc = get_unaligned_be32(skb2->data
+ len - ETH_FCS_LEN);
crc2 = 0xdeadbeef;
}
skb_trim(skb2, len - ETH_FCS_LEN);

if (is_last)
return crc == crc2;
Expand Down

0 comments on commit 9ca33a0

Please sign in to comment.