Browse Source

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: Brian Niebuhr <bniebuhr@efjohnson.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Brian Niebuhr 16 years ago
parent
commit
9ca33a0f1a
1 changed files with 10 additions and 7 deletions
  1. 10 7
      drivers/net/usb/cdc_eem.c

+ 10 - 7
drivers/net/usb/cdc_eem.c

@@ -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;