189a51591SEric Biggers // SPDX-License-Identifier: GPL-2.0-only 289a51591SEric Biggers /* 389a51591SEric Biggers * crc16.c 489a51591SEric Biggers */ 589a51591SEric Biggers 689a51591SEric Biggers #include <linux/crc16.h> 7*1a822ea5SEric Biggers #include <linux/export.h> 8*1a822ea5SEric Biggers #include <linux/module.h> 9*1a822ea5SEric Biggers #include <linux/types.h> 1089a51591SEric Biggers 1189a51591SEric Biggers /** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ 1289a51591SEric Biggers static const u16 crc16_table[256] = { 1389a51591SEric Biggers 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 1489a51591SEric Biggers 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 1589a51591SEric Biggers 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 1689a51591SEric Biggers 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 1789a51591SEric Biggers 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 1889a51591SEric Biggers 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 1989a51591SEric Biggers 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 2089a51591SEric Biggers 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 2189a51591SEric Biggers 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 2289a51591SEric Biggers 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 2389a51591SEric Biggers 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 2489a51591SEric Biggers 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 2589a51591SEric Biggers 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 2689a51591SEric Biggers 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 2789a51591SEric Biggers 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 2889a51591SEric Biggers 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 2989a51591SEric Biggers 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 3089a51591SEric Biggers 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 3189a51591SEric Biggers 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 3289a51591SEric Biggers 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 3389a51591SEric Biggers 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 3489a51591SEric Biggers 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 3589a51591SEric Biggers 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 3689a51591SEric Biggers 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 3789a51591SEric Biggers 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 3889a51591SEric Biggers 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 3989a51591SEric Biggers 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 4089a51591SEric Biggers 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 4189a51591SEric Biggers 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 4289a51591SEric Biggers 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 4389a51591SEric Biggers 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 4489a51591SEric Biggers 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 4589a51591SEric Biggers }; 4689a51591SEric Biggers 4789a51591SEric Biggers /** 4889a51591SEric Biggers * crc16 - compute the CRC-16 for the data buffer 4989a51591SEric Biggers * @crc: previous CRC value 5089a51591SEric Biggers * @p: data pointer 5189a51591SEric Biggers * @len: number of bytes in the buffer 5289a51591SEric Biggers * 5389a51591SEric Biggers * Returns the updated CRC value. 5489a51591SEric Biggers */ 5589a51591SEric Biggers u16 crc16(u16 crc, const u8 *p, size_t len) 5689a51591SEric Biggers { 5789a51591SEric Biggers while (len--) 5889a51591SEric Biggers crc = (crc >> 8) ^ crc16_table[(crc & 0xff) ^ *p++]; 5989a51591SEric Biggers return crc; 6089a51591SEric Biggers } 6189a51591SEric Biggers EXPORT_SYMBOL(crc16); 6289a51591SEric Biggers 6389a51591SEric Biggers MODULE_DESCRIPTION("CRC16 calculations"); 6489a51591SEric Biggers MODULE_LICENSE("GPL"); 6589a51591SEric Biggers 66