189a51591SEric Biggers /* 289a51591SEric Biggers * Copyright (c) 2011 Broadcom Corporation 389a51591SEric Biggers * 489a51591SEric Biggers * Permission to use, copy, modify, and/or distribute this software for any 589a51591SEric Biggers * purpose with or without fee is hereby granted, provided that the above 689a51591SEric Biggers * copyright notice and this permission notice appear in all copies. 789a51591SEric Biggers * 889a51591SEric Biggers * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 989a51591SEric Biggers * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1089a51591SEric Biggers * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 1189a51591SEric Biggers * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1289a51591SEric Biggers * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1389a51591SEric Biggers * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1489a51591SEric Biggers * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1589a51591SEric Biggers */ 1689a51591SEric Biggers 1789a51591SEric Biggers #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 1889a51591SEric Biggers 1989a51591SEric Biggers #include <linux/crc8.h> 20*1a822ea5SEric Biggers #include <linux/export.h> 21*1a822ea5SEric Biggers #include <linux/module.h> 2289a51591SEric Biggers #include <linux/printk.h> 2389a51591SEric Biggers 2489a51591SEric Biggers /** 2589a51591SEric Biggers * crc8_populate_msb - fill crc table for given polynomial in reverse bit order. 2689a51591SEric Biggers * 2789a51591SEric Biggers * @table: table to be filled. 2889a51591SEric Biggers * @polynomial: polynomial for which table is to be filled. 2989a51591SEric Biggers */ 3089a51591SEric Biggers void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial) 3189a51591SEric Biggers { 3289a51591SEric Biggers int i, j; 3389a51591SEric Biggers const u8 msbit = 0x80; 3489a51591SEric Biggers u8 t = msbit; 3589a51591SEric Biggers 3689a51591SEric Biggers table[0] = 0; 3789a51591SEric Biggers 3889a51591SEric Biggers for (i = 1; i < CRC8_TABLE_SIZE; i *= 2) { 3989a51591SEric Biggers t = (t << 1) ^ (t & msbit ? polynomial : 0); 4089a51591SEric Biggers for (j = 0; j < i; j++) 4189a51591SEric Biggers table[i+j] = table[j] ^ t; 4289a51591SEric Biggers } 4389a51591SEric Biggers } 4489a51591SEric Biggers EXPORT_SYMBOL(crc8_populate_msb); 4589a51591SEric Biggers 4689a51591SEric Biggers /** 4789a51591SEric Biggers * crc8_populate_lsb - fill crc table for given polynomial in regular bit order. 4889a51591SEric Biggers * 4989a51591SEric Biggers * @table: table to be filled. 5089a51591SEric Biggers * @polynomial: polynomial for which table is to be filled. 5189a51591SEric Biggers */ 5289a51591SEric Biggers void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial) 5389a51591SEric Biggers { 5489a51591SEric Biggers int i, j; 5589a51591SEric Biggers u8 t = 1; 5689a51591SEric Biggers 5789a51591SEric Biggers table[0] = 0; 5889a51591SEric Biggers 5989a51591SEric Biggers for (i = (CRC8_TABLE_SIZE >> 1); i; i >>= 1) { 6089a51591SEric Biggers t = (t >> 1) ^ (t & 1 ? polynomial : 0); 6189a51591SEric Biggers for (j = 0; j < CRC8_TABLE_SIZE; j += 2*i) 6289a51591SEric Biggers table[i+j] = table[j] ^ t; 6389a51591SEric Biggers } 6489a51591SEric Biggers } 6589a51591SEric Biggers EXPORT_SYMBOL(crc8_populate_lsb); 6689a51591SEric Biggers 6789a51591SEric Biggers /** 6889a51591SEric Biggers * crc8 - calculate a crc8 over the given input data. 6989a51591SEric Biggers * 7089a51591SEric Biggers * @table: crc table used for calculation. 7189a51591SEric Biggers * @pdata: pointer to data buffer. 7289a51591SEric Biggers * @nbytes: number of bytes in data buffer. 7389a51591SEric Biggers * @crc: previous returned crc8 value. 7489a51591SEric Biggers */ 7589a51591SEric Biggers u8 crc8(const u8 table[CRC8_TABLE_SIZE], const u8 *pdata, size_t nbytes, u8 crc) 7689a51591SEric Biggers { 7789a51591SEric Biggers /* loop over the buffer data */ 7889a51591SEric Biggers while (nbytes-- > 0) 7989a51591SEric Biggers crc = table[(crc ^ *pdata++) & 0xff]; 8089a51591SEric Biggers 8189a51591SEric Biggers return crc; 8289a51591SEric Biggers } 8389a51591SEric Biggers EXPORT_SYMBOL(crc8); 8489a51591SEric Biggers 8589a51591SEric Biggers MODULE_DESCRIPTION("CRC8 (by Williams, Ross N.) function"); 8689a51591SEric Biggers MODULE_AUTHOR("Broadcom Corporation"); 8789a51591SEric Biggers MODULE_LICENSE("Dual BSD/GPL"); 88