xref: /openbmc/linux/lib/crc16.c (revision 40b0b3f8)
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