Commit 9ca33a0f authored by Brian Niebuhr's avatar Brian Niebuhr Committed by Greg Kroah-Hartman

USB: Fix CDC EEM host driver 'sentinel' CRC validation

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: default avatarBrian Niebuhr <bniebuhr@efjohnson.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 5429c731
...@@ -300,20 +300,23 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ...@@ -300,20 +300,23 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 0; 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 bmCRC helps to denote when the CRC field in
* the Ethernet frame contains a calculated CRC: * the Ethernet frame contains a calculated CRC:
* bmCRC = 1 : CRC is calculated * bmCRC = 1 : CRC is calculated
* bmCRC = 0 : CRC = 0xDEADBEEF * bmCRC = 0 : CRC = 0xDEADBEEF
*/ */
if (header & BIT(14)) if (header & BIT(14)) {
crc2 = ~crc32_le(~0, skb2->data, skb2->len); crc = get_unaligned_le32(skb2->data
else + 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; crc2 = 0xdeadbeef;
}
skb_trim(skb2, len - ETH_FCS_LEN);
if (is_last) if (is_last)
return crc == crc2; return crc == crc2;
......
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