]> git.ipfire.org Git - thirdparty/mdadm.git/blob - crc32c.c
mdadm.h: Introduced unaligned {get,put}_unaligned{16,32}()
[thirdparty/mdadm.git] / crc32c.c
1 /*
2 * Oct 28, 2015 Song Liu simplified the code and port it to mdadm
3 *
4 * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin
5 * cleaned up code to current version of sparse and added the slicing-by-8
6 * algorithm to the closely similar existing slicing-by-4 algorithm.
7 *
8 * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
9 * Nicer crc32 functions/docs submitted by linux@horizon.com. Thanks!
10 * Code was from the public domain, copyright abandoned. Code was
11 * subsequently included in the kernel, thus was re-licensed under the
12 * GNU GPL v2.
13 *
14 * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com>
15 * Same crc32 function was used in 5 other places in the kernel.
16 * I made one version, and deleted the others.
17 * There are various incantations of crc32(). Some use a seed of 0 or ~0.
18 * Some xor at the end with ~0. The generic crc32() function takes
19 * seed as an argument, and doesn't xor at the end. Then individual
20 * users can do whatever they need.
21 * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
22 * fs/jffs2 uses seed 0, doesn't xor with ~0.
23 * fs/partitions/efi.c uses seed ~0, xor's with ~0.
24 *
25 * This source code is licensed under the GNU General Public License,
26 * Version 2. See the file COPYING for more details.
27 */
28
29 #include <sys/types.h>
30 #include <asm/types.h>
31 #include <stdlib.h>
32
33 /*
34 * There are multiple 16-bit CRC polynomials in common use, but this is
35 * *the* standard CRC-32 polynomial, first popularized by Ethernet.
36 * 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
37 */
38 #define CRCPOLY_LE 0xedb88320
39 #define CRCPOLY_BE 0x04c11db7
40
41 /*
42 * This is the CRC32c polynomial, as outlined by Castagnoli.
43 * 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+
44 * x^8+x^6+x^0
45 */
46 #define CRC32C_POLY_LE 0x82F63B78
47
48 /**
49 * crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II
50 * CRC32/CRC32C
51 * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for other
52 * uses, or the previous crc32/crc32c value if computing incrementally.
53 * @p: pointer to buffer over which CRC32/CRC32C is run
54 * @len: length of buffer @p
55 * @polynomial: CRC32/CRC32c LE polynomial
56 */
57 static inline __u32 crc32_le_generic(__u32 crc, unsigned char const *p,
58 size_t len, __u32 polynomial)
59 {
60 int i;
61 while (len--) {
62 crc ^= *p++;
63 for (i = 0; i < 8; i++)
64 crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
65 }
66 return crc;
67 }
68
69 __u32 crc32_le(__u32 crc, unsigned char const *p, size_t len)
70 {
71 return crc32_le_generic(crc, p, len, CRCPOLY_LE);
72 }
73
74 __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len)
75 {
76 return crc32_le_generic(crc, p, len, CRC32C_POLY_LE);
77 }
78
79 /**
80 * crc32_be_generic() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
81 * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for
82 * other uses, or the previous crc32 value if computing incrementally.
83 * @p: pointer to buffer over which CRC32 is run
84 * @len: length of buffer @p
85 * @polynomial: CRC32 BE polynomial
86 */
87 static inline __u32 crc32_be_generic(__u32 crc, unsigned char const *p,
88 size_t len, __u32 polynomial)
89 {
90 int i;
91 while (len--) {
92 crc ^= *p++ << 24;
93 for (i = 0; i < 8; i++)
94 crc =
95 (crc << 1) ^ ((crc & 0x80000000) ? polynomial :
96 0);
97 }
98 return crc;
99 }
100
101 __u32 crc32_be(__u32 crc, unsigned char const *p, size_t len)
102 {
103 return crc32_be_generic(crc, p, len, CRCPOLY_BE);
104 }