1969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe/*
2969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe *      crc16.c
3969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe *
4969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe * This source code is licensed under the GNU General Public License,
5969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe * Version 2. See the file COPYING for more details.
6969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe */
7969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe
8969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe#include "crc16.h"
9969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe
10969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
11969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboeunsigned short const crc16_table[256] = {
12969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
13969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
14969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
15969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
16969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
17969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
18969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
19969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
20969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
21969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
22969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
23969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
24969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
25969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
26969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
27969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
28969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
29969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
30969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
31969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
32969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
33969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
34969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
35969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
36969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
37969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
38969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
39969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
40969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
41969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
42969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
43969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
44969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe};
45969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe
4625dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboeunsigned short fio_crc16(const void *buffer, unsigned int len)
47969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe{
483095ffa9747a679e4f655388c782e4b201047fd3Jens Axboe	const unsigned char *cp = (const unsigned char *) buffer;
49969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	unsigned short crc = 0;
50969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe
51969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	while (len--)
523095ffa9747a679e4f655388c782e4b201047fd3Jens Axboe		crc = crc16_byte(crc, *cp++);
53969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe	return crc;
54969f7ed32353ade93ea30542a4993b75b94e3f8aJens Axboe}
55