140b0b3f8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
27657ec1fSEvgeniy Polyakov /*
37657ec1fSEvgeniy Polyakov * crc16.c
47657ec1fSEvgeniy Polyakov */
57657ec1fSEvgeniy Polyakov
67657ec1fSEvgeniy Polyakov #include <linux/types.h>
77657ec1fSEvgeniy Polyakov #include <linux/module.h>
87657ec1fSEvgeniy Polyakov #include <linux/crc16.h>
97657ec1fSEvgeniy Polyakov
107657ec1fSEvgeniy Polyakov /** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
117657ec1fSEvgeniy Polyakov u16 const crc16_table[256] = {
127657ec1fSEvgeniy Polyakov 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
137657ec1fSEvgeniy Polyakov 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
147657ec1fSEvgeniy Polyakov 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
157657ec1fSEvgeniy Polyakov 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
167657ec1fSEvgeniy Polyakov 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
177657ec1fSEvgeniy Polyakov 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
187657ec1fSEvgeniy Polyakov 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
197657ec1fSEvgeniy Polyakov 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
207657ec1fSEvgeniy Polyakov 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
217657ec1fSEvgeniy Polyakov 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
227657ec1fSEvgeniy Polyakov 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
237657ec1fSEvgeniy Polyakov 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
247657ec1fSEvgeniy Polyakov 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
257657ec1fSEvgeniy Polyakov 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
267657ec1fSEvgeniy Polyakov 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
277657ec1fSEvgeniy Polyakov 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
287657ec1fSEvgeniy Polyakov 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
297657ec1fSEvgeniy Polyakov 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
307657ec1fSEvgeniy Polyakov 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
317657ec1fSEvgeniy Polyakov 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
327657ec1fSEvgeniy Polyakov 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
337657ec1fSEvgeniy Polyakov 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
347657ec1fSEvgeniy Polyakov 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
357657ec1fSEvgeniy Polyakov 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
367657ec1fSEvgeniy Polyakov 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
377657ec1fSEvgeniy Polyakov 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
387657ec1fSEvgeniy Polyakov 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
397657ec1fSEvgeniy Polyakov 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
407657ec1fSEvgeniy Polyakov 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
417657ec1fSEvgeniy Polyakov 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
427657ec1fSEvgeniy Polyakov 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
437657ec1fSEvgeniy Polyakov 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
447657ec1fSEvgeniy Polyakov };
457657ec1fSEvgeniy Polyakov EXPORT_SYMBOL(crc16_table);
467657ec1fSEvgeniy Polyakov
477657ec1fSEvgeniy Polyakov /**
482f72100cSRandy Dunlap * crc16 - compute the CRC-16 for the data buffer
492f72100cSRandy Dunlap * @crc: previous CRC value
502f72100cSRandy Dunlap * @buffer: data pointer
512f72100cSRandy Dunlap * @len: number of bytes in the buffer
527657ec1fSEvgeniy Polyakov *
532f72100cSRandy Dunlap * Returns the updated CRC value.
547657ec1fSEvgeniy Polyakov */
crc16(u16 crc,u8 const * buffer,size_t len)557657ec1fSEvgeniy Polyakov u16 crc16(u16 crc, u8 const *buffer, size_t len)
567657ec1fSEvgeniy Polyakov {
577657ec1fSEvgeniy Polyakov while (len--)
587657ec1fSEvgeniy Polyakov crc = crc16_byte(crc, *buffer++);
597657ec1fSEvgeniy Polyakov return crc;
607657ec1fSEvgeniy Polyakov }
617657ec1fSEvgeniy Polyakov EXPORT_SYMBOL(crc16);
627657ec1fSEvgeniy Polyakov
637657ec1fSEvgeniy Polyakov MODULE_DESCRIPTION("CRC16 calculations");
647657ec1fSEvgeniy Polyakov MODULE_LICENSE("GPL");
657657ec1fSEvgeniy Polyakov
66