diff options
author | Bob Pearson <rpearson@systemfabricworks.com> | 2012-03-23 18:02:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 19:58:37 -0400 |
commit | 9a1dbf6a29694c9d81b498019f103aee0f8b5b6c (patch) | |
tree | 1f331fa108ea29ccf06a7b5816da4dbcaa12bf2d /lib | |
parent | ce4320ddda4c2520fe77194d3c801ad4e8a8aa11 (diff) |
crc32: make CRC_*_BITS definition correspond to actual bit counts
crc32.c provides a choice of one of several algorithms for computing the
LSB and LSB versions of the CRC32 checksum based on the parameters
CRC_LE_BITS and CRC_BE_BITS.
In the original version the values 1, 2, 4 and 8 respectively selected
versions of the alrogithm that computed the crc 1, 2, 4 and 32 bits as a
time.
This patch series adds a new version that computes the CRC 64 bits at a
time. To make things easier to understand the parameter has been
reinterpreted to actually stand for the number of bits processed in each
step of the algorithm so that the old value 8 has been replaced with the
value 32.
This also allows us to add in a widely used crc algorithm that computes
the crc 8 bits at a time called the Sarwate algorithm.
[djwong@us.ibm.com: Minor changelog tweaks]
Signed-off-by: Bob Pearson <rpearson@systemfabricworks.com>
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/crc32.c | 17 | ||||
-rw-r--r-- | lib/crc32defs.h | 18 | ||||
-rw-r--r-- | lib/gen_crc32table.c | 11 |
3 files changed, 34 insertions, 12 deletions
diff --git a/lib/crc32.c b/lib/crc32.c index 7394288c045c..5971f2ad46d5 100644 --- a/lib/crc32.c +++ b/lib/crc32.c | |||
@@ -27,13 +27,13 @@ | |||
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include "crc32defs.h" | 28 | #include "crc32defs.h" |
29 | 29 | ||
30 | #if CRC_LE_BITS == 8 | 30 | #if CRC_LE_BITS > 8 |
31 | # define tole(x) ((__force u32) __constant_cpu_to_le32(x)) | 31 | # define tole(x) ((__force u32) __constant_cpu_to_le32(x)) |
32 | #else | 32 | #else |
33 | # define tole(x) (x) | 33 | # define tole(x) (x) |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | #if CRC_BE_BITS == 8 | 36 | #if CRC_BE_BITS > 8 |
37 | # define tobe(x) ((__force u32) __constant_cpu_to_be32(x)) | 37 | # define tobe(x) ((__force u32) __constant_cpu_to_be32(x)) |
38 | #else | 38 | #else |
39 | # define tobe(x) (x) | 39 | # define tobe(x) (x) |
@@ -45,7 +45,7 @@ MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>"); | |||
45 | MODULE_DESCRIPTION("Ethernet CRC32 calculations"); | 45 | MODULE_DESCRIPTION("Ethernet CRC32 calculations"); |
46 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
47 | 47 | ||
48 | #if CRC_LE_BITS == 8 || CRC_BE_BITS == 8 | 48 | #if CRC_LE_BITS > 8 || CRC_BE_BITS > 8 |
49 | 49 | ||
50 | static inline u32 | 50 | static inline u32 |
51 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) | 51 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) |
@@ -126,6 +126,12 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | |||
126 | crc = (crc >> 4) ^ crc32table_le[0][crc & 15]; | 126 | crc = (crc >> 4) ^ crc32table_le[0][crc & 15]; |
127 | } | 127 | } |
128 | # elif CRC_LE_BITS == 8 | 128 | # elif CRC_LE_BITS == 8 |
129 | /* aka Sarwate algorithm */ | ||
130 | while (len--) { | ||
131 | crc ^= *p++; | ||
132 | crc = (crc >> 8) ^ crc32table_le[0][crc & 255]; | ||
133 | } | ||
134 | # else | ||
129 | const u32 (*tab)[] = crc32table_le; | 135 | const u32 (*tab)[] = crc32table_le; |
130 | 136 | ||
131 | crc = (__force u32) __cpu_to_le32(crc); | 137 | crc = (__force u32) __cpu_to_le32(crc); |
@@ -169,6 +175,11 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | |||
169 | crc = (crc << 4) ^ crc32table_be[0][crc >> 28]; | 175 | crc = (crc << 4) ^ crc32table_be[0][crc >> 28]; |
170 | } | 176 | } |
171 | # elif CRC_BE_BITS == 8 | 177 | # elif CRC_BE_BITS == 8 |
178 | while (len--) { | ||
179 | crc ^= *p++ << 24; | ||
180 | crc = (crc << 8) ^ crc32table_be[0][crc >> 24]; | ||
181 | } | ||
182 | # else | ||
172 | const u32 (*tab)[] = crc32table_be; | 183 | const u32 (*tab)[] = crc32table_be; |
173 | 184 | ||
174 | crc = (__force u32) __cpu_to_be32(crc); | 185 | crc = (__force u32) __cpu_to_be32(crc); |
diff --git a/lib/crc32defs.h b/lib/crc32defs.h index f5a540176571..daa3a5e85f60 100644 --- a/lib/crc32defs.h +++ b/lib/crc32defs.h | |||
@@ -6,27 +6,29 @@ | |||
6 | #define CRCPOLY_LE 0xedb88320 | 6 | #define CRCPOLY_LE 0xedb88320 |
7 | #define CRCPOLY_BE 0x04c11db7 | 7 | #define CRCPOLY_BE 0x04c11db7 |
8 | 8 | ||
9 | /* How many bits at a time to use. Requires a table of 4<<CRC_xx_BITS bytes. */ | 9 | /* How many bits at a time to use. Valid values are 1, 2, 4, 8, and 32. */ |
10 | /* For less performance-sensitive, use 4 */ | 10 | /* For less performance-sensitive, use 4 or 8 */ |
11 | #ifndef CRC_LE_BITS | 11 | #ifndef CRC_LE_BITS |
12 | # define CRC_LE_BITS 8 | 12 | # define CRC_LE_BITS 32 |
13 | #endif | 13 | #endif |
14 | #ifndef CRC_BE_BITS | 14 | #ifndef CRC_BE_BITS |
15 | # define CRC_BE_BITS 8 | 15 | # define CRC_BE_BITS 32 |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Little-endian CRC computation. Used with serial bit streams sent | 19 | * Little-endian CRC computation. Used with serial bit streams sent |
20 | * lsbit-first. Be sure to use cpu_to_le32() to append the computed CRC. | 20 | * lsbit-first. Be sure to use cpu_to_le32() to append the computed CRC. |
21 | */ | 21 | */ |
22 | #if CRC_LE_BITS > 8 || CRC_LE_BITS < 1 || CRC_LE_BITS & CRC_LE_BITS-1 | 22 | #if CRC_LE_BITS > 32 || CRC_LE_BITS < 1 || CRC_LE_BITS == 16 || \ |
23 | # error CRC_LE_BITS must be a power of 2 between 1 and 8 | 23 | CRC_LE_BITS & CRC_LE_BITS-1 |
24 | # error "CRC_LE_BITS must be one of {1, 2, 4, 8, 32}" | ||
24 | #endif | 25 | #endif |
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Big-endian CRC computation. Used with serial bit streams sent | 28 | * Big-endian CRC computation. Used with serial bit streams sent |
28 | * msbit-first. Be sure to use cpu_to_be32() to append the computed CRC. | 29 | * msbit-first. Be sure to use cpu_to_be32() to append the computed CRC. |
29 | */ | 30 | */ |
30 | #if CRC_BE_BITS > 8 || CRC_BE_BITS < 1 || CRC_BE_BITS & CRC_BE_BITS-1 | 31 | #if CRC_BE_BITS > 32 || CRC_BE_BITS < 1 || CRC_BE_BITS == 16 || \ |
31 | # error CRC_BE_BITS must be a power of 2 between 1 and 8 | 32 | CRC_BE_BITS & CRC_BE_BITS-1 |
33 | # error "CRC_BE_BITS must be one of {1, 2, 4, 8, 32}" | ||
32 | #endif | 34 | #endif |
diff --git a/lib/gen_crc32table.c b/lib/gen_crc32table.c index eced7696eb7c..99ac744848fb 100644 --- a/lib/gen_crc32table.c +++ b/lib/gen_crc32table.c | |||
@@ -4,8 +4,17 @@ | |||
4 | 4 | ||
5 | #define ENTRIES_PER_LINE 4 | 5 | #define ENTRIES_PER_LINE 4 |
6 | 6 | ||
7 | #if CRC_LE_BITS <= 8 | ||
7 | #define LE_TABLE_SIZE (1 << CRC_LE_BITS) | 8 | #define LE_TABLE_SIZE (1 << CRC_LE_BITS) |
9 | #else | ||
10 | #define LE_TABLE_SIZE 256 | ||
11 | #endif | ||
12 | |||
13 | #if CRC_BE_BITS <= 8 | ||
8 | #define BE_TABLE_SIZE (1 << CRC_BE_BITS) | 14 | #define BE_TABLE_SIZE (1 << CRC_BE_BITS) |
15 | #else | ||
16 | #define BE_TABLE_SIZE 256 | ||
17 | #endif | ||
9 | 18 | ||
10 | static uint32_t crc32table_le[4][256]; | 19 | static uint32_t crc32table_le[4][256]; |
11 | static uint32_t crc32table_be[4][256]; | 20 | static uint32_t crc32table_be[4][256]; |
@@ -24,7 +33,7 @@ static void crc32init_le(void) | |||
24 | 33 | ||
25 | crc32table_le[0][0] = 0; | 34 | crc32table_le[0][0] = 0; |
26 | 35 | ||
27 | for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) { | 36 | for (i = LE_TABLE_SIZE >> 1; i; i >>= 1) { |
28 | crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); | 37 | crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); |
29 | for (j = 0; j < LE_TABLE_SIZE; j += 2 * i) | 38 | for (j = 0; j < LE_TABLE_SIZE; j += 2 * i) |
30 | crc32table_le[0][i + j] = crc ^ crc32table_le[0][j]; | 39 | crc32table_le[0][i + j] = crc ^ crc32table_le[0][j]; |