Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crc32: bolt on crc32c

Reuse the existing crc32 code to stamp out a crc32c implementation.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Bob Pearson <rpearson@systemfabricworks.com>
Cc: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Darrick J. Wong and committed by
Linus Torvalds
46c5801e 78dff418

+97 -34
+2
include/linux/crc32.h
··· 11 11 extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len); 12 12 extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len); 13 13 14 + extern u32 __crc32c_le(u32 crc, unsigned char const *p, size_t len); 15 + 14 16 #define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)(data), length) 15 17 16 18 /*
+4 -4
lib/Kconfig
··· 61 61 functions require M here. 62 62 63 63 config CRC32 64 - tristate "CRC32 functions" 64 + tristate "CRC32/CRC32c functions" 65 65 default y 66 66 select BITREVERSE 67 67 help 68 68 This option is provided for the case where no in-kernel-tree 69 - modules require CRC32 functions, but a module built outside the 70 - kernel tree does. Such modules that use library CRC32 functions 71 - require M here. 69 + modules require CRC32/CRC32c functions, but a module built outside 70 + the kernel tree does. Such modules that use library CRC32/CRC32c 71 + functions require M here. 72 72 73 73 config CRC32_SELFTEST 74 74 bool "CRC32 perform self test on init"
+56 -23
lib/crc32.c
··· 46 46 #include "crc32table.h" 47 47 48 48 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>"); 49 - MODULE_DESCRIPTION("Ethernet CRC32 calculations"); 49 + MODULE_DESCRIPTION("Various CRC32 calculations"); 50 50 MODULE_LICENSE("GPL"); 51 51 52 52 #if CRC_LE_BITS > 8 || CRC_BE_BITS > 8 ··· 135 135 * @p: pointer to buffer over which CRC is run 136 136 * @len: length of buffer @p 137 137 */ 138 - u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) 138 + static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p, 139 + size_t len, const u32 (*tab)[256], 140 + u32 polynomial) 139 141 { 140 142 #if CRC_LE_BITS == 1 141 143 int i; 142 144 while (len--) { 143 145 crc ^= *p++; 144 146 for (i = 0; i < 8; i++) 145 - crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); 147 + crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0); 146 148 } 147 149 # elif CRC_LE_BITS == 2 148 150 while (len--) { 149 151 crc ^= *p++; 150 - crc = (crc >> 2) ^ crc32table_le[0][crc & 3]; 151 - crc = (crc >> 2) ^ crc32table_le[0][crc & 3]; 152 - crc = (crc >> 2) ^ crc32table_le[0][crc & 3]; 153 - crc = (crc >> 2) ^ crc32table_le[0][crc & 3]; 152 + crc = (crc >> 2) ^ tab[0][crc & 3]; 153 + crc = (crc >> 2) ^ tab[0][crc & 3]; 154 + crc = (crc >> 2) ^ tab[0][crc & 3]; 155 + crc = (crc >> 2) ^ tab[0][crc & 3]; 154 156 } 155 157 # elif CRC_LE_BITS == 4 156 158 while (len--) { 157 159 crc ^= *p++; 158 - crc = (crc >> 4) ^ crc32table_le[0][crc & 15]; 159 - crc = (crc >> 4) ^ crc32table_le[0][crc & 15]; 160 + crc = (crc >> 4) ^ tab[0][crc & 15]; 161 + crc = (crc >> 4) ^ tab[0][crc & 15]; 160 162 } 161 163 # elif CRC_LE_BITS == 8 162 164 /* aka Sarwate algorithm */ 163 165 while (len--) { 164 166 crc ^= *p++; 165 - crc = (crc >> 8) ^ crc32table_le[0][crc & 255]; 167 + crc = (crc >> 8) ^ tab[0][crc & 255]; 166 168 } 167 169 # else 168 - const u32 (*tab)[] = crc32table_le; 169 - 170 170 crc = (__force u32) __cpu_to_le32(crc); 171 171 crc = crc32_body(crc, p, len, tab); 172 172 crc = __le32_to_cpu((__force __le32)crc); 173 173 #endif 174 174 return crc; 175 175 } 176 + 177 + #if CRC_LE_BITS == 1 178 + u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) 179 + { 180 + return crc32_le_generic(crc, p, len, NULL, CRCPOLY_LE); 181 + } 182 + u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len) 183 + { 184 + return crc32_le_generic(crc, p, len, NULL, CRC32C_POLY_LE); 185 + } 186 + #else 187 + u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) 188 + { 189 + return crc32_le_generic(crc, p, len, crc32table_le, CRCPOLY_LE); 190 + } 191 + u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len) 192 + { 193 + return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE); 194 + } 195 + #endif 176 196 EXPORT_SYMBOL(crc32_le); 197 + EXPORT_SYMBOL(__crc32c_le); 177 198 178 199 /** 179 200 * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32 ··· 203 182 * @p: pointer to buffer over which CRC is run 204 183 * @len: length of buffer @p 205 184 */ 206 - u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) 185 + static inline u32 __pure crc32_be_generic(u32 crc, unsigned char const *p, 186 + size_t len, const u32 (*tab)[256], 187 + u32 polynomial) 207 188 { 208 189 #if CRC_BE_BITS == 1 209 190 int i; ··· 213 190 crc ^= *p++ << 24; 214 191 for (i = 0; i < 8; i++) 215 192 crc = 216 - (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 193 + (crc << 1) ^ ((crc & 0x80000000) ? polynomial : 217 194 0); 218 195 } 219 196 # elif CRC_BE_BITS == 2 220 197 while (len--) { 221 198 crc ^= *p++ << 24; 222 - crc = (crc << 2) ^ crc32table_be[0][crc >> 30]; 223 - crc = (crc << 2) ^ crc32table_be[0][crc >> 30]; 224 - crc = (crc << 2) ^ crc32table_be[0][crc >> 30]; 225 - crc = (crc << 2) ^ crc32table_be[0][crc >> 30]; 199 + crc = (crc << 2) ^ tab[0][crc >> 30]; 200 + crc = (crc << 2) ^ tab[0][crc >> 30]; 201 + crc = (crc << 2) ^ tab[0][crc >> 30]; 202 + crc = (crc << 2) ^ tab[0][crc >> 30]; 226 203 } 227 204 # elif CRC_BE_BITS == 4 228 205 while (len--) { 229 206 crc ^= *p++ << 24; 230 - crc = (crc << 4) ^ crc32table_be[0][crc >> 28]; 231 - crc = (crc << 4) ^ crc32table_be[0][crc >> 28]; 207 + crc = (crc << 4) ^ tab[0][crc >> 28]; 208 + crc = (crc << 4) ^ tab[0][crc >> 28]; 232 209 } 233 210 # elif CRC_BE_BITS == 8 234 211 while (len--) { 235 212 crc ^= *p++ << 24; 236 - crc = (crc << 8) ^ crc32table_be[0][crc >> 24]; 213 + crc = (crc << 8) ^ tab[0][crc >> 24]; 237 214 } 238 215 # else 239 - const u32 (*tab)[] = crc32table_be; 240 - 241 216 crc = (__force u32) __cpu_to_be32(crc); 242 217 crc = crc32_body(crc, p, len, tab); 243 218 crc = __be32_to_cpu((__force __be32)crc); 244 219 # endif 245 220 return crc; 246 221 } 222 + 223 + #if CRC_LE_BITS == 1 224 + u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) 225 + { 226 + return crc32_be_generic(crc, p, len, NULL, CRCPOLY_BE); 227 + } 228 + #else 229 + u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) 230 + { 231 + return crc32_be_generic(crc, p, len, crc32table_be, CRCPOLY_BE); 232 + } 233 + #endif 247 234 EXPORT_SYMBOL(crc32_be); 248 235 249 236 #ifdef CONFIG_CRC32_SELFTEST
+7
lib/crc32defs.h
··· 7 7 #define CRCPOLY_BE 0x04c11db7 8 8 9 9 /* 10 + * This is the CRC32c polynomial, as outlined by Castagnoli. 11 + * 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+ 12 + * x^8+x^6+x^0 13 + */ 14 + #define CRC32C_POLY_LE 0x82F63B78 15 + 16 + /* 10 17 * How many bits at a time to use. Valid values are 1, 2, 4, 8, 32 and 64. 11 18 * For less performance-sensitive, use 4 or 8 to save table size. 12 19 * For larger systems choose same as CPU architecture as default.
+28 -7
lib/gen_crc32table.c
··· 23 23 24 24 static uint32_t crc32table_le[LE_TABLE_ROWS][256]; 25 25 static uint32_t crc32table_be[BE_TABLE_ROWS][256]; 26 + static uint32_t crc32ctable_le[LE_TABLE_ROWS][256]; 26 27 27 28 /** 28 29 * crc32init_le() - allocate and initialize LE table data ··· 32 31 * fact that crctable[i^j] = crctable[i] ^ crctable[j]. 33 32 * 34 33 */ 35 - static void crc32init_le(void) 34 + static void crc32init_le_generic(const uint32_t polynomial, 35 + uint32_t (*tab)[256]) 36 36 { 37 37 unsigned i, j; 38 38 uint32_t crc = 1; 39 39 40 - crc32table_le[0][0] = 0; 40 + tab[0][0] = 0; 41 41 42 42 for (i = LE_TABLE_SIZE >> 1; i; i >>= 1) { 43 - crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); 43 + crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0); 44 44 for (j = 0; j < LE_TABLE_SIZE; j += 2 * i) 45 - crc32table_le[0][i + j] = crc ^ crc32table_le[0][j]; 45 + tab[0][i + j] = crc ^ tab[0][j]; 46 46 } 47 47 for (i = 0; i < LE_TABLE_SIZE; i++) { 48 - crc = crc32table_le[0][i]; 48 + crc = tab[0][i]; 49 49 for (j = 1; j < LE_TABLE_ROWS; j++) { 50 - crc = crc32table_le[0][crc & 0xff] ^ (crc >> 8); 51 - crc32table_le[j][i] = crc; 50 + crc = tab[0][crc & 0xff] ^ (crc >> 8); 51 + tab[j][i] = crc; 52 52 } 53 53 } 54 + } 55 + 56 + static void crc32init_le(void) 57 + { 58 + crc32init_le_generic(CRCPOLY_LE, crc32table_le); 59 + } 60 + 61 + static void crc32cinit_le(void) 62 + { 63 + crc32init_le_generic(CRC32C_POLY_LE, crc32ctable_le); 54 64 } 55 65 56 66 /** ··· 124 112 BE_TABLE_ROWS, BE_TABLE_SIZE); 125 113 output_table(crc32table_be, LE_TABLE_ROWS, 126 114 BE_TABLE_SIZE, "tobe"); 115 + printf("};\n"); 116 + } 117 + if (CRC_LE_BITS > 1) { 118 + crc32cinit_le(); 119 + printf("static const u32 __cacheline_aligned " 120 + "crc32ctable_le[%d][%d] = {", 121 + LE_TABLE_ROWS, LE_TABLE_SIZE); 122 + output_table(crc32ctable_le, LE_TABLE_ROWS, 123 + LE_TABLE_SIZE, "tole"); 127 124 printf("};\n"); 128 125 } 129 126