2 * Copyright (C) STMicroelectronics SA 2017
3 * Author: Fabien Dessenne <fabien.dessenne@st.com>
4 * License terms: GNU General Public License (GPL), version 2
7 #include <linux/bitrev.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
12 #include <crypto/internal/hash.h>
14 #include <asm/unaligned.h>
16 #define DRIVER_NAME "stm32-crc32"
17 #define CHKSUM_DIGEST_SIZE 4
18 #define CHKSUM_BLOCK_SIZE 1
21 #define CRC_DR 0x00000000
22 #define CRC_CR 0x00000008
23 #define CRC_INIT 0x00000010
24 #define CRC_POL 0x00000014
26 /* Registers values */
27 #define CRC_CR_RESET BIT(0)
28 #define CRC_CR_REVERSE (BIT(7) | BIT(6) | BIT(5))
29 #define CRC_INIT_DEFAULT 0xFFFFFFFF
31 /* Polynomial reversed */
32 #define POLY_CRC32 0xEDB88320
33 #define POLY_CRC32C 0x82F63B78
36 struct list_head list
;
40 u8 pending_data
[sizeof(u32
)];
41 size_t nb_pending_bytes
;
44 struct stm32_crc_list
{
45 struct list_head dev_list
;
46 spinlock_t lock
; /* protect dev_list */
49 static struct stm32_crc_list crc_list
= {
50 .dev_list
= LIST_HEAD_INIT(crc_list
.dev_list
),
51 .lock
= __SPIN_LOCK_UNLOCKED(crc_list
.lock
),
54 struct stm32_crc_ctx
{
59 struct stm32_crc_desc_ctx
{
60 u32 partial
; /* crc32c: partial in first 4 bytes of that struct */
61 struct stm32_crc
*crc
;
64 static int stm32_crc32_cra_init(struct crypto_tfm
*tfm
)
66 struct stm32_crc_ctx
*mctx
= crypto_tfm_ctx(tfm
);
68 mctx
->key
= CRC_INIT_DEFAULT
;
69 mctx
->poly
= POLY_CRC32
;
73 static int stm32_crc32c_cra_init(struct crypto_tfm
*tfm
)
75 struct stm32_crc_ctx
*mctx
= crypto_tfm_ctx(tfm
);
77 mctx
->key
= CRC_INIT_DEFAULT
;
78 mctx
->poly
= POLY_CRC32C
;
82 static int stm32_crc_setkey(struct crypto_shash
*tfm
, const u8
*key
,
85 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(tfm
);
87 if (keylen
!= sizeof(u32
)) {
88 crypto_shash_set_flags(tfm
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
92 mctx
->key
= get_unaligned_le32(key
);
96 static int stm32_crc_init(struct shash_desc
*desc
)
98 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
99 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(desc
->tfm
);
100 struct stm32_crc
*crc
;
102 spin_lock_bh(&crc_list
.lock
);
103 list_for_each_entry(crc
, &crc_list
.dev_list
, list
) {
107 spin_unlock_bh(&crc_list
.lock
);
109 /* Reset, set key, poly and configure in bit reverse mode */
110 writel_relaxed(bitrev32(mctx
->key
), ctx
->crc
->regs
+ CRC_INIT
);
111 writel_relaxed(bitrev32(mctx
->poly
), ctx
->crc
->regs
+ CRC_POL
);
112 writel_relaxed(CRC_CR_RESET
| CRC_CR_REVERSE
, ctx
->crc
->regs
+ CRC_CR
);
114 /* Store partial result */
115 ctx
->partial
= readl_relaxed(ctx
->crc
->regs
+ CRC_DR
);
116 ctx
->crc
->nb_pending_bytes
= 0;
121 static int stm32_crc_update(struct shash_desc
*desc
, const u8
*d8
,
124 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
125 struct stm32_crc
*crc
= ctx
->crc
;
129 if (unlikely(crc
->nb_pending_bytes
)) {
130 while (crc
->nb_pending_bytes
!= sizeof(u32
) && length
) {
131 /* Fill in pending data */
132 crc
->pending_data
[crc
->nb_pending_bytes
++] = *(d8
++);
136 if (crc
->nb_pending_bytes
== sizeof(u32
)) {
137 /* Process completed pending data */
138 writel_relaxed(*(u32
*)crc
->pending_data
,
140 crc
->nb_pending_bytes
= 0;
145 for (i
= 0; i
< length
>> 2; i
++)
146 /* Process 32 bits data */
147 writel_relaxed(*(d32
++), crc
->regs
+ CRC_DR
);
149 /* Store partial result */
150 ctx
->partial
= readl_relaxed(crc
->regs
+ CRC_DR
);
152 /* Check for pending data (non 32 bits) */
157 if ((crc
->nb_pending_bytes
+ length
) >= sizeof(u32
)) {
158 /* Shall not happen */
159 dev_err(crc
->dev
, "Pending data overflow\n");
163 d8
= (const u8
*)d32
;
164 for (i
= 0; i
< length
; i
++)
165 /* Store pending data */
166 crc
->pending_data
[crc
->nb_pending_bytes
++] = *(d8
++);
171 static int stm32_crc_final(struct shash_desc
*desc
, u8
*out
)
173 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
174 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(desc
->tfm
);
176 /* Send computed CRC */
177 put_unaligned_le32(mctx
->poly
== POLY_CRC32C
?
178 ~ctx
->partial
: ctx
->partial
, out
);
183 static int stm32_crc_finup(struct shash_desc
*desc
, const u8
*data
,
184 unsigned int length
, u8
*out
)
186 return stm32_crc_update(desc
, data
, length
) ?:
187 stm32_crc_final(desc
, out
);
190 static int stm32_crc_digest(struct shash_desc
*desc
, const u8
*data
,
191 unsigned int length
, u8
*out
)
193 return stm32_crc_init(desc
) ?: stm32_crc_finup(desc
, data
, length
, out
);
196 static struct shash_alg algs
[] = {
199 .setkey
= stm32_crc_setkey
,
200 .init
= stm32_crc_init
,
201 .update
= stm32_crc_update
,
202 .final
= stm32_crc_final
,
203 .finup
= stm32_crc_finup
,
204 .digest
= stm32_crc_digest
,
205 .descsize
= sizeof(struct stm32_crc_desc_ctx
),
206 .digestsize
= CHKSUM_DIGEST_SIZE
,
209 .cra_driver_name
= DRIVER_NAME
,
211 .cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
212 .cra_blocksize
= CHKSUM_BLOCK_SIZE
,
214 .cra_ctxsize
= sizeof(struct stm32_crc_ctx
),
215 .cra_module
= THIS_MODULE
,
216 .cra_init
= stm32_crc32_cra_init
,
219 /* CRC-32Castagnoli */
221 .setkey
= stm32_crc_setkey
,
222 .init
= stm32_crc_init
,
223 .update
= stm32_crc_update
,
224 .final
= stm32_crc_final
,
225 .finup
= stm32_crc_finup
,
226 .digest
= stm32_crc_digest
,
227 .descsize
= sizeof(struct stm32_crc_desc_ctx
),
228 .digestsize
= CHKSUM_DIGEST_SIZE
,
230 .cra_name
= "crc32c",
231 .cra_driver_name
= DRIVER_NAME
,
233 .cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
234 .cra_blocksize
= CHKSUM_BLOCK_SIZE
,
236 .cra_ctxsize
= sizeof(struct stm32_crc_ctx
),
237 .cra_module
= THIS_MODULE
,
238 .cra_init
= stm32_crc32c_cra_init
,
243 static int stm32_crc_probe(struct platform_device
*pdev
)
245 struct device
*dev
= &pdev
->dev
;
246 struct stm32_crc
*crc
;
247 struct resource
*res
;
250 crc
= devm_kzalloc(dev
, sizeof(*crc
), GFP_KERNEL
);
256 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
257 crc
->regs
= devm_ioremap_resource(dev
, res
);
258 if (IS_ERR(crc
->regs
)) {
259 dev_err(dev
, "Cannot map CRC IO\n");
260 return PTR_ERR(crc
->regs
);
263 crc
->clk
= devm_clk_get(dev
, NULL
);
264 if (IS_ERR(crc
->clk
)) {
265 dev_err(dev
, "Could not get clock\n");
266 return PTR_ERR(crc
->clk
);
269 ret
= clk_prepare_enable(crc
->clk
);
271 dev_err(crc
->dev
, "Failed to enable clock\n");
275 platform_set_drvdata(pdev
, crc
);
277 spin_lock(&crc_list
.lock
);
278 list_add(&crc
->list
, &crc_list
.dev_list
);
279 spin_unlock(&crc_list
.lock
);
281 ret
= crypto_register_shashes(algs
, ARRAY_SIZE(algs
));
283 dev_err(dev
, "Failed to register\n");
284 clk_disable_unprepare(crc
->clk
);
288 dev_info(dev
, "Initialized\n");
293 static int stm32_crc_remove(struct platform_device
*pdev
)
295 struct stm32_crc
*crc
= platform_get_drvdata(pdev
);
297 spin_lock(&crc_list
.lock
);
298 list_del(&crc
->list
);
299 spin_unlock(&crc_list
.lock
);
301 crypto_unregister_shashes(algs
, ARRAY_SIZE(algs
));
303 clk_disable_unprepare(crc
->clk
);
308 static const struct of_device_id stm32_dt_ids
[] = {
309 { .compatible
= "st,stm32f7-crc", },
312 MODULE_DEVICE_TABLE(of
, stm32_dt_ids
);
314 static struct platform_driver stm32_crc_driver
= {
315 .probe
= stm32_crc_probe
,
316 .remove
= stm32_crc_remove
,
319 .of_match_table
= stm32_dt_ids
,
323 module_platform_driver(stm32_crc_driver
);
325 MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
326 MODULE_DESCRIPTION("STMicrolectronics STM32 CRC32 hardware driver");
327 MODULE_LICENSE("GPL");