]>
Commit | Line | Data |
---|---|---|
198d5478 SL |
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 | } |