Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Normal 64-bit CRC calculation.
0004  *
0005  * This is a basic crc64 implementation following ECMA-182 specification,
0006  * which can be found from,
0007  * https://www.ecma-international.org/publications/standards/Ecma-182.htm
0008  *
0009  * Dr. Ross N. Williams has a great document to introduce the idea of CRC
0010  * algorithm, here the CRC64 code is also inspired by the table-driven
0011  * algorithm and detail example from this paper. This paper can be found
0012  * from,
0013  * http://www.ross.net/crc/download/crc_v3.txt
0014  *
0015  * crc64table[256] is the lookup table of a table-driven 64-bit CRC
0016  * calculation, which is generated by gen_crc64table.c in kernel build
0017  * time. The polynomial of crc64 arithmetic is from ECMA-182 specification
0018  * as well, which is defined as,
0019  *
0020  * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
0021  * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
0022  * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
0023  * x^7 + x^4 + x + 1
0024  *
0025  * crc64rocksoft[256] table is from the Rocksoft specification polynomial
0026  * defined as,
0027  *
0028  * x^64 + x^63 + x^61 + x^59 + x^58 + x^56 + x^55 + x^52 + x^49 + x^48 + x^47 +
0029  * x^46 + x^44 + x^41 + x^37 + x^36 + x^34 + x^32 + x^31 + x^28 + x^26 + x^23 +
0030  * x^22 + x^19 + x^16 + x^13 + x^12 + x^10 + x^9 + x^6 + x^4 + x^3 + 1
0031  *
0032  * Copyright 2018 SUSE Linux.
0033  *   Author: Coly Li <colyli@suse.de>
0034  */
0035 
0036 #include <linux/module.h>
0037 #include <linux/types.h>
0038 #include <linux/crc64.h>
0039 #include "crc64table.h"
0040 
0041 MODULE_DESCRIPTION("CRC64 calculations");
0042 MODULE_LICENSE("GPL v2");
0043 
0044 /**
0045  * crc64_be - Calculate bitwise big-endian ECMA-182 CRC64
0046  * @crc: seed value for computation. 0 or (u64)~0 for a new CRC calculation,
0047  *       or the previous crc64 value if computing incrementally.
0048  * @p: pointer to buffer over which CRC64 is run
0049  * @len: length of buffer @p
0050  */
0051 u64 __pure crc64_be(u64 crc, const void *p, size_t len)
0052 {
0053     size_t i, t;
0054 
0055     const unsigned char *_p = p;
0056 
0057     for (i = 0; i < len; i++) {
0058         t = ((crc >> 56) ^ (*_p++)) & 0xFF;
0059         crc = crc64table[t] ^ (crc << 8);
0060     }
0061 
0062     return crc;
0063 }
0064 EXPORT_SYMBOL_GPL(crc64_be);
0065 
0066 /**
0067  * crc64_rocksoft_generic - Calculate bitwise Rocksoft CRC64
0068  * @crc: seed value for computation. 0 for a new CRC calculation, or the
0069  *   previous crc64 value if computing incrementally.
0070  * @p: pointer to buffer over which CRC64 is run
0071  * @len: length of buffer @p
0072  */
0073 u64 __pure crc64_rocksoft_generic(u64 crc, const void *p, size_t len)
0074 {
0075     const unsigned char *_p = p;
0076     size_t i;
0077 
0078     crc = ~crc;
0079 
0080     for (i = 0; i < len; i++)
0081         crc = (crc >> 8) ^ crc64rocksofttable[(crc & 0xff) ^ *_p++];
0082 
0083     return ~crc;
0084 }
0085 EXPORT_SYMBOL_GPL(crc64_rocksoft_generic);