|
50 | 50 | MODULE_DESCRIPTION("Various CRC32 calculations");
|
51 | 51 | MODULE_LICENSE("GPL");
|
52 | 52 |
|
53 |
| -#define GF2_DIM 32 |
54 |
| - |
55 |
| -static u32 gf2_matrix_times(u32 *mat, u32 vec) |
56 |
| -{ |
57 |
| - u32 sum = 0; |
58 |
| - |
59 |
| - while (vec) { |
60 |
| - if (vec & 1) |
61 |
| - sum ^= *mat; |
62 |
| - vec >>= 1; |
63 |
| - mat++; |
64 |
| - } |
65 |
| - |
66 |
| - return sum; |
67 |
| -} |
68 |
| - |
69 |
| -static void gf2_matrix_square(u32 *square, u32 *mat) |
70 |
| -{ |
71 |
| - int i; |
72 |
| - |
73 |
| - for (i = 0; i < GF2_DIM; i++) |
74 |
| - square[i] = gf2_matrix_times(mat, mat[i]); |
75 |
| -} |
76 |
| - |
77 | 53 | #if CRC_LE_BITS > 8 || CRC_BE_BITS > 8
|
78 | 54 |
|
79 | 55 | /* implements slicing-by-4 or slicing-by-8 algorithm */
|
80 |
| -static inline u32 |
| 56 | +static inline u32 __pure |
81 | 57 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
|
82 | 58 | {
|
83 | 59 | # ifdef __LITTLE_ENDIAN
|
@@ -155,51 +131,6 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
|
155 | 131 | }
|
156 | 132 | #endif
|
157 | 133 |
|
158 |
| -/* For conditions of distribution and use, see copyright notice in zlib.h */ |
159 |
| -static u32 crc32_generic_combine(u32 crc1, u32 crc2, size_t len2, |
160 |
| - u32 polynomial) |
161 |
| -{ |
162 |
| - u32 even[GF2_DIM]; /* Even-power-of-two zeros operator */ |
163 |
| - u32 odd[GF2_DIM]; /* Odd-power-of-two zeros operator */ |
164 |
| - u32 row; |
165 |
| - int i; |
166 |
| - |
167 |
| - if (len2 <= 0) |
168 |
| - return crc1; |
169 |
| - |
170 |
| - /* Put operator for one zero bit in odd */ |
171 |
| - odd[0] = polynomial; |
172 |
| - row = 1; |
173 |
| - for (i = 1; i < GF2_DIM; i++) { |
174 |
| - odd[i] = row; |
175 |
| - row <<= 1; |
176 |
| - } |
177 |
| - |
178 |
| - gf2_matrix_square(even, odd); /* Put operator for two zero bits in even */ |
179 |
| - gf2_matrix_square(odd, even); /* Put operator for four zero bits in odd */ |
180 |
| - |
181 |
| - /* Apply len2 zeros to crc1 (first square will put the operator for one |
182 |
| - * zero byte, eight zero bits, in even). |
183 |
| - */ |
184 |
| - do { |
185 |
| - /* Apply zeros operator for this bit of len2 */ |
186 |
| - gf2_matrix_square(even, odd); |
187 |
| - if (len2 & 1) |
188 |
| - crc1 = gf2_matrix_times(even, crc1); |
189 |
| - len2 >>= 1; |
190 |
| - /* If no more bits set, then done */ |
191 |
| - if (len2 == 0) |
192 |
| - break; |
193 |
| - /* Another iteration of the loop with odd and even swapped */ |
194 |
| - gf2_matrix_square(odd, even); |
195 |
| - if (len2 & 1) |
196 |
| - crc1 = gf2_matrix_times(odd, crc1); |
197 |
| - len2 >>= 1; |
198 |
| - } while (len2 != 0); |
199 |
| - |
200 |
| - crc1 ^= crc2; |
201 |
| - return crc1; |
202 |
| -} |
203 | 134 |
|
204 | 135 | /**
|
205 | 136 | * crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II
|
@@ -271,19 +202,81 @@ u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
|
271 | 202 | (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE);
|
272 | 203 | }
|
273 | 204 | #endif
|
274 |
| -u32 __pure crc32_le_combine(u32 crc1, u32 crc2, size_t len2) |
| 205 | +EXPORT_SYMBOL(crc32_le); |
| 206 | +EXPORT_SYMBOL(__crc32c_le); |
| 207 | + |
| 208 | +/* |
| 209 | + * This multiplies the polynomials x and y modulo the given modulus. |
| 210 | + * This follows the "little-endian" CRC convention that the lsbit |
| 211 | + * represents the highest power of x, and the msbit represents x^0. |
| 212 | + */ |
| 213 | +static u32 __attribute_const__ gf2_multiply(u32 x, u32 y, u32 modulus) |
275 | 214 | {
|
276 |
| - return crc32_generic_combine(crc1, crc2, len2, CRCPOLY_LE); |
| 215 | + u32 product = x & 1 ? y : 0; |
| 216 | + int i; |
| 217 | + |
| 218 | + for (i = 0; i < 31; i++) { |
| 219 | + product = (product >> 1) ^ (product & 1 ? modulus : 0); |
| 220 | + x >>= 1; |
| 221 | + product ^= x & 1 ? y : 0; |
| 222 | + } |
| 223 | + |
| 224 | + return product; |
277 | 225 | }
|
278 | 226 |
|
279 |
| -u32 __pure __crc32c_le_combine(u32 crc1, u32 crc2, size_t len2) |
| 227 | +/** |
| 228 | + * crc32_generic_shift - Append len 0 bytes to crc, in logarithmic time |
| 229 | + * @crc: The original little-endian CRC (i.e. lsbit is x^31 coefficient) |
| 230 | + * @len: The number of bytes. @crc is multiplied by x^(8*@len) |
| 231 | + * @polynomial: The modulus used to reduce the result to 32 bits. |
| 232 | + * |
| 233 | + * It's possible to parallelize CRC computations by computing a CRC |
| 234 | + * over separate ranges of a buffer, then summing them. |
| 235 | + * This shifts the given CRC by 8*len bits (i.e. produces the same effect |
| 236 | + * as appending len bytes of zero to the data), in time proportional |
| 237 | + * to log(len). |
| 238 | + */ |
| 239 | +static u32 __attribute_const__ crc32_generic_shift(u32 crc, size_t len, |
| 240 | + u32 polynomial) |
280 | 241 | {
|
281 |
| - return crc32_generic_combine(crc1, crc2, len2, CRC32C_POLY_LE); |
| 242 | + u32 power = polynomial; /* CRC of x^32 */ |
| 243 | + int i; |
| 244 | + |
| 245 | + /* Shift up to 32 bits in the simple linear way */ |
| 246 | + for (i = 0; i < 8 * (int)(len & 3); i++) |
| 247 | + crc = (crc >> 1) ^ (crc & 1 ? polynomial : 0); |
| 248 | + |
| 249 | + len >>= 2; |
| 250 | + if (!len) |
| 251 | + return crc; |
| 252 | + |
| 253 | + for (;;) { |
| 254 | + /* "power" is x^(2^i), modulo the polynomial */ |
| 255 | + if (len & 1) |
| 256 | + crc = gf2_multiply(crc, power, polynomial); |
| 257 | + |
| 258 | + len >>= 1; |
| 259 | + if (!len) |
| 260 | + break; |
| 261 | + |
| 262 | + /* Square power, advancing to x^(2^(i+1)) */ |
| 263 | + power = gf2_multiply(power, power, polynomial); |
| 264 | + } |
| 265 | + |
| 266 | + return crc; |
282 | 267 | }
|
283 |
| -EXPORT_SYMBOL(crc32_le); |
284 |
| -EXPORT_SYMBOL(crc32_le_combine); |
285 |
| -EXPORT_SYMBOL(__crc32c_le); |
286 |
| -EXPORT_SYMBOL(__crc32c_le_combine); |
| 268 | + |
| 269 | +u32 __attribute_const__ crc32_le_shift(u32 crc, size_t len) |
| 270 | +{ |
| 271 | + return crc32_generic_shift(crc, len, CRCPOLY_LE); |
| 272 | +} |
| 273 | + |
| 274 | +u32 __attribute_const__ __crc32c_le_shift(u32 crc, size_t len) |
| 275 | +{ |
| 276 | + return crc32_generic_shift(crc, len, CRC32C_POLY_LE); |
| 277 | +} |
| 278 | +EXPORT_SYMBOL(crc32_le_shift); |
| 279 | +EXPORT_SYMBOL(__crc32c_le_shift); |
287 | 280 |
|
288 | 281 | /**
|
289 | 282 | * crc32_be_generic() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
|
@@ -351,7 +344,7 @@ EXPORT_SYMBOL(crc32_be);
|
351 | 344 | #ifdef CONFIG_CRC32_SELFTEST
|
352 | 345 |
|
353 | 346 | /* 4096 random bytes */
|
354 |
| -static u8 __attribute__((__aligned__(8))) test_buf[] = |
| 347 | +static u8 const __aligned(8) test_buf[] __initconst = |
355 | 348 | {
|
356 | 349 | 0x5b, 0x85, 0x21, 0xcb, 0x09, 0x68, 0x7d, 0x30,
|
357 | 350 | 0xc7, 0x69, 0xd7, 0x30, 0x92, 0xde, 0x59, 0xe4,
|
@@ -875,7 +868,7 @@ static struct crc_test {
|
875 | 868 | u32 crc_le; /* expected crc32_le result */
|
876 | 869 | u32 crc_be; /* expected crc32_be result */
|
877 | 870 | u32 crc32c_le; /* expected crc32c_le result */
|
878 |
| -} test[] = |
| 871 | +} const test[] __initconst = |
879 | 872 | {
|
880 | 873 | {0x674bf11d, 0x00000038, 0x00000542, 0x0af6d466, 0xd8b6e4c1, 0xf6e93d6c},
|
881 | 874 | {0x35c672c6, 0x0000003a, 0x000001aa, 0xc6d3dfba, 0x28aaf3ad, 0x0fe92aca},
|
|
0 commit comments