1*0bcfca56SEric Biggers // SPDX-License-Identifier: GPL-2.0-only 2*0bcfca56SEric Biggers /* 3*0bcfca56SEric Biggers * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin 4*0bcfca56SEric Biggers * cleaned up code to current version of sparse and added the slicing-by-8 5*0bcfca56SEric Biggers * algorithm to the closely similar existing slicing-by-4 algorithm. 6*0bcfca56SEric Biggers * 7*0bcfca56SEric Biggers * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com> 8*0bcfca56SEric Biggers * Nicer crc32 functions/docs submitted by linux@horizon.com. Thanks! 9*0bcfca56SEric Biggers * Code was from the public domain, copyright abandoned. Code was 10*0bcfca56SEric Biggers * subsequently included in the kernel, thus was re-licensed under the 11*0bcfca56SEric Biggers * GNU GPL v2. 12*0bcfca56SEric Biggers * 13*0bcfca56SEric Biggers * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com> 14*0bcfca56SEric Biggers * Same crc32 function was used in 5 other places in the kernel. 15*0bcfca56SEric Biggers * I made one version, and deleted the others. 16*0bcfca56SEric Biggers * There are various incantations of crc32(). Some use a seed of 0 or ~0. 17*0bcfca56SEric Biggers * Some xor at the end with ~0. The generic crc32() function takes 18*0bcfca56SEric Biggers * seed as an argument, and doesn't xor at the end. Then individual 19*0bcfca56SEric Biggers * users can do whatever they need. 20*0bcfca56SEric Biggers * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0. 21*0bcfca56SEric Biggers * fs/jffs2 uses seed 0, doesn't xor with ~0. 22*0bcfca56SEric Biggers * fs/partitions/efi.c uses seed ~0, xor's with ~0. 23*0bcfca56SEric Biggers */ 24*0bcfca56SEric Biggers 25*0bcfca56SEric Biggers /* see: Documentation/staging/crc32.rst for a description of algorithms */ 26*0bcfca56SEric Biggers 27*0bcfca56SEric Biggers #include <linux/crc32.h> 28*0bcfca56SEric Biggers #include <linux/module.h> 29*0bcfca56SEric Biggers #include <linux/types.h> 30*0bcfca56SEric Biggers 31*0bcfca56SEric Biggers #include "crc32table.h" 32*0bcfca56SEric Biggers 33*0bcfca56SEric Biggers static inline u32 __maybe_unused 34*0bcfca56SEric Biggers crc32_le_base(u32 crc, const u8 *p, size_t len) 35*0bcfca56SEric Biggers { 36*0bcfca56SEric Biggers while (len--) 37*0bcfca56SEric Biggers crc = (crc >> 8) ^ crc32table_le[(crc & 255) ^ *p++]; 38*0bcfca56SEric Biggers return crc; 39*0bcfca56SEric Biggers } 40*0bcfca56SEric Biggers 41*0bcfca56SEric Biggers static inline u32 __maybe_unused 42*0bcfca56SEric Biggers crc32_be_base(u32 crc, const u8 *p, size_t len) 43*0bcfca56SEric Biggers { 44*0bcfca56SEric Biggers while (len--) 45*0bcfca56SEric Biggers crc = (crc << 8) ^ crc32table_be[(crc >> 24) ^ *p++]; 46*0bcfca56SEric Biggers return crc; 47*0bcfca56SEric Biggers } 48*0bcfca56SEric Biggers 49*0bcfca56SEric Biggers static inline u32 __maybe_unused 50*0bcfca56SEric Biggers crc32c_base(u32 crc, const u8 *p, size_t len) 51*0bcfca56SEric Biggers { 52*0bcfca56SEric Biggers while (len--) 53*0bcfca56SEric Biggers crc = (crc >> 8) ^ crc32ctable_le[(crc & 255) ^ *p++]; 54*0bcfca56SEric Biggers return crc; 55*0bcfca56SEric Biggers } 56*0bcfca56SEric Biggers 57*0bcfca56SEric Biggers #ifdef CONFIG_CRC32_ARCH 58*0bcfca56SEric Biggers #include "crc32.h" /* $(SRCARCH)/crc32.h */ 59*0bcfca56SEric Biggers 60*0bcfca56SEric Biggers u32 crc32_optimizations(void) 61*0bcfca56SEric Biggers { 62*0bcfca56SEric Biggers return crc32_optimizations_arch(); 63*0bcfca56SEric Biggers } 64*0bcfca56SEric Biggers EXPORT_SYMBOL(crc32_optimizations); 65*0bcfca56SEric Biggers #else 66*0bcfca56SEric Biggers #define crc32_le_arch crc32_le_base 67*0bcfca56SEric Biggers #define crc32_be_arch crc32_be_base 68*0bcfca56SEric Biggers #define crc32c_arch crc32c_base 69*0bcfca56SEric Biggers #endif 70*0bcfca56SEric Biggers 71*0bcfca56SEric Biggers u32 crc32_le(u32 crc, const void *p, size_t len) 72*0bcfca56SEric Biggers { 73*0bcfca56SEric Biggers return crc32_le_arch(crc, p, len); 74*0bcfca56SEric Biggers } 75*0bcfca56SEric Biggers EXPORT_SYMBOL(crc32_le); 76*0bcfca56SEric Biggers 77*0bcfca56SEric Biggers u32 crc32_be(u32 crc, const void *p, size_t len) 78*0bcfca56SEric Biggers { 79*0bcfca56SEric Biggers return crc32_be_arch(crc, p, len); 80*0bcfca56SEric Biggers } 81*0bcfca56SEric Biggers EXPORT_SYMBOL(crc32_be); 82*0bcfca56SEric Biggers 83*0bcfca56SEric Biggers u32 crc32c(u32 crc, const void *p, size_t len) 84*0bcfca56SEric Biggers { 85*0bcfca56SEric Biggers return crc32c_arch(crc, p, len); 86*0bcfca56SEric Biggers } 87*0bcfca56SEric Biggers EXPORT_SYMBOL(crc32c); 88*0bcfca56SEric Biggers 89*0bcfca56SEric Biggers #ifdef crc32_mod_init_arch 90*0bcfca56SEric Biggers static int __init crc32_mod_init(void) 91*0bcfca56SEric Biggers { 92*0bcfca56SEric Biggers crc32_mod_init_arch(); 93*0bcfca56SEric Biggers return 0; 94*0bcfca56SEric Biggers } 95*0bcfca56SEric Biggers subsys_initcall(crc32_mod_init); 96*0bcfca56SEric Biggers 97*0bcfca56SEric Biggers static void __exit crc32_mod_exit(void) 98*0bcfca56SEric Biggers { 99*0bcfca56SEric Biggers } 100*0bcfca56SEric Biggers module_exit(crc32_mod_exit); 101*0bcfca56SEric Biggers #endif 102*0bcfca56SEric Biggers 103*0bcfca56SEric Biggers MODULE_DESCRIPTION("CRC32 library functions"); 104*0bcfca56SEric Biggers MODULE_LICENSE("GPL"); 105