]> git.apps.os.sepia.ceph.com Git - ceph-client.git/commitdiff
lib/crc: Move files into lib/crc/
authorEric Biggers <ebiggers@kernel.org>
Sat, 7 Jun 2025 20:04:43 +0000 (13:04 -0700)
committerEric Biggers <ebiggers@kernel.org>
Mon, 30 Jun 2025 16:31:57 +0000 (09:31 -0700)
Move all CRC files in lib/ into a subdirectory lib/crc/ to keep them
from cluttering up the main lib/ directory.

Reviewed-by: "Martin K. Petersen" <martin.petersen@oracle.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
Link: https://lore.kernel.org/r/20250607200454.73587-2-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
35 files changed:
Documentation/core-api/kernel-api.rst
MAINTAINERS
include/linux/crc64.h
lib/Kconfig
lib/Kconfig.debug
lib/Makefile
lib/crc-ccitt.c [deleted file]
lib/crc-itu-t.c [deleted file]
lib/crc-t10dif.c [deleted file]
lib/crc/.gitignore [new file with mode: 0644]
lib/crc/Kconfig [new file with mode: 0644]
lib/crc/Makefile [new file with mode: 0644]
lib/crc/crc-ccitt.c [new file with mode: 0644]
lib/crc/crc-itu-t.c [new file with mode: 0644]
lib/crc/crc-t10dif.c [new file with mode: 0644]
lib/crc/crc16.c [new file with mode: 0644]
lib/crc/crc32.c [new file with mode: 0644]
lib/crc/crc4.c [new file with mode: 0644]
lib/crc/crc64.c [new file with mode: 0644]
lib/crc/crc7.c [new file with mode: 0644]
lib/crc/crc8.c [new file with mode: 0644]
lib/crc/gen_crc32table.c [new file with mode: 0644]
lib/crc/gen_crc64table.c [new file with mode: 0644]
lib/crc/tests/Makefile [new file with mode: 0644]
lib/crc/tests/crc_kunit.c [new file with mode: 0644]
lib/crc16.c [deleted file]
lib/crc32.c [deleted file]
lib/crc4.c [deleted file]
lib/crc64.c [deleted file]
lib/crc7.c [deleted file]
lib/crc8.c [deleted file]
lib/gen_crc32table.c [deleted file]
lib/gen_crc64table.c [deleted file]
lib/tests/Makefile
lib/tests/crc_kunit.c [deleted file]

index ae92a2571388ae7fc0b7c5f23a19ed59ac1312cc..c4642d9f13a9cd42bf24769d7d77f075f476b2ec 100644 (file)
@@ -136,24 +136,24 @@ Arithmetic Overflow Checking
 CRC Functions
 -------------
 
-.. kernel-doc:: lib/crc4.c
+.. kernel-doc:: lib/crc/crc4.c
    :export:
 
-.. kernel-doc:: lib/crc7.c
+.. kernel-doc:: lib/crc/crc7.c
    :export:
 
-.. kernel-doc:: lib/crc8.c
+.. kernel-doc:: lib/crc/crc8.c
    :export:
 
-.. kernel-doc:: lib/crc16.c
+.. kernel-doc:: lib/crc/crc16.c
    :export:
 
-.. kernel-doc:: lib/crc32.c
+.. kernel-doc:: lib/crc/crc32.c
 
-.. kernel-doc:: lib/crc-ccitt.c
+.. kernel-doc:: lib/crc/crc-ccitt.c
    :export:
 
-.. kernel-doc:: lib/crc-itu-t.c
+.. kernel-doc:: lib/crc/crc-itu-t.c
    :export:
 
 Base 2 log and power Functions
index 4bac4ea21b64445069e1518bd906354627dca438..b0ec17dfbe0353a79e91175f2669ffb3db7dee86 100644 (file)
@@ -6361,8 +6361,7 @@ T:        git https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc-ne
 F:     Documentation/staging/crc*
 F:     arch/*/lib/crc*
 F:     include/linux/crc*
-F:     lib/crc*
-F:     lib/tests/crc_kunit.c
+F:     lib/crc/
 F:     scripts/gen-crc-consts.py
 
 CREATIVE SB0540
index 41de30b907dff891fec961a05b12474a234104b0..b6aa290a79312fe2f52138f1a0ff441fde0cf1ff 100644 (file)
@@ -1,7 +1,4 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/*
- * See lib/crc64.c for the related specification and polynomial arithmetic.
- */
 #ifndef _LINUX_CRC64_H
 #define _LINUX_CRC64_H
 
index 37db228f70a99fb5cf563ec10f707cb605c4e508..c483951b624ff8111217b25598bd574b8ff18193 100644 (file)
@@ -136,95 +136,9 @@ config TRACE_MMIO_ACCESS
          Create tracepoints for MMIO read/write operations. These trace events
          can be used for logging all MMIO read/write operations.
 
+source "lib/crc/Kconfig"
 source "lib/crypto/Kconfig"
 
-config CRC_CCITT
-       tristate
-       help
-         The CRC-CCITT library functions.  Select this if your module uses any
-         of the functions from <linux/crc-ccitt.h>.
-
-config CRC16
-       tristate
-       help
-         The CRC16 library functions.  Select this if your module uses any of
-         the functions from <linux/crc16.h>.
-
-config CRC_T10DIF
-       tristate
-       help
-         The CRC-T10DIF library functions.  Select this if your module uses
-         any of the functions from <linux/crc-t10dif.h>.
-
-config ARCH_HAS_CRC_T10DIF
-       bool
-
-config CRC_T10DIF_ARCH
-       tristate
-       default CRC_T10DIF if ARCH_HAS_CRC_T10DIF && CRC_OPTIMIZATIONS
-
-config CRC_ITU_T
-       tristate
-       help
-         The CRC-ITU-T library functions.  Select this if your module uses
-         any of the functions from <linux/crc-itu-t.h>.
-
-config CRC32
-       tristate
-       select BITREVERSE
-       help
-         The CRC32 library functions.  Select this if your module uses any of
-         the functions from <linux/crc32.h> or <linux/crc32c.h>.
-
-config ARCH_HAS_CRC32
-       bool
-
-config CRC32_ARCH
-       tristate
-       default CRC32 if ARCH_HAS_CRC32 && CRC_OPTIMIZATIONS
-
-config CRC64
-       tristate
-       help
-         The CRC64 library functions.  Select this if your module uses any of
-         the functions from <linux/crc64.h>.
-
-config ARCH_HAS_CRC64
-       bool
-
-config CRC64_ARCH
-       tristate
-       default CRC64 if ARCH_HAS_CRC64 && CRC_OPTIMIZATIONS
-
-config CRC4
-       tristate
-       help
-         The CRC4 library functions.  Select this if your module uses any of
-         the functions from <linux/crc4.h>.
-
-config CRC7
-       tristate
-       help
-         The CRC7 library functions.  Select this if your module uses any of
-         the functions from <linux/crc7.h>.
-
-config CRC8
-       tristate
-       help
-         The CRC8 library functions.  Select this if your module uses any of
-         the functions from <linux/crc8.h>.
-
-config CRC_OPTIMIZATIONS
-       bool "Enable optimized CRC implementations" if EXPERT
-       default y
-       help
-         Disabling this option reduces code size slightly by disabling the
-         architecture-optimized implementations of any CRC variants that are
-         enabled.  CRC checksumming performance may get much slower.
-
-         Keep this enabled unless you're really trying to minimize the size of
-         the kernel.
-
 config XXHASH
        tristate
 
index ebe33181b6e6e0fb4243b400e9187881707efe23..3fda96761adbc209b6db43da2e80ad40668c9085 100644 (file)
@@ -2901,27 +2901,6 @@ config HW_BREAKPOINT_KUNIT_TEST
 
          If unsure, say N.
 
-config CRC_KUNIT_TEST
-       tristate "KUnit tests for CRC functions" if !KUNIT_ALL_TESTS
-       depends on KUNIT
-       default KUNIT_ALL_TESTS
-       select CRC7
-       select CRC16
-       select CRC_T10DIF
-       select CRC32
-       select CRC64
-       help
-         Unit tests for the CRC library functions.
-
-         This is intended to help people writing architecture-specific
-         optimized versions.  If unsure, say N.
-
-config CRC_BENCHMARK
-       bool "Benchmark for the CRC functions"
-       depends on CRC_KUNIT_TEST
-       help
-         Include benchmarks in the KUnit test suite for the CRC functions.
-
 config SIPHASH_KUNIT_TEST
        tristate "Perform selftest on siphash functions" if !KUNIT_ALL_TESTS
        depends on KUNIT
index c38582f187dd81916113319072e5cfef26f26c84..14a5928bb57f52fabe8635e9209b91d24680c9b3 100644 (file)
@@ -122,7 +122,7 @@ endif
 obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o
 CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any)
 
-obj-y += math/ crypto/ tests/ vdso/
+obj-y += math/ crc/ crypto/ tests/ vdso/
 
 obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
 obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
@@ -148,15 +148,6 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o
 obj-$(CONFIG_LINEAR_RANGES) += linear_ranges.o
 obj-$(CONFIG_PACKING)  += packing.o
 obj-$(CONFIG_PACKING_KUNIT_TEST) += packing_test.o
-obj-$(CONFIG_CRC_CCITT)        += crc-ccitt.o
-obj-$(CONFIG_CRC16)    += crc16.o
-obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o
-obj-$(CONFIG_CRC_ITU_T)        += crc-itu-t.o
-obj-$(CONFIG_CRC32)    += crc32.o
-obj-$(CONFIG_CRC64)     += crc64.o
-obj-$(CONFIG_CRC4)     += crc4.o
-obj-$(CONFIG_CRC7)     += crc7.o
-obj-$(CONFIG_CRC8)     += crc8.o
 obj-$(CONFIG_XXHASH)   += xxhash.o
 obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
 
@@ -294,27 +285,6 @@ obj-$(CONFIG_ASN1_ENCODER) += asn1_encoder.o
 
 obj-$(CONFIG_FONT_SUPPORT) += fonts/
 
-hostprogs      := gen_crc32table
-hostprogs      += gen_crc64table
-clean-files    := crc32table.h
-clean-files    += crc64table.h
-
-$(obj)/crc32.o: $(obj)/crc32table.h
-
-quiet_cmd_crc32 = GEN     $@
-      cmd_crc32 = $< > $@
-
-$(obj)/crc32table.h: $(obj)/gen_crc32table
-       $(call cmd,crc32)
-
-$(obj)/crc64.o: $(obj)/crc64table.h
-
-quiet_cmd_crc64 = GEN     $@
-      cmd_crc64 = $< > $@
-
-$(obj)/crc64table.h: $(obj)/gen_crc64table
-       $(call cmd,crc64)
-
 #
 # Build a fast OID lookip registry from include/linux/oid_registry.h
 #
diff --git a/lib/crc-ccitt.c b/lib/crc-ccitt.c
deleted file mode 100644 (file)
index 9cddf35..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *     linux/lib/crc-ccitt.c
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/crc-ccitt.h>
-
-/*
- * This mysterious table is just the CRC of each possible byte. It can be
- * computed using the standard bit-at-a-time methods. The polynomial can
- * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12.
- * Add the implicit x^16, and you have the standard CRC-CCITT.
- */
-u16 const crc_ccitt_table[256] = {
-       0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-       0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-       0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-       0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-       0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-       0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-       0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-       0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-       0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-       0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-       0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-       0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-       0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-       0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-       0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-       0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-       0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-       0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-       0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-       0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-       0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-       0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-       0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-       0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-       0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-       0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-       0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-       0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-       0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-       0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-       0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-       0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-EXPORT_SYMBOL(crc_ccitt_table);
-
-/**
- *     crc_ccitt - recompute the CRC (CRC-CCITT variant) for the data
- *     buffer
- *     @crc: previous CRC value
- *     @buffer: data pointer
- *     @len: number of bytes in the buffer
- */
-u16 crc_ccitt(u16 crc, u8 const *buffer, size_t len)
-{
-       while (len--)
-               crc = crc_ccitt_byte(crc, *buffer++);
-       return crc;
-}
-EXPORT_SYMBOL(crc_ccitt);
-
-MODULE_DESCRIPTION("CRC-CCITT calculations");
-MODULE_LICENSE("GPL");
diff --git a/lib/crc-itu-t.c b/lib/crc-itu-t.c
deleted file mode 100644 (file)
index 1d26a16..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *      crc-itu-t.c
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/crc-itu-t.h>
-
-/* CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^5 + 1) */
-const u16 crc_itu_t_table[256] = {
-       0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
-       0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
-       0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
-       0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
-       0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
-       0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
-       0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
-       0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
-       0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
-       0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
-       0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
-       0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
-       0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
-       0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
-       0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
-       0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
-       0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
-       0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
-       0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
-       0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
-       0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
-       0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
-       0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
-       0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
-       0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
-       0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
-       0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
-       0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
-       0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
-       0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
-       0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
-       0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
-};
-
-EXPORT_SYMBOL(crc_itu_t_table);
-
-/**
- * crc_itu_t - Compute the CRC-ITU-T for the data buffer
- *
- * @crc:     previous CRC value
- * @buffer:  data pointer
- * @len:     number of bytes in the buffer
- *
- * Returns the updated CRC value
- */
-u16 crc_itu_t(u16 crc, const u8 *buffer, size_t len)
-{
-       while (len--)
-               crc = crc_itu_t_byte(crc, *buffer++);
-       return crc;
-}
-EXPORT_SYMBOL(crc_itu_t);
-
-MODULE_DESCRIPTION("CRC ITU-T V.41 calculations");
-MODULE_LICENSE("GPL");
-
diff --git a/lib/crc-t10dif.c b/lib/crc-t10dif.c
deleted file mode 100644 (file)
index 311c2ab..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * T10 Data Integrity Field CRC16 calculation
- *
- * Copyright (c) 2007 Oracle Corporation.  All rights reserved.
- * Written by Martin K. Petersen <martin.petersen@oracle.com>
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/crc-t10dif.h>
-
-/*
- * Table generated using the following polynomial:
- * x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
- * gt: 0x8bb7
- */
-static const u16 t10_dif_crc_table[256] = {
-       0x0000, 0x8BB7, 0x9CD9, 0x176E, 0xB205, 0x39B2, 0x2EDC, 0xA56B,
-       0xEFBD, 0x640A, 0x7364, 0xF8D3, 0x5DB8, 0xD60F, 0xC161, 0x4AD6,
-       0x54CD, 0xDF7A, 0xC814, 0x43A3, 0xE6C8, 0x6D7F, 0x7A11, 0xF1A6,
-       0xBB70, 0x30C7, 0x27A9, 0xAC1E, 0x0975, 0x82C2, 0x95AC, 0x1E1B,
-       0xA99A, 0x222D, 0x3543, 0xBEF4, 0x1B9F, 0x9028, 0x8746, 0x0CF1,
-       0x4627, 0xCD90, 0xDAFE, 0x5149, 0xF422, 0x7F95, 0x68FB, 0xE34C,
-       0xFD57, 0x76E0, 0x618E, 0xEA39, 0x4F52, 0xC4E5, 0xD38B, 0x583C,
-       0x12EA, 0x995D, 0x8E33, 0x0584, 0xA0EF, 0x2B58, 0x3C36, 0xB781,
-       0xD883, 0x5334, 0x445A, 0xCFED, 0x6A86, 0xE131, 0xF65F, 0x7DE8,
-       0x373E, 0xBC89, 0xABE7, 0x2050, 0x853B, 0x0E8C, 0x19E2, 0x9255,
-       0x8C4E, 0x07F9, 0x1097, 0x9B20, 0x3E4B, 0xB5FC, 0xA292, 0x2925,
-       0x63F3, 0xE844, 0xFF2A, 0x749D, 0xD1F6, 0x5A41, 0x4D2F, 0xC698,
-       0x7119, 0xFAAE, 0xEDC0, 0x6677, 0xC31C, 0x48AB, 0x5FC5, 0xD472,
-       0x9EA4, 0x1513, 0x027D, 0x89CA, 0x2CA1, 0xA716, 0xB078, 0x3BCF,
-       0x25D4, 0xAE63, 0xB90D, 0x32BA, 0x97D1, 0x1C66, 0x0B08, 0x80BF,
-       0xCA69, 0x41DE, 0x56B0, 0xDD07, 0x786C, 0xF3DB, 0xE4B5, 0x6F02,
-       0x3AB1, 0xB106, 0xA668, 0x2DDF, 0x88B4, 0x0303, 0x146D, 0x9FDA,
-       0xD50C, 0x5EBB, 0x49D5, 0xC262, 0x6709, 0xECBE, 0xFBD0, 0x7067,
-       0x6E7C, 0xE5CB, 0xF2A5, 0x7912, 0xDC79, 0x57CE, 0x40A0, 0xCB17,
-       0x81C1, 0x0A76, 0x1D18, 0x96AF, 0x33C4, 0xB873, 0xAF1D, 0x24AA,
-       0x932B, 0x189C, 0x0FF2, 0x8445, 0x212E, 0xAA99, 0xBDF7, 0x3640,
-       0x7C96, 0xF721, 0xE04F, 0x6BF8, 0xCE93, 0x4524, 0x524A, 0xD9FD,
-       0xC7E6, 0x4C51, 0x5B3F, 0xD088, 0x75E3, 0xFE54, 0xE93A, 0x628D,
-       0x285B, 0xA3EC, 0xB482, 0x3F35, 0x9A5E, 0x11E9, 0x0687, 0x8D30,
-       0xE232, 0x6985, 0x7EEB, 0xF55C, 0x5037, 0xDB80, 0xCCEE, 0x4759,
-       0x0D8F, 0x8638, 0x9156, 0x1AE1, 0xBF8A, 0x343D, 0x2353, 0xA8E4,
-       0xB6FF, 0x3D48, 0x2A26, 0xA191, 0x04FA, 0x8F4D, 0x9823, 0x1394,
-       0x5942, 0xD2F5, 0xC59B, 0x4E2C, 0xEB47, 0x60F0, 0x779E, 0xFC29,
-       0x4BA8, 0xC01F, 0xD771, 0x5CC6, 0xF9AD, 0x721A, 0x6574, 0xEEC3,
-       0xA415, 0x2FA2, 0x38CC, 0xB37B, 0x1610, 0x9DA7, 0x8AC9, 0x017E,
-       0x1F65, 0x94D2, 0x83BC, 0x080B, 0xAD60, 0x26D7, 0x31B9, 0xBA0E,
-       0xF0D8, 0x7B6F, 0x6C01, 0xE7B6, 0x42DD, 0xC96A, 0xDE04, 0x55B3
-};
-
-u16 crc_t10dif_generic(u16 crc, const u8 *p, size_t len)
-{
-       size_t i;
-
-       for (i = 0; i < len; i++)
-               crc = (crc << 8) ^ t10_dif_crc_table[(crc >> 8) ^ p[i]];
-
-       return crc;
-}
-EXPORT_SYMBOL(crc_t10dif_generic);
-
-MODULE_DESCRIPTION("T10 DIF CRC calculation");
-MODULE_LICENSE("GPL");
diff --git a/lib/crc/.gitignore b/lib/crc/.gitignore
new file mode 100644 (file)
index 0000000..a9e4810
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+/crc32table.h
+/crc64table.h
+/gen_crc32table
+/gen_crc64table
diff --git a/lib/crc/Kconfig b/lib/crc/Kconfig
new file mode 100644 (file)
index 0000000..e0e7168
--- /dev/null
@@ -0,0 +1,111 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Kconfig for the kernel's cyclic redundancy check (CRC) library code
+
+config CRC4
+       tristate
+       help
+         The CRC4 library functions.  Select this if your module uses any of
+         the functions from <linux/crc4.h>.
+
+config CRC7
+       tristate
+       help
+         The CRC7 library functions.  Select this if your module uses any of
+         the functions from <linux/crc7.h>.
+
+config CRC8
+       tristate
+       help
+         The CRC8 library functions.  Select this if your module uses any of
+         the functions from <linux/crc8.h>.
+
+config CRC16
+       tristate
+       help
+         The CRC16 library functions.  Select this if your module uses any of
+         the functions from <linux/crc16.h>.
+
+config CRC_CCITT
+       tristate
+       help
+         The CRC-CCITT library functions.  Select this if your module uses any
+         of the functions from <linux/crc-ccitt.h>.
+
+config CRC_ITU_T
+       tristate
+       help
+         The CRC-ITU-T library functions.  Select this if your module uses
+         any of the functions from <linux/crc-itu-t.h>.
+
+config CRC_T10DIF
+       tristate
+       help
+         The CRC-T10DIF library functions.  Select this if your module uses
+         any of the functions from <linux/crc-t10dif.h>.
+
+config ARCH_HAS_CRC_T10DIF
+       bool
+
+config CRC_T10DIF_ARCH
+       tristate
+       default CRC_T10DIF if ARCH_HAS_CRC_T10DIF && CRC_OPTIMIZATIONS
+
+config CRC32
+       tristate
+       select BITREVERSE
+       help
+         The CRC32 library functions.  Select this if your module uses any of
+         the functions from <linux/crc32.h> or <linux/crc32c.h>.
+
+config ARCH_HAS_CRC32
+       bool
+
+config CRC32_ARCH
+       tristate
+       default CRC32 if ARCH_HAS_CRC32 && CRC_OPTIMIZATIONS
+
+config CRC64
+       tristate
+       help
+         The CRC64 library functions.  Select this if your module uses any of
+         the functions from <linux/crc64.h>.
+
+config ARCH_HAS_CRC64
+       bool
+
+config CRC64_ARCH
+       tristate
+       default CRC64 if ARCH_HAS_CRC64 && CRC_OPTIMIZATIONS
+
+config CRC_OPTIMIZATIONS
+       bool "Enable optimized CRC implementations" if EXPERT
+       default y
+       help
+         Disabling this option reduces code size slightly by disabling the
+         architecture-optimized implementations of any CRC variants that are
+         enabled.  CRC checksumming performance may get much slower.
+
+         Keep this enabled unless you're really trying to minimize the size of
+         the kernel.
+
+config CRC_KUNIT_TEST
+       tristate "KUnit tests for CRC functions" if !KUNIT_ALL_TESTS
+       depends on KUNIT
+       default KUNIT_ALL_TESTS
+       select CRC7
+       select CRC16
+       select CRC_T10DIF
+       select CRC32
+       select CRC64
+       help
+         Unit tests for the CRC library functions.
+
+         This is intended to help people writing architecture-specific
+         optimized versions.  If unsure, say N.
+
+config CRC_BENCHMARK
+       bool "Benchmark for the CRC functions"
+       depends on CRC_KUNIT_TEST
+       help
+         Include benchmarks in the KUnit test suite for the CRC functions.
diff --git a/lib/crc/Makefile b/lib/crc/Makefile
new file mode 100644 (file)
index 0000000..ff4c30d
--- /dev/null
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Makefile for the kernel's cyclic redundancy check (CRC) library code
+
+obj-$(CONFIG_CRC4) += crc4.o
+obj-$(CONFIG_CRC7) += crc7.o
+obj-$(CONFIG_CRC8) += crc8.o
+obj-$(CONFIG_CRC16) += crc16.o
+obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
+obj-$(CONFIG_CRC_ITU_T) += crc-itu-t.o
+obj-$(CONFIG_CRC_T10DIF) += crc-t10dif.o
+obj-$(CONFIG_CRC32) += crc32.o
+obj-$(CONFIG_CRC64) += crc64.o
+obj-y += tests/
+
+hostprogs := gen_crc32table gen_crc64table
+clean-files := crc32table.h crc64table.h
+
+$(obj)/crc32.o: $(obj)/crc32table.h
+$(obj)/crc64.o: $(obj)/crc64table.h
+
+quiet_cmd_crc32 = GEN     $@
+      cmd_crc32 = $< > $@
+
+quiet_cmd_crc64 = GEN     $@
+      cmd_crc64 = $< > $@
+
+$(obj)/crc32table.h: $(obj)/gen_crc32table
+       $(call cmd,crc32)
+
+$(obj)/crc64table.h: $(obj)/gen_crc64table
+       $(call cmd,crc64)
diff --git a/lib/crc/crc-ccitt.c b/lib/crc/crc-ccitt.c
new file mode 100644 (file)
index 0000000..8d2bc41
--- /dev/null
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc-ccitt.h>
+
+/*
+ * This mysterious table is just the CRC of each possible byte. It can be
+ * computed using the standard bit-at-a-time methods. The polynomial can
+ * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12.
+ * Add the implicit x^16, and you have the standard CRC-CCITT.
+ */
+u16 const crc_ccitt_table[256] = {
+       0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+       0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+       0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+       0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+       0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+       0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+       0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+       0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+       0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+       0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+       0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+       0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+       0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+       0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+       0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+       0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+       0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+       0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+       0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+       0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+       0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+       0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+       0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+       0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+       0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+       0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+       0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+       0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+       0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+       0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+       0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+       0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+EXPORT_SYMBOL(crc_ccitt_table);
+
+/**
+ *     crc_ccitt - recompute the CRC (CRC-CCITT variant) for the data
+ *     buffer
+ *     @crc: previous CRC value
+ *     @buffer: data pointer
+ *     @len: number of bytes in the buffer
+ */
+u16 crc_ccitt(u16 crc, u8 const *buffer, size_t len)
+{
+       while (len--)
+               crc = crc_ccitt_byte(crc, *buffer++);
+       return crc;
+}
+EXPORT_SYMBOL(crc_ccitt);
+
+MODULE_DESCRIPTION("CRC-CCITT calculations");
+MODULE_LICENSE("GPL");
diff --git a/lib/crc/crc-itu-t.c b/lib/crc/crc-itu-t.c
new file mode 100644 (file)
index 0000000..1d26a16
--- /dev/null
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *      crc-itu-t.c
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc-itu-t.h>
+
+/* CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^5 + 1) */
+const u16 crc_itu_t_table[256] = {
+       0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+       0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+       0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+       0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+       0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+       0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+       0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+       0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+       0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+       0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+       0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+       0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+       0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+       0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+       0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+       0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+       0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+       0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+       0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+       0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+       0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+       0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+       0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+       0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+       0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+       0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+       0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+       0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+       0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+       0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+       0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+       0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+EXPORT_SYMBOL(crc_itu_t_table);
+
+/**
+ * crc_itu_t - Compute the CRC-ITU-T for the data buffer
+ *
+ * @crc:     previous CRC value
+ * @buffer:  data pointer
+ * @len:     number of bytes in the buffer
+ *
+ * Returns the updated CRC value
+ */
+u16 crc_itu_t(u16 crc, const u8 *buffer, size_t len)
+{
+       while (len--)
+               crc = crc_itu_t_byte(crc, *buffer++);
+       return crc;
+}
+EXPORT_SYMBOL(crc_itu_t);
+
+MODULE_DESCRIPTION("CRC ITU-T V.41 calculations");
+MODULE_LICENSE("GPL");
+
diff --git a/lib/crc/crc-t10dif.c b/lib/crc/crc-t10dif.c
new file mode 100644 (file)
index 0000000..311c2ab
--- /dev/null
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * T10 Data Integrity Field CRC16 calculation
+ *
+ * Copyright (c) 2007 Oracle Corporation.  All rights reserved.
+ * Written by Martin K. Petersen <martin.petersen@oracle.com>
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc-t10dif.h>
+
+/*
+ * Table generated using the following polynomial:
+ * x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
+ * gt: 0x8bb7
+ */
+static const u16 t10_dif_crc_table[256] = {
+       0x0000, 0x8BB7, 0x9CD9, 0x176E, 0xB205, 0x39B2, 0x2EDC, 0xA56B,
+       0xEFBD, 0x640A, 0x7364, 0xF8D3, 0x5DB8, 0xD60F, 0xC161, 0x4AD6,
+       0x54CD, 0xDF7A, 0xC814, 0x43A3, 0xE6C8, 0x6D7F, 0x7A11, 0xF1A6,
+       0xBB70, 0x30C7, 0x27A9, 0xAC1E, 0x0975, 0x82C2, 0x95AC, 0x1E1B,
+       0xA99A, 0x222D, 0x3543, 0xBEF4, 0x1B9F, 0x9028, 0x8746, 0x0CF1,
+       0x4627, 0xCD90, 0xDAFE, 0x5149, 0xF422, 0x7F95, 0x68FB, 0xE34C,
+       0xFD57, 0x76E0, 0x618E, 0xEA39, 0x4F52, 0xC4E5, 0xD38B, 0x583C,
+       0x12EA, 0x995D, 0x8E33, 0x0584, 0xA0EF, 0x2B58, 0x3C36, 0xB781,
+       0xD883, 0x5334, 0x445A, 0xCFED, 0x6A86, 0xE131, 0xF65F, 0x7DE8,
+       0x373E, 0xBC89, 0xABE7, 0x2050, 0x853B, 0x0E8C, 0x19E2, 0x9255,
+       0x8C4E, 0x07F9, 0x1097, 0x9B20, 0x3E4B, 0xB5FC, 0xA292, 0x2925,
+       0x63F3, 0xE844, 0xFF2A, 0x749D, 0xD1F6, 0x5A41, 0x4D2F, 0xC698,
+       0x7119, 0xFAAE, 0xEDC0, 0x6677, 0xC31C, 0x48AB, 0x5FC5, 0xD472,
+       0x9EA4, 0x1513, 0x027D, 0x89CA, 0x2CA1, 0xA716, 0xB078, 0x3BCF,
+       0x25D4, 0xAE63, 0xB90D, 0x32BA, 0x97D1, 0x1C66, 0x0B08, 0x80BF,
+       0xCA69, 0x41DE, 0x56B0, 0xDD07, 0x786C, 0xF3DB, 0xE4B5, 0x6F02,
+       0x3AB1, 0xB106, 0xA668, 0x2DDF, 0x88B4, 0x0303, 0x146D, 0x9FDA,
+       0xD50C, 0x5EBB, 0x49D5, 0xC262, 0x6709, 0xECBE, 0xFBD0, 0x7067,
+       0x6E7C, 0xE5CB, 0xF2A5, 0x7912, 0xDC79, 0x57CE, 0x40A0, 0xCB17,
+       0x81C1, 0x0A76, 0x1D18, 0x96AF, 0x33C4, 0xB873, 0xAF1D, 0x24AA,
+       0x932B, 0x189C, 0x0FF2, 0x8445, 0x212E, 0xAA99, 0xBDF7, 0x3640,
+       0x7C96, 0xF721, 0xE04F, 0x6BF8, 0xCE93, 0x4524, 0x524A, 0xD9FD,
+       0xC7E6, 0x4C51, 0x5B3F, 0xD088, 0x75E3, 0xFE54, 0xE93A, 0x628D,
+       0x285B, 0xA3EC, 0xB482, 0x3F35, 0x9A5E, 0x11E9, 0x0687, 0x8D30,
+       0xE232, 0x6985, 0x7EEB, 0xF55C, 0x5037, 0xDB80, 0xCCEE, 0x4759,
+       0x0D8F, 0x8638, 0x9156, 0x1AE1, 0xBF8A, 0x343D, 0x2353, 0xA8E4,
+       0xB6FF, 0x3D48, 0x2A26, 0xA191, 0x04FA, 0x8F4D, 0x9823, 0x1394,
+       0x5942, 0xD2F5, 0xC59B, 0x4E2C, 0xEB47, 0x60F0, 0x779E, 0xFC29,
+       0x4BA8, 0xC01F, 0xD771, 0x5CC6, 0xF9AD, 0x721A, 0x6574, 0xEEC3,
+       0xA415, 0x2FA2, 0x38CC, 0xB37B, 0x1610, 0x9DA7, 0x8AC9, 0x017E,
+       0x1F65, 0x94D2, 0x83BC, 0x080B, 0xAD60, 0x26D7, 0x31B9, 0xBA0E,
+       0xF0D8, 0x7B6F, 0x6C01, 0xE7B6, 0x42DD, 0xC96A, 0xDE04, 0x55B3
+};
+
+u16 crc_t10dif_generic(u16 crc, const u8 *p, size_t len)
+{
+       size_t i;
+
+       for (i = 0; i < len; i++)
+               crc = (crc << 8) ^ t10_dif_crc_table[(crc >> 8) ^ p[i]];
+
+       return crc;
+}
+EXPORT_SYMBOL(crc_t10dif_generic);
+
+MODULE_DESCRIPTION("T10 DIF CRC calculation");
+MODULE_LICENSE("GPL");
diff --git a/lib/crc/crc16.c b/lib/crc/crc16.c
new file mode 100644 (file)
index 0000000..9c71eda
--- /dev/null
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *      crc16.c
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc16.h>
+
+/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
+static const u16 crc16_table[256] = {
+       0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+       0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+       0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+       0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+       0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+       0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+       0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+       0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+       0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+       0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+       0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+       0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+       0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+       0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+       0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+       0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+       0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+       0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+       0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+       0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+       0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+       0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+       0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+       0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+       0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+       0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+       0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+       0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+       0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+       0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+       0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+       0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+/**
+ * crc16 - compute the CRC-16 for the data buffer
+ * @crc:       previous CRC value
+ * @p:         data pointer
+ * @len:       number of bytes in the buffer
+ *
+ * Returns the updated CRC value.
+ */
+u16 crc16(u16 crc, const u8 *p, size_t len)
+{
+       while (len--)
+               crc = (crc >> 8) ^ crc16_table[(crc & 0xff) ^ *p++];
+       return crc;
+}
+EXPORT_SYMBOL(crc16);
+
+MODULE_DESCRIPTION("CRC16 calculations");
+MODULE_LICENSE("GPL");
+
diff --git a/lib/crc/crc32.c b/lib/crc/crc32.c
new file mode 100644 (file)
index 0000000..6811b37
--- /dev/null
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin
+ * cleaned up code to current version of sparse and added the slicing-by-8
+ * algorithm to the closely similar existing slicing-by-4 algorithm.
+ *
+ * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * Nicer crc32 functions/docs submitted by linux@horizon.com.  Thanks!
+ * Code was from the public domain, copyright abandoned.  Code was
+ * subsequently included in the kernel, thus was re-licensed under the
+ * GNU GPL v2.
+ *
+ * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * Same crc32 function was used in 5 other places in the kernel.
+ * I made one version, and deleted the others.
+ * There are various incantations of crc32().  Some use a seed of 0 or ~0.
+ * Some xor at the end with ~0.  The generic crc32() function takes
+ * seed as an argument, and doesn't xor at the end.  Then individual
+ * users can do whatever they need.
+ *   drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
+ *   fs/jffs2 uses seed 0, doesn't xor with ~0.
+ *   fs/partitions/efi.c uses seed ~0, xor's with ~0.
+ */
+
+/* see: Documentation/staging/crc32.rst for a description of algorithms */
+
+#include <linux/crc32.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include "crc32table.h"
+
+MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
+MODULE_DESCRIPTION("Various CRC32 calculations");
+MODULE_LICENSE("GPL");
+
+u32 crc32_le_base(u32 crc, const u8 *p, size_t len)
+{
+       while (len--)
+               crc = (crc >> 8) ^ crc32table_le[(crc & 255) ^ *p++];
+       return crc;
+}
+EXPORT_SYMBOL(crc32_le_base);
+
+u32 crc32c_base(u32 crc, const u8 *p, size_t len)
+{
+       while (len--)
+               crc = (crc >> 8) ^ crc32ctable_le[(crc & 255) ^ *p++];
+       return crc;
+}
+EXPORT_SYMBOL(crc32c_base);
+
+u32 crc32_be_base(u32 crc, const u8 *p, size_t len)
+{
+       while (len--)
+               crc = (crc << 8) ^ crc32table_be[(crc >> 24) ^ *p++];
+       return crc;
+}
+EXPORT_SYMBOL(crc32_be_base);
diff --git a/lib/crc/crc4.c b/lib/crc/crc4.c
new file mode 100644 (file)
index 0000000..e7e1779
--- /dev/null
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * crc4.c - simple crc-4 calculations.
+ */
+
+#include <linux/crc4.h>
+#include <linux/module.h>
+
+static const uint8_t crc4_tab[] = {
+       0x0, 0x7, 0xe, 0x9, 0xb, 0xc, 0x5, 0x2,
+       0x1, 0x6, 0xf, 0x8, 0xa, 0xd, 0x4, 0x3,
+};
+
+/**
+ * crc4 - calculate the 4-bit crc of a value.
+ * @c:    starting crc4
+ * @x:    value to checksum
+ * @bits: number of bits in @x to checksum
+ *
+ * Returns the crc4 value of @x, using polynomial 0b10111.
+ *
+ * The @x value is treated as left-aligned, and bits above @bits are ignored
+ * in the crc calculations.
+ */
+uint8_t crc4(uint8_t c, uint64_t x, int bits)
+{
+       int i;
+
+       /* mask off anything above the top bit */
+       x &= (1ull << bits) - 1;
+
+       /* Align to 4-bits */
+       bits = (bits + 3) & ~0x3;
+
+       /* Calculate crc4 over four-bit nibbles, starting at the MSbit */
+       for (i = bits - 4; i >= 0; i -= 4)
+               c = crc4_tab[c ^ ((x >> i) & 0xf)];
+
+       return c;
+}
+EXPORT_SYMBOL_GPL(crc4);
+
+MODULE_DESCRIPTION("CRC4 calculations");
+MODULE_LICENSE("GPL");
diff --git a/lib/crc/crc64.c b/lib/crc/crc64.c
new file mode 100644 (file)
index 0000000..5b1b170
--- /dev/null
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Normal 64-bit CRC calculation.
+ *
+ * This is a basic crc64 implementation following ECMA-182 specification,
+ * which can be found from,
+ * https://www.ecma-international.org/publications/standards/Ecma-182.htm
+ *
+ * Dr. Ross N. Williams has a great document to introduce the idea of CRC
+ * algorithm, here the CRC64 code is also inspired by the table-driven
+ * algorithm and detail example from this paper. This paper can be found
+ * from,
+ * http://www.ross.net/crc/download/crc_v3.txt
+ *
+ * crc64table[256] is the lookup table of a table-driven 64-bit CRC
+ * calculation, which is generated by gen_crc64table.c in kernel build
+ * time. The polynomial of crc64 arithmetic is from ECMA-182 specification
+ * as well, which is defined as,
+ *
+ * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
+ * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
+ * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
+ * x^7 + x^4 + x + 1
+ *
+ * crc64nvmetable[256] uses the CRC64 polynomial from the NVME NVM Command Set
+ * Specification and uses least-significant-bit first bit order:
+ *
+ * x^64 + x^63 + x^61 + x^59 + x^58 + x^56 + x^55 + x^52 + x^49 + x^48 + x^47 +
+ * x^46 + x^44 + x^41 + x^37 + x^36 + x^34 + x^32 + x^31 + x^28 + x^26 + x^23 +
+ * x^22 + x^19 + x^16 + x^13 + x^12 + x^10 + x^9 + x^6 + x^4 + x^3 + 1
+ *
+ * Copyright 2018 SUSE Linux.
+ *   Author: Coly Li <colyli@suse.de>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/crc64.h>
+#include "crc64table.h"
+
+MODULE_DESCRIPTION("CRC64 calculations");
+MODULE_LICENSE("GPL v2");
+
+u64 crc64_be_generic(u64 crc, const u8 *p, size_t len)
+{
+       while (len--)
+               crc = (crc << 8) ^ crc64table[(crc >> 56) ^ *p++];
+       return crc;
+}
+EXPORT_SYMBOL_GPL(crc64_be_generic);
+
+u64 crc64_nvme_generic(u64 crc, const u8 *p, size_t len)
+{
+       while (len--)
+               crc = (crc >> 8) ^ crc64nvmetable[(crc & 0xff) ^ *p++];
+       return crc;
+}
+EXPORT_SYMBOL_GPL(crc64_nvme_generic);
diff --git a/lib/crc/crc7.c b/lib/crc/crc7.c
new file mode 100644 (file)
index 0000000..8dd991c
--- /dev/null
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *      crc7.c
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc7.h>
+
+/*
+ * Table for CRC-7 (polynomial x^7 + x^3 + 1).
+ * This is a big-endian CRC (msbit is highest power of x),
+ * aligned so the msbit of the byte is the x^6 coefficient
+ * and the lsbit is not used.
+ */
+static const u8 crc7_be_syndrome_table[256] = {
+       0x00, 0x12, 0x24, 0x36, 0x48, 0x5a, 0x6c, 0x7e,
+       0x90, 0x82, 0xb4, 0xa6, 0xd8, 0xca, 0xfc, 0xee,
+       0x32, 0x20, 0x16, 0x04, 0x7a, 0x68, 0x5e, 0x4c,
+       0xa2, 0xb0, 0x86, 0x94, 0xea, 0xf8, 0xce, 0xdc,
+       0x64, 0x76, 0x40, 0x52, 0x2c, 0x3e, 0x08, 0x1a,
+       0xf4, 0xe6, 0xd0, 0xc2, 0xbc, 0xae, 0x98, 0x8a,
+       0x56, 0x44, 0x72, 0x60, 0x1e, 0x0c, 0x3a, 0x28,
+       0xc6, 0xd4, 0xe2, 0xf0, 0x8e, 0x9c, 0xaa, 0xb8,
+       0xc8, 0xda, 0xec, 0xfe, 0x80, 0x92, 0xa4, 0xb6,
+       0x58, 0x4a, 0x7c, 0x6e, 0x10, 0x02, 0x34, 0x26,
+       0xfa, 0xe8, 0xde, 0xcc, 0xb2, 0xa0, 0x96, 0x84,
+       0x6a, 0x78, 0x4e, 0x5c, 0x22, 0x30, 0x06, 0x14,
+       0xac, 0xbe, 0x88, 0x9a, 0xe4, 0xf6, 0xc0, 0xd2,
+       0x3c, 0x2e, 0x18, 0x0a, 0x74, 0x66, 0x50, 0x42,
+       0x9e, 0x8c, 0xba, 0xa8, 0xd6, 0xc4, 0xf2, 0xe0,
+       0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, 0x70,
+       0x82, 0x90, 0xa6, 0xb4, 0xca, 0xd8, 0xee, 0xfc,
+       0x12, 0x00, 0x36, 0x24, 0x5a, 0x48, 0x7e, 0x6c,
+       0xb0, 0xa2, 0x94, 0x86, 0xf8, 0xea, 0xdc, 0xce,
+       0x20, 0x32, 0x04, 0x16, 0x68, 0x7a, 0x4c, 0x5e,
+       0xe6, 0xf4, 0xc2, 0xd0, 0xae, 0xbc, 0x8a, 0x98,
+       0x76, 0x64, 0x52, 0x40, 0x3e, 0x2c, 0x1a, 0x08,
+       0xd4, 0xc6, 0xf0, 0xe2, 0x9c, 0x8e, 0xb8, 0xaa,
+       0x44, 0x56, 0x60, 0x72, 0x0c, 0x1e, 0x28, 0x3a,
+       0x4a, 0x58, 0x6e, 0x7c, 0x02, 0x10, 0x26, 0x34,
+       0xda, 0xc8, 0xfe, 0xec, 0x92, 0x80, 0xb6, 0xa4,
+       0x78, 0x6a, 0x5c, 0x4e, 0x30, 0x22, 0x14, 0x06,
+       0xe8, 0xfa, 0xcc, 0xde, 0xa0, 0xb2, 0x84, 0x96,
+       0x2e, 0x3c, 0x0a, 0x18, 0x66, 0x74, 0x42, 0x50,
+       0xbe, 0xac, 0x9a, 0x88, 0xf6, 0xe4, 0xd2, 0xc0,
+       0x1c, 0x0e, 0x38, 0x2a, 0x54, 0x46, 0x70, 0x62,
+       0x8c, 0x9e, 0xa8, 0xba, 0xc4, 0xd6, 0xe0, 0xf2
+};
+
+/**
+ * crc7_be - update the CRC7 for the data buffer
+ * @crc:     previous CRC7 value
+ * @buffer:  data pointer
+ * @len:     number of bytes in the buffer
+ * Context: any
+ *
+ * Returns the updated CRC7 value.
+ * The CRC7 is left-aligned in the byte (the lsbit is always 0), as that
+ * makes the computation easier, and all callers want it in that form.
+ *
+ */
+u8 crc7_be(u8 crc, const u8 *buffer, size_t len)
+{
+       while (len--)
+               crc = crc7_be_syndrome_table[crc ^ *buffer++];
+       return crc;
+}
+EXPORT_SYMBOL(crc7_be);
+
+MODULE_DESCRIPTION("CRC7 calculations");
+MODULE_LICENSE("GPL");
diff --git a/lib/crc/crc8.c b/lib/crc/crc8.c
new file mode 100644 (file)
index 0000000..1ad8e50
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define pr_fmt(fmt)            KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/crc8.h>
+#include <linux/printk.h>
+
+/**
+ * crc8_populate_msb - fill crc table for given polynomial in reverse bit order.
+ *
+ * @table:     table to be filled.
+ * @polynomial:        polynomial for which table is to be filled.
+ */
+void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial)
+{
+       int i, j;
+       const u8 msbit = 0x80;
+       u8 t = msbit;
+
+       table[0] = 0;
+
+       for (i = 1; i < CRC8_TABLE_SIZE; i *= 2) {
+               t = (t << 1) ^ (t & msbit ? polynomial : 0);
+               for (j = 0; j < i; j++)
+                       table[i+j] = table[j] ^ t;
+       }
+}
+EXPORT_SYMBOL(crc8_populate_msb);
+
+/**
+ * crc8_populate_lsb - fill crc table for given polynomial in regular bit order.
+ *
+ * @table:     table to be filled.
+ * @polynomial:        polynomial for which table is to be filled.
+ */
+void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial)
+{
+       int i, j;
+       u8 t = 1;
+
+       table[0] = 0;
+
+       for (i = (CRC8_TABLE_SIZE >> 1); i; i >>= 1) {
+               t = (t >> 1) ^ (t & 1 ? polynomial : 0);
+               for (j = 0; j < CRC8_TABLE_SIZE; j += 2*i)
+                       table[i+j] = table[j] ^ t;
+       }
+}
+EXPORT_SYMBOL(crc8_populate_lsb);
+
+/**
+ * crc8 - calculate a crc8 over the given input data.
+ *
+ * @table: crc table used for calculation.
+ * @pdata: pointer to data buffer.
+ * @nbytes: number of bytes in data buffer.
+ * @crc: previous returned crc8 value.
+ */
+u8 crc8(const u8 table[CRC8_TABLE_SIZE], const u8 *pdata, size_t nbytes, u8 crc)
+{
+       /* loop over the buffer data */
+       while (nbytes-- > 0)
+               crc = table[(crc ^ *pdata++) & 0xff];
+
+       return crc;
+}
+EXPORT_SYMBOL(crc8);
+
+MODULE_DESCRIPTION("CRC8 (by Williams, Ross N.) function");
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/crc/gen_crc32table.c b/lib/crc/gen_crc32table.c
new file mode 100644 (file)
index 0000000..9a7f316
--- /dev/null
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdio.h>
+#include "../../include/linux/crc32poly.h"
+#include "../../include/generated/autoconf.h"
+#include <inttypes.h>
+
+static uint32_t crc32table_le[256];
+static uint32_t crc32table_be[256];
+static uint32_t crc32ctable_le[256];
+
+/**
+ * crc32init_le() - allocate and initialize LE table data
+ *
+ * crc is the crc of the byte i; other entries are filled in based on the
+ * fact that crctable[i^j] = crctable[i] ^ crctable[j].
+ *
+ */
+static void crc32init_le_generic(const uint32_t polynomial, uint32_t tab[256])
+{
+       unsigned i, j;
+       uint32_t crc = 1;
+
+       tab[0] = 0;
+
+       for (i = 128; i; i >>= 1) {
+               crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
+               for (j = 0; j < 256; j += 2 * i)
+                       tab[i + j] = crc ^ tab[j];
+       }
+}
+
+static void crc32init_le(void)
+{
+       crc32init_le_generic(CRC32_POLY_LE, crc32table_le);
+}
+
+static void crc32cinit_le(void)
+{
+       crc32init_le_generic(CRC32C_POLY_LE, crc32ctable_le);
+}
+
+/**
+ * crc32init_be() - allocate and initialize BE table data
+ */
+static void crc32init_be(void)
+{
+       unsigned i, j;
+       uint32_t crc = 0x80000000;
+
+       crc32table_be[0] = 0;
+
+       for (i = 1; i < 256; i <<= 1) {
+               crc = (crc << 1) ^ ((crc & 0x80000000) ? CRC32_POLY_BE : 0);
+               for (j = 0; j < i; j++)
+                       crc32table_be[i + j] = crc ^ crc32table_be[j];
+       }
+}
+
+static void output_table(const uint32_t table[256])
+{
+       int i;
+
+       for (i = 0; i < 256; i += 4) {
+               printf("\t0x%08x, 0x%08x, 0x%08x, 0x%08x,\n",
+                      table[i], table[i + 1], table[i + 2], table[i + 3]);
+       }
+}
+
+int main(int argc, char** argv)
+{
+       printf("/* this file is generated - do not edit */\n\n");
+
+       crc32init_le();
+       printf("static const u32 ____cacheline_aligned crc32table_le[256] = {\n");
+       output_table(crc32table_le);
+       printf("};\n");
+
+       crc32init_be();
+       printf("static const u32 ____cacheline_aligned crc32table_be[256] = {\n");
+       output_table(crc32table_be);
+       printf("};\n");
+
+       crc32cinit_le();
+       printf("static const u32 ____cacheline_aligned crc32ctable_le[256] = {\n");
+       output_table(crc32ctable_le);
+       printf("};\n");
+
+       return 0;
+}
diff --git a/lib/crc/gen_crc64table.c b/lib/crc/gen_crc64table.c
new file mode 100644 (file)
index 0000000..f2be9f6
--- /dev/null
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This host program runs at kernel build time and generates the lookup tables
+ * used by the generic CRC64 code.
+ *
+ * Copyright 2018 SUSE Linux.
+ *   Author: Coly Li <colyli@suse.de>
+ */
+#include <inttypes.h>
+#include <stdio.h>
+
+#define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL
+#define CRC64_NVME_POLY 0x9A6C9329AC4BC9B5ULL
+
+static uint64_t crc64_table[256] = {0};
+static uint64_t crc64_nvme_table[256] = {0};
+
+static void generate_reflected_crc64_table(uint64_t table[256], uint64_t poly)
+{
+       uint64_t i, j, c, crc;
+
+       for (i = 0; i < 256; i++) {
+               crc = 0ULL;
+               c = i;
+
+               for (j = 0; j < 8; j++) {
+                       if ((crc ^ (c >> j)) & 1)
+                               crc = (crc >> 1) ^ poly;
+                       else
+                               crc >>= 1;
+               }
+               table[i] = crc;
+       }
+}
+
+static void generate_crc64_table(uint64_t table[256], uint64_t poly)
+{
+       uint64_t i, j, c, crc;
+
+       for (i = 0; i < 256; i++) {
+               crc = 0;
+               c = i << 56;
+
+               for (j = 0; j < 8; j++) {
+                       if ((crc ^ c) & 0x8000000000000000ULL)
+                               crc = (crc << 1) ^ poly;
+                       else
+                               crc <<= 1;
+                       c <<= 1;
+               }
+
+               table[i] = crc;
+       }
+}
+
+static void output_table(uint64_t table[256])
+{
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               printf("\t0x%016" PRIx64 "ULL", table[i]);
+               if (i & 0x1)
+                       printf(",\n");
+               else
+                       printf(", ");
+       }
+       printf("};\n");
+}
+
+static void print_crc64_tables(void)
+{
+       printf("/* this file is generated - do not edit */\n\n");
+       printf("#include <linux/types.h>\n");
+       printf("#include <linux/cache.h>\n\n");
+       printf("static const u64 ____cacheline_aligned crc64table[256] = {\n");
+       output_table(crc64_table);
+
+       printf("\nstatic const u64 ____cacheline_aligned crc64nvmetable[256] = {\n");
+       output_table(crc64_nvme_table);
+}
+
+int main(int argc, char *argv[])
+{
+       generate_crc64_table(crc64_table, CRC64_ECMA182_POLY);
+       generate_reflected_crc64_table(crc64_nvme_table, CRC64_NVME_POLY);
+       print_crc64_tables();
+       return 0;
+}
diff --git a/lib/crc/tests/Makefile b/lib/crc/tests/Makefile
new file mode 100644 (file)
index 0000000..65f63c3
--- /dev/null
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CRC_KUNIT_TEST) += crc_kunit.o
diff --git a/lib/crc/tests/crc_kunit.c b/lib/crc/tests/crc_kunit.c
new file mode 100644 (file)
index 0000000..f08d985
--- /dev/null
@@ -0,0 +1,452 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Unit tests and benchmarks for the CRC library functions
+ *
+ * Copyright 2024 Google LLC
+ *
+ * Author: Eric Biggers <ebiggers@google.com>
+ */
+#include <kunit/test.h>
+#include <linux/crc7.h>
+#include <linux/crc16.h>
+#include <linux/crc-t10dif.h>
+#include <linux/crc32.h>
+#include <linux/crc32c.h>
+#include <linux/crc64.h>
+#include <linux/prandom.h>
+#include <linux/vmalloc.h>
+
+#define CRC_KUNIT_SEED                 42
+#define CRC_KUNIT_MAX_LEN              16384
+#define CRC_KUNIT_NUM_TEST_ITERS       1000
+
+static struct rnd_state rng;
+static u8 *test_buffer;
+static size_t test_buflen;
+
+/**
+ * struct crc_variant - describes a CRC variant
+ * @bits: Number of bits in the CRC, 1 <= @bits <= 64.
+ * @le: true if it's a "little endian" CRC (reversed mapping between bits and
+ *     polynomial coefficients in each byte), false if it's a "big endian" CRC
+ *     (natural mapping between bits and polynomial coefficients in each byte)
+ * @poly: The generator polynomial with the highest-order term omitted.
+ *       Bit-reversed if @le is true.
+ * @func: The function to compute a CRC.  The type signature uses u64 so that it
+ *       can fit any CRC up to CRC-64.  The CRC is passed in, and is expected
+ *       to be returned in, the least significant bits of the u64.  The
+ *       function is expected to *not* invert the CRC at the beginning and end.
+ */
+struct crc_variant {
+       int bits;
+       bool le;
+       u64 poly;
+       u64 (*func)(u64 crc, const u8 *p, size_t len);
+};
+
+static u32 rand32(void)
+{
+       return prandom_u32_state(&rng);
+}
+
+static u64 rand64(void)
+{
+       u32 n = rand32();
+
+       return ((u64)n << 32) | rand32();
+}
+
+static u64 crc_mask(const struct crc_variant *v)
+{
+       return (u64)-1 >> (64 - v->bits);
+}
+
+/* Reference implementation of any CRC variant */
+static u64 crc_ref(const struct crc_variant *v,
+                  u64 crc, const u8 *p, size_t len)
+{
+       size_t i, j;
+
+       for (i = 0; i < len; i++) {
+               for (j = 0; j < 8; j++) {
+                       if (v->le) {
+                               crc ^= (p[i] >> j) & 1;
+                               crc = (crc >> 1) ^ ((crc & 1) ? v->poly : 0);
+                       } else {
+                               crc ^= (u64)((p[i] >> (7 - j)) & 1) <<
+                                      (v->bits - 1);
+                               if (crc & (1ULL << (v->bits - 1)))
+                                       crc = ((crc << 1) ^ v->poly) &
+                                             crc_mask(v);
+                               else
+                                       crc <<= 1;
+                       }
+               }
+       }
+       return crc;
+}
+
+static int crc_suite_init(struct kunit_suite *suite)
+{
+       /*
+        * Allocate the test buffer using vmalloc() with a page-aligned length
+        * so that it is immediately followed by a guard page.  This allows
+        * buffer overreads to be detected, even in assembly code.
+        */
+       test_buflen = round_up(CRC_KUNIT_MAX_LEN, PAGE_SIZE);
+       test_buffer = vmalloc(test_buflen);
+       if (!test_buffer)
+               return -ENOMEM;
+
+       prandom_seed_state(&rng, CRC_KUNIT_SEED);
+       prandom_bytes_state(&rng, test_buffer, test_buflen);
+       return 0;
+}
+
+static void crc_suite_exit(struct kunit_suite *suite)
+{
+       vfree(test_buffer);
+       test_buffer = NULL;
+}
+
+/* Generate a random initial CRC. */
+static u64 generate_random_initial_crc(const struct crc_variant *v)
+{
+       switch (rand32() % 4) {
+       case 0:
+               return 0;
+       case 1:
+               return crc_mask(v); /* All 1 bits */
+       default:
+               return rand64() & crc_mask(v);
+       }
+}
+
+/* Generate a random length, preferring small lengths. */
+static size_t generate_random_length(size_t max_length)
+{
+       size_t len;
+
+       switch (rand32() % 3) {
+       case 0:
+               len = rand32() % 128;
+               break;
+       case 1:
+               len = rand32() % 3072;
+               break;
+       default:
+               len = rand32();
+               break;
+       }
+       return len % (max_length + 1);
+}
+
+/* Test that v->func gives the same CRCs as a reference implementation. */
+static void crc_test(struct kunit *test, const struct crc_variant *v)
+{
+       size_t i;
+
+       for (i = 0; i < CRC_KUNIT_NUM_TEST_ITERS; i++) {
+               u64 init_crc, expected_crc, actual_crc;
+               size_t len, offset;
+               bool nosimd;
+
+               init_crc = generate_random_initial_crc(v);
+               len = generate_random_length(CRC_KUNIT_MAX_LEN);
+
+               /* Generate a random offset. */
+               if (rand32() % 2 == 0) {
+                       /* Use a random alignment mod 64 */
+                       offset = rand32() % 64;
+                       offset = min(offset, CRC_KUNIT_MAX_LEN - len);
+               } else {
+                       /* Go up to the guard page, to catch buffer overreads */
+                       offset = test_buflen - len;
+               }
+
+               if (rand32() % 8 == 0)
+                       /* Refresh the data occasionally. */
+                       prandom_bytes_state(&rng, &test_buffer[offset], len);
+
+               nosimd = rand32() % 8 == 0;
+
+               /*
+                * Compute the CRC, and verify that it equals the CRC computed
+                * by a simple bit-at-a-time reference implementation.
+                */
+               expected_crc = crc_ref(v, init_crc, &test_buffer[offset], len);
+               if (nosimd)
+                       local_irq_disable();
+               actual_crc = v->func(init_crc, &test_buffer[offset], len);
+               if (nosimd)
+                       local_irq_enable();
+               KUNIT_EXPECT_EQ_MSG(test, expected_crc, actual_crc,
+                                   "Wrong result with len=%zu offset=%zu nosimd=%d",
+                                   len, offset, nosimd);
+       }
+}
+
+static __always_inline void
+crc_benchmark(struct kunit *test,
+             u64 (*crc_func)(u64 crc, const u8 *p, size_t len))
+{
+       static const size_t lens_to_test[] = {
+               1, 16, 64, 127, 128, 200, 256, 511, 512, 1024, 3173, 4096, 16384,
+       };
+       size_t len, i, j, num_iters;
+       /*
+        * The CRC value that this function computes in a series of calls to
+        * crc_func is never actually used, so use volatile to ensure that the
+        * computations are done as intended and don't all get optimized out.
+        */
+       volatile u64 crc = 0;
+       u64 t;
+
+       if (!IS_ENABLED(CONFIG_CRC_BENCHMARK))
+               kunit_skip(test, "not enabled");
+
+       /* warm-up */
+       for (i = 0; i < 10000000; i += CRC_KUNIT_MAX_LEN)
+               crc = crc_func(crc, test_buffer, CRC_KUNIT_MAX_LEN);
+
+       for (i = 0; i < ARRAY_SIZE(lens_to_test); i++) {
+               len = lens_to_test[i];
+               KUNIT_ASSERT_LE(test, len, CRC_KUNIT_MAX_LEN);
+               num_iters = 10000000 / (len + 128);
+               preempt_disable();
+               t = ktime_get_ns();
+               for (j = 0; j < num_iters; j++)
+                       crc = crc_func(crc, test_buffer, len);
+               t = ktime_get_ns() - t;
+               preempt_enable();
+               kunit_info(test, "len=%zu: %llu MB/s\n",
+                          len, div64_u64((u64)len * num_iters * 1000, t));
+       }
+}
+
+/* crc7_be */
+
+static u64 crc7_be_wrapper(u64 crc, const u8 *p, size_t len)
+{
+       /*
+        * crc7_be() left-aligns the 7-bit CRC in a u8, whereas the test wants a
+        * right-aligned CRC (in a u64).  Convert between the conventions.
+        */
+       return crc7_be(crc << 1, p, len) >> 1;
+}
+
+static const struct crc_variant crc_variant_crc7_be = {
+       .bits = 7,
+       .poly = 0x9,
+       .func = crc7_be_wrapper,
+};
+
+static void crc7_be_test(struct kunit *test)
+{
+       crc_test(test, &crc_variant_crc7_be);
+}
+
+static void crc7_be_benchmark(struct kunit *test)
+{
+       crc_benchmark(test, crc7_be_wrapper);
+}
+
+/* crc16 */
+
+static u64 crc16_wrapper(u64 crc, const u8 *p, size_t len)
+{
+       return crc16(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc16 = {
+       .bits = 16,
+       .le = true,
+       .poly = 0xa001,
+       .func = crc16_wrapper,
+};
+
+static void crc16_test(struct kunit *test)
+{
+       crc_test(test, &crc_variant_crc16);
+}
+
+static void crc16_benchmark(struct kunit *test)
+{
+       crc_benchmark(test, crc16_wrapper);
+}
+
+/* crc_t10dif */
+
+static u64 crc_t10dif_wrapper(u64 crc, const u8 *p, size_t len)
+{
+       return crc_t10dif_update(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc_t10dif = {
+       .bits = 16,
+       .le = false,
+       .poly = 0x8bb7,
+       .func = crc_t10dif_wrapper,
+};
+
+static void crc_t10dif_test(struct kunit *test)
+{
+       crc_test(test, &crc_variant_crc_t10dif);
+}
+
+static void crc_t10dif_benchmark(struct kunit *test)
+{
+       crc_benchmark(test, crc_t10dif_wrapper);
+}
+
+/* crc32_le */
+
+static u64 crc32_le_wrapper(u64 crc, const u8 *p, size_t len)
+{
+       return crc32_le(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc32_le = {
+       .bits = 32,
+       .le = true,
+       .poly = 0xedb88320,
+       .func = crc32_le_wrapper,
+};
+
+static void crc32_le_test(struct kunit *test)
+{
+       crc_test(test, &crc_variant_crc32_le);
+}
+
+static void crc32_le_benchmark(struct kunit *test)
+{
+       crc_benchmark(test, crc32_le_wrapper);
+}
+
+/* crc32_be */
+
+static u64 crc32_be_wrapper(u64 crc, const u8 *p, size_t len)
+{
+       return crc32_be(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc32_be = {
+       .bits = 32,
+       .le = false,
+       .poly = 0x04c11db7,
+       .func = crc32_be_wrapper,
+};
+
+static void crc32_be_test(struct kunit *test)
+{
+       crc_test(test, &crc_variant_crc32_be);
+}
+
+static void crc32_be_benchmark(struct kunit *test)
+{
+       crc_benchmark(test, crc32_be_wrapper);
+}
+
+/* crc32c */
+
+static u64 crc32c_wrapper(u64 crc, const u8 *p, size_t len)
+{
+       return crc32c(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc32c = {
+       .bits = 32,
+       .le = true,
+       .poly = 0x82f63b78,
+       .func = crc32c_wrapper,
+};
+
+static void crc32c_test(struct kunit *test)
+{
+       crc_test(test, &crc_variant_crc32c);
+}
+
+static void crc32c_benchmark(struct kunit *test)
+{
+       crc_benchmark(test, crc32c_wrapper);
+}
+
+/* crc64_be */
+
+static u64 crc64_be_wrapper(u64 crc, const u8 *p, size_t len)
+{
+       return crc64_be(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc64_be = {
+       .bits = 64,
+       .le = false,
+       .poly = 0x42f0e1eba9ea3693,
+       .func = crc64_be_wrapper,
+};
+
+static void crc64_be_test(struct kunit *test)
+{
+       crc_test(test, &crc_variant_crc64_be);
+}
+
+static void crc64_be_benchmark(struct kunit *test)
+{
+       crc_benchmark(test, crc64_be_wrapper);
+}
+
+/* crc64_nvme */
+
+static u64 crc64_nvme_wrapper(u64 crc, const u8 *p, size_t len)
+{
+       /* The inversions that crc64_nvme() does have to be undone here. */
+       return ~crc64_nvme(~crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc64_nvme = {
+       .bits = 64,
+       .le = true,
+       .poly = 0x9a6c9329ac4bc9b5,
+       .func = crc64_nvme_wrapper,
+};
+
+static void crc64_nvme_test(struct kunit *test)
+{
+       crc_test(test, &crc_variant_crc64_nvme);
+}
+
+static void crc64_nvme_benchmark(struct kunit *test)
+{
+       crc_benchmark(test, crc64_nvme_wrapper);
+}
+
+static struct kunit_case crc_test_cases[] = {
+       KUNIT_CASE(crc7_be_test),
+       KUNIT_CASE(crc7_be_benchmark),
+       KUNIT_CASE(crc16_test),
+       KUNIT_CASE(crc16_benchmark),
+       KUNIT_CASE(crc_t10dif_test),
+       KUNIT_CASE(crc_t10dif_benchmark),
+       KUNIT_CASE(crc32_le_test),
+       KUNIT_CASE(crc32_le_benchmark),
+       KUNIT_CASE(crc32_be_test),
+       KUNIT_CASE(crc32_be_benchmark),
+       KUNIT_CASE(crc32c_test),
+       KUNIT_CASE(crc32c_benchmark),
+       KUNIT_CASE(crc64_be_test),
+       KUNIT_CASE(crc64_be_benchmark),
+       KUNIT_CASE(crc64_nvme_test),
+       KUNIT_CASE(crc64_nvme_benchmark),
+       {},
+};
+
+static struct kunit_suite crc_test_suite = {
+       .name = "crc",
+       .test_cases = crc_test_cases,
+       .suite_init = crc_suite_init,
+       .suite_exit = crc_suite_exit,
+};
+kunit_test_suite(crc_test_suite);
+
+MODULE_DESCRIPTION("Unit tests and benchmarks for the CRC library functions");
+MODULE_LICENSE("GPL");
diff --git a/lib/crc16.c b/lib/crc16.c
deleted file mode 100644 (file)
index 9c71eda..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *      crc16.c
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/crc16.h>
-
-/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
-static const u16 crc16_table[256] = {
-       0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
-       0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
-       0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
-       0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
-       0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
-       0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
-       0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
-       0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
-       0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
-       0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
-       0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
-       0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
-       0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
-       0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
-       0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
-       0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
-       0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
-       0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
-       0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
-       0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
-       0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
-       0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
-       0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
-       0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
-       0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
-       0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
-       0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
-       0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
-       0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
-       0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
-       0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
-       0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
-};
-
-/**
- * crc16 - compute the CRC-16 for the data buffer
- * @crc:       previous CRC value
- * @p:         data pointer
- * @len:       number of bytes in the buffer
- *
- * Returns the updated CRC value.
- */
-u16 crc16(u16 crc, const u8 *p, size_t len)
-{
-       while (len--)
-               crc = (crc >> 8) ^ crc16_table[(crc & 0xff) ^ *p++];
-       return crc;
-}
-EXPORT_SYMBOL(crc16);
-
-MODULE_DESCRIPTION("CRC16 calculations");
-MODULE_LICENSE("GPL");
-
diff --git a/lib/crc32.c b/lib/crc32.c
deleted file mode 100644 (file)
index 6811b37..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin
- * cleaned up code to current version of sparse and added the slicing-by-8
- * algorithm to the closely similar existing slicing-by-4 algorithm.
- *
- * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
- * Nicer crc32 functions/docs submitted by linux@horizon.com.  Thanks!
- * Code was from the public domain, copyright abandoned.  Code was
- * subsequently included in the kernel, thus was re-licensed under the
- * GNU GPL v2.
- *
- * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com>
- * Same crc32 function was used in 5 other places in the kernel.
- * I made one version, and deleted the others.
- * There are various incantations of crc32().  Some use a seed of 0 or ~0.
- * Some xor at the end with ~0.  The generic crc32() function takes
- * seed as an argument, and doesn't xor at the end.  Then individual
- * users can do whatever they need.
- *   drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
- *   fs/jffs2 uses seed 0, doesn't xor with ~0.
- *   fs/partitions/efi.c uses seed ~0, xor's with ~0.
- */
-
-/* see: Documentation/staging/crc32.rst for a description of algorithms */
-
-#include <linux/crc32.h>
-#include <linux/module.h>
-#include <linux/types.h>
-
-#include "crc32table.h"
-
-MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
-MODULE_DESCRIPTION("Various CRC32 calculations");
-MODULE_LICENSE("GPL");
-
-u32 crc32_le_base(u32 crc, const u8 *p, size_t len)
-{
-       while (len--)
-               crc = (crc >> 8) ^ crc32table_le[(crc & 255) ^ *p++];
-       return crc;
-}
-EXPORT_SYMBOL(crc32_le_base);
-
-u32 crc32c_base(u32 crc, const u8 *p, size_t len)
-{
-       while (len--)
-               crc = (crc >> 8) ^ crc32ctable_le[(crc & 255) ^ *p++];
-       return crc;
-}
-EXPORT_SYMBOL(crc32c_base);
-
-u32 crc32_be_base(u32 crc, const u8 *p, size_t len)
-{
-       while (len--)
-               crc = (crc << 8) ^ crc32table_be[(crc >> 24) ^ *p++];
-       return crc;
-}
-EXPORT_SYMBOL(crc32_be_base);
diff --git a/lib/crc4.c b/lib/crc4.c
deleted file mode 100644 (file)
index e7e1779..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * crc4.c - simple crc-4 calculations.
- */
-
-#include <linux/crc4.h>
-#include <linux/module.h>
-
-static const uint8_t crc4_tab[] = {
-       0x0, 0x7, 0xe, 0x9, 0xb, 0xc, 0x5, 0x2,
-       0x1, 0x6, 0xf, 0x8, 0xa, 0xd, 0x4, 0x3,
-};
-
-/**
- * crc4 - calculate the 4-bit crc of a value.
- * @c:    starting crc4
- * @x:    value to checksum
- * @bits: number of bits in @x to checksum
- *
- * Returns the crc4 value of @x, using polynomial 0b10111.
- *
- * The @x value is treated as left-aligned, and bits above @bits are ignored
- * in the crc calculations.
- */
-uint8_t crc4(uint8_t c, uint64_t x, int bits)
-{
-       int i;
-
-       /* mask off anything above the top bit */
-       x &= (1ull << bits) - 1;
-
-       /* Align to 4-bits */
-       bits = (bits + 3) & ~0x3;
-
-       /* Calculate crc4 over four-bit nibbles, starting at the MSbit */
-       for (i = bits - 4; i >= 0; i -= 4)
-               c = crc4_tab[c ^ ((x >> i) & 0xf)];
-
-       return c;
-}
-EXPORT_SYMBOL_GPL(crc4);
-
-MODULE_DESCRIPTION("CRC4 calculations");
-MODULE_LICENSE("GPL");
diff --git a/lib/crc64.c b/lib/crc64.c
deleted file mode 100644 (file)
index 5b1b170..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Normal 64-bit CRC calculation.
- *
- * This is a basic crc64 implementation following ECMA-182 specification,
- * which can be found from,
- * https://www.ecma-international.org/publications/standards/Ecma-182.htm
- *
- * Dr. Ross N. Williams has a great document to introduce the idea of CRC
- * algorithm, here the CRC64 code is also inspired by the table-driven
- * algorithm and detail example from this paper. This paper can be found
- * from,
- * http://www.ross.net/crc/download/crc_v3.txt
- *
- * crc64table[256] is the lookup table of a table-driven 64-bit CRC
- * calculation, which is generated by gen_crc64table.c in kernel build
- * time. The polynomial of crc64 arithmetic is from ECMA-182 specification
- * as well, which is defined as,
- *
- * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
- * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
- * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
- * x^7 + x^4 + x + 1
- *
- * crc64nvmetable[256] uses the CRC64 polynomial from the NVME NVM Command Set
- * Specification and uses least-significant-bit first bit order:
- *
- * x^64 + x^63 + x^61 + x^59 + x^58 + x^56 + x^55 + x^52 + x^49 + x^48 + x^47 +
- * x^46 + x^44 + x^41 + x^37 + x^36 + x^34 + x^32 + x^31 + x^28 + x^26 + x^23 +
- * x^22 + x^19 + x^16 + x^13 + x^12 + x^10 + x^9 + x^6 + x^4 + x^3 + 1
- *
- * Copyright 2018 SUSE Linux.
- *   Author: Coly Li <colyli@suse.de>
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/crc64.h>
-#include "crc64table.h"
-
-MODULE_DESCRIPTION("CRC64 calculations");
-MODULE_LICENSE("GPL v2");
-
-u64 crc64_be_generic(u64 crc, const u8 *p, size_t len)
-{
-       while (len--)
-               crc = (crc << 8) ^ crc64table[(crc >> 56) ^ *p++];
-       return crc;
-}
-EXPORT_SYMBOL_GPL(crc64_be_generic);
-
-u64 crc64_nvme_generic(u64 crc, const u8 *p, size_t len)
-{
-       while (len--)
-               crc = (crc >> 8) ^ crc64nvmetable[(crc & 0xff) ^ *p++];
-       return crc;
-}
-EXPORT_SYMBOL_GPL(crc64_nvme_generic);
diff --git a/lib/crc7.c b/lib/crc7.c
deleted file mode 100644 (file)
index 8dd991c..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *      crc7.c
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/crc7.h>
-
-/*
- * Table for CRC-7 (polynomial x^7 + x^3 + 1).
- * This is a big-endian CRC (msbit is highest power of x),
- * aligned so the msbit of the byte is the x^6 coefficient
- * and the lsbit is not used.
- */
-static const u8 crc7_be_syndrome_table[256] = {
-       0x00, 0x12, 0x24, 0x36, 0x48, 0x5a, 0x6c, 0x7e,
-       0x90, 0x82, 0xb4, 0xa6, 0xd8, 0xca, 0xfc, 0xee,
-       0x32, 0x20, 0x16, 0x04, 0x7a, 0x68, 0x5e, 0x4c,
-       0xa2, 0xb0, 0x86, 0x94, 0xea, 0xf8, 0xce, 0xdc,
-       0x64, 0x76, 0x40, 0x52, 0x2c, 0x3e, 0x08, 0x1a,
-       0xf4, 0xe6, 0xd0, 0xc2, 0xbc, 0xae, 0x98, 0x8a,
-       0x56, 0x44, 0x72, 0x60, 0x1e, 0x0c, 0x3a, 0x28,
-       0xc6, 0xd4, 0xe2, 0xf0, 0x8e, 0x9c, 0xaa, 0xb8,
-       0xc8, 0xda, 0xec, 0xfe, 0x80, 0x92, 0xa4, 0xb6,
-       0x58, 0x4a, 0x7c, 0x6e, 0x10, 0x02, 0x34, 0x26,
-       0xfa, 0xe8, 0xde, 0xcc, 0xb2, 0xa0, 0x96, 0x84,
-       0x6a, 0x78, 0x4e, 0x5c, 0x22, 0x30, 0x06, 0x14,
-       0xac, 0xbe, 0x88, 0x9a, 0xe4, 0xf6, 0xc0, 0xd2,
-       0x3c, 0x2e, 0x18, 0x0a, 0x74, 0x66, 0x50, 0x42,
-       0x9e, 0x8c, 0xba, 0xa8, 0xd6, 0xc4, 0xf2, 0xe0,
-       0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, 0x70,
-       0x82, 0x90, 0xa6, 0xb4, 0xca, 0xd8, 0xee, 0xfc,
-       0x12, 0x00, 0x36, 0x24, 0x5a, 0x48, 0x7e, 0x6c,
-       0xb0, 0xa2, 0x94, 0x86, 0xf8, 0xea, 0xdc, 0xce,
-       0x20, 0x32, 0x04, 0x16, 0x68, 0x7a, 0x4c, 0x5e,
-       0xe6, 0xf4, 0xc2, 0xd0, 0xae, 0xbc, 0x8a, 0x98,
-       0x76, 0x64, 0x52, 0x40, 0x3e, 0x2c, 0x1a, 0x08,
-       0xd4, 0xc6, 0xf0, 0xe2, 0x9c, 0x8e, 0xb8, 0xaa,
-       0x44, 0x56, 0x60, 0x72, 0x0c, 0x1e, 0x28, 0x3a,
-       0x4a, 0x58, 0x6e, 0x7c, 0x02, 0x10, 0x26, 0x34,
-       0xda, 0xc8, 0xfe, 0xec, 0x92, 0x80, 0xb6, 0xa4,
-       0x78, 0x6a, 0x5c, 0x4e, 0x30, 0x22, 0x14, 0x06,
-       0xe8, 0xfa, 0xcc, 0xde, 0xa0, 0xb2, 0x84, 0x96,
-       0x2e, 0x3c, 0x0a, 0x18, 0x66, 0x74, 0x42, 0x50,
-       0xbe, 0xac, 0x9a, 0x88, 0xf6, 0xe4, 0xd2, 0xc0,
-       0x1c, 0x0e, 0x38, 0x2a, 0x54, 0x46, 0x70, 0x62,
-       0x8c, 0x9e, 0xa8, 0xba, 0xc4, 0xd6, 0xe0, 0xf2
-};
-
-/**
- * crc7_be - update the CRC7 for the data buffer
- * @crc:     previous CRC7 value
- * @buffer:  data pointer
- * @len:     number of bytes in the buffer
- * Context: any
- *
- * Returns the updated CRC7 value.
- * The CRC7 is left-aligned in the byte (the lsbit is always 0), as that
- * makes the computation easier, and all callers want it in that form.
- *
- */
-u8 crc7_be(u8 crc, const u8 *buffer, size_t len)
-{
-       while (len--)
-               crc = crc7_be_syndrome_table[crc ^ *buffer++];
-       return crc;
-}
-EXPORT_SYMBOL(crc7_be);
-
-MODULE_DESCRIPTION("CRC7 calculations");
-MODULE_LICENSE("GPL");
diff --git a/lib/crc8.c b/lib/crc8.c
deleted file mode 100644 (file)
index 1ad8e50..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2011 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define pr_fmt(fmt)            KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/crc8.h>
-#include <linux/printk.h>
-
-/**
- * crc8_populate_msb - fill crc table for given polynomial in reverse bit order.
- *
- * @table:     table to be filled.
- * @polynomial:        polynomial for which table is to be filled.
- */
-void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial)
-{
-       int i, j;
-       const u8 msbit = 0x80;
-       u8 t = msbit;
-
-       table[0] = 0;
-
-       for (i = 1; i < CRC8_TABLE_SIZE; i *= 2) {
-               t = (t << 1) ^ (t & msbit ? polynomial : 0);
-               for (j = 0; j < i; j++)
-                       table[i+j] = table[j] ^ t;
-       }
-}
-EXPORT_SYMBOL(crc8_populate_msb);
-
-/**
- * crc8_populate_lsb - fill crc table for given polynomial in regular bit order.
- *
- * @table:     table to be filled.
- * @polynomial:        polynomial for which table is to be filled.
- */
-void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial)
-{
-       int i, j;
-       u8 t = 1;
-
-       table[0] = 0;
-
-       for (i = (CRC8_TABLE_SIZE >> 1); i; i >>= 1) {
-               t = (t >> 1) ^ (t & 1 ? polynomial : 0);
-               for (j = 0; j < CRC8_TABLE_SIZE; j += 2*i)
-                       table[i+j] = table[j] ^ t;
-       }
-}
-EXPORT_SYMBOL(crc8_populate_lsb);
-
-/**
- * crc8 - calculate a crc8 over the given input data.
- *
- * @table: crc table used for calculation.
- * @pdata: pointer to data buffer.
- * @nbytes: number of bytes in data buffer.
- * @crc: previous returned crc8 value.
- */
-u8 crc8(const u8 table[CRC8_TABLE_SIZE], const u8 *pdata, size_t nbytes, u8 crc)
-{
-       /* loop over the buffer data */
-       while (nbytes-- > 0)
-               crc = table[(crc ^ *pdata++) & 0xff];
-
-       return crc;
-}
-EXPORT_SYMBOL(crc8);
-
-MODULE_DESCRIPTION("CRC8 (by Williams, Ross N.) function");
-MODULE_AUTHOR("Broadcom Corporation");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/gen_crc32table.c b/lib/gen_crc32table.c
deleted file mode 100644 (file)
index 6d03425..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <stdio.h>
-#include "../include/linux/crc32poly.h"
-#include "../include/generated/autoconf.h"
-#include <inttypes.h>
-
-static uint32_t crc32table_le[256];
-static uint32_t crc32table_be[256];
-static uint32_t crc32ctable_le[256];
-
-/**
- * crc32init_le() - allocate and initialize LE table data
- *
- * crc is the crc of the byte i; other entries are filled in based on the
- * fact that crctable[i^j] = crctable[i] ^ crctable[j].
- *
- */
-static void crc32init_le_generic(const uint32_t polynomial, uint32_t tab[256])
-{
-       unsigned i, j;
-       uint32_t crc = 1;
-
-       tab[0] = 0;
-
-       for (i = 128; i; i >>= 1) {
-               crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
-               for (j = 0; j < 256; j += 2 * i)
-                       tab[i + j] = crc ^ tab[j];
-       }
-}
-
-static void crc32init_le(void)
-{
-       crc32init_le_generic(CRC32_POLY_LE, crc32table_le);
-}
-
-static void crc32cinit_le(void)
-{
-       crc32init_le_generic(CRC32C_POLY_LE, crc32ctable_le);
-}
-
-/**
- * crc32init_be() - allocate and initialize BE table data
- */
-static void crc32init_be(void)
-{
-       unsigned i, j;
-       uint32_t crc = 0x80000000;
-
-       crc32table_be[0] = 0;
-
-       for (i = 1; i < 256; i <<= 1) {
-               crc = (crc << 1) ^ ((crc & 0x80000000) ? CRC32_POLY_BE : 0);
-               for (j = 0; j < i; j++)
-                       crc32table_be[i + j] = crc ^ crc32table_be[j];
-       }
-}
-
-static void output_table(const uint32_t table[256])
-{
-       int i;
-
-       for (i = 0; i < 256; i += 4) {
-               printf("\t0x%08x, 0x%08x, 0x%08x, 0x%08x,\n",
-                      table[i], table[i + 1], table[i + 2], table[i + 3]);
-       }
-}
-
-int main(int argc, char** argv)
-{
-       printf("/* this file is generated - do not edit */\n\n");
-
-       crc32init_le();
-       printf("static const u32 ____cacheline_aligned crc32table_le[256] = {\n");
-       output_table(crc32table_le);
-       printf("};\n");
-
-       crc32init_be();
-       printf("static const u32 ____cacheline_aligned crc32table_be[256] = {\n");
-       output_table(crc32table_be);
-       printf("};\n");
-
-       crc32cinit_le();
-       printf("static const u32 ____cacheline_aligned crc32ctable_le[256] = {\n");
-       output_table(crc32ctable_le);
-       printf("};\n");
-
-       return 0;
-}
diff --git a/lib/gen_crc64table.c b/lib/gen_crc64table.c
deleted file mode 100644 (file)
index e05a423..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Generate lookup table for the table-driven CRC64 calculation.
- *
- * gen_crc64table is executed in kernel build time and generates
- * lib/crc64table.h. This header is included by lib/crc64.c for
- * the table-driven CRC64 calculation.
- *
- * See lib/crc64.c for more information about which specification
- * and polynomial arithmetic that gen_crc64table.c follows to
- * generate the lookup table.
- *
- * Copyright 2018 SUSE Linux.
- *   Author: Coly Li <colyli@suse.de>
- */
-#include <inttypes.h>
-#include <stdio.h>
-
-#define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL
-#define CRC64_NVME_POLY 0x9A6C9329AC4BC9B5ULL
-
-static uint64_t crc64_table[256] = {0};
-static uint64_t crc64_nvme_table[256] = {0};
-
-static void generate_reflected_crc64_table(uint64_t table[256], uint64_t poly)
-{
-       uint64_t i, j, c, crc;
-
-       for (i = 0; i < 256; i++) {
-               crc = 0ULL;
-               c = i;
-
-               for (j = 0; j < 8; j++) {
-                       if ((crc ^ (c >> j)) & 1)
-                               crc = (crc >> 1) ^ poly;
-                       else
-                               crc >>= 1;
-               }
-               table[i] = crc;
-       }
-}
-
-static void generate_crc64_table(uint64_t table[256], uint64_t poly)
-{
-       uint64_t i, j, c, crc;
-
-       for (i = 0; i < 256; i++) {
-               crc = 0;
-               c = i << 56;
-
-               for (j = 0; j < 8; j++) {
-                       if ((crc ^ c) & 0x8000000000000000ULL)
-                               crc = (crc << 1) ^ poly;
-                       else
-                               crc <<= 1;
-                       c <<= 1;
-               }
-
-               table[i] = crc;
-       }
-}
-
-static void output_table(uint64_t table[256])
-{
-       int i;
-
-       for (i = 0; i < 256; i++) {
-               printf("\t0x%016" PRIx64 "ULL", table[i]);
-               if (i & 0x1)
-                       printf(",\n");
-               else
-                       printf(", ");
-       }
-       printf("};\n");
-}
-
-static void print_crc64_tables(void)
-{
-       printf("/* this file is generated - do not edit */\n\n");
-       printf("#include <linux/types.h>\n");
-       printf("#include <linux/cache.h>\n\n");
-       printf("static const u64 ____cacheline_aligned crc64table[256] = {\n");
-       output_table(crc64_table);
-
-       printf("\nstatic const u64 ____cacheline_aligned crc64nvmetable[256] = {\n");
-       output_table(crc64_nvme_table);
-}
-
-int main(int argc, char *argv[])
-{
-       generate_crc64_table(crc64_table, CRC64_ECMA182_POLY);
-       generate_reflected_crc64_table(crc64_nvme_table, CRC64_NVME_POLY);
-       print_crc64_tables();
-       return 0;
-}
index 56d6450144828ee7bfe27878d3fca33dc863fd3d..741d3ac2cba252592c7abc982f89012fa5dfd3bd 100644 (file)
@@ -10,7 +10,6 @@ obj-$(CONFIG_BLACKHOLE_DEV_KUNIT_TEST) += blackhole_dev_kunit.o
 obj-$(CONFIG_CHECKSUM_KUNIT) += checksum_kunit.o
 obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
 obj-$(CONFIG_CPUMASK_KUNIT_TEST) += cpumask_kunit.o
-obj-$(CONFIG_CRC_KUNIT_TEST) += crc_kunit.o
 CFLAGS_fortify_kunit.o += $(call cc-disable-warning, unsequenced)
 CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-overread)
 CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-truncation)
diff --git a/lib/tests/crc_kunit.c b/lib/tests/crc_kunit.c
deleted file mode 100644 (file)
index f08d985..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Unit tests and benchmarks for the CRC library functions
- *
- * Copyright 2024 Google LLC
- *
- * Author: Eric Biggers <ebiggers@google.com>
- */
-#include <kunit/test.h>
-#include <linux/crc7.h>
-#include <linux/crc16.h>
-#include <linux/crc-t10dif.h>
-#include <linux/crc32.h>
-#include <linux/crc32c.h>
-#include <linux/crc64.h>
-#include <linux/prandom.h>
-#include <linux/vmalloc.h>
-
-#define CRC_KUNIT_SEED                 42
-#define CRC_KUNIT_MAX_LEN              16384
-#define CRC_KUNIT_NUM_TEST_ITERS       1000
-
-static struct rnd_state rng;
-static u8 *test_buffer;
-static size_t test_buflen;
-
-/**
- * struct crc_variant - describes a CRC variant
- * @bits: Number of bits in the CRC, 1 <= @bits <= 64.
- * @le: true if it's a "little endian" CRC (reversed mapping between bits and
- *     polynomial coefficients in each byte), false if it's a "big endian" CRC
- *     (natural mapping between bits and polynomial coefficients in each byte)
- * @poly: The generator polynomial with the highest-order term omitted.
- *       Bit-reversed if @le is true.
- * @func: The function to compute a CRC.  The type signature uses u64 so that it
- *       can fit any CRC up to CRC-64.  The CRC is passed in, and is expected
- *       to be returned in, the least significant bits of the u64.  The
- *       function is expected to *not* invert the CRC at the beginning and end.
- */
-struct crc_variant {
-       int bits;
-       bool le;
-       u64 poly;
-       u64 (*func)(u64 crc, const u8 *p, size_t len);
-};
-
-static u32 rand32(void)
-{
-       return prandom_u32_state(&rng);
-}
-
-static u64 rand64(void)
-{
-       u32 n = rand32();
-
-       return ((u64)n << 32) | rand32();
-}
-
-static u64 crc_mask(const struct crc_variant *v)
-{
-       return (u64)-1 >> (64 - v->bits);
-}
-
-/* Reference implementation of any CRC variant */
-static u64 crc_ref(const struct crc_variant *v,
-                  u64 crc, const u8 *p, size_t len)
-{
-       size_t i, j;
-
-       for (i = 0; i < len; i++) {
-               for (j = 0; j < 8; j++) {
-                       if (v->le) {
-                               crc ^= (p[i] >> j) & 1;
-                               crc = (crc >> 1) ^ ((crc & 1) ? v->poly : 0);
-                       } else {
-                               crc ^= (u64)((p[i] >> (7 - j)) & 1) <<
-                                      (v->bits - 1);
-                               if (crc & (1ULL << (v->bits - 1)))
-                                       crc = ((crc << 1) ^ v->poly) &
-                                             crc_mask(v);
-                               else
-                                       crc <<= 1;
-                       }
-               }
-       }
-       return crc;
-}
-
-static int crc_suite_init(struct kunit_suite *suite)
-{
-       /*
-        * Allocate the test buffer using vmalloc() with a page-aligned length
-        * so that it is immediately followed by a guard page.  This allows
-        * buffer overreads to be detected, even in assembly code.
-        */
-       test_buflen = round_up(CRC_KUNIT_MAX_LEN, PAGE_SIZE);
-       test_buffer = vmalloc(test_buflen);
-       if (!test_buffer)
-               return -ENOMEM;
-
-       prandom_seed_state(&rng, CRC_KUNIT_SEED);
-       prandom_bytes_state(&rng, test_buffer, test_buflen);
-       return 0;
-}
-
-static void crc_suite_exit(struct kunit_suite *suite)
-{
-       vfree(test_buffer);
-       test_buffer = NULL;
-}
-
-/* Generate a random initial CRC. */
-static u64 generate_random_initial_crc(const struct crc_variant *v)
-{
-       switch (rand32() % 4) {
-       case 0:
-               return 0;
-       case 1:
-               return crc_mask(v); /* All 1 bits */
-       default:
-               return rand64() & crc_mask(v);
-       }
-}
-
-/* Generate a random length, preferring small lengths. */
-static size_t generate_random_length(size_t max_length)
-{
-       size_t len;
-
-       switch (rand32() % 3) {
-       case 0:
-               len = rand32() % 128;
-               break;
-       case 1:
-               len = rand32() % 3072;
-               break;
-       default:
-               len = rand32();
-               break;
-       }
-       return len % (max_length + 1);
-}
-
-/* Test that v->func gives the same CRCs as a reference implementation. */
-static void crc_test(struct kunit *test, const struct crc_variant *v)
-{
-       size_t i;
-
-       for (i = 0; i < CRC_KUNIT_NUM_TEST_ITERS; i++) {
-               u64 init_crc, expected_crc, actual_crc;
-               size_t len, offset;
-               bool nosimd;
-
-               init_crc = generate_random_initial_crc(v);
-               len = generate_random_length(CRC_KUNIT_MAX_LEN);
-
-               /* Generate a random offset. */
-               if (rand32() % 2 == 0) {
-                       /* Use a random alignment mod 64 */
-                       offset = rand32() % 64;
-                       offset = min(offset, CRC_KUNIT_MAX_LEN - len);
-               } else {
-                       /* Go up to the guard page, to catch buffer overreads */
-                       offset = test_buflen - len;
-               }
-
-               if (rand32() % 8 == 0)
-                       /* Refresh the data occasionally. */
-                       prandom_bytes_state(&rng, &test_buffer[offset], len);
-
-               nosimd = rand32() % 8 == 0;
-
-               /*
-                * Compute the CRC, and verify that it equals the CRC computed
-                * by a simple bit-at-a-time reference implementation.
-                */
-               expected_crc = crc_ref(v, init_crc, &test_buffer[offset], len);
-               if (nosimd)
-                       local_irq_disable();
-               actual_crc = v->func(init_crc, &test_buffer[offset], len);
-               if (nosimd)
-                       local_irq_enable();
-               KUNIT_EXPECT_EQ_MSG(test, expected_crc, actual_crc,
-                                   "Wrong result with len=%zu offset=%zu nosimd=%d",
-                                   len, offset, nosimd);
-       }
-}
-
-static __always_inline void
-crc_benchmark(struct kunit *test,
-             u64 (*crc_func)(u64 crc, const u8 *p, size_t len))
-{
-       static const size_t lens_to_test[] = {
-               1, 16, 64, 127, 128, 200, 256, 511, 512, 1024, 3173, 4096, 16384,
-       };
-       size_t len, i, j, num_iters;
-       /*
-        * The CRC value that this function computes in a series of calls to
-        * crc_func is never actually used, so use volatile to ensure that the
-        * computations are done as intended and don't all get optimized out.
-        */
-       volatile u64 crc = 0;
-       u64 t;
-
-       if (!IS_ENABLED(CONFIG_CRC_BENCHMARK))
-               kunit_skip(test, "not enabled");
-
-       /* warm-up */
-       for (i = 0; i < 10000000; i += CRC_KUNIT_MAX_LEN)
-               crc = crc_func(crc, test_buffer, CRC_KUNIT_MAX_LEN);
-
-       for (i = 0; i < ARRAY_SIZE(lens_to_test); i++) {
-               len = lens_to_test[i];
-               KUNIT_ASSERT_LE(test, len, CRC_KUNIT_MAX_LEN);
-               num_iters = 10000000 / (len + 128);
-               preempt_disable();
-               t = ktime_get_ns();
-               for (j = 0; j < num_iters; j++)
-                       crc = crc_func(crc, test_buffer, len);
-               t = ktime_get_ns() - t;
-               preempt_enable();
-               kunit_info(test, "len=%zu: %llu MB/s\n",
-                          len, div64_u64((u64)len * num_iters * 1000, t));
-       }
-}
-
-/* crc7_be */
-
-static u64 crc7_be_wrapper(u64 crc, const u8 *p, size_t len)
-{
-       /*
-        * crc7_be() left-aligns the 7-bit CRC in a u8, whereas the test wants a
-        * right-aligned CRC (in a u64).  Convert between the conventions.
-        */
-       return crc7_be(crc << 1, p, len) >> 1;
-}
-
-static const struct crc_variant crc_variant_crc7_be = {
-       .bits = 7,
-       .poly = 0x9,
-       .func = crc7_be_wrapper,
-};
-
-static void crc7_be_test(struct kunit *test)
-{
-       crc_test(test, &crc_variant_crc7_be);
-}
-
-static void crc7_be_benchmark(struct kunit *test)
-{
-       crc_benchmark(test, crc7_be_wrapper);
-}
-
-/* crc16 */
-
-static u64 crc16_wrapper(u64 crc, const u8 *p, size_t len)
-{
-       return crc16(crc, p, len);
-}
-
-static const struct crc_variant crc_variant_crc16 = {
-       .bits = 16,
-       .le = true,
-       .poly = 0xa001,
-       .func = crc16_wrapper,
-};
-
-static void crc16_test(struct kunit *test)
-{
-       crc_test(test, &crc_variant_crc16);
-}
-
-static void crc16_benchmark(struct kunit *test)
-{
-       crc_benchmark(test, crc16_wrapper);
-}
-
-/* crc_t10dif */
-
-static u64 crc_t10dif_wrapper(u64 crc, const u8 *p, size_t len)
-{
-       return crc_t10dif_update(crc, p, len);
-}
-
-static const struct crc_variant crc_variant_crc_t10dif = {
-       .bits = 16,
-       .le = false,
-       .poly = 0x8bb7,
-       .func = crc_t10dif_wrapper,
-};
-
-static void crc_t10dif_test(struct kunit *test)
-{
-       crc_test(test, &crc_variant_crc_t10dif);
-}
-
-static void crc_t10dif_benchmark(struct kunit *test)
-{
-       crc_benchmark(test, crc_t10dif_wrapper);
-}
-
-/* crc32_le */
-
-static u64 crc32_le_wrapper(u64 crc, const u8 *p, size_t len)
-{
-       return crc32_le(crc, p, len);
-}
-
-static const struct crc_variant crc_variant_crc32_le = {
-       .bits = 32,
-       .le = true,
-       .poly = 0xedb88320,
-       .func = crc32_le_wrapper,
-};
-
-static void crc32_le_test(struct kunit *test)
-{
-       crc_test(test, &crc_variant_crc32_le);
-}
-
-static void crc32_le_benchmark(struct kunit *test)
-{
-       crc_benchmark(test, crc32_le_wrapper);
-}
-
-/* crc32_be */
-
-static u64 crc32_be_wrapper(u64 crc, const u8 *p, size_t len)
-{
-       return crc32_be(crc, p, len);
-}
-
-static const struct crc_variant crc_variant_crc32_be = {
-       .bits = 32,
-       .le = false,
-       .poly = 0x04c11db7,
-       .func = crc32_be_wrapper,
-};
-
-static void crc32_be_test(struct kunit *test)
-{
-       crc_test(test, &crc_variant_crc32_be);
-}
-
-static void crc32_be_benchmark(struct kunit *test)
-{
-       crc_benchmark(test, crc32_be_wrapper);
-}
-
-/* crc32c */
-
-static u64 crc32c_wrapper(u64 crc, const u8 *p, size_t len)
-{
-       return crc32c(crc, p, len);
-}
-
-static const struct crc_variant crc_variant_crc32c = {
-       .bits = 32,
-       .le = true,
-       .poly = 0x82f63b78,
-       .func = crc32c_wrapper,
-};
-
-static void crc32c_test(struct kunit *test)
-{
-       crc_test(test, &crc_variant_crc32c);
-}
-
-static void crc32c_benchmark(struct kunit *test)
-{
-       crc_benchmark(test, crc32c_wrapper);
-}
-
-/* crc64_be */
-
-static u64 crc64_be_wrapper(u64 crc, const u8 *p, size_t len)
-{
-       return crc64_be(crc, p, len);
-}
-
-static const struct crc_variant crc_variant_crc64_be = {
-       .bits = 64,
-       .le = false,
-       .poly = 0x42f0e1eba9ea3693,
-       .func = crc64_be_wrapper,
-};
-
-static void crc64_be_test(struct kunit *test)
-{
-       crc_test(test, &crc_variant_crc64_be);
-}
-
-static void crc64_be_benchmark(struct kunit *test)
-{
-       crc_benchmark(test, crc64_be_wrapper);
-}
-
-/* crc64_nvme */
-
-static u64 crc64_nvme_wrapper(u64 crc, const u8 *p, size_t len)
-{
-       /* The inversions that crc64_nvme() does have to be undone here. */
-       return ~crc64_nvme(~crc, p, len);
-}
-
-static const struct crc_variant crc_variant_crc64_nvme = {
-       .bits = 64,
-       .le = true,
-       .poly = 0x9a6c9329ac4bc9b5,
-       .func = crc64_nvme_wrapper,
-};
-
-static void crc64_nvme_test(struct kunit *test)
-{
-       crc_test(test, &crc_variant_crc64_nvme);
-}
-
-static void crc64_nvme_benchmark(struct kunit *test)
-{
-       crc_benchmark(test, crc64_nvme_wrapper);
-}
-
-static struct kunit_case crc_test_cases[] = {
-       KUNIT_CASE(crc7_be_test),
-       KUNIT_CASE(crc7_be_benchmark),
-       KUNIT_CASE(crc16_test),
-       KUNIT_CASE(crc16_benchmark),
-       KUNIT_CASE(crc_t10dif_test),
-       KUNIT_CASE(crc_t10dif_benchmark),
-       KUNIT_CASE(crc32_le_test),
-       KUNIT_CASE(crc32_le_benchmark),
-       KUNIT_CASE(crc32_be_test),
-       KUNIT_CASE(crc32_be_benchmark),
-       KUNIT_CASE(crc32c_test),
-       KUNIT_CASE(crc32c_benchmark),
-       KUNIT_CASE(crc64_be_test),
-       KUNIT_CASE(crc64_be_benchmark),
-       KUNIT_CASE(crc64_nvme_test),
-       KUNIT_CASE(crc64_nvme_benchmark),
-       {},
-};
-
-static struct kunit_suite crc_test_suite = {
-       .name = "crc",
-       .test_cases = crc_test_cases,
-       .suite_init = crc_suite_init,
-       .suite_exit = crc_suite_exit,
-};
-kunit_test_suite(crc_test_suite);
-
-MODULE_DESCRIPTION("Unit tests and benchmarks for the CRC library functions");
-MODULE_LICENSE("GPL");