diff --git a/lib/Kconfig b/lib/Kconfig index ba3d104..39a777d 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -55,6 +55,14 @@ config CRC7 the kernel tree does. Such modules that use library CRC7 functions require M here. +config CRC5 + tristate "CRC5 functions" + help + This option is provided for the case where no in-kernel-tree + modules require CRC5 functions, but a module built outside + the kernel tree does. Such modules that use library CRC5 + functions require M here. + config LIBCRC32C tristate "CRC32c (Castagnoli, et al) Cyclic Redundancy-Check" help diff --git a/lib/Makefile b/lib/Makefile index 23de261..bcfda50 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_CRC16) += crc16.o obj-$(CONFIG_CRC_ITU_T) += crc-itu-t.o obj-$(CONFIG_CRC32) += crc32.o obj-$(CONFIG_CRC7) += crc7.o +obj-$(CONFIG_CRC5) += crc5.o obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o diff --git a/include/linux/crc5.h b/include/linux/crc5.h new file mode 100644 index 0000000..8aca5f8 --- /dev/null +++ b/include/linux/crc5.h @@ -0,0 +1,14 @@ +#ifndef _LINUX_CRC5_H +#define _LINUX_CRC5_H +#include + +extern const u8 crc5_syndrome_table[256]; + +static inline u8 crc5_byte(u8 crc, u8 data) +{ + return crc5_syndrome_table[crc ^ data]; +} + +extern u8 crc5(u8 crc, const u8 *buffer, size_t len); + +#endif diff --git a/lib/crc5.c b/lib/crc5.c new file mode 100644 index 0000000..6dd4014 --- /dev/null +++ b/lib/crc5.c @@ -0,0 +1,69 @@ +/* + * crc5.c + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include + + +/* Table for CRC-5 (polynomial x^5 + x^3 + 1) */ +const u8 crc5_syndrome_table[256] = { + 0x00, 0x0e, 0x1c, 0x12, 0x11, 0x1f, 0x0d, 0x03, + 0x0b, 0x05, 0x17, 0x19, 0x1a, 0x14, 0x06, 0x08, + 0x16, 0x18, 0x0a, 0x04, 0x07, 0x09, 0x1b, 0x15, + 0x1d, 0x13, 0x01, 0x0f, 0x0c, 0x02, 0x10, 0x1e, + 0x05, 0x0b, 0x19, 0x17, 0x14, 0x1a, 0x08, 0x06, + 0x0e, 0x00, 0x12, 0x1c, 0x1f, 0x11, 0x03, 0x0d, + 0x13, 0x1d, 0x0f, 0x01, 0x02, 0x0c, 0x1e, 0x10, + 0x18, 0x16, 0x04, 0x0a, 0x09, 0x07, 0x15, 0x1b, + 0x0a, 0x04, 0x16, 0x18, 0x1b, 0x15, 0x07, 0x09, + 0x01, 0x0f, 0x1d, 0x13, 0x10, 0x1e, 0x0c, 0x02, + 0x1c, 0x12, 0x00, 0x0e, 0x0d, 0x03, 0x11, 0x1f, + 0x17, 0x19, 0x0b, 0x05, 0x06, 0x08, 0x1a, 0x14, + 0x0f, 0x01, 0x13, 0x1d, 0x1e, 0x10, 0x02, 0x0c, + 0x04, 0x0a, 0x18, 0x16, 0x15, 0x1b, 0x09, 0x07, + 0x19, 0x17, 0x05, 0x0b, 0x08, 0x06, 0x14, 0x1a, + 0x12, 0x1c, 0x0e, 0x00, 0x03, 0x0d, 0x1f, 0x11, + 0x14, 0x1a, 0x08, 0x06, 0x05, 0x0b, 0x19, 0x17, + 0x1f, 0x11, 0x03, 0x0d, 0x0e, 0x00, 0x12, 0x1c, + 0x02, 0x0c, 0x1e, 0x10, 0x13, 0x1d, 0x0f, 0x01, + 0x09, 0x07, 0x15, 0x1b, 0x18, 0x16, 0x04, 0x0a, + 0x11, 0x1f, 0x0d, 0x03, 0x00, 0x0e, 0x1c, 0x12, + 0x1a, 0x14, 0x06, 0x08, 0x0b, 0x05, 0x17, 0x19, + 0x07, 0x09, 0x1b, 0x15, 0x16, 0x18, 0x0a, 0x04, + 0x0c, 0x02, 0x10, 0x1e, 0x1d, 0x13, 0x01, 0x0f, + 0x1e, 0x10, 0x02, 0x0c, 0x0f, 0x01, 0x13, 0x1d, + 0x15, 0x1b, 0x09, 0x07, 0x04, 0x0a, 0x18, 0x16, + 0x08, 0x06, 0x14, 0x1a, 0x19, 0x17, 0x05, 0x0b, + 0x03, 0x0d, 0x1f, 0x11, 0x12, 0x1c, 0x0e, 0x00, + 0x1b, 0x15, 0x07, 0x09, 0x0a, 0x04, 0x16, 0x18, + 0x10, 0x1e, 0x0c, 0x02, 0x01, 0x0f, 0x1d, 0x13, + 0x0d, 0x03, 0x11, 0x1f, 0x1c, 0x12, 0x00, 0x0e, + 0x06, 0x08, 0x1a, 0x14, 0x17, 0x19, 0x0b, 0x05 + +}; +EXPORT_SYMBOL(crc5_syndrome_table); + +/** + * crc5 - update the CRC5 for the data buffer + * @crc: previous CRC5 value + * @buffer: data pointer + * @len: number of bytes in the buffer + * Context: any + * + * Returns the updated CRC5 value. + */ +u8 crc5(u8 crc, const u8 *buffer, size_t len) +{ + while (len--) + crc = crc5_byte(crc, *buffer++); + return crc; +} +EXPORT_SYMBOL(crc5); + +MODULE_DESCRIPTION("CRC5 calculations"); +MODULE_LICENSE("GPL");