Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -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;