| /* |
| * Oct 28, 2015 Song Liu simplified the code and port it to mdadm |
| * |
| * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin |
| * cleaned up code to current version of sparse and added the slicing-by-8 |
| * algorithm to the closely similar existing slicing-by-4 algorithm. |
| * |
| * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com> |
| * Nicer crc32 functions/docs submitted by linux@horizon.com. Thanks! |
| * Code was from the public domain, copyright abandoned. Code was |
| * subsequently included in the kernel, thus was re-licensed under the |
| * GNU GPL v2. |
| * |
| * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com> |
| * Same crc32 function was used in 5 other places in the kernel. |
| * I made one version, and deleted the others. |
| * There are various incantations of crc32(). Some use a seed of 0 or ~0. |
| * Some xor at the end with ~0. The generic crc32() function takes |
| * seed as an argument, and doesn't xor at the end. Then individual |
| * users can do whatever they need. |
| * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0. |
| * fs/jffs2 uses seed 0, doesn't xor with ~0. |
| * fs/partitions/efi.c uses seed ~0, xor's with ~0. |
| * |
| * This source code is licensed under the GNU General Public License, |
| * Version 2. See the file COPYING for more details. |
| */ |
| |
| #include <sys/types.h> |
| #include <asm/types.h> |
| #include <stdlib.h> |
| |
| /* |
| * There are multiple 16-bit CRC polynomials in common use, but this is |
| * *the* standard CRC-32 polynomial, first popularized by Ethernet. |
| * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 |
| */ |
| #define CRCPOLY_LE 0xedb88320 |
| #define CRCPOLY_BE 0x04c11db7 |
| |
| /* |
| * This is the CRC32c polynomial, as outlined by Castagnoli. |
| * x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+ |
| * x^8+x^6+x^0 |
| */ |
| #define CRC32C_POLY_LE 0x82F63B78 |
| |
| /** |
| * crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II |
| * CRC32/CRC32C |
| * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for other |
| * uses, or the previous crc32/crc32c value if computing incrementally. |
| * @p: pointer to buffer over which CRC32/CRC32C is run |
| * @len: length of buffer @p |
| * @polynomial: CRC32/CRC32c LE polynomial |
| */ |
| static inline __u32 crc32_le_generic(__u32 crc, unsigned char const *p, |
| size_t len, __u32 polynomial) |
| { |
| int i; |
| while (len--) { |
| crc ^= *p++; |
| for (i = 0; i < 8; i++) |
| crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0); |
| } |
| return crc; |
| } |
| |
| __u32 crc32_le(__u32 crc, unsigned char const *p, size_t len) |
| { |
| return crc32_le_generic(crc, p, len, CRCPOLY_LE); |
| } |
| |
| __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len) |
| { |
| return crc32_le_generic(crc, p, len, CRC32C_POLY_LE); |
| } |
| |
| /** |
| * crc32_be_generic() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32 |
| * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for |
| * other uses, or the previous crc32 value if computing incrementally. |
| * @p: pointer to buffer over which CRC32 is run |
| * @len: length of buffer @p |
| * @polynomial: CRC32 BE polynomial |
| */ |
| static inline __u32 crc32_be_generic(__u32 crc, unsigned char const *p, |
| size_t len, __u32 polynomial) |
| { |
| int i; |
| while (len--) { |
| crc ^= *p++ << 24; |
| for (i = 0; i < 8; i++) |
| crc = |
| (crc << 1) ^ ((crc & 0x80000000) ? polynomial : |
| 0); |
| } |
| return crc; |
| } |
| |
| __u32 crc32_be(__u32 crc, unsigned char const *p, size_t len) |
| { |
| return crc32_be_generic(crc, p, len, CRCPOLY_BE); |
| } |