aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/crc32.c104
-rw-r--r--lib/gen_crc32table.c6
2 files changed, 39 insertions, 71 deletions
diff --git a/lib/crc32.c b/lib/crc32.c
index 996115d4f377..bf03922c5d69 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -23,13 +23,10 @@
23/* see: Documentation/crc32.txt for a description of algorithms */ 23/* see: Documentation/crc32.txt for a description of algorithms */
24 24
25#include <linux/crc32.h> 25#include <linux/crc32.h>
26#include <linux/kernel.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/compiler.h>
29#include <linux/types.h> 27#include <linux/types.h>
30#include <linux/init.h>
31#include <linux/atomic.h>
32#include "crc32defs.h" 28#include "crc32defs.h"
29
33#if CRC_LE_BITS == 8 30#if CRC_LE_BITS == 8
34# define tole(x) __constant_cpu_to_le32(x) 31# define tole(x) __constant_cpu_to_le32(x)
35#else 32#else
@@ -41,6 +38,7 @@
41#else 38#else
42# define tobe(x) (x) 39# define tobe(x) (x)
43#endif 40#endif
41
44#include "crc32table.h" 42#include "crc32table.h"
45 43
46MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>"); 44MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
@@ -96,6 +94,7 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
96#undef DO_CRC4 94#undef DO_CRC4
97} 95}
98#endif 96#endif
97
99/** 98/**
100 * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32 99 * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
101 * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for 100 * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for
@@ -103,53 +102,39 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
103 * @p: pointer to buffer over which CRC is run 102 * @p: pointer to buffer over which CRC is run
104 * @len: length of buffer @p 103 * @len: length of buffer @p
105 */ 104 */
106u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
107
108#if CRC_LE_BITS == 1
109/*
110 * In fact, the table-based code will work in this case, but it can be
111 * simplified by inlining the table in ?: form.
112 */
113
114u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) 105u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
115{ 106{
107#if CRC_LE_BITS == 1
116 int i; 108 int i;
117 while (len--) { 109 while (len--) {
118 crc ^= *p++; 110 crc ^= *p++;
119 for (i = 0; i < 8; i++) 111 for (i = 0; i < 8; i++)
120 crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); 112 crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
121 } 113 }
122 return crc; 114# elif CRC_LE_BITS == 2
123}
124#else /* Table-based approach */
125
126u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
127{
128# if CRC_LE_BITS == 8
129 const u32 (*tab)[] = crc32table_le;
130
131 crc = __cpu_to_le32(crc);
132 crc = crc32_body(crc, p, len, tab);
133 return __le32_to_cpu(crc);
134# elif CRC_LE_BITS == 4
135 while (len--) { 115 while (len--) {
136 crc ^= *p++; 116 crc ^= *p++;
137 crc = (crc >> 4) ^ crc32table_le[crc & 15]; 117 crc = (crc >> 2) ^ crc32table_le[0][crc & 3];
138 crc = (crc >> 4) ^ crc32table_le[crc & 15]; 118 crc = (crc >> 2) ^ crc32table_le[0][crc & 3];
119 crc = (crc >> 2) ^ crc32table_le[0][crc & 3];
120 crc = (crc >> 2) ^ crc32table_le[0][crc & 3];
139 } 121 }
140 return crc; 122# elif CRC_LE_BITS == 4
141# elif CRC_LE_BITS == 2
142 while (len--) { 123 while (len--) {
143 crc ^= *p++; 124 crc ^= *p++;
144 crc = (crc >> 2) ^ crc32table_le[crc & 3]; 125 crc = (crc >> 4) ^ crc32table_le[0][crc & 15];
145 crc = (crc >> 2) ^ crc32table_le[crc & 3]; 126 crc = (crc >> 4) ^ crc32table_le[0][crc & 15];
146 crc = (crc >> 2) ^ crc32table_le[crc & 3];
147 crc = (crc >> 2) ^ crc32table_le[crc & 3];
148 } 127 }
128# elif CRC_LE_BITS == 8
129 const u32 (*tab)[] = crc32table_le;
130
131 crc = __cpu_to_le32(crc);
132 crc = crc32_body(crc, p, len, tab);
133 crc = __le32_to_cpu(crc);
134#endif
149 return crc; 135 return crc;
150# endif
151} 136}
152#endif 137EXPORT_SYMBOL(crc32_le);
153 138
154/** 139/**
155 * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32 140 * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
@@ -158,16 +143,9 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
158 * @p: pointer to buffer over which CRC is run 143 * @p: pointer to buffer over which CRC is run
159 * @len: length of buffer @p 144 * @len: length of buffer @p
160 */ 145 */
161u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
162
163#if CRC_BE_BITS == 1
164/*
165 * In fact, the table-based code will work in this case, but it can be
166 * simplified by inlining the table in ?: form.
167 */
168
169u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) 146u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
170{ 147{
148#if CRC_BE_BITS == 1
171 int i; 149 int i;
172 while (len--) { 150 while (len--) {
173 crc ^= *p++ << 24; 151 crc ^= *p++ << 24;
@@ -176,39 +154,29 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
176 (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 154 (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE :
177 0); 155 0);
178 } 156 }
179 return crc; 157# elif CRC_BE_BITS == 2
180}
181
182#else /* Table-based approach */
183u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
184{
185# if CRC_BE_BITS == 8
186 const u32 (*tab)[] = crc32table_be;
187
188 crc = __cpu_to_be32(crc);
189 crc = crc32_body(crc, p, len, tab);
190 return __be32_to_cpu(crc);
191# elif CRC_BE_BITS == 4
192 while (len--) { 158 while (len--) {
193 crc ^= *p++ << 24; 159 crc ^= *p++ << 24;
194 crc = (crc << 4) ^ crc32table_be[crc >> 28]; 160 crc = (crc << 2) ^ crc32table_be[0][crc >> 30];
195 crc = (crc << 4) ^ crc32table_be[crc >> 28]; 161 crc = (crc << 2) ^ crc32table_be[0][crc >> 30];
162 crc = (crc << 2) ^ crc32table_be[0][crc >> 30];
163 crc = (crc << 2) ^ crc32table_be[0][crc >> 30];
196 } 164 }
197 return crc; 165# elif CRC_BE_BITS == 4
198# elif CRC_BE_BITS == 2
199 while (len--) { 166 while (len--) {
200 crc ^= *p++ << 24; 167 crc ^= *p++ << 24;
201 crc = (crc << 2) ^ crc32table_be[crc >> 30]; 168 crc = (crc << 4) ^ crc32table_be[0][crc >> 28];
202 crc = (crc << 2) ^ crc32table_be[crc >> 30]; 169 crc = (crc << 4) ^ crc32table_be[0][crc >> 28];
203 crc = (crc << 2) ^ crc32table_be[crc >> 30];
204 crc = (crc << 2) ^ crc32table_be[crc >> 30];
205 } 170 }
206 return crc; 171# elif CRC_BE_BITS == 8
172 const u32 (*tab)[] = crc32table_be;
173
174 crc = __cpu_to_be32(crc);
175 crc = crc32_body(crc, p, len, tab);
176 crc = __be32_to_cpu(crc);
207# endif 177# endif
178 return crc;
208} 179}
209#endif
210
211EXPORT_SYMBOL(crc32_le);
212EXPORT_SYMBOL(crc32_be); 180EXPORT_SYMBOL(crc32_be);
213 181
214#ifdef CONFIG_CRC32_SELFTEST 182#ifdef CONFIG_CRC32_SELFTEST
diff --git a/lib/gen_crc32table.c b/lib/gen_crc32table.c
index 85d0e412a04f..eced7696eb7c 100644
--- a/lib/gen_crc32table.c
+++ b/lib/gen_crc32table.c
@@ -7,8 +7,8 @@
7#define LE_TABLE_SIZE (1 << CRC_LE_BITS) 7#define LE_TABLE_SIZE (1 << CRC_LE_BITS)
8#define BE_TABLE_SIZE (1 << CRC_BE_BITS) 8#define BE_TABLE_SIZE (1 << CRC_BE_BITS)
9 9
10static uint32_t crc32table_le[4][LE_TABLE_SIZE]; 10static uint32_t crc32table_le[4][256];
11static uint32_t crc32table_be[4][BE_TABLE_SIZE]; 11static uint32_t crc32table_be[4][256];
12 12
13/** 13/**
14 * crc32init_le() - allocate and initialize LE table data 14 * crc32init_le() - allocate and initialize LE table data
@@ -62,7 +62,7 @@ static void crc32init_be(void)
62 } 62 }
63} 63}
64 64
65static void output_table(uint32_t table[4][256], int len, char *trans) 65static void output_table(uint32_t (*table)[256], int len, char *trans)
66{ 66{
67 int i, j; 67 int i, j;
68 68