xref: /linux/arch/x86/lib/crc-t10dif.c (revision 15d90a5e5524532b7456a24f4626cf28c1629c4c)
135984c73SEric Biggers // SPDX-License-Identifier: GPL-2.0-or-later
235984c73SEric Biggers /*
335984c73SEric Biggers  * CRC-T10DIF using [V]PCLMULQDQ instructions
435984c73SEric Biggers  *
535984c73SEric Biggers  * Copyright 2024 Google LLC
635984c73SEric Biggers  */
735984c73SEric Biggers 
835984c73SEric Biggers #include <linux/crc-t10dif.h>
935984c73SEric Biggers #include <linux/module.h>
1035984c73SEric Biggers #include "crc-pclmul-template.h"
1135984c73SEric Biggers 
1235984c73SEric Biggers static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_pclmulqdq);
1335984c73SEric Biggers 
1435984c73SEric Biggers DECLARE_CRC_PCLMUL_FUNCS(crc16_msb, u16);
1535984c73SEric Biggers 
1635984c73SEric Biggers u16 crc_t10dif_arch(u16 crc, const u8 *p, size_t len)
1735984c73SEric Biggers {
1835984c73SEric Biggers 	CRC_PCLMUL(crc, p, len, crc16_msb, crc16_msb_0x8bb7_consts,
1935984c73SEric Biggers 		   have_pclmulqdq);
2035984c73SEric Biggers 	return crc_t10dif_generic(crc, p, len);
2135984c73SEric Biggers }
2235984c73SEric Biggers EXPORT_SYMBOL(crc_t10dif_arch);
2335984c73SEric Biggers 
2435984c73SEric Biggers static int __init crc_t10dif_x86_init(void)
2535984c73SEric Biggers {
2635984c73SEric Biggers 	if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) {
2735984c73SEric Biggers 		static_branch_enable(&have_pclmulqdq);
2835984c73SEric Biggers 		INIT_CRC_PCLMUL(crc16_msb);
2935984c73SEric Biggers 	}
3035984c73SEric Biggers 	return 0;
3135984c73SEric Biggers }
32*648c7fb1SEric Biggers subsys_initcall(crc_t10dif_x86_init);
3335984c73SEric Biggers 
3435984c73SEric Biggers static void __exit crc_t10dif_x86_exit(void)
3535984c73SEric Biggers {
3635984c73SEric Biggers }
3735984c73SEric Biggers module_exit(crc_t10dif_x86_exit);
3835984c73SEric Biggers 
3935984c73SEric Biggers MODULE_DESCRIPTION("CRC-T10DIF using [V]PCLMULQDQ instructions");
4035984c73SEric Biggers MODULE_LICENSE("GPL");
41