xref: /linux/lib/crc/arm64/crc64.h (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
163432fd6SDemian Shulhan /* SPDX-License-Identifier: GPL-2.0-only */
263432fd6SDemian Shulhan /*
363432fd6SDemian Shulhan  * CRC64 using ARM64 PMULL instructions
463432fd6SDemian Shulhan  */
563432fd6SDemian Shulhan 
663432fd6SDemian Shulhan #include <linux/cpufeature.h>
763432fd6SDemian Shulhan #include <asm/simd.h>
863432fd6SDemian Shulhan #include <linux/minmax.h>
963432fd6SDemian Shulhan #include <linux/sizes.h>
1063432fd6SDemian Shulhan 
1163432fd6SDemian Shulhan u64 crc64_nvme_arm64_c(u64 crc, const u8 *p, size_t len);
1263432fd6SDemian Shulhan 
1363432fd6SDemian Shulhan #define crc64_be_arch crc64_be_generic
1463432fd6SDemian Shulhan 
1563432fd6SDemian Shulhan static inline u64 crc64_nvme_arch(u64 crc, const u8 *p, size_t len)
1663432fd6SDemian Shulhan {
1763432fd6SDemian Shulhan 	if (len >= 128 && cpu_have_named_feature(PMULL) &&
1863432fd6SDemian Shulhan 	    likely(may_use_simd())) {
19*e0718ed6SArd Biesheuvel 		size_t chunk = len & ~15;
2063432fd6SDemian Shulhan 
2163432fd6SDemian Shulhan 		scoped_ksimd()
2263432fd6SDemian Shulhan 			crc = crc64_nvme_arm64_c(crc, p, chunk);
2363432fd6SDemian Shulhan 
2463432fd6SDemian Shulhan 		p += chunk;
25*e0718ed6SArd Biesheuvel 		len &= 15;
2663432fd6SDemian Shulhan 	}
2763432fd6SDemian Shulhan 	return crc64_nvme_generic(crc, p, len);
2863432fd6SDemian Shulhan }
29