xref: /linux/drivers/crypto/stm32/stm32-cryp.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1af873fceSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29e054ec2SFabien DESSENNE /*
39e054ec2SFabien DESSENNE  * Copyright (C) STMicroelectronics SA 2017
49e054ec2SFabien DESSENNE  * Author: Fabien Dessenne <fabien.dessenne@st.com>
50b496efbSLinus Walleij  * Ux500 support taken from snippets in the old Ux500 cryp driver
69e054ec2SFabien DESSENNE  */
79e054ec2SFabien DESSENNE 
8d5e6b48fSHerbert Xu #include <crypto/aes.h>
9d5e6b48fSHerbert Xu #include <crypto/engine.h>
10d5e6b48fSHerbert Xu #include <crypto/internal/aead.h>
11d5e6b48fSHerbert Xu #include <crypto/internal/des.h>
12d5e6b48fSHerbert Xu #include <crypto/internal/skcipher.h>
13d5e6b48fSHerbert Xu #include <crypto/scatterwalk.h>
14*56ddb9aaSMaxime Méré #include <linux/bottom_half.h>
159e054ec2SFabien DESSENNE #include <linux/clk.h>
169e054ec2SFabien DESSENNE #include <linux/delay.h>
17fb11a4f6SMaxime Méré #include <linux/dma-mapping.h>
18fb11a4f6SMaxime Méré #include <linux/dmaengine.h>
19d5e6b48fSHerbert Xu #include <linux/err.h>
209e054ec2SFabien DESSENNE #include <linux/iopoll.h>
21d5e6b48fSHerbert Xu #include <linux/interrupt.h>
22d5e6b48fSHerbert Xu #include <linux/kernel.h>
239e054ec2SFabien DESSENNE #include <linux/module.h>
24b0cc7491SRob Herring #include <linux/of.h>
259e054ec2SFabien DESSENNE #include <linux/platform_device.h>
2665f9aa36Slionel.debieve@st.com #include <linux/pm_runtime.h>
279e054ec2SFabien DESSENNE #include <linux/reset.h>
28d5e6b48fSHerbert Xu #include <linux/string.h>
299e054ec2SFabien DESSENNE 
309e054ec2SFabien DESSENNE #define DRIVER_NAME             "stm32-cryp"
319e054ec2SFabien DESSENNE 
329e054ec2SFabien DESSENNE /* Bit [0] encrypt / decrypt */
339e054ec2SFabien DESSENNE #define FLG_ENCRYPT             BIT(0)
349e054ec2SFabien DESSENNE /* Bit [8..1] algo & operation mode */
359e054ec2SFabien DESSENNE #define FLG_AES                 BIT(1)
369e054ec2SFabien DESSENNE #define FLG_DES                 BIT(2)
379e054ec2SFabien DESSENNE #define FLG_TDES                BIT(3)
389e054ec2SFabien DESSENNE #define FLG_ECB                 BIT(4)
399e054ec2SFabien DESSENNE #define FLG_CBC                 BIT(5)
409e054ec2SFabien DESSENNE #define FLG_CTR                 BIT(6)
419d3b5030SFabien DESSENNE #define FLG_GCM                 BIT(7)
429d3b5030SFabien DESSENNE #define FLG_CCM                 BIT(8)
439e054ec2SFabien DESSENNE /* Mode mask = bits [15..0] */
449e054ec2SFabien DESSENNE #define FLG_MODE_MASK           GENMASK(15, 0)
459d3b5030SFabien DESSENNE /* Bit [31..16] status  */
46fb11a4f6SMaxime Méré #define FLG_IN_OUT_DMA          BIT(16)
47fb11a4f6SMaxime Méré #define FLG_HEADER_DMA          BIT(17)
489e054ec2SFabien DESSENNE 
499e054ec2SFabien DESSENNE /* Registers */
509e054ec2SFabien DESSENNE #define CRYP_CR                 0x00000000
519e054ec2SFabien DESSENNE #define CRYP_SR                 0x00000004
529e054ec2SFabien DESSENNE #define CRYP_DIN                0x00000008
539e054ec2SFabien DESSENNE #define CRYP_DOUT               0x0000000C
549e054ec2SFabien DESSENNE #define CRYP_DMACR              0x00000010
559e054ec2SFabien DESSENNE #define CRYP_IMSCR              0x00000014
569e054ec2SFabien DESSENNE #define CRYP_RISR               0x00000018
579e054ec2SFabien DESSENNE #define CRYP_MISR               0x0000001C
589e054ec2SFabien DESSENNE #define CRYP_K0LR               0x00000020
599e054ec2SFabien DESSENNE #define CRYP_K0RR               0x00000024
609e054ec2SFabien DESSENNE #define CRYP_K1LR               0x00000028
619e054ec2SFabien DESSENNE #define CRYP_K1RR               0x0000002C
629e054ec2SFabien DESSENNE #define CRYP_K2LR               0x00000030
639e054ec2SFabien DESSENNE #define CRYP_K2RR               0x00000034
649e054ec2SFabien DESSENNE #define CRYP_K3LR               0x00000038
659e054ec2SFabien DESSENNE #define CRYP_K3RR               0x0000003C
669e054ec2SFabien DESSENNE #define CRYP_IV0LR              0x00000040
679e054ec2SFabien DESSENNE #define CRYP_IV0RR              0x00000044
689e054ec2SFabien DESSENNE #define CRYP_IV1LR              0x00000048
699e054ec2SFabien DESSENNE #define CRYP_IV1RR              0x0000004C
709d3b5030SFabien DESSENNE #define CRYP_CSGCMCCM0R         0x00000050
719d3b5030SFabien DESSENNE #define CRYP_CSGCM0R            0x00000070
729e054ec2SFabien DESSENNE 
730b496efbSLinus Walleij #define UX500_CRYP_CR		0x00000000
740b496efbSLinus Walleij #define UX500_CRYP_SR		0x00000004
750b496efbSLinus Walleij #define UX500_CRYP_DIN		0x00000008
760b496efbSLinus Walleij #define UX500_CRYP_DINSIZE	0x0000000C
770b496efbSLinus Walleij #define UX500_CRYP_DOUT		0x00000010
780b496efbSLinus Walleij #define UX500_CRYP_DOUSIZE	0x00000014
790b496efbSLinus Walleij #define UX500_CRYP_DMACR	0x00000018
800b496efbSLinus Walleij #define UX500_CRYP_IMSC		0x0000001C
810b496efbSLinus Walleij #define UX500_CRYP_RIS		0x00000020
820b496efbSLinus Walleij #define UX500_CRYP_MIS		0x00000024
830b496efbSLinus Walleij #define UX500_CRYP_K1L		0x00000028
840b496efbSLinus Walleij #define UX500_CRYP_K1R		0x0000002C
850b496efbSLinus Walleij #define UX500_CRYP_K2L		0x00000030
860b496efbSLinus Walleij #define UX500_CRYP_K2R		0x00000034
870b496efbSLinus Walleij #define UX500_CRYP_K3L		0x00000038
880b496efbSLinus Walleij #define UX500_CRYP_K3R		0x0000003C
890b496efbSLinus Walleij #define UX500_CRYP_K4L		0x00000040
900b496efbSLinus Walleij #define UX500_CRYP_K4R		0x00000044
910b496efbSLinus Walleij #define UX500_CRYP_IV0L		0x00000048
920b496efbSLinus Walleij #define UX500_CRYP_IV0R		0x0000004C
930b496efbSLinus Walleij #define UX500_CRYP_IV1L		0x00000050
940b496efbSLinus Walleij #define UX500_CRYP_IV1R		0x00000054
950b496efbSLinus Walleij 
969e054ec2SFabien DESSENNE /* Registers values */
979e054ec2SFabien DESSENNE #define CR_DEC_NOT_ENC          0x00000004
989e054ec2SFabien DESSENNE #define CR_TDES_ECB             0x00000000
999e054ec2SFabien DESSENNE #define CR_TDES_CBC             0x00000008
1009e054ec2SFabien DESSENNE #define CR_DES_ECB              0x00000010
1019e054ec2SFabien DESSENNE #define CR_DES_CBC              0x00000018
1029e054ec2SFabien DESSENNE #define CR_AES_ECB              0x00000020
1039e054ec2SFabien DESSENNE #define CR_AES_CBC              0x00000028
1049e054ec2SFabien DESSENNE #define CR_AES_CTR              0x00000030
1050b496efbSLinus Walleij #define CR_AES_KP               0x00000038 /* Not on Ux500 */
1060b496efbSLinus Walleij #define CR_AES_XTS              0x00000038 /* Only on Ux500 */
1079d3b5030SFabien DESSENNE #define CR_AES_GCM              0x00080000
1089d3b5030SFabien DESSENNE #define CR_AES_CCM              0x00080008
1099e054ec2SFabien DESSENNE #define CR_AES_UNKNOWN          0xFFFFFFFF
1109e054ec2SFabien DESSENNE #define CR_ALGO_MASK            0x00080038
1119e054ec2SFabien DESSENNE #define CR_DATA32               0x00000000
1129e054ec2SFabien DESSENNE #define CR_DATA16               0x00000040
1139e054ec2SFabien DESSENNE #define CR_DATA8                0x00000080
1149e054ec2SFabien DESSENNE #define CR_DATA1                0x000000C0
1159e054ec2SFabien DESSENNE #define CR_KEY128               0x00000000
1169e054ec2SFabien DESSENNE #define CR_KEY192               0x00000100
1179e054ec2SFabien DESSENNE #define CR_KEY256               0x00000200
1180b496efbSLinus Walleij #define CR_KEYRDEN              0x00000400 /* Only on Ux500 */
1190b496efbSLinus Walleij #define CR_KSE                  0x00000800 /* Only on Ux500 */
1209e054ec2SFabien DESSENNE #define CR_FFLUSH               0x00004000
1219e054ec2SFabien DESSENNE #define CR_CRYPEN               0x00008000
1229d3b5030SFabien DESSENNE #define CR_PH_INIT              0x00000000
1239d3b5030SFabien DESSENNE #define CR_PH_HEADER            0x00010000
1249d3b5030SFabien DESSENNE #define CR_PH_PAYLOAD           0x00020000
1259d3b5030SFabien DESSENNE #define CR_PH_FINAL             0x00030000
1269d3b5030SFabien DESSENNE #define CR_PH_MASK              0x00030000
1279d3b5030SFabien DESSENNE #define CR_NBPBL_SHIFT          20
1289e054ec2SFabien DESSENNE 
129fb11a4f6SMaxime Méré #define SR_IFNF                 BIT(1)
130fb11a4f6SMaxime Méré #define SR_OFNE                 BIT(2)
131fb11a4f6SMaxime Méré #define SR_BUSY                 BIT(8)
132fb11a4f6SMaxime Méré 
133fb11a4f6SMaxime Méré #define DMACR_DIEN              BIT(0)
134fb11a4f6SMaxime Méré #define DMACR_DOEN              BIT(1)
1359e054ec2SFabien DESSENNE 
1369e054ec2SFabien DESSENNE #define IMSCR_IN                BIT(0)
1379e054ec2SFabien DESSENNE #define IMSCR_OUT               BIT(1)
1389e054ec2SFabien DESSENNE 
1399e054ec2SFabien DESSENNE #define MISR_IN                 BIT(0)
1409e054ec2SFabien DESSENNE #define MISR_OUT                BIT(1)
1419e054ec2SFabien DESSENNE 
1429e054ec2SFabien DESSENNE /* Misc */
1439e054ec2SFabien DESSENNE #define AES_BLOCK_32            (AES_BLOCK_SIZE / sizeof(u32))
1449d3b5030SFabien DESSENNE #define GCM_CTR_INIT            2
14565f9aa36Slionel.debieve@st.com #define CRYP_AUTOSUSPEND_DELAY  50
1469e054ec2SFabien DESSENNE 
147fb11a4f6SMaxime Méré #define CRYP_DMA_BURST_REG      4
148fb11a4f6SMaxime Méré 
149fb11a4f6SMaxime Méré enum stm32_dma_mode {
150fb11a4f6SMaxime Méré 	NO_DMA,
151fb11a4f6SMaxime Méré 	DMA_PLAIN_SG,
152fb11a4f6SMaxime Méré 	DMA_NEED_SG_TRUNC
153fb11a4f6SMaxime Méré };
154fb11a4f6SMaxime Méré 
1559d3b5030SFabien DESSENNE struct stm32_cryp_caps {
1560b496efbSLinus Walleij 	bool			aeads_support;
1570b496efbSLinus Walleij 	bool			linear_aes_key;
1580b496efbSLinus Walleij 	bool			kp_mode;
1590b496efbSLinus Walleij 	bool			iv_protection;
1609d3b5030SFabien DESSENNE 	bool			swap_final;
1619d3b5030SFabien DESSENNE 	bool			padding_wa;
1620b496efbSLinus Walleij 	u32			cr;
1630b496efbSLinus Walleij 	u32			sr;
1640b496efbSLinus Walleij 	u32			din;
1650b496efbSLinus Walleij 	u32			dout;
166fb11a4f6SMaxime Méré 	u32			dmacr;
1670b496efbSLinus Walleij 	u32			imsc;
1680b496efbSLinus Walleij 	u32			mis;
1690b496efbSLinus Walleij 	u32			k1l;
1700b496efbSLinus Walleij 	u32			k1r;
1710b496efbSLinus Walleij 	u32			k3r;
1720b496efbSLinus Walleij 	u32			iv0l;
1730b496efbSLinus Walleij 	u32			iv0r;
1740b496efbSLinus Walleij 	u32			iv1l;
1750b496efbSLinus Walleij 	u32			iv1r;
1769d3b5030SFabien DESSENNE };
1779d3b5030SFabien DESSENNE 
1789e054ec2SFabien DESSENNE struct stm32_cryp_ctx {
1799e054ec2SFabien DESSENNE 	struct stm32_cryp       *cryp;
1809e054ec2SFabien DESSENNE 	int                     keylen;
181bbb28326SHerbert Xu 	__be32                  key[AES_KEYSIZE_256 / sizeof(u32)];
1829e054ec2SFabien DESSENNE 	unsigned long           flags;
1839e054ec2SFabien DESSENNE };
1849e054ec2SFabien DESSENNE 
1859e054ec2SFabien DESSENNE struct stm32_cryp_reqctx {
1869e054ec2SFabien DESSENNE 	unsigned long mode;
1879e054ec2SFabien DESSENNE };
1889e054ec2SFabien DESSENNE 
1899e054ec2SFabien DESSENNE struct stm32_cryp {
1909e054ec2SFabien DESSENNE 	struct list_head        list;
1919e054ec2SFabien DESSENNE 	struct device           *dev;
1929e054ec2SFabien DESSENNE 	void __iomem            *regs;
193fb11a4f6SMaxime Méré 	phys_addr_t             phys_base;
1949e054ec2SFabien DESSENNE 	struct clk              *clk;
1959e054ec2SFabien DESSENNE 	unsigned long           flags;
1969e054ec2SFabien DESSENNE 	u32                     irq_status;
1979d3b5030SFabien DESSENNE 	const struct stm32_cryp_caps *caps;
1989e054ec2SFabien DESSENNE 	struct stm32_cryp_ctx   *ctx;
1999e054ec2SFabien DESSENNE 
2009e054ec2SFabien DESSENNE 	struct crypto_engine    *engine;
2019e054ec2SFabien DESSENNE 
20247ece481SArd Biesheuvel 	struct skcipher_request *req;
2039d3b5030SFabien DESSENNE 	struct aead_request     *areq;
2049e054ec2SFabien DESSENNE 
2059d3b5030SFabien DESSENNE 	size_t                  authsize;
2069e054ec2SFabien DESSENNE 	size_t                  hw_blocksize;
2079e054ec2SFabien DESSENNE 
2084b898d5cSNicolas Toromanoff 	size_t                  payload_in;
2094b898d5cSNicolas Toromanoff 	size_t                  header_in;
2104b898d5cSNicolas Toromanoff 	size_t                  payload_out;
2119e054ec2SFabien DESSENNE 
212fb11a4f6SMaxime Méré 	/* DMA process fields */
213fb11a4f6SMaxime Méré 	struct scatterlist      *in_sg;
214fb11a4f6SMaxime Méré 	struct scatterlist      *header_sg;
2159e054ec2SFabien DESSENNE 	struct scatterlist      *out_sg;
216fb11a4f6SMaxime Méré 	size_t                  in_sg_len;
217fb11a4f6SMaxime Méré 	size_t                  header_sg_len;
218fb11a4f6SMaxime Méré 	size_t                  out_sg_len;
219fb11a4f6SMaxime Méré 	struct completion	dma_completion;
2209e054ec2SFabien DESSENNE 
221fb11a4f6SMaxime Méré 	struct dma_chan         *dma_lch_in;
222fb11a4f6SMaxime Méré 	struct dma_chan         *dma_lch_out;
223fb11a4f6SMaxime Méré 	enum stm32_dma_mode     dma_mode;
224fb11a4f6SMaxime Méré 
225fb11a4f6SMaxime Méré 	/* IT process fields */
2269e054ec2SFabien DESSENNE 	struct scatter_walk     in_walk;
2279e054ec2SFabien DESSENNE 	struct scatter_walk     out_walk;
2289e054ec2SFabien DESSENNE 
22941c76690SNicolas Toromanoff 	__be32                  last_ctr[4];
2309d3b5030SFabien DESSENNE 	u32                     gcm_ctr;
2319e054ec2SFabien DESSENNE };
2329e054ec2SFabien DESSENNE 
2339e054ec2SFabien DESSENNE struct stm32_cryp_list {
2349e054ec2SFabien DESSENNE 	struct list_head        dev_list;
2359e054ec2SFabien DESSENNE 	spinlock_t              lock; /* protect dev_list */
2369e054ec2SFabien DESSENNE };
2379e054ec2SFabien DESSENNE 
2389e054ec2SFabien DESSENNE static struct stm32_cryp_list cryp_list = {
2399e054ec2SFabien DESSENNE 	.dev_list = LIST_HEAD_INIT(cryp_list.dev_list),
2409e054ec2SFabien DESSENNE 	.lock     = __SPIN_LOCK_UNLOCKED(cryp_list.lock),
2419e054ec2SFabien DESSENNE };
2429e054ec2SFabien DESSENNE 
is_aes(struct stm32_cryp * cryp)2439e054ec2SFabien DESSENNE static inline bool is_aes(struct stm32_cryp *cryp)
2449e054ec2SFabien DESSENNE {
2459e054ec2SFabien DESSENNE 	return cryp->flags & FLG_AES;
2469e054ec2SFabien DESSENNE }
2479e054ec2SFabien DESSENNE 
is_des(struct stm32_cryp * cryp)2489e054ec2SFabien DESSENNE static inline bool is_des(struct stm32_cryp *cryp)
2499e054ec2SFabien DESSENNE {
2509e054ec2SFabien DESSENNE 	return cryp->flags & FLG_DES;
2519e054ec2SFabien DESSENNE }
2529e054ec2SFabien DESSENNE 
is_tdes(struct stm32_cryp * cryp)2539e054ec2SFabien DESSENNE static inline bool is_tdes(struct stm32_cryp *cryp)
2549e054ec2SFabien DESSENNE {
2559e054ec2SFabien DESSENNE 	return cryp->flags & FLG_TDES;
2569e054ec2SFabien DESSENNE }
2579e054ec2SFabien DESSENNE 
is_ecb(struct stm32_cryp * cryp)2589e054ec2SFabien DESSENNE static inline bool is_ecb(struct stm32_cryp *cryp)
2599e054ec2SFabien DESSENNE {
2609e054ec2SFabien DESSENNE 	return cryp->flags & FLG_ECB;
2619e054ec2SFabien DESSENNE }
2629e054ec2SFabien DESSENNE 
is_cbc(struct stm32_cryp * cryp)2639e054ec2SFabien DESSENNE static inline bool is_cbc(struct stm32_cryp *cryp)
2649e054ec2SFabien DESSENNE {
2659e054ec2SFabien DESSENNE 	return cryp->flags & FLG_CBC;
2669e054ec2SFabien DESSENNE }
2679e054ec2SFabien DESSENNE 
is_ctr(struct stm32_cryp * cryp)2689e054ec2SFabien DESSENNE static inline bool is_ctr(struct stm32_cryp *cryp)
2699e054ec2SFabien DESSENNE {
2709e054ec2SFabien DESSENNE 	return cryp->flags & FLG_CTR;
2719e054ec2SFabien DESSENNE }
2729e054ec2SFabien DESSENNE 
is_gcm(struct stm32_cryp * cryp)2739d3b5030SFabien DESSENNE static inline bool is_gcm(struct stm32_cryp *cryp)
2749d3b5030SFabien DESSENNE {
2759d3b5030SFabien DESSENNE 	return cryp->flags & FLG_GCM;
2769d3b5030SFabien DESSENNE }
2779d3b5030SFabien DESSENNE 
is_ccm(struct stm32_cryp * cryp)2789d3b5030SFabien DESSENNE static inline bool is_ccm(struct stm32_cryp *cryp)
2799d3b5030SFabien DESSENNE {
2809d3b5030SFabien DESSENNE 	return cryp->flags & FLG_CCM;
2819d3b5030SFabien DESSENNE }
2829d3b5030SFabien DESSENNE 
is_encrypt(struct stm32_cryp * cryp)2839e054ec2SFabien DESSENNE static inline bool is_encrypt(struct stm32_cryp *cryp)
2849e054ec2SFabien DESSENNE {
2859e054ec2SFabien DESSENNE 	return cryp->flags & FLG_ENCRYPT;
2869e054ec2SFabien DESSENNE }
2879e054ec2SFabien DESSENNE 
is_decrypt(struct stm32_cryp * cryp)2889e054ec2SFabien DESSENNE static inline bool is_decrypt(struct stm32_cryp *cryp)
2899e054ec2SFabien DESSENNE {
2909e054ec2SFabien DESSENNE 	return !is_encrypt(cryp);
2919e054ec2SFabien DESSENNE }
2929e054ec2SFabien DESSENNE 
stm32_cryp_read(struct stm32_cryp * cryp,u32 ofst)2939e054ec2SFabien DESSENNE static inline u32 stm32_cryp_read(struct stm32_cryp *cryp, u32 ofst)
2949e054ec2SFabien DESSENNE {
2959e054ec2SFabien DESSENNE 	return readl_relaxed(cryp->regs + ofst);
2969e054ec2SFabien DESSENNE }
2979e054ec2SFabien DESSENNE 
stm32_cryp_write(struct stm32_cryp * cryp,u32 ofst,u32 val)2989e054ec2SFabien DESSENNE static inline void stm32_cryp_write(struct stm32_cryp *cryp, u32 ofst, u32 val)
2999e054ec2SFabien DESSENNE {
3009e054ec2SFabien DESSENNE 	writel_relaxed(val, cryp->regs + ofst);
3019e054ec2SFabien DESSENNE }
3029e054ec2SFabien DESSENNE 
stm32_cryp_wait_busy(struct stm32_cryp * cryp)3039e054ec2SFabien DESSENNE static inline int stm32_cryp_wait_busy(struct stm32_cryp *cryp)
3049e054ec2SFabien DESSENNE {
3059e054ec2SFabien DESSENNE 	u32 status;
3069e054ec2SFabien DESSENNE 
3070b496efbSLinus Walleij 	return readl_relaxed_poll_timeout(cryp->regs + cryp->caps->sr, status,
3089e054ec2SFabien DESSENNE 			!(status & SR_BUSY), 10, 100000);
3099e054ec2SFabien DESSENNE }
3109e054ec2SFabien DESSENNE 
stm32_cryp_enable(struct stm32_cryp * cryp)31195fe2253SNicolas Toromanoff static inline void stm32_cryp_enable(struct stm32_cryp *cryp)
31295fe2253SNicolas Toromanoff {
3130b496efbSLinus Walleij 	writel_relaxed(readl_relaxed(cryp->regs + cryp->caps->cr) | CR_CRYPEN,
3140b496efbSLinus Walleij 		       cryp->regs + cryp->caps->cr);
31595fe2253SNicolas Toromanoff }
31695fe2253SNicolas Toromanoff 
stm32_cryp_wait_enable(struct stm32_cryp * cryp)3179d3b5030SFabien DESSENNE static inline int stm32_cryp_wait_enable(struct stm32_cryp *cryp)
3189d3b5030SFabien DESSENNE {
3199d3b5030SFabien DESSENNE 	u32 status;
3209d3b5030SFabien DESSENNE 
3210b496efbSLinus Walleij 	return readl_relaxed_poll_timeout(cryp->regs + cryp->caps->cr, status,
3229d3b5030SFabien DESSENNE 			!(status & CR_CRYPEN), 10, 100000);
3239d3b5030SFabien DESSENNE }
3249d3b5030SFabien DESSENNE 
stm32_cryp_wait_input(struct stm32_cryp * cryp)325fb11a4f6SMaxime Méré static inline int stm32_cryp_wait_input(struct stm32_cryp *cryp)
326fb11a4f6SMaxime Méré {
327fb11a4f6SMaxime Méré 	u32 status;
328fb11a4f6SMaxime Méré 
329fb11a4f6SMaxime Méré 	return readl_relaxed_poll_timeout_atomic(cryp->regs + cryp->caps->sr, status,
330fb11a4f6SMaxime Méré 			status & SR_IFNF, 1, 10);
331fb11a4f6SMaxime Méré }
332fb11a4f6SMaxime Méré 
stm32_cryp_wait_output(struct stm32_cryp * cryp)3339d3b5030SFabien DESSENNE static inline int stm32_cryp_wait_output(struct stm32_cryp *cryp)
3349d3b5030SFabien DESSENNE {
3359d3b5030SFabien DESSENNE 	u32 status;
3369d3b5030SFabien DESSENNE 
337fb11a4f6SMaxime Méré 	return readl_relaxed_poll_timeout_atomic(cryp->regs + cryp->caps->sr, status,
338fb11a4f6SMaxime Méré 			status & SR_OFNE, 1, 10);
3399d3b5030SFabien DESSENNE }
3409d3b5030SFabien DESSENNE 
stm32_cryp_key_read_enable(struct stm32_cryp * cryp)3410b496efbSLinus Walleij static inline void stm32_cryp_key_read_enable(struct stm32_cryp *cryp)
3420b496efbSLinus Walleij {
3430b496efbSLinus Walleij 	writel_relaxed(readl_relaxed(cryp->regs + cryp->caps->cr) | CR_KEYRDEN,
3440b496efbSLinus Walleij 		       cryp->regs + cryp->caps->cr);
3450b496efbSLinus Walleij }
3460b496efbSLinus Walleij 
stm32_cryp_key_read_disable(struct stm32_cryp * cryp)3470b496efbSLinus Walleij static inline void stm32_cryp_key_read_disable(struct stm32_cryp *cryp)
3480b496efbSLinus Walleij {
3490b496efbSLinus Walleij 	writel_relaxed(readl_relaxed(cryp->regs + cryp->caps->cr) & ~CR_KEYRDEN,
3500b496efbSLinus Walleij 		       cryp->regs + cryp->caps->cr);
3510b496efbSLinus Walleij }
3520b496efbSLinus Walleij 
353fb11a4f6SMaxime Méré static void stm32_cryp_irq_read_data(struct stm32_cryp *cryp);
354fb11a4f6SMaxime Méré static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp);
355fb11a4f6SMaxime Méré static void stm32_cryp_irq_write_gcmccm_header(struct stm32_cryp *cryp);
3569d3b5030SFabien DESSENNE static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp);
3574b898d5cSNicolas Toromanoff static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err);
358fb11a4f6SMaxime Méré static int stm32_cryp_dma_start(struct stm32_cryp *cryp);
359fb11a4f6SMaxime Méré static int stm32_cryp_it_start(struct stm32_cryp *cryp);
3609d3b5030SFabien DESSENNE 
stm32_cryp_find_dev(struct stm32_cryp_ctx * ctx)3619e054ec2SFabien DESSENNE static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx)
3629e054ec2SFabien DESSENNE {
3639e054ec2SFabien DESSENNE 	struct stm32_cryp *tmp, *cryp = NULL;
3649e054ec2SFabien DESSENNE 
3659e054ec2SFabien DESSENNE 	spin_lock_bh(&cryp_list.lock);
3669e054ec2SFabien DESSENNE 	if (!ctx->cryp) {
3679e054ec2SFabien DESSENNE 		list_for_each_entry(tmp, &cryp_list.dev_list, list) {
3689e054ec2SFabien DESSENNE 			cryp = tmp;
3699e054ec2SFabien DESSENNE 			break;
3709e054ec2SFabien DESSENNE 		}
3719e054ec2SFabien DESSENNE 		ctx->cryp = cryp;
3729e054ec2SFabien DESSENNE 	} else {
3739e054ec2SFabien DESSENNE 		cryp = ctx->cryp;
3749e054ec2SFabien DESSENNE 	}
3759e054ec2SFabien DESSENNE 
3769e054ec2SFabien DESSENNE 	spin_unlock_bh(&cryp_list.lock);
3779e054ec2SFabien DESSENNE 
3789e054ec2SFabien DESSENNE 	return cryp;
3799e054ec2SFabien DESSENNE }
3809e054ec2SFabien DESSENNE 
stm32_cryp_hw_write_iv(struct stm32_cryp * cryp,__be32 * iv)381bbb28326SHerbert Xu static void stm32_cryp_hw_write_iv(struct stm32_cryp *cryp, __be32 *iv)
3829e054ec2SFabien DESSENNE {
3839e054ec2SFabien DESSENNE 	if (!iv)
3849e054ec2SFabien DESSENNE 		return;
3859e054ec2SFabien DESSENNE 
3860b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->iv0l, be32_to_cpu(*iv++));
3870b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->iv0r, be32_to_cpu(*iv++));
3889e054ec2SFabien DESSENNE 
3899e054ec2SFabien DESSENNE 	if (is_aes(cryp)) {
3900b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->iv1l, be32_to_cpu(*iv++));
3910b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->iv1r, be32_to_cpu(*iv++));
3929e054ec2SFabien DESSENNE 	}
3939e054ec2SFabien DESSENNE }
3949e054ec2SFabien DESSENNE 
stm32_cryp_get_iv(struct stm32_cryp * cryp)3955f49f18dSLionel Debieve static void stm32_cryp_get_iv(struct stm32_cryp *cryp)
3965f49f18dSLionel Debieve {
39747ece481SArd Biesheuvel 	struct skcipher_request *req = cryp->req;
398bbb28326SHerbert Xu 	__be32 *tmp = (void *)req->iv;
3995f49f18dSLionel Debieve 
4005f49f18dSLionel Debieve 	if (!tmp)
4015f49f18dSLionel Debieve 		return;
4025f49f18dSLionel Debieve 
4030b496efbSLinus Walleij 	if (cryp->caps->iv_protection)
4040b496efbSLinus Walleij 		stm32_cryp_key_read_enable(cryp);
4050b496efbSLinus Walleij 
4060b496efbSLinus Walleij 	*tmp++ = cpu_to_be32(stm32_cryp_read(cryp, cryp->caps->iv0l));
4070b496efbSLinus Walleij 	*tmp++ = cpu_to_be32(stm32_cryp_read(cryp, cryp->caps->iv0r));
4085f49f18dSLionel Debieve 
4095f49f18dSLionel Debieve 	if (is_aes(cryp)) {
4100b496efbSLinus Walleij 		*tmp++ = cpu_to_be32(stm32_cryp_read(cryp, cryp->caps->iv1l));
4110b496efbSLinus Walleij 		*tmp++ = cpu_to_be32(stm32_cryp_read(cryp, cryp->caps->iv1r));
4120b496efbSLinus Walleij 	}
4130b496efbSLinus Walleij 
4140b496efbSLinus Walleij 	if (cryp->caps->iv_protection)
4150b496efbSLinus Walleij 		stm32_cryp_key_read_disable(cryp);
4160b496efbSLinus Walleij }
4170b496efbSLinus Walleij 
4180b496efbSLinus Walleij /**
4190b496efbSLinus Walleij  * ux500_swap_bits_in_byte() - mirror the bits in a byte
4200b496efbSLinus Walleij  * @b: the byte to be mirrored
4210b496efbSLinus Walleij  *
4220b496efbSLinus Walleij  * The bits are swapped the following way:
4230b496efbSLinus Walleij  *  Byte b include bits 0-7, nibble 1 (n1) include bits 0-3 and
4240b496efbSLinus Walleij  *  nibble 2 (n2) bits 4-7.
4250b496efbSLinus Walleij  *
4260b496efbSLinus Walleij  *  Nibble 1 (n1):
4270b496efbSLinus Walleij  *  (The "old" (moved) bit is replaced with a zero)
4280b496efbSLinus Walleij  *  1. Move bit 6 and 7, 4 positions to the left.
4290b496efbSLinus Walleij  *  2. Move bit 3 and 5, 2 positions to the left.
4300b496efbSLinus Walleij  *  3. Move bit 1-4, 1 position to the left.
4310b496efbSLinus Walleij  *
4320b496efbSLinus Walleij  *  Nibble 2 (n2):
4330b496efbSLinus Walleij  *  1. Move bit 0 and 1, 4 positions to the right.
4340b496efbSLinus Walleij  *  2. Move bit 2 and 4, 2 positions to the right.
4350b496efbSLinus Walleij  *  3. Move bit 3-6, 1 position to the right.
4360b496efbSLinus Walleij  *
4370b496efbSLinus Walleij  *  Combine the two nibbles to a complete and swapped byte.
4380b496efbSLinus Walleij  */
ux500_swap_bits_in_byte(u8 b)4390b496efbSLinus Walleij static inline u8 ux500_swap_bits_in_byte(u8 b)
4400b496efbSLinus Walleij {
4410b496efbSLinus Walleij #define R_SHIFT_4_MASK  0xc0 /* Bits 6 and 7, right shift 4 */
4420b496efbSLinus Walleij #define R_SHIFT_2_MASK  0x28 /* (After right shift 4) Bits 3 and 5,
4430b496efbSLinus Walleij 				  right shift 2 */
4440b496efbSLinus Walleij #define R_SHIFT_1_MASK  0x1e /* (After right shift 2) Bits 1-4,
4450b496efbSLinus Walleij 				  right shift 1 */
4460b496efbSLinus Walleij #define L_SHIFT_4_MASK  0x03 /* Bits 0 and 1, left shift 4 */
4470b496efbSLinus Walleij #define L_SHIFT_2_MASK  0x14 /* (After left shift 4) Bits 2 and 4,
4480b496efbSLinus Walleij 				  left shift 2 */
4490b496efbSLinus Walleij #define L_SHIFT_1_MASK  0x78 /* (After left shift 1) Bits 3-6,
4500b496efbSLinus Walleij 				  left shift 1 */
4510b496efbSLinus Walleij 
4520b496efbSLinus Walleij 	u8 n1;
4530b496efbSLinus Walleij 	u8 n2;
4540b496efbSLinus Walleij 
4550b496efbSLinus Walleij 	/* Swap most significant nibble */
4560b496efbSLinus Walleij 	/* Right shift 4, bits 6 and 7 */
4570b496efbSLinus Walleij 	n1 = ((b  & R_SHIFT_4_MASK) >> 4) | (b  & ~(R_SHIFT_4_MASK >> 4));
4580b496efbSLinus Walleij 	/* Right shift 2, bits 3 and 5 */
4590b496efbSLinus Walleij 	n1 = ((n1 & R_SHIFT_2_MASK) >> 2) | (n1 & ~(R_SHIFT_2_MASK >> 2));
4600b496efbSLinus Walleij 	/* Right shift 1, bits 1-4 */
4610b496efbSLinus Walleij 	n1 = (n1  & R_SHIFT_1_MASK) >> 1;
4620b496efbSLinus Walleij 
4630b496efbSLinus Walleij 	/* Swap least significant nibble */
4640b496efbSLinus Walleij 	/* Left shift 4, bits 0 and 1 */
4650b496efbSLinus Walleij 	n2 = ((b  & L_SHIFT_4_MASK) << 4) | (b  & ~(L_SHIFT_4_MASK << 4));
4660b496efbSLinus Walleij 	/* Left shift 2, bits 2 and 4 */
4670b496efbSLinus Walleij 	n2 = ((n2 & L_SHIFT_2_MASK) << 2) | (n2 & ~(L_SHIFT_2_MASK << 2));
4680b496efbSLinus Walleij 	/* Left shift 1, bits 3-6 */
4690b496efbSLinus Walleij 	n2 = (n2  & L_SHIFT_1_MASK) << 1;
4700b496efbSLinus Walleij 
4710b496efbSLinus Walleij 	return n1 | n2;
4720b496efbSLinus Walleij }
4730b496efbSLinus Walleij 
4740b496efbSLinus Walleij /**
4750b496efbSLinus Walleij  * ux500_swizzle_key() - Shuffle around words and bits in the AES key
4760b496efbSLinus Walleij  * @in: key to swizzle
4770b496efbSLinus Walleij  * @out: swizzled key
4780b496efbSLinus Walleij  * @len: length of key, in bytes
4790b496efbSLinus Walleij  *
4800b496efbSLinus Walleij  * This "key swizzling procedure" is described in the examples in the
4810b496efbSLinus Walleij  * DB8500 design specification. There is no real description of why
4820b496efbSLinus Walleij  * the bits have been arranged like this in the hardware.
4830b496efbSLinus Walleij  */
ux500_swizzle_key(const u8 * in,u8 * out,u32 len)4840b496efbSLinus Walleij static inline void ux500_swizzle_key(const u8 *in, u8 *out, u32 len)
4850b496efbSLinus Walleij {
4860b496efbSLinus Walleij 	int i = 0;
4870b496efbSLinus Walleij 	int bpw = sizeof(u32);
4880b496efbSLinus Walleij 	int j;
4890b496efbSLinus Walleij 	int index = 0;
4900b496efbSLinus Walleij 
4910b496efbSLinus Walleij 	j = len - bpw;
4920b496efbSLinus Walleij 	while (j >= 0) {
4930b496efbSLinus Walleij 		for (i = 0; i < bpw; i++) {
4940b496efbSLinus Walleij 			index = len - j - bpw + i;
4950b496efbSLinus Walleij 			out[j + i] =
4960b496efbSLinus Walleij 				ux500_swap_bits_in_byte(in[index]);
4970b496efbSLinus Walleij 		}
4980b496efbSLinus Walleij 		j -= bpw;
4995f49f18dSLionel Debieve 	}
5005f49f18dSLionel Debieve }
5015f49f18dSLionel Debieve 
stm32_cryp_hw_write_key(struct stm32_cryp * c)5029e054ec2SFabien DESSENNE static void stm32_cryp_hw_write_key(struct stm32_cryp *c)
5039e054ec2SFabien DESSENNE {
5049e054ec2SFabien DESSENNE 	unsigned int i;
5059e054ec2SFabien DESSENNE 	int r_id;
5069e054ec2SFabien DESSENNE 
5079e054ec2SFabien DESSENNE 	if (is_des(c)) {
5080b496efbSLinus Walleij 		stm32_cryp_write(c, c->caps->k1l, be32_to_cpu(c->ctx->key[0]));
5090b496efbSLinus Walleij 		stm32_cryp_write(c, c->caps->k1r, be32_to_cpu(c->ctx->key[1]));
5100b496efbSLinus Walleij 		return;
5119e054ec2SFabien DESSENNE 	}
5120b496efbSLinus Walleij 
5130b496efbSLinus Walleij 	/*
5140b496efbSLinus Walleij 	 * On the Ux500 the AES key is considered as a single bit sequence
5150b496efbSLinus Walleij 	 * of 128, 192 or 256 bits length. It is written linearly into the
5160b496efbSLinus Walleij 	 * registers from K1L and down, and need to be processed to become
5170b496efbSLinus Walleij 	 * a proper big-endian bit sequence.
5180b496efbSLinus Walleij 	 */
5190b496efbSLinus Walleij 	if (is_aes(c) && c->caps->linear_aes_key) {
5200b496efbSLinus Walleij 		u32 tmpkey[8];
5210b496efbSLinus Walleij 
5220b496efbSLinus Walleij 		ux500_swizzle_key((u8 *)c->ctx->key,
5230b496efbSLinus Walleij 				  (u8 *)tmpkey, c->ctx->keylen);
5240b496efbSLinus Walleij 
5250b496efbSLinus Walleij 		r_id = c->caps->k1l;
5260b496efbSLinus Walleij 		for (i = 0; i < c->ctx->keylen / sizeof(u32); i++, r_id += 4)
5270b496efbSLinus Walleij 			stm32_cryp_write(c, r_id, tmpkey[i]);
5280b496efbSLinus Walleij 
5290b496efbSLinus Walleij 		return;
5300b496efbSLinus Walleij 	}
5310b496efbSLinus Walleij 
5320b496efbSLinus Walleij 	r_id = c->caps->k3r;
5330b496efbSLinus Walleij 	for (i = c->ctx->keylen / sizeof(u32); i > 0; i--, r_id -= 4)
5340b496efbSLinus Walleij 		stm32_cryp_write(c, r_id, be32_to_cpu(c->ctx->key[i - 1]));
5359e054ec2SFabien DESSENNE }
5369e054ec2SFabien DESSENNE 
stm32_cryp_get_hw_mode(struct stm32_cryp * cryp)5379e054ec2SFabien DESSENNE static u32 stm32_cryp_get_hw_mode(struct stm32_cryp *cryp)
5389e054ec2SFabien DESSENNE {
5399e054ec2SFabien DESSENNE 	if (is_aes(cryp) && is_ecb(cryp))
5409e054ec2SFabien DESSENNE 		return CR_AES_ECB;
5419e054ec2SFabien DESSENNE 
5429e054ec2SFabien DESSENNE 	if (is_aes(cryp) && is_cbc(cryp))
5439e054ec2SFabien DESSENNE 		return CR_AES_CBC;
5449e054ec2SFabien DESSENNE 
5459e054ec2SFabien DESSENNE 	if (is_aes(cryp) && is_ctr(cryp))
5469e054ec2SFabien DESSENNE 		return CR_AES_CTR;
5479e054ec2SFabien DESSENNE 
5489d3b5030SFabien DESSENNE 	if (is_aes(cryp) && is_gcm(cryp))
5499d3b5030SFabien DESSENNE 		return CR_AES_GCM;
5509d3b5030SFabien DESSENNE 
5519d3b5030SFabien DESSENNE 	if (is_aes(cryp) && is_ccm(cryp))
5529d3b5030SFabien DESSENNE 		return CR_AES_CCM;
5539d3b5030SFabien DESSENNE 
5549e054ec2SFabien DESSENNE 	if (is_des(cryp) && is_ecb(cryp))
5559e054ec2SFabien DESSENNE 		return CR_DES_ECB;
5569e054ec2SFabien DESSENNE 
5579e054ec2SFabien DESSENNE 	if (is_des(cryp) && is_cbc(cryp))
5589e054ec2SFabien DESSENNE 		return CR_DES_CBC;
5599e054ec2SFabien DESSENNE 
5609e054ec2SFabien DESSENNE 	if (is_tdes(cryp) && is_ecb(cryp))
5619e054ec2SFabien DESSENNE 		return CR_TDES_ECB;
5629e054ec2SFabien DESSENNE 
5639e054ec2SFabien DESSENNE 	if (is_tdes(cryp) && is_cbc(cryp))
5649e054ec2SFabien DESSENNE 		return CR_TDES_CBC;
5659e054ec2SFabien DESSENNE 
5669e054ec2SFabien DESSENNE 	dev_err(cryp->dev, "Unknown mode\n");
5679e054ec2SFabien DESSENNE 	return CR_AES_UNKNOWN;
5689e054ec2SFabien DESSENNE }
5699e054ec2SFabien DESSENNE 
stm32_cryp_get_input_text_len(struct stm32_cryp * cryp)5709d3b5030SFabien DESSENNE static unsigned int stm32_cryp_get_input_text_len(struct stm32_cryp *cryp)
5719d3b5030SFabien DESSENNE {
5729d3b5030SFabien DESSENNE 	return is_encrypt(cryp) ? cryp->areq->cryptlen :
5739d3b5030SFabien DESSENNE 				  cryp->areq->cryptlen - cryp->authsize;
5749d3b5030SFabien DESSENNE }
5759d3b5030SFabien DESSENNE 
stm32_cryp_gcm_init(struct stm32_cryp * cryp,u32 cfg)5769d3b5030SFabien DESSENNE static int stm32_cryp_gcm_init(struct stm32_cryp *cryp, u32 cfg)
5779d3b5030SFabien DESSENNE {
5789d3b5030SFabien DESSENNE 	int ret;
579bbb28326SHerbert Xu 	__be32 iv[4];
5809d3b5030SFabien DESSENNE 
5819d3b5030SFabien DESSENNE 	/* Phase 1 : init */
5829d3b5030SFabien DESSENNE 	memcpy(iv, cryp->areq->iv, 12);
5839d3b5030SFabien DESSENNE 	iv[3] = cpu_to_be32(GCM_CTR_INIT);
5849d3b5030SFabien DESSENNE 	cryp->gcm_ctr = GCM_CTR_INIT;
5859d3b5030SFabien DESSENNE 	stm32_cryp_hw_write_iv(cryp, iv);
5869d3b5030SFabien DESSENNE 
5870b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg | CR_PH_INIT | CR_CRYPEN);
5889d3b5030SFabien DESSENNE 
5899d3b5030SFabien DESSENNE 	/* Wait for end of processing */
5909d3b5030SFabien DESSENNE 	ret = stm32_cryp_wait_enable(cryp);
5914b898d5cSNicolas Toromanoff 	if (ret) {
5929d3b5030SFabien DESSENNE 		dev_err(cryp->dev, "Timeout (gcm init)\n");
5939d3b5030SFabien DESSENNE 		return ret;
5949d3b5030SFabien DESSENNE 	}
5959d3b5030SFabien DESSENNE 
5964b898d5cSNicolas Toromanoff 	/* Prepare next phase */
5974b898d5cSNicolas Toromanoff 	if (cryp->areq->assoclen) {
5984b898d5cSNicolas Toromanoff 		cfg |= CR_PH_HEADER;
5990b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->cr, cfg);
6004b898d5cSNicolas Toromanoff 	} else if (stm32_cryp_get_input_text_len(cryp)) {
6014b898d5cSNicolas Toromanoff 		cfg |= CR_PH_PAYLOAD;
6020b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->cr, cfg);
6034b898d5cSNicolas Toromanoff 	}
6044b898d5cSNicolas Toromanoff 
6054b898d5cSNicolas Toromanoff 	return 0;
6064b898d5cSNicolas Toromanoff }
6074b898d5cSNicolas Toromanoff 
stm32_crypt_gcmccm_end_header(struct stm32_cryp * cryp)6084b898d5cSNicolas Toromanoff static void stm32_crypt_gcmccm_end_header(struct stm32_cryp *cryp)
6094b898d5cSNicolas Toromanoff {
6104b898d5cSNicolas Toromanoff 	u32 cfg;
6114b898d5cSNicolas Toromanoff 	int err;
6124b898d5cSNicolas Toromanoff 
6134b898d5cSNicolas Toromanoff 	/* Check if whole header written */
6144b898d5cSNicolas Toromanoff 	if (!cryp->header_in) {
6154b898d5cSNicolas Toromanoff 		/* Wait for completion */
6164b898d5cSNicolas Toromanoff 		err = stm32_cryp_wait_busy(cryp);
6174b898d5cSNicolas Toromanoff 		if (err) {
6184b898d5cSNicolas Toromanoff 			dev_err(cryp->dev, "Timeout (gcm/ccm header)\n");
6190b496efbSLinus Walleij 			stm32_cryp_write(cryp, cryp->caps->imsc, 0);
6204b898d5cSNicolas Toromanoff 			stm32_cryp_finish_req(cryp, err);
6214b898d5cSNicolas Toromanoff 			return;
6224b898d5cSNicolas Toromanoff 		}
6234b898d5cSNicolas Toromanoff 
6244b898d5cSNicolas Toromanoff 		if (stm32_cryp_get_input_text_len(cryp)) {
6254b898d5cSNicolas Toromanoff 			/* Phase 3 : payload */
6260b496efbSLinus Walleij 			cfg = stm32_cryp_read(cryp, cryp->caps->cr);
6274b898d5cSNicolas Toromanoff 			cfg &= ~CR_CRYPEN;
6280b496efbSLinus Walleij 			stm32_cryp_write(cryp, cryp->caps->cr, cfg);
6294b898d5cSNicolas Toromanoff 
6304b898d5cSNicolas Toromanoff 			cfg &= ~CR_PH_MASK;
6314b898d5cSNicolas Toromanoff 			cfg |= CR_PH_PAYLOAD | CR_CRYPEN;
6320b496efbSLinus Walleij 			stm32_cryp_write(cryp, cryp->caps->cr, cfg);
6334b898d5cSNicolas Toromanoff 		} else {
6344b898d5cSNicolas Toromanoff 			/*
6354b898d5cSNicolas Toromanoff 			 * Phase 4 : tag.
6364b898d5cSNicolas Toromanoff 			 * Nothing to read, nothing to write, caller have to
6374b898d5cSNicolas Toromanoff 			 * end request
6384b898d5cSNicolas Toromanoff 			 */
6394b898d5cSNicolas Toromanoff 		}
6404b898d5cSNicolas Toromanoff 	}
6414b898d5cSNicolas Toromanoff }
6424b898d5cSNicolas Toromanoff 
stm32_cryp_write_ccm_first_header(struct stm32_cryp * cryp)6434b898d5cSNicolas Toromanoff static void stm32_cryp_write_ccm_first_header(struct stm32_cryp *cryp)
6444b898d5cSNicolas Toromanoff {
6454b898d5cSNicolas Toromanoff 	size_t written;
6464b898d5cSNicolas Toromanoff 	size_t len;
6474b898d5cSNicolas Toromanoff 	u32 alen = cryp->areq->assoclen;
6484b898d5cSNicolas Toromanoff 	u32 block[AES_BLOCK_32] = {0};
6494b898d5cSNicolas Toromanoff 	u8 *b8 = (u8 *)block;
6504b898d5cSNicolas Toromanoff 
6514b898d5cSNicolas Toromanoff 	if (alen <= 65280) {
6524b898d5cSNicolas Toromanoff 		/* Write first u32 of B1 */
6534b898d5cSNicolas Toromanoff 		b8[0] = (alen >> 8) & 0xFF;
6544b898d5cSNicolas Toromanoff 		b8[1] = alen & 0xFF;
6554b898d5cSNicolas Toromanoff 		len = 2;
6564b898d5cSNicolas Toromanoff 	} else {
6574b898d5cSNicolas Toromanoff 		/* Build the two first u32 of B1 */
6584b898d5cSNicolas Toromanoff 		b8[0] = 0xFF;
6594b898d5cSNicolas Toromanoff 		b8[1] = 0xFE;
6604b898d5cSNicolas Toromanoff 		b8[2] = (alen & 0xFF000000) >> 24;
6614b898d5cSNicolas Toromanoff 		b8[3] = (alen & 0x00FF0000) >> 16;
6624b898d5cSNicolas Toromanoff 		b8[4] = (alen & 0x0000FF00) >> 8;
6634b898d5cSNicolas Toromanoff 		b8[5] = alen & 0x000000FF;
6644b898d5cSNicolas Toromanoff 		len = 6;
6654b898d5cSNicolas Toromanoff 	}
6664b898d5cSNicolas Toromanoff 
6674b898d5cSNicolas Toromanoff 	written = min_t(size_t, AES_BLOCK_SIZE - len, alen);
6684b898d5cSNicolas Toromanoff 
6694b898d5cSNicolas Toromanoff 	scatterwalk_copychunks((char *)block + len, &cryp->in_walk, written, 0);
670319ad16dSLinus Walleij 
671319ad16dSLinus Walleij 	writesl(cryp->regs + cryp->caps->din, block, AES_BLOCK_32);
6724b898d5cSNicolas Toromanoff 
6734b898d5cSNicolas Toromanoff 	cryp->header_in -= written;
6744b898d5cSNicolas Toromanoff 
6754b898d5cSNicolas Toromanoff 	stm32_crypt_gcmccm_end_header(cryp);
6764b898d5cSNicolas Toromanoff }
6774b898d5cSNicolas Toromanoff 
stm32_cryp_ccm_init(struct stm32_cryp * cryp,u32 cfg)6789d3b5030SFabien DESSENNE static int stm32_cryp_ccm_init(struct stm32_cryp *cryp, u32 cfg)
6799d3b5030SFabien DESSENNE {
6809d3b5030SFabien DESSENNE 	int ret;
6814b898d5cSNicolas Toromanoff 	u32 iv_32[AES_BLOCK_32], b0_32[AES_BLOCK_32];
6824b898d5cSNicolas Toromanoff 	u8 *iv = (u8 *)iv_32, *b0 = (u8 *)b0_32;
683bbb28326SHerbert Xu 	__be32 *bd;
6849d3b5030SFabien DESSENNE 	u32 *d;
6859d3b5030SFabien DESSENNE 	unsigned int i, textlen;
6869d3b5030SFabien DESSENNE 
6879d3b5030SFabien DESSENNE 	/* Phase 1 : init. Firstly set the CTR value to 1 (not 0) */
6889d3b5030SFabien DESSENNE 	memcpy(iv, cryp->areq->iv, AES_BLOCK_SIZE);
6899d3b5030SFabien DESSENNE 	memset(iv + AES_BLOCK_SIZE - 1 - iv[0], 0, iv[0] + 1);
6909d3b5030SFabien DESSENNE 	iv[AES_BLOCK_SIZE - 1] = 1;
691bbb28326SHerbert Xu 	stm32_cryp_hw_write_iv(cryp, (__be32 *)iv);
6929d3b5030SFabien DESSENNE 
6939d3b5030SFabien DESSENNE 	/* Build B0 */
6949d3b5030SFabien DESSENNE 	memcpy(b0, iv, AES_BLOCK_SIZE);
6959d3b5030SFabien DESSENNE 
6969d3b5030SFabien DESSENNE 	b0[0] |= (8 * ((cryp->authsize - 2) / 2));
6979d3b5030SFabien DESSENNE 
6989d3b5030SFabien DESSENNE 	if (cryp->areq->assoclen)
6999d3b5030SFabien DESSENNE 		b0[0] |= 0x40;
7009d3b5030SFabien DESSENNE 
7019d3b5030SFabien DESSENNE 	textlen = stm32_cryp_get_input_text_len(cryp);
7029d3b5030SFabien DESSENNE 
7039d3b5030SFabien DESSENNE 	b0[AES_BLOCK_SIZE - 2] = textlen >> 8;
7049d3b5030SFabien DESSENNE 	b0[AES_BLOCK_SIZE - 1] = textlen & 0xFF;
7059d3b5030SFabien DESSENNE 
7069d3b5030SFabien DESSENNE 	/* Enable HW */
7070b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg | CR_PH_INIT | CR_CRYPEN);
7089d3b5030SFabien DESSENNE 
7099d3b5030SFabien DESSENNE 	/* Write B0 */
7109d3b5030SFabien DESSENNE 	d = (u32 *)b0;
711bbb28326SHerbert Xu 	bd = (__be32 *)b0;
7129d3b5030SFabien DESSENNE 
7139d3b5030SFabien DESSENNE 	for (i = 0; i < AES_BLOCK_32; i++) {
714bbb28326SHerbert Xu 		u32 xd = d[i];
715bbb28326SHerbert Xu 
7169d3b5030SFabien DESSENNE 		if (!cryp->caps->padding_wa)
717bbb28326SHerbert Xu 			xd = be32_to_cpu(bd[i]);
7180b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->din, xd);
7199d3b5030SFabien DESSENNE 	}
7209d3b5030SFabien DESSENNE 
7219d3b5030SFabien DESSENNE 	/* Wait for end of processing */
7229d3b5030SFabien DESSENNE 	ret = stm32_cryp_wait_enable(cryp);
7234b898d5cSNicolas Toromanoff 	if (ret) {
7249d3b5030SFabien DESSENNE 		dev_err(cryp->dev, "Timeout (ccm init)\n");
7259d3b5030SFabien DESSENNE 		return ret;
7269d3b5030SFabien DESSENNE 	}
7279d3b5030SFabien DESSENNE 
7284b898d5cSNicolas Toromanoff 	/* Prepare next phase */
7294b898d5cSNicolas Toromanoff 	if (cryp->areq->assoclen) {
7304b898d5cSNicolas Toromanoff 		cfg |= CR_PH_HEADER | CR_CRYPEN;
7310b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->cr, cfg);
7324b898d5cSNicolas Toromanoff 
7334b898d5cSNicolas Toromanoff 		/* Write first (special) block (may move to next phase [payload]) */
7344b898d5cSNicolas Toromanoff 		stm32_cryp_write_ccm_first_header(cryp);
7354b898d5cSNicolas Toromanoff 	} else if (stm32_cryp_get_input_text_len(cryp)) {
7364b898d5cSNicolas Toromanoff 		cfg |= CR_PH_PAYLOAD;
7370b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->cr, cfg);
7384b898d5cSNicolas Toromanoff 	}
7394b898d5cSNicolas Toromanoff 
7404b898d5cSNicolas Toromanoff 	return 0;
7414b898d5cSNicolas Toromanoff }
7424b898d5cSNicolas Toromanoff 
stm32_cryp_hw_init(struct stm32_cryp * cryp)7439e054ec2SFabien DESSENNE static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
7449e054ec2SFabien DESSENNE {
7459e054ec2SFabien DESSENNE 	int ret;
7469e054ec2SFabien DESSENNE 	u32 cfg, hw_mode;
7473d6b6613SHerbert Xu 
7483d6b6613SHerbert Xu 	pm_runtime_get_sync(cryp->dev);
74965f9aa36Slionel.debieve@st.com 
7509e054ec2SFabien DESSENNE 	/* Disable interrupt */
7510b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->imsc, 0);
7529e054ec2SFabien DESSENNE 
7539e054ec2SFabien DESSENNE 	/* Set configuration */
7549e054ec2SFabien DESSENNE 	cfg = CR_DATA8 | CR_FFLUSH;
7559e054ec2SFabien DESSENNE 
7569e054ec2SFabien DESSENNE 	switch (cryp->ctx->keylen) {
7579e054ec2SFabien DESSENNE 	case AES_KEYSIZE_128:
7589e054ec2SFabien DESSENNE 		cfg |= CR_KEY128;
7599e054ec2SFabien DESSENNE 		break;
7609e054ec2SFabien DESSENNE 
7619e054ec2SFabien DESSENNE 	case AES_KEYSIZE_192:
7629e054ec2SFabien DESSENNE 		cfg |= CR_KEY192;
7639e054ec2SFabien DESSENNE 		break;
7649e054ec2SFabien DESSENNE 
7659e054ec2SFabien DESSENNE 	default:
7669e054ec2SFabien DESSENNE 	case AES_KEYSIZE_256:
7679e054ec2SFabien DESSENNE 		cfg |= CR_KEY256;
7689e054ec2SFabien DESSENNE 		break;
7699e054ec2SFabien DESSENNE 	}
7709e054ec2SFabien DESSENNE 
7719e054ec2SFabien DESSENNE 	hw_mode = stm32_cryp_get_hw_mode(cryp);
7729e054ec2SFabien DESSENNE 	if (hw_mode == CR_AES_UNKNOWN)
7739e054ec2SFabien DESSENNE 		return -EINVAL;
7749e054ec2SFabien DESSENNE 
7759e054ec2SFabien DESSENNE 	/* AES ECB/CBC decrypt: run key preparation first */
7769e054ec2SFabien DESSENNE 	if (is_decrypt(cryp) &&
7779e054ec2SFabien DESSENNE 	    ((hw_mode == CR_AES_ECB) || (hw_mode == CR_AES_CBC))) {
77895fe2253SNicolas Toromanoff 		/* Configure in key preparation mode */
7790b496efbSLinus Walleij 		if (cryp->caps->kp_mode)
7800b496efbSLinus Walleij 			stm32_cryp_write(cryp, cryp->caps->cr,
7810b496efbSLinus Walleij 				cfg | CR_AES_KP);
7820b496efbSLinus Walleij 		else
7830b496efbSLinus Walleij 			stm32_cryp_write(cryp,
7840b496efbSLinus Walleij 				cryp->caps->cr, cfg | CR_AES_ECB | CR_KSE);
7859e054ec2SFabien DESSENNE 
78695fe2253SNicolas Toromanoff 		/* Set key only after full configuration done */
78795fe2253SNicolas Toromanoff 		stm32_cryp_hw_write_key(cryp);
78895fe2253SNicolas Toromanoff 
78995fe2253SNicolas Toromanoff 		/* Start prepare key */
79095fe2253SNicolas Toromanoff 		stm32_cryp_enable(cryp);
7919e054ec2SFabien DESSENNE 		/* Wait for end of processing */
7929e054ec2SFabien DESSENNE 		ret = stm32_cryp_wait_busy(cryp);
7939e054ec2SFabien DESSENNE 		if (ret) {
7949e054ec2SFabien DESSENNE 			dev_err(cryp->dev, "Timeout (key preparation)\n");
7959e054ec2SFabien DESSENNE 			return ret;
7969e054ec2SFabien DESSENNE 		}
7979e054ec2SFabien DESSENNE 
79895fe2253SNicolas Toromanoff 		cfg |= hw_mode | CR_DEC_NOT_ENC;
79995fe2253SNicolas Toromanoff 
80095fe2253SNicolas Toromanoff 		/* Apply updated config (Decrypt + algo) and flush */
8010b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->cr, cfg);
80295fe2253SNicolas Toromanoff 	} else {
8039e054ec2SFabien DESSENNE 		cfg |= hw_mode;
8049e054ec2SFabien DESSENNE 		if (is_decrypt(cryp))
8059e054ec2SFabien DESSENNE 			cfg |= CR_DEC_NOT_ENC;
8069e054ec2SFabien DESSENNE 
80795fe2253SNicolas Toromanoff 		/* Apply config and flush */
8080b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->cr, cfg);
8099e054ec2SFabien DESSENNE 
81095fe2253SNicolas Toromanoff 		/* Set key only after configuration done */
81195fe2253SNicolas Toromanoff 		stm32_cryp_hw_write_key(cryp);
81295fe2253SNicolas Toromanoff 	}
81395fe2253SNicolas Toromanoff 
8149e054ec2SFabien DESSENNE 	switch (hw_mode) {
8159d3b5030SFabien DESSENNE 	case CR_AES_GCM:
8169d3b5030SFabien DESSENNE 	case CR_AES_CCM:
8179d3b5030SFabien DESSENNE 		/* Phase 1 : init */
8189d3b5030SFabien DESSENNE 		if (hw_mode == CR_AES_CCM)
8199d3b5030SFabien DESSENNE 			ret = stm32_cryp_ccm_init(cryp, cfg);
8209d3b5030SFabien DESSENNE 		else
8219d3b5030SFabien DESSENNE 			ret = stm32_cryp_gcm_init(cryp, cfg);
8229d3b5030SFabien DESSENNE 
8239d3b5030SFabien DESSENNE 		if (ret)
8249d3b5030SFabien DESSENNE 			return ret;
8259d3b5030SFabien DESSENNE 
8269d3b5030SFabien DESSENNE 		break;
8279d3b5030SFabien DESSENNE 
8289e054ec2SFabien DESSENNE 	case CR_DES_CBC:
8299e054ec2SFabien DESSENNE 	case CR_TDES_CBC:
8309e054ec2SFabien DESSENNE 	case CR_AES_CBC:
8319e054ec2SFabien DESSENNE 	case CR_AES_CTR:
832bbb28326SHerbert Xu 		stm32_cryp_hw_write_iv(cryp, (__be32 *)cryp->req->iv);
8339e054ec2SFabien DESSENNE 		break;
8349e054ec2SFabien DESSENNE 
8359e054ec2SFabien DESSENNE 	default:
8369e054ec2SFabien DESSENNE 		break;
8379e054ec2SFabien DESSENNE 	}
8389e054ec2SFabien DESSENNE 
8399e054ec2SFabien DESSENNE 	/* Enable now */
84095fe2253SNicolas Toromanoff 	stm32_cryp_enable(cryp);
8419e054ec2SFabien DESSENNE 
8429e054ec2SFabien DESSENNE 	return 0;
8439e054ec2SFabien DESSENNE }
8449e054ec2SFabien DESSENNE 
stm32_cryp_finish_req(struct stm32_cryp * cryp,int err)8459d3b5030SFabien DESSENNE static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err)
8469e054ec2SFabien DESSENNE {
8479d3b5030SFabien DESSENNE 	if (!err && (is_gcm(cryp) || is_ccm(cryp)))
8489d3b5030SFabien DESSENNE 		/* Phase 4 : output tag */
8499d3b5030SFabien DESSENNE 		err = stm32_cryp_read_auth_tag(cryp);
8509e054ec2SFabien DESSENNE 
851fa97dc2dSNicolas Toromanoff 	if (!err && (!(is_gcm(cryp) || is_ccm(cryp) || is_ecb(cryp))))
8525f49f18dSLionel Debieve 		stm32_cryp_get_iv(cryp);
8535f49f18dSLionel Debieve 
85465f9aa36Slionel.debieve@st.com 	pm_runtime_mark_last_busy(cryp->dev);
85565f9aa36Slionel.debieve@st.com 	pm_runtime_put_autosuspend(cryp->dev);
85665f9aa36Slionel.debieve@st.com 
85729aed438SLionel Debieve 	if (is_gcm(cryp) || is_ccm(cryp))
8589d3b5030SFabien DESSENNE 		crypto_finalize_aead_request(cryp->engine, cryp->areq, err);
85929aed438SLionel Debieve 	else
860fb11a4f6SMaxime Méré 		crypto_finalize_skcipher_request(cryp->engine, cryp->req, err);
8619e054ec2SFabien DESSENNE }
8629e054ec2SFabien DESSENNE 
stm32_cryp_header_dma_callback(void * param)863fb11a4f6SMaxime Méré static void stm32_cryp_header_dma_callback(void *param)
864fb11a4f6SMaxime Méré {
865fb11a4f6SMaxime Méré 	struct stm32_cryp *cryp = (struct stm32_cryp *)param;
866fb11a4f6SMaxime Méré 	int ret;
867fb11a4f6SMaxime Méré 	u32 reg;
868fb11a4f6SMaxime Méré 
869fb11a4f6SMaxime Méré 	dma_unmap_sg(cryp->dev, cryp->header_sg, cryp->header_sg_len, DMA_TO_DEVICE);
870fb11a4f6SMaxime Méré 
871fb11a4f6SMaxime Méré 	reg = stm32_cryp_read(cryp, cryp->caps->dmacr);
872fb11a4f6SMaxime Méré 	stm32_cryp_write(cryp, cryp->caps->dmacr, reg & ~(DMACR_DOEN | DMACR_DIEN));
873fb11a4f6SMaxime Méré 
874fb11a4f6SMaxime Méré 	kfree(cryp->header_sg);
875fb11a4f6SMaxime Méré 
876fb11a4f6SMaxime Méré 	reg = stm32_cryp_read(cryp, cryp->caps->cr);
877fb11a4f6SMaxime Méré 
878fb11a4f6SMaxime Méré 	if (cryp->header_in) {
879fb11a4f6SMaxime Méré 		stm32_cryp_write(cryp, cryp->caps->cr, reg | CR_CRYPEN);
880fb11a4f6SMaxime Méré 
881fb11a4f6SMaxime Méré 		ret = stm32_cryp_wait_input(cryp);
882fb11a4f6SMaxime Méré 		if (ret) {
883fb11a4f6SMaxime Méré 			dev_err(cryp->dev, "input header ready timeout after dma\n");
884fb11a4f6SMaxime Méré 			stm32_cryp_finish_req(cryp, ret);
885fb11a4f6SMaxime Méré 			return;
886fb11a4f6SMaxime Méré 		}
887fb11a4f6SMaxime Méré 		stm32_cryp_irq_write_gcmccm_header(cryp);
888fb11a4f6SMaxime Méré 		WARN_ON(cryp->header_in);
889fb11a4f6SMaxime Méré 	}
890fb11a4f6SMaxime Méré 
891fb11a4f6SMaxime Méré 	if (stm32_cryp_get_input_text_len(cryp)) {
892fb11a4f6SMaxime Méré 		/* Phase 3 : payload */
893fb11a4f6SMaxime Méré 		reg = stm32_cryp_read(cryp, cryp->caps->cr);
894fb11a4f6SMaxime Méré 		stm32_cryp_write(cryp, cryp->caps->cr, reg & ~CR_CRYPEN);
895fb11a4f6SMaxime Méré 
896fb11a4f6SMaxime Méré 		reg &= ~CR_PH_MASK;
897fb11a4f6SMaxime Méré 		reg |= CR_PH_PAYLOAD | CR_CRYPEN;
898fb11a4f6SMaxime Méré 		stm32_cryp_write(cryp, cryp->caps->cr, reg);
899fb11a4f6SMaxime Méré 
900fb11a4f6SMaxime Méré 		if (cryp->flags & FLG_IN_OUT_DMA) {
901fb11a4f6SMaxime Méré 			ret = stm32_cryp_dma_start(cryp);
902fb11a4f6SMaxime Méré 			if (ret)
903fb11a4f6SMaxime Méré 				stm32_cryp_finish_req(cryp, ret);
904fb11a4f6SMaxime Méré 		} else {
905fb11a4f6SMaxime Méré 			stm32_cryp_it_start(cryp);
906fb11a4f6SMaxime Méré 		}
907fb11a4f6SMaxime Méré 	} else {
908fb11a4f6SMaxime Méré 		/*
909fb11a4f6SMaxime Méré 		 * Phase 4 : tag.
910fb11a4f6SMaxime Méré 		 * Nothing to read, nothing to write => end request
911fb11a4f6SMaxime Méré 		 */
912fb11a4f6SMaxime Méré 		stm32_cryp_finish_req(cryp, 0);
913fb11a4f6SMaxime Méré 	}
914fb11a4f6SMaxime Méré }
915fb11a4f6SMaxime Méré 
stm32_cryp_dma_callback(void * param)916fb11a4f6SMaxime Méré static void stm32_cryp_dma_callback(void *param)
917fb11a4f6SMaxime Méré {
918fb11a4f6SMaxime Méré 	struct stm32_cryp *cryp = (struct stm32_cryp *)param;
919fb11a4f6SMaxime Méré 	int ret;
920fb11a4f6SMaxime Méré 	u32 reg;
921fb11a4f6SMaxime Méré 
922fb11a4f6SMaxime Méré 	complete(&cryp->dma_completion); /* completion to indicate no timeout */
923fb11a4f6SMaxime Méré 
924fb11a4f6SMaxime Méré 	dma_sync_sg_for_device(cryp->dev, cryp->out_sg, cryp->out_sg_len, DMA_FROM_DEVICE);
925fb11a4f6SMaxime Méré 
926fb11a4f6SMaxime Méré 	if (cryp->in_sg != cryp->out_sg)
927fb11a4f6SMaxime Méré 		dma_unmap_sg(cryp->dev, cryp->in_sg, cryp->in_sg_len, DMA_TO_DEVICE);
928fb11a4f6SMaxime Méré 
929fb11a4f6SMaxime Méré 	dma_unmap_sg(cryp->dev, cryp->out_sg, cryp->out_sg_len, DMA_FROM_DEVICE);
930fb11a4f6SMaxime Méré 
931fb11a4f6SMaxime Méré 	reg = stm32_cryp_read(cryp, cryp->caps->dmacr);
932fb11a4f6SMaxime Méré 	stm32_cryp_write(cryp, cryp->caps->dmacr, reg & ~(DMACR_DOEN | DMACR_DIEN));
933fb11a4f6SMaxime Méré 
934fb11a4f6SMaxime Méré 	reg = stm32_cryp_read(cryp, cryp->caps->cr);
935fb11a4f6SMaxime Méré 
936fb11a4f6SMaxime Méré 	if (is_gcm(cryp) || is_ccm(cryp)) {
937fb11a4f6SMaxime Méré 		kfree(cryp->in_sg);
938fb11a4f6SMaxime Méré 		kfree(cryp->out_sg);
939fb11a4f6SMaxime Méré 	} else {
940fb11a4f6SMaxime Méré 		if (cryp->in_sg != cryp->req->src)
941fb11a4f6SMaxime Méré 			kfree(cryp->in_sg);
942fb11a4f6SMaxime Méré 		if (cryp->out_sg != cryp->req->dst)
943fb11a4f6SMaxime Méré 			kfree(cryp->out_sg);
944fb11a4f6SMaxime Méré 	}
945fb11a4f6SMaxime Méré 
946fb11a4f6SMaxime Méré 	if (cryp->payload_in) {
947fb11a4f6SMaxime Méré 		stm32_cryp_write(cryp, cryp->caps->cr, reg | CR_CRYPEN);
948fb11a4f6SMaxime Méré 
949fb11a4f6SMaxime Méré 		ret = stm32_cryp_wait_input(cryp);
950fb11a4f6SMaxime Méré 		if (ret) {
951fb11a4f6SMaxime Méré 			dev_err(cryp->dev, "input ready timeout after dma\n");
952fb11a4f6SMaxime Méré 			stm32_cryp_finish_req(cryp, ret);
953fb11a4f6SMaxime Méré 			return;
954fb11a4f6SMaxime Méré 		}
955fb11a4f6SMaxime Méré 		stm32_cryp_irq_write_data(cryp);
956fb11a4f6SMaxime Méré 
957fb11a4f6SMaxime Méré 		ret = stm32_cryp_wait_output(cryp);
958fb11a4f6SMaxime Méré 		if (ret) {
959fb11a4f6SMaxime Méré 			dev_err(cryp->dev, "output ready timeout after dma\n");
960fb11a4f6SMaxime Méré 			stm32_cryp_finish_req(cryp, ret);
961fb11a4f6SMaxime Méré 			return;
962fb11a4f6SMaxime Méré 		}
963fb11a4f6SMaxime Méré 		stm32_cryp_irq_read_data(cryp);
964fb11a4f6SMaxime Méré 	}
965fb11a4f6SMaxime Méré 
966fb11a4f6SMaxime Méré 	stm32_cryp_finish_req(cryp, 0);
967fb11a4f6SMaxime Méré }
968fb11a4f6SMaxime Méré 
stm32_cryp_header_dma_start(struct stm32_cryp * cryp)969fb11a4f6SMaxime Méré static int stm32_cryp_header_dma_start(struct stm32_cryp *cryp)
970fb11a4f6SMaxime Méré {
971fb11a4f6SMaxime Méré 	int ret;
972fb11a4f6SMaxime Méré 	struct dma_async_tx_descriptor *tx_in;
973fb11a4f6SMaxime Méré 	u32 reg;
974fb11a4f6SMaxime Méré 	size_t align_size;
975fb11a4f6SMaxime Méré 
976fb11a4f6SMaxime Méré 	ret = dma_map_sg(cryp->dev, cryp->header_sg, cryp->header_sg_len, DMA_TO_DEVICE);
977fb11a4f6SMaxime Méré 	if (!ret) {
978fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "dma_map_sg() error\n");
979fb11a4f6SMaxime Méré 		return -ENOMEM;
980fb11a4f6SMaxime Méré 	}
981fb11a4f6SMaxime Méré 
982fb11a4f6SMaxime Méré 	dma_sync_sg_for_device(cryp->dev, cryp->header_sg, cryp->header_sg_len, DMA_TO_DEVICE);
983fb11a4f6SMaxime Méré 
984fb11a4f6SMaxime Méré 	tx_in = dmaengine_prep_slave_sg(cryp->dma_lch_in, cryp->header_sg, cryp->header_sg_len,
985fb11a4f6SMaxime Méré 					DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
986fb11a4f6SMaxime Méré 	if (!tx_in) {
987fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "IN prep_slave_sg() failed\n");
988fb11a4f6SMaxime Méré 		return -EINVAL;
989fb11a4f6SMaxime Méré 	}
990fb11a4f6SMaxime Méré 
991fb11a4f6SMaxime Méré 	tx_in->callback_param = cryp;
992fb11a4f6SMaxime Méré 	tx_in->callback = stm32_cryp_header_dma_callback;
993fb11a4f6SMaxime Méré 
994fb11a4f6SMaxime Méré 	/* Advance scatterwalk to not DMA'ed data */
995fb11a4f6SMaxime Méré 	align_size = ALIGN_DOWN(cryp->header_in, cryp->hw_blocksize);
996fb11a4f6SMaxime Méré 	scatterwalk_copychunks(NULL, &cryp->in_walk, align_size, 2);
997fb11a4f6SMaxime Méré 	cryp->header_in -= align_size;
998fb11a4f6SMaxime Méré 
999fb11a4f6SMaxime Méré 	ret = dma_submit_error(dmaengine_submit(tx_in));
1000fb11a4f6SMaxime Méré 	if (ret < 0) {
1001fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "DMA in submit failed\n");
1002fb11a4f6SMaxime Méré 		return ret;
1003fb11a4f6SMaxime Méré 	}
1004fb11a4f6SMaxime Méré 	dma_async_issue_pending(cryp->dma_lch_in);
1005fb11a4f6SMaxime Méré 
1006fb11a4f6SMaxime Méré 	reg = stm32_cryp_read(cryp, cryp->caps->dmacr);
1007fb11a4f6SMaxime Méré 	stm32_cryp_write(cryp, cryp->caps->dmacr, reg | DMACR_DIEN);
1008fb11a4f6SMaxime Méré 
1009fb11a4f6SMaxime Méré 	return 0;
1010fb11a4f6SMaxime Méré }
1011fb11a4f6SMaxime Méré 
stm32_cryp_dma_start(struct stm32_cryp * cryp)1012fb11a4f6SMaxime Méré static int stm32_cryp_dma_start(struct stm32_cryp *cryp)
1013fb11a4f6SMaxime Méré {
1014fb11a4f6SMaxime Méré 	int ret;
1015fb11a4f6SMaxime Méré 	size_t align_size;
1016fb11a4f6SMaxime Méré 	struct dma_async_tx_descriptor *tx_in, *tx_out;
1017fb11a4f6SMaxime Méré 	u32 reg;
1018fb11a4f6SMaxime Méré 
1019fb11a4f6SMaxime Méré 	if (cryp->in_sg != cryp->out_sg) {
1020fb11a4f6SMaxime Méré 		ret = dma_map_sg(cryp->dev, cryp->in_sg, cryp->in_sg_len, DMA_TO_DEVICE);
1021fb11a4f6SMaxime Méré 		if (!ret) {
1022fb11a4f6SMaxime Méré 			dev_err(cryp->dev, "dma_map_sg() error\n");
1023fb11a4f6SMaxime Méré 			return -ENOMEM;
1024fb11a4f6SMaxime Méré 		}
1025fb11a4f6SMaxime Méré 	}
1026fb11a4f6SMaxime Méré 
1027fb11a4f6SMaxime Méré 	ret = dma_map_sg(cryp->dev, cryp->out_sg, cryp->out_sg_len, DMA_FROM_DEVICE);
1028fb11a4f6SMaxime Méré 	if (!ret) {
1029fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "dma_map_sg() error\n");
1030fb11a4f6SMaxime Méré 		return -ENOMEM;
1031fb11a4f6SMaxime Méré 	}
1032fb11a4f6SMaxime Méré 
1033fb11a4f6SMaxime Méré 	dma_sync_sg_for_device(cryp->dev, cryp->in_sg, cryp->in_sg_len, DMA_TO_DEVICE);
1034fb11a4f6SMaxime Méré 
1035fb11a4f6SMaxime Méré 	tx_in = dmaengine_prep_slave_sg(cryp->dma_lch_in, cryp->in_sg, cryp->in_sg_len,
1036fb11a4f6SMaxime Méré 					DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1037fb11a4f6SMaxime Méré 	if (!tx_in) {
1038fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "IN prep_slave_sg() failed\n");
1039fb11a4f6SMaxime Méré 		return -EINVAL;
1040fb11a4f6SMaxime Méré 	}
1041fb11a4f6SMaxime Méré 
1042fb11a4f6SMaxime Méré 	/* No callback necessary */
1043fb11a4f6SMaxime Méré 	tx_in->callback_param = cryp;
1044fb11a4f6SMaxime Méré 	tx_in->callback = NULL;
1045fb11a4f6SMaxime Méré 
1046fb11a4f6SMaxime Méré 	tx_out = dmaengine_prep_slave_sg(cryp->dma_lch_out, cryp->out_sg, cryp->out_sg_len,
1047fb11a4f6SMaxime Méré 					 DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1048fb11a4f6SMaxime Méré 	if (!tx_out) {
1049fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "OUT prep_slave_sg() failed\n");
1050fb11a4f6SMaxime Méré 		return -EINVAL;
1051fb11a4f6SMaxime Méré 	}
1052fb11a4f6SMaxime Méré 
1053fb11a4f6SMaxime Méré 	reinit_completion(&cryp->dma_completion);
1054fb11a4f6SMaxime Méré 	tx_out->callback = stm32_cryp_dma_callback;
1055fb11a4f6SMaxime Méré 	tx_out->callback_param = cryp;
1056fb11a4f6SMaxime Méré 
1057fb11a4f6SMaxime Méré 	/* Advance scatterwalk to not DMA'ed data */
1058fb11a4f6SMaxime Méré 	align_size = ALIGN_DOWN(cryp->payload_in, cryp->hw_blocksize);
1059fb11a4f6SMaxime Méré 	scatterwalk_copychunks(NULL, &cryp->in_walk, align_size, 2);
1060fb11a4f6SMaxime Méré 	cryp->payload_in -= align_size;
1061fb11a4f6SMaxime Méré 
1062fb11a4f6SMaxime Méré 	ret = dma_submit_error(dmaengine_submit(tx_in));
1063fb11a4f6SMaxime Méré 	if (ret < 0) {
1064fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "DMA in submit failed\n");
1065fb11a4f6SMaxime Méré 		return ret;
1066fb11a4f6SMaxime Méré 	}
1067fb11a4f6SMaxime Méré 	dma_async_issue_pending(cryp->dma_lch_in);
1068fb11a4f6SMaxime Méré 
1069fb11a4f6SMaxime Méré 	/* Advance scatterwalk to not DMA'ed data */
1070fb11a4f6SMaxime Méré 	scatterwalk_copychunks(NULL, &cryp->out_walk, align_size, 2);
1071fb11a4f6SMaxime Méré 	cryp->payload_out -= align_size;
1072fb11a4f6SMaxime Méré 	ret = dma_submit_error(dmaengine_submit(tx_out));
1073fb11a4f6SMaxime Méré 	if (ret < 0) {
1074fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "DMA out submit failed\n");
1075fb11a4f6SMaxime Méré 		return ret;
1076fb11a4f6SMaxime Méré 	}
1077fb11a4f6SMaxime Méré 	dma_async_issue_pending(cryp->dma_lch_out);
1078fb11a4f6SMaxime Méré 
1079fb11a4f6SMaxime Méré 	reg = stm32_cryp_read(cryp, cryp->caps->dmacr);
1080fb11a4f6SMaxime Méré 	stm32_cryp_write(cryp, cryp->caps->dmacr, reg | DMACR_DOEN | DMACR_DIEN);
1081fb11a4f6SMaxime Méré 
1082fb11a4f6SMaxime Méré 	if (!wait_for_completion_timeout(&cryp->dma_completion, msecs_to_jiffies(1000))) {
1083fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "DMA out timed out\n");
1084fb11a4f6SMaxime Méré 		dmaengine_terminate_sync(cryp->dma_lch_out);
1085fb11a4f6SMaxime Méré 		return -ETIMEDOUT;
1086fb11a4f6SMaxime Méré 	}
1087fb11a4f6SMaxime Méré 
1088fb11a4f6SMaxime Méré 	return 0;
1089fb11a4f6SMaxime Méré }
1090fb11a4f6SMaxime Méré 
stm32_cryp_it_start(struct stm32_cryp * cryp)1091fb11a4f6SMaxime Méré static int stm32_cryp_it_start(struct stm32_cryp *cryp)
10929e054ec2SFabien DESSENNE {
10939e054ec2SFabien DESSENNE 	/* Enable interrupt and let the IRQ handler do everything */
10940b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->imsc, IMSCR_IN | IMSCR_OUT);
10959e054ec2SFabien DESSENNE 
10969e054ec2SFabien DESSENNE 	return 0;
10979e054ec2SFabien DESSENNE }
10989e054ec2SFabien DESSENNE 
1099dc7bcef5SCorentin LABBE static int stm32_cryp_cipher_one_req(struct crypto_engine *engine, void *areq);
1100dc7bcef5SCorentin LABBE 
stm32_cryp_init_tfm(struct crypto_skcipher * tfm)110147ece481SArd Biesheuvel static int stm32_cryp_init_tfm(struct crypto_skcipher *tfm)
11029e054ec2SFabien DESSENNE {
110347ece481SArd Biesheuvel 	crypto_skcipher_set_reqsize(tfm, sizeof(struct stm32_cryp_reqctx));
11049e054ec2SFabien DESSENNE 
11059e054ec2SFabien DESSENNE 	return 0;
11069e054ec2SFabien DESSENNE }
11079e054ec2SFabien DESSENNE 
11089d3b5030SFabien DESSENNE static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq);
11099d3b5030SFabien DESSENNE 
stm32_cryp_aes_aead_init(struct crypto_aead * tfm)11109d3b5030SFabien DESSENNE static int stm32_cryp_aes_aead_init(struct crypto_aead *tfm)
11119d3b5030SFabien DESSENNE {
11127b0795d9SOvidiu Panait 	crypto_aead_set_reqsize(tfm, sizeof(struct stm32_cryp_reqctx));
11139d3b5030SFabien DESSENNE 
11149d3b5030SFabien DESSENNE 	return 0;
11159d3b5030SFabien DESSENNE }
11169d3b5030SFabien DESSENNE 
stm32_cryp_crypt(struct skcipher_request * req,unsigned long mode)111747ece481SArd Biesheuvel static int stm32_cryp_crypt(struct skcipher_request *req, unsigned long mode)
11189e054ec2SFabien DESSENNE {
111947ece481SArd Biesheuvel 	struct stm32_cryp_ctx *ctx = crypto_skcipher_ctx(
112047ece481SArd Biesheuvel 			crypto_skcipher_reqtfm(req));
112147ece481SArd Biesheuvel 	struct stm32_cryp_reqctx *rctx = skcipher_request_ctx(req);
11229e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = stm32_cryp_find_dev(ctx);
11239e054ec2SFabien DESSENNE 
11249e054ec2SFabien DESSENNE 	if (!cryp)
11259e054ec2SFabien DESSENNE 		return -ENODEV;
11269e054ec2SFabien DESSENNE 
11279e054ec2SFabien DESSENNE 	rctx->mode = mode;
11289e054ec2SFabien DESSENNE 
112947ece481SArd Biesheuvel 	return crypto_transfer_skcipher_request_to_engine(cryp->engine, req);
11309e054ec2SFabien DESSENNE }
11319e054ec2SFabien DESSENNE 
stm32_cryp_aead_crypt(struct aead_request * req,unsigned long mode)11329d3b5030SFabien DESSENNE static int stm32_cryp_aead_crypt(struct aead_request *req, unsigned long mode)
11339d3b5030SFabien DESSENNE {
11349d3b5030SFabien DESSENNE 	struct stm32_cryp_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
11359d3b5030SFabien DESSENNE 	struct stm32_cryp_reqctx *rctx = aead_request_ctx(req);
11369d3b5030SFabien DESSENNE 	struct stm32_cryp *cryp = stm32_cryp_find_dev(ctx);
11379d3b5030SFabien DESSENNE 
11389d3b5030SFabien DESSENNE 	if (!cryp)
11399d3b5030SFabien DESSENNE 		return -ENODEV;
11409d3b5030SFabien DESSENNE 
11419d3b5030SFabien DESSENNE 	rctx->mode = mode;
11429d3b5030SFabien DESSENNE 
11439d3b5030SFabien DESSENNE 	return crypto_transfer_aead_request_to_engine(cryp->engine, req);
11449d3b5030SFabien DESSENNE }
11459d3b5030SFabien DESSENNE 
stm32_cryp_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)114647ece481SArd Biesheuvel static int stm32_cryp_setkey(struct crypto_skcipher *tfm, const u8 *key,
11479e054ec2SFabien DESSENNE 			     unsigned int keylen)
11489e054ec2SFabien DESSENNE {
114947ece481SArd Biesheuvel 	struct stm32_cryp_ctx *ctx = crypto_skcipher_ctx(tfm);
11509e054ec2SFabien DESSENNE 
11519e054ec2SFabien DESSENNE 	memcpy(ctx->key, key, keylen);
11529e054ec2SFabien DESSENNE 	ctx->keylen = keylen;
11539e054ec2SFabien DESSENNE 
11549e054ec2SFabien DESSENNE 	return 0;
11559e054ec2SFabien DESSENNE }
11569e054ec2SFabien DESSENNE 
stm32_cryp_aes_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)115747ece481SArd Biesheuvel static int stm32_cryp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
11589e054ec2SFabien DESSENNE 				 unsigned int keylen)
11599e054ec2SFabien DESSENNE {
11609e054ec2SFabien DESSENNE 	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
11619e054ec2SFabien DESSENNE 	    keylen != AES_KEYSIZE_256)
11629e054ec2SFabien DESSENNE 		return -EINVAL;
11639e054ec2SFabien DESSENNE 	else
11649e054ec2SFabien DESSENNE 		return stm32_cryp_setkey(tfm, key, keylen);
11659e054ec2SFabien DESSENNE }
11669e054ec2SFabien DESSENNE 
stm32_cryp_des_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)116747ece481SArd Biesheuvel static int stm32_cryp_des_setkey(struct crypto_skcipher *tfm, const u8 *key,
11689e054ec2SFabien DESSENNE 				 unsigned int keylen)
11699e054ec2SFabien DESSENNE {
117047ece481SArd Biesheuvel 	return verify_skcipher_des_key(tfm, key) ?:
1171b5d0ba83SArd Biesheuvel 	       stm32_cryp_setkey(tfm, key, keylen);
11729e054ec2SFabien DESSENNE }
11739e054ec2SFabien DESSENNE 
stm32_cryp_tdes_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)117447ece481SArd Biesheuvel static int stm32_cryp_tdes_setkey(struct crypto_skcipher *tfm, const u8 *key,
11759e054ec2SFabien DESSENNE 				  unsigned int keylen)
11769e054ec2SFabien DESSENNE {
117747ece481SArd Biesheuvel 	return verify_skcipher_des3_key(tfm, key) ?:
1178b5d0ba83SArd Biesheuvel 	       stm32_cryp_setkey(tfm, key, keylen);
11799e054ec2SFabien DESSENNE }
11809e054ec2SFabien DESSENNE 
stm32_cryp_aes_aead_setkey(struct crypto_aead * tfm,const u8 * key,unsigned int keylen)11819d3b5030SFabien DESSENNE static int stm32_cryp_aes_aead_setkey(struct crypto_aead *tfm, const u8 *key,
11829d3b5030SFabien DESSENNE 				      unsigned int keylen)
11839d3b5030SFabien DESSENNE {
11849d3b5030SFabien DESSENNE 	struct stm32_cryp_ctx *ctx = crypto_aead_ctx(tfm);
11859d3b5030SFabien DESSENNE 
11869d3b5030SFabien DESSENNE 	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
11879d3b5030SFabien DESSENNE 	    keylen != AES_KEYSIZE_256)
11889d3b5030SFabien DESSENNE 		return -EINVAL;
11899d3b5030SFabien DESSENNE 
11909d3b5030SFabien DESSENNE 	memcpy(ctx->key, key, keylen);
11919d3b5030SFabien DESSENNE 	ctx->keylen = keylen;
11929d3b5030SFabien DESSENNE 
11939d3b5030SFabien DESSENNE 	return 0;
11949d3b5030SFabien DESSENNE }
11959d3b5030SFabien DESSENNE 
stm32_cryp_aes_gcm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)11969d3b5030SFabien DESSENNE static int stm32_cryp_aes_gcm_setauthsize(struct crypto_aead *tfm,
11979d3b5030SFabien DESSENNE 					  unsigned int authsize)
11989d3b5030SFabien DESSENNE {
119939e6e699SNicolas Toromanoff 	switch (authsize) {
120039e6e699SNicolas Toromanoff 	case 4:
120139e6e699SNicolas Toromanoff 	case 8:
120239e6e699SNicolas Toromanoff 	case 12:
120339e6e699SNicolas Toromanoff 	case 13:
120439e6e699SNicolas Toromanoff 	case 14:
120539e6e699SNicolas Toromanoff 	case 15:
120639e6e699SNicolas Toromanoff 	case 16:
120739e6e699SNicolas Toromanoff 		break;
120839e6e699SNicolas Toromanoff 	default:
120939e6e699SNicolas Toromanoff 		return -EINVAL;
121039e6e699SNicolas Toromanoff 	}
121139e6e699SNicolas Toromanoff 
121239e6e699SNicolas Toromanoff 	return 0;
12139d3b5030SFabien DESSENNE }
12149d3b5030SFabien DESSENNE 
stm32_cryp_aes_ccm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)12159d3b5030SFabien DESSENNE static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm,
12169d3b5030SFabien DESSENNE 					  unsigned int authsize)
12179d3b5030SFabien DESSENNE {
12189d3b5030SFabien DESSENNE 	switch (authsize) {
12199d3b5030SFabien DESSENNE 	case 4:
12209d3b5030SFabien DESSENNE 	case 6:
12219d3b5030SFabien DESSENNE 	case 8:
12229d3b5030SFabien DESSENNE 	case 10:
12239d3b5030SFabien DESSENNE 	case 12:
12249d3b5030SFabien DESSENNE 	case 14:
12259d3b5030SFabien DESSENNE 	case 16:
12269d3b5030SFabien DESSENNE 		break;
12279d3b5030SFabien DESSENNE 	default:
12289d3b5030SFabien DESSENNE 		return -EINVAL;
12299d3b5030SFabien DESSENNE 	}
12309d3b5030SFabien DESSENNE 
12319d3b5030SFabien DESSENNE 	return 0;
12329d3b5030SFabien DESSENNE }
12339d3b5030SFabien DESSENNE 
stm32_cryp_aes_ecb_encrypt(struct skcipher_request * req)123447ece481SArd Biesheuvel static int stm32_cryp_aes_ecb_encrypt(struct skcipher_request *req)
12359e054ec2SFabien DESSENNE {
123639e6e699SNicolas Toromanoff 	if (req->cryptlen % AES_BLOCK_SIZE)
123739e6e699SNicolas Toromanoff 		return -EINVAL;
123839e6e699SNicolas Toromanoff 
123939e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
124039e6e699SNicolas Toromanoff 		return 0;
124139e6e699SNicolas Toromanoff 
12429e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_ECB | FLG_ENCRYPT);
12439e054ec2SFabien DESSENNE }
12449e054ec2SFabien DESSENNE 
stm32_cryp_aes_ecb_decrypt(struct skcipher_request * req)124547ece481SArd Biesheuvel static int stm32_cryp_aes_ecb_decrypt(struct skcipher_request *req)
12469e054ec2SFabien DESSENNE {
124739e6e699SNicolas Toromanoff 	if (req->cryptlen % AES_BLOCK_SIZE)
124839e6e699SNicolas Toromanoff 		return -EINVAL;
124939e6e699SNicolas Toromanoff 
125039e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
125139e6e699SNicolas Toromanoff 		return 0;
125239e6e699SNicolas Toromanoff 
12539e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_ECB);
12549e054ec2SFabien DESSENNE }
12559e054ec2SFabien DESSENNE 
stm32_cryp_aes_cbc_encrypt(struct skcipher_request * req)125647ece481SArd Biesheuvel static int stm32_cryp_aes_cbc_encrypt(struct skcipher_request *req)
12579e054ec2SFabien DESSENNE {
125839e6e699SNicolas Toromanoff 	if (req->cryptlen % AES_BLOCK_SIZE)
125939e6e699SNicolas Toromanoff 		return -EINVAL;
126039e6e699SNicolas Toromanoff 
126139e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
126239e6e699SNicolas Toromanoff 		return 0;
126339e6e699SNicolas Toromanoff 
12649e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_CBC | FLG_ENCRYPT);
12659e054ec2SFabien DESSENNE }
12669e054ec2SFabien DESSENNE 
stm32_cryp_aes_cbc_decrypt(struct skcipher_request * req)126747ece481SArd Biesheuvel static int stm32_cryp_aes_cbc_decrypt(struct skcipher_request *req)
12689e054ec2SFabien DESSENNE {
126939e6e699SNicolas Toromanoff 	if (req->cryptlen % AES_BLOCK_SIZE)
127039e6e699SNicolas Toromanoff 		return -EINVAL;
127139e6e699SNicolas Toromanoff 
127239e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
127339e6e699SNicolas Toromanoff 		return 0;
127439e6e699SNicolas Toromanoff 
12759e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_CBC);
12769e054ec2SFabien DESSENNE }
12779e054ec2SFabien DESSENNE 
stm32_cryp_aes_ctr_encrypt(struct skcipher_request * req)127847ece481SArd Biesheuvel static int stm32_cryp_aes_ctr_encrypt(struct skcipher_request *req)
12799e054ec2SFabien DESSENNE {
128039e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
128139e6e699SNicolas Toromanoff 		return 0;
128239e6e699SNicolas Toromanoff 
12839e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_CTR | FLG_ENCRYPT);
12849e054ec2SFabien DESSENNE }
12859e054ec2SFabien DESSENNE 
stm32_cryp_aes_ctr_decrypt(struct skcipher_request * req)128647ece481SArd Biesheuvel static int stm32_cryp_aes_ctr_decrypt(struct skcipher_request *req)
12879e054ec2SFabien DESSENNE {
128839e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
128939e6e699SNicolas Toromanoff 		return 0;
129039e6e699SNicolas Toromanoff 
12919e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_CTR);
12929e054ec2SFabien DESSENNE }
12939e054ec2SFabien DESSENNE 
stm32_cryp_aes_gcm_encrypt(struct aead_request * req)12949d3b5030SFabien DESSENNE static int stm32_cryp_aes_gcm_encrypt(struct aead_request *req)
12959d3b5030SFabien DESSENNE {
12969d3b5030SFabien DESSENNE 	return stm32_cryp_aead_crypt(req, FLG_AES | FLG_GCM | FLG_ENCRYPT);
12979d3b5030SFabien DESSENNE }
12989d3b5030SFabien DESSENNE 
stm32_cryp_aes_gcm_decrypt(struct aead_request * req)12999d3b5030SFabien DESSENNE static int stm32_cryp_aes_gcm_decrypt(struct aead_request *req)
13009d3b5030SFabien DESSENNE {
13019d3b5030SFabien DESSENNE 	return stm32_cryp_aead_crypt(req, FLG_AES | FLG_GCM);
13029d3b5030SFabien DESSENNE }
13039d3b5030SFabien DESSENNE 
crypto_ccm_check_iv(const u8 * iv)130439e6e699SNicolas Toromanoff static inline int crypto_ccm_check_iv(const u8 *iv)
130539e6e699SNicolas Toromanoff {
130639e6e699SNicolas Toromanoff 	/* 2 <= L <= 8, so 1 <= L' <= 7. */
130739e6e699SNicolas Toromanoff 	if (iv[0] < 1 || iv[0] > 7)
130839e6e699SNicolas Toromanoff 		return -EINVAL;
130939e6e699SNicolas Toromanoff 
131039e6e699SNicolas Toromanoff 	return 0;
131139e6e699SNicolas Toromanoff }
131239e6e699SNicolas Toromanoff 
stm32_cryp_aes_ccm_encrypt(struct aead_request * req)13139d3b5030SFabien DESSENNE static int stm32_cryp_aes_ccm_encrypt(struct aead_request *req)
13149d3b5030SFabien DESSENNE {
131539e6e699SNicolas Toromanoff 	int err;
131639e6e699SNicolas Toromanoff 
131739e6e699SNicolas Toromanoff 	err = crypto_ccm_check_iv(req->iv);
131839e6e699SNicolas Toromanoff 	if (err)
131939e6e699SNicolas Toromanoff 		return err;
132039e6e699SNicolas Toromanoff 
13219d3b5030SFabien DESSENNE 	return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM | FLG_ENCRYPT);
13229d3b5030SFabien DESSENNE }
13239d3b5030SFabien DESSENNE 
stm32_cryp_aes_ccm_decrypt(struct aead_request * req)13249d3b5030SFabien DESSENNE static int stm32_cryp_aes_ccm_decrypt(struct aead_request *req)
13259d3b5030SFabien DESSENNE {
132639e6e699SNicolas Toromanoff 	int err;
132739e6e699SNicolas Toromanoff 
132839e6e699SNicolas Toromanoff 	err = crypto_ccm_check_iv(req->iv);
132939e6e699SNicolas Toromanoff 	if (err)
133039e6e699SNicolas Toromanoff 		return err;
133139e6e699SNicolas Toromanoff 
13329d3b5030SFabien DESSENNE 	return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM);
13339d3b5030SFabien DESSENNE }
13349d3b5030SFabien DESSENNE 
stm32_cryp_des_ecb_encrypt(struct skcipher_request * req)133547ece481SArd Biesheuvel static int stm32_cryp_des_ecb_encrypt(struct skcipher_request *req)
13369e054ec2SFabien DESSENNE {
133739e6e699SNicolas Toromanoff 	if (req->cryptlen % DES_BLOCK_SIZE)
133839e6e699SNicolas Toromanoff 		return -EINVAL;
133939e6e699SNicolas Toromanoff 
134039e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
134139e6e699SNicolas Toromanoff 		return 0;
134239e6e699SNicolas Toromanoff 
13439e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_DES | FLG_ECB | FLG_ENCRYPT);
13449e054ec2SFabien DESSENNE }
13459e054ec2SFabien DESSENNE 
stm32_cryp_des_ecb_decrypt(struct skcipher_request * req)134647ece481SArd Biesheuvel static int stm32_cryp_des_ecb_decrypt(struct skcipher_request *req)
13479e054ec2SFabien DESSENNE {
134839e6e699SNicolas Toromanoff 	if (req->cryptlen % DES_BLOCK_SIZE)
134939e6e699SNicolas Toromanoff 		return -EINVAL;
135039e6e699SNicolas Toromanoff 
135139e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
135239e6e699SNicolas Toromanoff 		return 0;
135339e6e699SNicolas Toromanoff 
13549e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_DES | FLG_ECB);
13559e054ec2SFabien DESSENNE }
13569e054ec2SFabien DESSENNE 
stm32_cryp_des_cbc_encrypt(struct skcipher_request * req)135747ece481SArd Biesheuvel static int stm32_cryp_des_cbc_encrypt(struct skcipher_request *req)
13589e054ec2SFabien DESSENNE {
135939e6e699SNicolas Toromanoff 	if (req->cryptlen % DES_BLOCK_SIZE)
136039e6e699SNicolas Toromanoff 		return -EINVAL;
136139e6e699SNicolas Toromanoff 
136239e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
136339e6e699SNicolas Toromanoff 		return 0;
136439e6e699SNicolas Toromanoff 
13659e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_DES | FLG_CBC | FLG_ENCRYPT);
13669e054ec2SFabien DESSENNE }
13679e054ec2SFabien DESSENNE 
stm32_cryp_des_cbc_decrypt(struct skcipher_request * req)136847ece481SArd Biesheuvel static int stm32_cryp_des_cbc_decrypt(struct skcipher_request *req)
13699e054ec2SFabien DESSENNE {
137039e6e699SNicolas Toromanoff 	if (req->cryptlen % DES_BLOCK_SIZE)
137139e6e699SNicolas Toromanoff 		return -EINVAL;
137239e6e699SNicolas Toromanoff 
137339e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
137439e6e699SNicolas Toromanoff 		return 0;
137539e6e699SNicolas Toromanoff 
13769e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_DES | FLG_CBC);
13779e054ec2SFabien DESSENNE }
13789e054ec2SFabien DESSENNE 
stm32_cryp_tdes_ecb_encrypt(struct skcipher_request * req)137947ece481SArd Biesheuvel static int stm32_cryp_tdes_ecb_encrypt(struct skcipher_request *req)
13809e054ec2SFabien DESSENNE {
138139e6e699SNicolas Toromanoff 	if (req->cryptlen % DES_BLOCK_SIZE)
138239e6e699SNicolas Toromanoff 		return -EINVAL;
138339e6e699SNicolas Toromanoff 
138439e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
138539e6e699SNicolas Toromanoff 		return 0;
138639e6e699SNicolas Toromanoff 
13879e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB | FLG_ENCRYPT);
13889e054ec2SFabien DESSENNE }
13899e054ec2SFabien DESSENNE 
stm32_cryp_tdes_ecb_decrypt(struct skcipher_request * req)139047ece481SArd Biesheuvel static int stm32_cryp_tdes_ecb_decrypt(struct skcipher_request *req)
13919e054ec2SFabien DESSENNE {
139239e6e699SNicolas Toromanoff 	if (req->cryptlen % DES_BLOCK_SIZE)
139339e6e699SNicolas Toromanoff 		return -EINVAL;
139439e6e699SNicolas Toromanoff 
139539e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
139639e6e699SNicolas Toromanoff 		return 0;
139739e6e699SNicolas Toromanoff 
13989e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB);
13999e054ec2SFabien DESSENNE }
14009e054ec2SFabien DESSENNE 
stm32_cryp_tdes_cbc_encrypt(struct skcipher_request * req)140147ece481SArd Biesheuvel static int stm32_cryp_tdes_cbc_encrypt(struct skcipher_request *req)
14029e054ec2SFabien DESSENNE {
140339e6e699SNicolas Toromanoff 	if (req->cryptlen % DES_BLOCK_SIZE)
140439e6e699SNicolas Toromanoff 		return -EINVAL;
140539e6e699SNicolas Toromanoff 
140639e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
140739e6e699SNicolas Toromanoff 		return 0;
140839e6e699SNicolas Toromanoff 
14099e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC | FLG_ENCRYPT);
14109e054ec2SFabien DESSENNE }
14119e054ec2SFabien DESSENNE 
stm32_cryp_tdes_cbc_decrypt(struct skcipher_request * req)141247ece481SArd Biesheuvel static int stm32_cryp_tdes_cbc_decrypt(struct skcipher_request *req)
14139e054ec2SFabien DESSENNE {
141439e6e699SNicolas Toromanoff 	if (req->cryptlen % DES_BLOCK_SIZE)
141539e6e699SNicolas Toromanoff 		return -EINVAL;
141639e6e699SNicolas Toromanoff 
141739e6e699SNicolas Toromanoff 	if (req->cryptlen == 0)
141839e6e699SNicolas Toromanoff 		return 0;
141939e6e699SNicolas Toromanoff 
14209e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC);
14219e054ec2SFabien DESSENNE }
14229e054ec2SFabien DESSENNE 
stm32_cryp_dma_check_sg(struct scatterlist * test_sg,size_t len,size_t block_size)1423fb11a4f6SMaxime Méré static enum stm32_dma_mode stm32_cryp_dma_check_sg(struct scatterlist *test_sg, size_t len,
1424fb11a4f6SMaxime Méré 						   size_t block_size)
1425fb11a4f6SMaxime Méré {
1426fb11a4f6SMaxime Méré 	struct scatterlist *sg;
1427fb11a4f6SMaxime Méré 	int i;
1428fb11a4f6SMaxime Méré 
1429fb11a4f6SMaxime Méré 	if (len <= 16)
1430fb11a4f6SMaxime Méré 		return NO_DMA; /* Faster */
1431fb11a4f6SMaxime Méré 
1432fb11a4f6SMaxime Méré 	for_each_sg(test_sg, sg, sg_nents(test_sg), i) {
1433fb11a4f6SMaxime Méré 		if (!IS_ALIGNED(sg->length, block_size) && !sg_is_last(sg))
1434fb11a4f6SMaxime Méré 			return NO_DMA;
1435fb11a4f6SMaxime Méré 
1436fb11a4f6SMaxime Méré 		if (sg->offset % sizeof(u32))
1437fb11a4f6SMaxime Méré 			return NO_DMA;
1438fb11a4f6SMaxime Méré 
1439fb11a4f6SMaxime Méré 		if (sg_is_last(sg) && !IS_ALIGNED(sg->length, AES_BLOCK_SIZE))
1440fb11a4f6SMaxime Méré 			return DMA_NEED_SG_TRUNC;
1441fb11a4f6SMaxime Méré 	}
1442fb11a4f6SMaxime Méré 
1443fb11a4f6SMaxime Méré 	return DMA_PLAIN_SG;
1444fb11a4f6SMaxime Méré }
1445fb11a4f6SMaxime Méré 
stm32_cryp_dma_check(struct stm32_cryp * cryp,struct scatterlist * in_sg,struct scatterlist * out_sg)1446fb11a4f6SMaxime Méré static enum stm32_dma_mode stm32_cryp_dma_check(struct stm32_cryp *cryp, struct scatterlist *in_sg,
1447fb11a4f6SMaxime Méré 						struct scatterlist *out_sg)
1448fb11a4f6SMaxime Méré {
1449fb11a4f6SMaxime Méré 	enum stm32_dma_mode ret = DMA_PLAIN_SG;
1450fb11a4f6SMaxime Méré 
1451fb11a4f6SMaxime Méré 	if (!is_aes(cryp))
1452fb11a4f6SMaxime Méré 		return NO_DMA;
1453fb11a4f6SMaxime Méré 
1454fb11a4f6SMaxime Méré 	if (!cryp->dma_lch_in || !cryp->dma_lch_out)
1455fb11a4f6SMaxime Méré 		return NO_DMA;
1456fb11a4f6SMaxime Méré 
1457fb11a4f6SMaxime Méré 	ret = stm32_cryp_dma_check_sg(in_sg, cryp->payload_in, AES_BLOCK_SIZE);
1458fb11a4f6SMaxime Méré 	if (ret == NO_DMA)
1459fb11a4f6SMaxime Méré 		return ret;
1460fb11a4f6SMaxime Méré 
1461fb11a4f6SMaxime Méré 	ret = stm32_cryp_dma_check_sg(out_sg, cryp->payload_out, AES_BLOCK_SIZE);
1462fb11a4f6SMaxime Méré 	if (ret == NO_DMA)
1463fb11a4f6SMaxime Méré 		return ret;
1464fb11a4f6SMaxime Méré 
1465fb11a4f6SMaxime Méré 	/* Check CTR counter overflow */
1466fb11a4f6SMaxime Méré 	if (is_aes(cryp) && is_ctr(cryp)) {
1467fb11a4f6SMaxime Méré 		u32 c;
1468fb11a4f6SMaxime Méré 		__be32 iv3;
1469fb11a4f6SMaxime Méré 
1470fb11a4f6SMaxime Méré 		memcpy(&iv3, &cryp->req->iv[3 * sizeof(u32)], sizeof(iv3));
1471fb11a4f6SMaxime Méré 		c = be32_to_cpu(iv3);
1472fb11a4f6SMaxime Méré 		if ((c + cryp->payload_in) < cryp->payload_in)
1473fb11a4f6SMaxime Méré 			return NO_DMA;
1474fb11a4f6SMaxime Méré 	}
1475fb11a4f6SMaxime Méré 
1476fb11a4f6SMaxime Méré 	/* Workaround */
1477fb11a4f6SMaxime Méré 	if (is_aes(cryp) && is_ctr(cryp) && ret == DMA_NEED_SG_TRUNC)
1478fb11a4f6SMaxime Méré 		return NO_DMA;
1479fb11a4f6SMaxime Méré 
1480fb11a4f6SMaxime Méré 	return ret;
1481fb11a4f6SMaxime Méré }
1482fb11a4f6SMaxime Méré 
stm32_cryp_truncate_sg(struct scatterlist ** new_sg,size_t * new_sg_len,struct scatterlist * sg,off_t skip,size_t size)1483fb11a4f6SMaxime Méré static int stm32_cryp_truncate_sg(struct scatterlist **new_sg, size_t *new_sg_len,
1484fb11a4f6SMaxime Méré 				  struct scatterlist *sg, off_t skip, size_t size)
1485fb11a4f6SMaxime Méré {
1486fb11a4f6SMaxime Méré 	struct scatterlist *cur;
1487fb11a4f6SMaxime Méré 	int alloc_sg_len;
1488fb11a4f6SMaxime Méré 
1489fb11a4f6SMaxime Méré 	*new_sg_len = 0;
1490fb11a4f6SMaxime Méré 
1491fb11a4f6SMaxime Méré 	if (!sg || !size) {
1492fb11a4f6SMaxime Méré 		*new_sg = NULL;
1493fb11a4f6SMaxime Méré 		return 0;
1494fb11a4f6SMaxime Méré 	}
1495fb11a4f6SMaxime Méré 
1496fb11a4f6SMaxime Méré 	alloc_sg_len = sg_nents_for_len(sg, skip + size);
1497fb11a4f6SMaxime Méré 	if (alloc_sg_len < 0)
1498fb11a4f6SMaxime Méré 		return alloc_sg_len;
1499fb11a4f6SMaxime Méré 
1500fb11a4f6SMaxime Méré 	/* We allocate to much sg entry, but it is easier */
1501fb11a4f6SMaxime Méré 	*new_sg = kmalloc_array((size_t)alloc_sg_len, sizeof(struct scatterlist), GFP_KERNEL);
1502fb11a4f6SMaxime Méré 	if (!*new_sg)
1503fb11a4f6SMaxime Méré 		return -ENOMEM;
1504fb11a4f6SMaxime Méré 
1505fb11a4f6SMaxime Méré 	sg_init_table(*new_sg, (unsigned int)alloc_sg_len);
1506fb11a4f6SMaxime Méré 
1507fb11a4f6SMaxime Méré 	cur = *new_sg;
1508fb11a4f6SMaxime Méré 	while (sg && size) {
1509fb11a4f6SMaxime Méré 		unsigned int len = sg->length;
1510fb11a4f6SMaxime Méré 		unsigned int offset = sg->offset;
1511fb11a4f6SMaxime Méré 
1512fb11a4f6SMaxime Méré 		if (skip > len) {
1513fb11a4f6SMaxime Méré 			skip -= len;
1514fb11a4f6SMaxime Méré 			sg = sg_next(sg);
1515fb11a4f6SMaxime Méré 			continue;
1516fb11a4f6SMaxime Méré 		}
1517fb11a4f6SMaxime Méré 
1518fb11a4f6SMaxime Méré 		if (skip) {
1519fb11a4f6SMaxime Méré 			len -= skip;
1520fb11a4f6SMaxime Méré 			offset += skip;
1521fb11a4f6SMaxime Méré 			skip = 0;
1522fb11a4f6SMaxime Méré 		}
1523fb11a4f6SMaxime Méré 
1524fb11a4f6SMaxime Méré 		if (size < len)
1525fb11a4f6SMaxime Méré 			len = size;
1526fb11a4f6SMaxime Méré 
1527fb11a4f6SMaxime Méré 		if (len > 0) {
1528fb11a4f6SMaxime Méré 			(*new_sg_len)++;
1529fb11a4f6SMaxime Méré 			size -= len;
1530fb11a4f6SMaxime Méré 			sg_set_page(cur, sg_page(sg), len, offset);
1531fb11a4f6SMaxime Méré 			if (size == 0)
1532fb11a4f6SMaxime Méré 				sg_mark_end(cur);
1533fb11a4f6SMaxime Méré 			cur = sg_next(cur);
1534fb11a4f6SMaxime Méré 		}
1535fb11a4f6SMaxime Méré 
1536fb11a4f6SMaxime Méré 		sg = sg_next(sg);
1537fb11a4f6SMaxime Méré 	}
1538fb11a4f6SMaxime Méré 
1539fb11a4f6SMaxime Méré 	return 0;
1540fb11a4f6SMaxime Méré }
1541fb11a4f6SMaxime Méré 
stm32_cryp_cipher_prepare(struct stm32_cryp * cryp,struct scatterlist * in_sg,struct scatterlist * out_sg)1542fb11a4f6SMaxime Méré static int stm32_cryp_cipher_prepare(struct stm32_cryp *cryp, struct scatterlist *in_sg,
1543fb11a4f6SMaxime Méré 				     struct scatterlist *out_sg)
1544fb11a4f6SMaxime Méré {
1545fb11a4f6SMaxime Méré 	size_t align_size;
1546fb11a4f6SMaxime Méré 	int ret;
1547fb11a4f6SMaxime Méré 
1548fb11a4f6SMaxime Méré 	cryp->dma_mode = stm32_cryp_dma_check(cryp, in_sg, out_sg);
1549fb11a4f6SMaxime Méré 
1550fb11a4f6SMaxime Méré 	scatterwalk_start(&cryp->in_walk, in_sg);
1551fb11a4f6SMaxime Méré 	scatterwalk_start(&cryp->out_walk, out_sg);
1552fb11a4f6SMaxime Méré 
1553fb11a4f6SMaxime Méré 	if (cryp->dma_mode == NO_DMA) {
1554fb11a4f6SMaxime Méré 		cryp->flags &= ~FLG_IN_OUT_DMA;
1555fb11a4f6SMaxime Méré 
1556fb11a4f6SMaxime Méré 		if (is_ctr(cryp))
1557fb11a4f6SMaxime Méré 			memset(cryp->last_ctr, 0, sizeof(cryp->last_ctr));
1558fb11a4f6SMaxime Méré 
1559fb11a4f6SMaxime Méré 	} else if (cryp->dma_mode == DMA_NEED_SG_TRUNC) {
1560fb11a4f6SMaxime Méré 
1561fb11a4f6SMaxime Méré 		cryp->flags |= FLG_IN_OUT_DMA;
1562fb11a4f6SMaxime Méré 
1563fb11a4f6SMaxime Méré 		align_size = ALIGN_DOWN(cryp->payload_in, cryp->hw_blocksize);
1564fb11a4f6SMaxime Méré 		ret = stm32_cryp_truncate_sg(&cryp->in_sg, &cryp->in_sg_len, in_sg, 0, align_size);
1565fb11a4f6SMaxime Méré 		if (ret)
1566fb11a4f6SMaxime Méré 			return ret;
1567fb11a4f6SMaxime Méré 
1568fb11a4f6SMaxime Méré 		ret = stm32_cryp_truncate_sg(&cryp->out_sg, &cryp->out_sg_len, out_sg, 0,
1569fb11a4f6SMaxime Méré 					     align_size);
1570fb11a4f6SMaxime Méré 		if (ret) {
1571fb11a4f6SMaxime Méré 			kfree(cryp->in_sg);
1572fb11a4f6SMaxime Méré 			return ret;
1573fb11a4f6SMaxime Méré 		}
1574fb11a4f6SMaxime Méré 	} else {
1575fb11a4f6SMaxime Méré 		cryp->flags |= FLG_IN_OUT_DMA;
1576fb11a4f6SMaxime Méré 
1577fb11a4f6SMaxime Méré 		cryp->in_sg = in_sg;
1578fb11a4f6SMaxime Méré 		cryp->out_sg = out_sg;
1579fb11a4f6SMaxime Méré 
1580fb11a4f6SMaxime Méré 		ret = sg_nents_for_len(cryp->in_sg, cryp->payload_in);
1581fb11a4f6SMaxime Méré 		if (ret < 0)
1582fb11a4f6SMaxime Méré 			return ret;
1583fb11a4f6SMaxime Méré 		cryp->in_sg_len = (size_t)ret;
1584fb11a4f6SMaxime Méré 
1585fb11a4f6SMaxime Méré 		ret = sg_nents_for_len(out_sg, cryp->payload_out);
1586fb11a4f6SMaxime Méré 		if (ret < 0)
1587fb11a4f6SMaxime Méré 			return ret;
1588fb11a4f6SMaxime Méré 		cryp->out_sg_len = (size_t)ret;
1589fb11a4f6SMaxime Méré 	}
1590fb11a4f6SMaxime Méré 
1591fb11a4f6SMaxime Méré 	return 0;
1592fb11a4f6SMaxime Méré }
1593fb11a4f6SMaxime Méré 
stm32_cryp_aead_prepare(struct stm32_cryp * cryp,struct scatterlist * in_sg,struct scatterlist * out_sg)1594fb11a4f6SMaxime Méré static int stm32_cryp_aead_prepare(struct stm32_cryp *cryp, struct scatterlist *in_sg,
1595fb11a4f6SMaxime Méré 				   struct scatterlist *out_sg)
1596fb11a4f6SMaxime Méré {
1597fb11a4f6SMaxime Méré 	size_t align_size;
1598fb11a4f6SMaxime Méré 	off_t skip;
1599fb11a4f6SMaxime Méré 	int ret, ret2;
1600fb11a4f6SMaxime Méré 
1601fb11a4f6SMaxime Méré 	cryp->header_sg = NULL;
1602fb11a4f6SMaxime Méré 	cryp->in_sg = NULL;
1603fb11a4f6SMaxime Méré 	cryp->out_sg = NULL;
1604fb11a4f6SMaxime Méré 
1605fb11a4f6SMaxime Méré 	if (!cryp->dma_lch_in || !cryp->dma_lch_out) {
1606fb11a4f6SMaxime Méré 		cryp->dma_mode = NO_DMA;
1607fb11a4f6SMaxime Méré 		cryp->flags &= ~(FLG_IN_OUT_DMA | FLG_HEADER_DMA);
1608fb11a4f6SMaxime Méré 
1609fb11a4f6SMaxime Méré 		return 0;
1610fb11a4f6SMaxime Méré 	}
1611fb11a4f6SMaxime Méré 
1612fb11a4f6SMaxime Méré 	/* CCM hw_init may have advanced in header */
1613fb11a4f6SMaxime Méré 	skip = cryp->areq->assoclen - cryp->header_in;
1614fb11a4f6SMaxime Méré 
1615fb11a4f6SMaxime Méré 	align_size = ALIGN_DOWN(cryp->header_in, cryp->hw_blocksize);
1616fb11a4f6SMaxime Méré 	ret = stm32_cryp_truncate_sg(&cryp->header_sg, &cryp->header_sg_len, in_sg, skip,
1617fb11a4f6SMaxime Méré 				     align_size);
1618fb11a4f6SMaxime Méré 	if (ret)
1619fb11a4f6SMaxime Méré 		return ret;
1620fb11a4f6SMaxime Méré 
1621fb11a4f6SMaxime Méré 	ret = stm32_cryp_dma_check_sg(cryp->header_sg, align_size, AES_BLOCK_SIZE);
1622fb11a4f6SMaxime Méré 	if (ret == NO_DMA) {
1623fb11a4f6SMaxime Méré 		/* We cannot DMA the header */
1624fb11a4f6SMaxime Méré 		kfree(cryp->header_sg);
1625fb11a4f6SMaxime Méré 		cryp->header_sg = NULL;
1626fb11a4f6SMaxime Méré 
1627fb11a4f6SMaxime Méré 		cryp->flags &= ~FLG_HEADER_DMA;
1628fb11a4f6SMaxime Méré 	} else {
1629fb11a4f6SMaxime Méré 		cryp->flags |= FLG_HEADER_DMA;
1630fb11a4f6SMaxime Méré 	}
1631fb11a4f6SMaxime Méré 
1632fb11a4f6SMaxime Méré 	/* Now skip all header to be at payload start */
1633fb11a4f6SMaxime Méré 	skip = cryp->areq->assoclen;
1634fb11a4f6SMaxime Méré 	align_size = ALIGN_DOWN(cryp->payload_in, cryp->hw_blocksize);
1635fb11a4f6SMaxime Méré 	ret = stm32_cryp_truncate_sg(&cryp->in_sg, &cryp->in_sg_len, in_sg, skip, align_size);
1636fb11a4f6SMaxime Méré 	if (ret) {
1637fb11a4f6SMaxime Méré 		kfree(cryp->header_sg);
1638fb11a4f6SMaxime Méré 		return ret;
1639fb11a4f6SMaxime Méré 	}
1640fb11a4f6SMaxime Méré 
1641fb11a4f6SMaxime Méré 	/* For out buffer align_size is same as in buffer */
1642fb11a4f6SMaxime Méré 	ret = stm32_cryp_truncate_sg(&cryp->out_sg, &cryp->out_sg_len, out_sg, skip, align_size);
1643fb11a4f6SMaxime Méré 	if (ret) {
1644fb11a4f6SMaxime Méré 		kfree(cryp->header_sg);
1645fb11a4f6SMaxime Méré 		kfree(cryp->in_sg);
1646fb11a4f6SMaxime Méré 		return ret;
1647fb11a4f6SMaxime Méré 	}
1648fb11a4f6SMaxime Méré 
1649fb11a4f6SMaxime Méré 	ret = stm32_cryp_dma_check_sg(cryp->in_sg, align_size, AES_BLOCK_SIZE);
1650fb11a4f6SMaxime Méré 	ret2 = stm32_cryp_dma_check_sg(cryp->out_sg, align_size, AES_BLOCK_SIZE);
1651fb11a4f6SMaxime Méré 	if (ret == NO_DMA || ret2 == NO_DMA) {
1652fb11a4f6SMaxime Méré 		kfree(cryp->in_sg);
1653fb11a4f6SMaxime Méré 		cryp->in_sg = NULL;
1654fb11a4f6SMaxime Méré 
1655fb11a4f6SMaxime Méré 		kfree(cryp->out_sg);
1656fb11a4f6SMaxime Méré 		cryp->out_sg = NULL;
1657fb11a4f6SMaxime Méré 
1658fb11a4f6SMaxime Méré 		cryp->flags &= ~FLG_IN_OUT_DMA;
1659fb11a4f6SMaxime Méré 	} else {
1660fb11a4f6SMaxime Méré 		cryp->flags |= FLG_IN_OUT_DMA;
1661fb11a4f6SMaxime Méré 	}
1662fb11a4f6SMaxime Méré 
1663fb11a4f6SMaxime Méré 	return 0;
1664fb11a4f6SMaxime Méré }
1665fb11a4f6SMaxime Méré 
stm32_cryp_prepare_req(struct skcipher_request * req,struct aead_request * areq)166647ece481SArd Biesheuvel static int stm32_cryp_prepare_req(struct skcipher_request *req,
16679d3b5030SFabien DESSENNE 				  struct aead_request *areq)
16689e054ec2SFabien DESSENNE {
16699e054ec2SFabien DESSENNE 	struct stm32_cryp_ctx *ctx;
16709e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp;
16719e054ec2SFabien DESSENNE 	struct stm32_cryp_reqctx *rctx;
1672fb11a4f6SMaxime Méré 	struct scatterlist *in_sg, *out_sg;
16739e054ec2SFabien DESSENNE 	int ret;
16749e054ec2SFabien DESSENNE 
16759d3b5030SFabien DESSENNE 	if (!req && !areq)
16769e054ec2SFabien DESSENNE 		return -EINVAL;
16779e054ec2SFabien DESSENNE 
167847ece481SArd Biesheuvel 	ctx = req ? crypto_skcipher_ctx(crypto_skcipher_reqtfm(req)) :
16799d3b5030SFabien DESSENNE 		    crypto_aead_ctx(crypto_aead_reqtfm(areq));
16809e054ec2SFabien DESSENNE 
16819e054ec2SFabien DESSENNE 	cryp = ctx->cryp;
16829e054ec2SFabien DESSENNE 
168347ece481SArd Biesheuvel 	rctx = req ? skcipher_request_ctx(req) : aead_request_ctx(areq);
16849e054ec2SFabien DESSENNE 	rctx->mode &= FLG_MODE_MASK;
16859e054ec2SFabien DESSENNE 
16869e054ec2SFabien DESSENNE 	cryp->flags = (cryp->flags & ~FLG_MODE_MASK) | rctx->mode;
16879e054ec2SFabien DESSENNE 	cryp->hw_blocksize = is_aes(cryp) ? AES_BLOCK_SIZE : DES_BLOCK_SIZE;
16889e054ec2SFabien DESSENNE 	cryp->ctx = ctx;
16899e054ec2SFabien DESSENNE 
16909d3b5030SFabien DESSENNE 	if (req) {
16919e054ec2SFabien DESSENNE 		cryp->req = req;
169229aed438SLionel Debieve 		cryp->areq = NULL;
16934b898d5cSNicolas Toromanoff 		cryp->header_in = 0;
16944b898d5cSNicolas Toromanoff 		cryp->payload_in = req->cryptlen;
16954b898d5cSNicolas Toromanoff 		cryp->payload_out = req->cryptlen;
16964b898d5cSNicolas Toromanoff 		cryp->authsize = 0;
1697fb11a4f6SMaxime Méré 
1698fb11a4f6SMaxime Méré 		in_sg = req->src;
1699fb11a4f6SMaxime Méré 		out_sg = req->dst;
1700fb11a4f6SMaxime Méré 
1701fb11a4f6SMaxime Méré 		ret = stm32_cryp_cipher_prepare(cryp, in_sg, out_sg);
1702fb11a4f6SMaxime Méré 		if (ret)
1703fb11a4f6SMaxime Méré 			return ret;
1704fb11a4f6SMaxime Méré 
1705fb11a4f6SMaxime Méré 		ret = stm32_cryp_hw_init(cryp);
17069d3b5030SFabien DESSENNE 	} else {
17079d3b5030SFabien DESSENNE 		/*
17089d3b5030SFabien DESSENNE 		 * Length of input and output data:
17099d3b5030SFabien DESSENNE 		 * Encryption case:
17109d3b5030SFabien DESSENNE 		 *  INPUT  = AssocData   ||     PlainText
17119d3b5030SFabien DESSENNE 		 *          <- assoclen ->  <- cryptlen ->
17129d3b5030SFabien DESSENNE 		 *
17139d3b5030SFabien DESSENNE 		 *  OUTPUT = AssocData    ||   CipherText   ||      AuthTag
17144b898d5cSNicolas Toromanoff 		 *          <- assoclen ->  <-- cryptlen -->  <- authsize ->
17159d3b5030SFabien DESSENNE 		 *
17169d3b5030SFabien DESSENNE 		 * Decryption case:
17174b898d5cSNicolas Toromanoff 		 *  INPUT  =  AssocData     ||    CipherTex   ||       AuthTag
17184b898d5cSNicolas Toromanoff 		 *          <- assoclen --->  <---------- cryptlen ---------->
17199d3b5030SFabien DESSENNE 		 *
17209d3b5030SFabien DESSENNE 		 *  OUTPUT = AssocData    ||               PlainText
17214b898d5cSNicolas Toromanoff 		 *          <- assoclen ->  <- cryptlen - authsize ->
17229d3b5030SFabien DESSENNE 		 */
17239d3b5030SFabien DESSENNE 		cryp->areq = areq;
172429aed438SLionel Debieve 		cryp->req = NULL;
17259d3b5030SFabien DESSENNE 		cryp->authsize = crypto_aead_authsize(crypto_aead_reqtfm(areq));
17264b898d5cSNicolas Toromanoff 		if (is_encrypt(cryp)) {
17274b898d5cSNicolas Toromanoff 			cryp->payload_in = areq->cryptlen;
17284b898d5cSNicolas Toromanoff 			cryp->header_in = areq->assoclen;
17294b898d5cSNicolas Toromanoff 			cryp->payload_out = areq->cryptlen;
17304b898d5cSNicolas Toromanoff 		} else {
17314b898d5cSNicolas Toromanoff 			cryp->payload_in = areq->cryptlen - cryp->authsize;
17324b898d5cSNicolas Toromanoff 			cryp->header_in = areq->assoclen;
17334b898d5cSNicolas Toromanoff 			cryp->payload_out = cryp->payload_in;
17344b898d5cSNicolas Toromanoff 		}
17359e054ec2SFabien DESSENNE 
1736fb11a4f6SMaxime Méré 		in_sg = areq->src;
1737fb11a4f6SMaxime Méré 		out_sg = areq->dst;
1738fb11a4f6SMaxime Méré 
17394b898d5cSNicolas Toromanoff 		scatterwalk_start(&cryp->in_walk, in_sg);
1740fb11a4f6SMaxime Méré 		scatterwalk_start(&cryp->out_walk, out_sg);
17419d3b5030SFabien DESSENNE 		/* In output, jump after assoc data */
17424b898d5cSNicolas Toromanoff 		scatterwalk_copychunks(NULL, &cryp->out_walk, cryp->areq->assoclen, 2);
17434b898d5cSNicolas Toromanoff 
17449e054ec2SFabien DESSENNE 		ret = stm32_cryp_hw_init(cryp);
1745fb11a4f6SMaxime Méré 		if (ret)
1746fb11a4f6SMaxime Méré 			return ret;
1747fb11a4f6SMaxime Méré 
1748fb11a4f6SMaxime Méré 		ret = stm32_cryp_aead_prepare(cryp, in_sg, out_sg);
1749fb11a4f6SMaxime Méré 	}
1750fb11a4f6SMaxime Méré 
17519e054ec2SFabien DESSENNE 	return ret;
17529e054ec2SFabien DESSENNE }
17539e054ec2SFabien DESSENNE 
stm32_cryp_cipher_one_req(struct crypto_engine * engine,void * areq)1754dc7bcef5SCorentin LABBE static int stm32_cryp_cipher_one_req(struct crypto_engine *engine, void *areq)
17559e054ec2SFabien DESSENNE {
175647ece481SArd Biesheuvel 	struct skcipher_request *req = container_of(areq,
175747ece481SArd Biesheuvel 						      struct skcipher_request,
1758dc7bcef5SCorentin LABBE 						      base);
175947ece481SArd Biesheuvel 	struct stm32_cryp_ctx *ctx = crypto_skcipher_ctx(
176047ece481SArd Biesheuvel 			crypto_skcipher_reqtfm(req));
17619e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = ctx->cryp;
1762fb11a4f6SMaxime Méré 	int ret;
17639e054ec2SFabien DESSENNE 
17649e054ec2SFabien DESSENNE 	if (!cryp)
17659e054ec2SFabien DESSENNE 		return -ENODEV;
17669e054ec2SFabien DESSENNE 
1767fb11a4f6SMaxime Méré 	ret = stm32_cryp_prepare_req(req, NULL);
1768fb11a4f6SMaxime Méré 	if (ret)
1769fb11a4f6SMaxime Méré 		return ret;
1770fb11a4f6SMaxime Méré 
1771fb11a4f6SMaxime Méré 	if (cryp->flags & FLG_IN_OUT_DMA)
1772fb11a4f6SMaxime Méré 		ret = stm32_cryp_dma_start(cryp);
1773fb11a4f6SMaxime Méré 	else
1774fb11a4f6SMaxime Méré 		ret = stm32_cryp_it_start(cryp);
1775fb11a4f6SMaxime Méré 
1776fb11a4f6SMaxime Méré 	if (ret == -ETIMEDOUT)
1777fb11a4f6SMaxime Méré 		stm32_cryp_finish_req(cryp, ret);
1778fb11a4f6SMaxime Méré 
1779fb11a4f6SMaxime Méré 	return ret;
17809d3b5030SFabien DESSENNE }
17819d3b5030SFabien DESSENNE 
stm32_cryp_aead_one_req(struct crypto_engine * engine,void * areq)17829d3b5030SFabien DESSENNE static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq)
17839d3b5030SFabien DESSENNE {
17849d3b5030SFabien DESSENNE 	struct aead_request *req = container_of(areq, struct aead_request,
17859d3b5030SFabien DESSENNE 						base);
17869d3b5030SFabien DESSENNE 	struct stm32_cryp_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
17879d3b5030SFabien DESSENNE 	struct stm32_cryp *cryp = ctx->cryp;
17886912b79dSHerbert Xu 	int err;
17899d3b5030SFabien DESSENNE 
17909d3b5030SFabien DESSENNE 	if (!cryp)
17919d3b5030SFabien DESSENNE 		return -ENODEV;
17929d3b5030SFabien DESSENNE 
17936912b79dSHerbert Xu 	err = stm32_cryp_prepare_req(NULL, req);
17946912b79dSHerbert Xu 	if (err)
17956912b79dSHerbert Xu 		return err;
17966912b79dSHerbert Xu 
1797fb11a4f6SMaxime Méré 	if (!stm32_cryp_get_input_text_len(cryp) && !cryp->header_in &&
1798fb11a4f6SMaxime Méré 	    !(cryp->flags & FLG_HEADER_DMA)) {
17999d3b5030SFabien DESSENNE 		/* No input data to process: get tag and finish */
18009d3b5030SFabien DESSENNE 		stm32_cryp_finish_req(cryp, 0);
18019d3b5030SFabien DESSENNE 		return 0;
18029d3b5030SFabien DESSENNE 	}
18039d3b5030SFabien DESSENNE 
1804fb11a4f6SMaxime Méré 	if (cryp->flags & FLG_HEADER_DMA)
1805fb11a4f6SMaxime Méré 		return stm32_cryp_header_dma_start(cryp);
1806fb11a4f6SMaxime Méré 
1807fb11a4f6SMaxime Méré 	if (!cryp->header_in && cryp->flags & FLG_IN_OUT_DMA)
1808fb11a4f6SMaxime Méré 		return stm32_cryp_dma_start(cryp);
1809fb11a4f6SMaxime Méré 
1810fb11a4f6SMaxime Méré 	return stm32_cryp_it_start(cryp);
18119d3b5030SFabien DESSENNE }
18129d3b5030SFabien DESSENNE 
stm32_cryp_read_auth_tag(struct stm32_cryp * cryp)18139d3b5030SFabien DESSENNE static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp)
18149d3b5030SFabien DESSENNE {
18154b898d5cSNicolas Toromanoff 	u32 cfg, size_bit;
18164b898d5cSNicolas Toromanoff 	unsigned int i;
18179d3b5030SFabien DESSENNE 	int ret = 0;
18189d3b5030SFabien DESSENNE 
18199d3b5030SFabien DESSENNE 	/* Update Config */
18200b496efbSLinus Walleij 	cfg = stm32_cryp_read(cryp, cryp->caps->cr);
18219d3b5030SFabien DESSENNE 
18229d3b5030SFabien DESSENNE 	cfg &= ~CR_PH_MASK;
18239d3b5030SFabien DESSENNE 	cfg |= CR_PH_FINAL;
18249d3b5030SFabien DESSENNE 	cfg &= ~CR_DEC_NOT_ENC;
18259d3b5030SFabien DESSENNE 	cfg |= CR_CRYPEN;
18269d3b5030SFabien DESSENNE 
18270b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
18289d3b5030SFabien DESSENNE 
18299d3b5030SFabien DESSENNE 	if (is_gcm(cryp)) {
18309d3b5030SFabien DESSENNE 		/* GCM: write aad and payload size (in bits) */
18319d3b5030SFabien DESSENNE 		size_bit = cryp->areq->assoclen * 8;
18329d3b5030SFabien DESSENNE 		if (cryp->caps->swap_final)
1833bbb28326SHerbert Xu 			size_bit = (__force u32)cpu_to_be32(size_bit);
18349d3b5030SFabien DESSENNE 
18350b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->din, 0);
18360b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->din, size_bit);
18379d3b5030SFabien DESSENNE 
18389d3b5030SFabien DESSENNE 		size_bit = is_encrypt(cryp) ? cryp->areq->cryptlen :
18394b898d5cSNicolas Toromanoff 				cryp->areq->cryptlen - cryp->authsize;
18409d3b5030SFabien DESSENNE 		size_bit *= 8;
18419d3b5030SFabien DESSENNE 		if (cryp->caps->swap_final)
1842bbb28326SHerbert Xu 			size_bit = (__force u32)cpu_to_be32(size_bit);
18439d3b5030SFabien DESSENNE 
18440b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->din, 0);
18450b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->din, size_bit);
18469d3b5030SFabien DESSENNE 	} else {
18479d3b5030SFabien DESSENNE 		/* CCM: write CTR0 */
18484b898d5cSNicolas Toromanoff 		u32 iv32[AES_BLOCK_32];
18494b898d5cSNicolas Toromanoff 		u8 *iv = (u8 *)iv32;
18504b898d5cSNicolas Toromanoff 		__be32 *biv = (__be32 *)iv32;
18519d3b5030SFabien DESSENNE 
18529d3b5030SFabien DESSENNE 		memcpy(iv, cryp->areq->iv, AES_BLOCK_SIZE);
18539d3b5030SFabien DESSENNE 		memset(iv + AES_BLOCK_SIZE - 1 - iv[0], 0, iv[0] + 1);
18549d3b5030SFabien DESSENNE 
18559d3b5030SFabien DESSENNE 		for (i = 0; i < AES_BLOCK_32; i++) {
1856bbb28326SHerbert Xu 			u32 xiv = iv32[i];
1857bbb28326SHerbert Xu 
18589d3b5030SFabien DESSENNE 			if (!cryp->caps->padding_wa)
1859bbb28326SHerbert Xu 				xiv = be32_to_cpu(biv[i]);
18600b496efbSLinus Walleij 			stm32_cryp_write(cryp, cryp->caps->din, xiv);
18619d3b5030SFabien DESSENNE 		}
18629d3b5030SFabien DESSENNE 	}
18639d3b5030SFabien DESSENNE 
18649d3b5030SFabien DESSENNE 	/* Wait for output data */
18659d3b5030SFabien DESSENNE 	ret = stm32_cryp_wait_output(cryp);
18669d3b5030SFabien DESSENNE 	if (ret) {
18679d3b5030SFabien DESSENNE 		dev_err(cryp->dev, "Timeout (read tag)\n");
18689d3b5030SFabien DESSENNE 		return ret;
18699d3b5030SFabien DESSENNE 	}
18709d3b5030SFabien DESSENNE 
18719d3b5030SFabien DESSENNE 	if (is_encrypt(cryp)) {
18724b898d5cSNicolas Toromanoff 		u32 out_tag[AES_BLOCK_32];
18734b898d5cSNicolas Toromanoff 
18749d3b5030SFabien DESSENNE 		/* Get and write tag */
1875319ad16dSLinus Walleij 		readsl(cryp->regs + cryp->caps->dout, out_tag, AES_BLOCK_32);
18764b898d5cSNicolas Toromanoff 		scatterwalk_copychunks(out_tag, &cryp->out_walk, cryp->authsize, 1);
18779d3b5030SFabien DESSENNE 	} else {
18789d3b5030SFabien DESSENNE 		/* Get and check tag */
18799d3b5030SFabien DESSENNE 		u32 in_tag[AES_BLOCK_32], out_tag[AES_BLOCK_32];
18809d3b5030SFabien DESSENNE 
18814b898d5cSNicolas Toromanoff 		scatterwalk_copychunks(in_tag, &cryp->in_walk, cryp->authsize, 0);
1882319ad16dSLinus Walleij 		readsl(cryp->regs + cryp->caps->dout, out_tag, AES_BLOCK_32);
18839d3b5030SFabien DESSENNE 
18849d3b5030SFabien DESSENNE 		if (crypto_memneq(in_tag, out_tag, cryp->authsize))
18859d3b5030SFabien DESSENNE 			ret = -EBADMSG;
18869d3b5030SFabien DESSENNE 	}
18879d3b5030SFabien DESSENNE 
18889d3b5030SFabien DESSENNE 	/* Disable cryp */
18899d3b5030SFabien DESSENNE 	cfg &= ~CR_CRYPEN;
18900b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
18919d3b5030SFabien DESSENNE 
18929d3b5030SFabien DESSENNE 	return ret;
18939d3b5030SFabien DESSENNE }
18949d3b5030SFabien DESSENNE 
stm32_cryp_check_ctr_counter(struct stm32_cryp * cryp)18959e054ec2SFabien DESSENNE static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp)
18969e054ec2SFabien DESSENNE {
18979e054ec2SFabien DESSENNE 	u32 cr;
18989e054ec2SFabien DESSENNE 
189941c76690SNicolas Toromanoff 	if (unlikely(cryp->last_ctr[3] == cpu_to_be32(0xFFFFFFFF))) {
190041c76690SNicolas Toromanoff 		/*
190141c76690SNicolas Toromanoff 		 * In this case, we need to increment manually the ctr counter,
190241c76690SNicolas Toromanoff 		 * as HW doesn't handle the U32 carry.
190341c76690SNicolas Toromanoff 		 */
190441c76690SNicolas Toromanoff 		crypto_inc((u8 *)cryp->last_ctr, sizeof(cryp->last_ctr));
19059e054ec2SFabien DESSENNE 
19060b496efbSLinus Walleij 		cr = stm32_cryp_read(cryp, cryp->caps->cr);
19070b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->cr, cr & ~CR_CRYPEN);
19089e054ec2SFabien DESSENNE 
190941c76690SNicolas Toromanoff 		stm32_cryp_hw_write_iv(cryp, cryp->last_ctr);
19109e054ec2SFabien DESSENNE 
19110b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->cr, cr);
19129e054ec2SFabien DESSENNE 	}
19139e054ec2SFabien DESSENNE 
191441c76690SNicolas Toromanoff 	/* The IV registers are BE  */
19150b496efbSLinus Walleij 	cryp->last_ctr[0] = cpu_to_be32(stm32_cryp_read(cryp, cryp->caps->iv0l));
19160b496efbSLinus Walleij 	cryp->last_ctr[1] = cpu_to_be32(stm32_cryp_read(cryp, cryp->caps->iv0r));
19170b496efbSLinus Walleij 	cryp->last_ctr[2] = cpu_to_be32(stm32_cryp_read(cryp, cryp->caps->iv1l));
19180b496efbSLinus Walleij 	cryp->last_ctr[3] = cpu_to_be32(stm32_cryp_read(cryp, cryp->caps->iv1r));
19199e054ec2SFabien DESSENNE }
19209e054ec2SFabien DESSENNE 
stm32_cryp_irq_read_data(struct stm32_cryp * cryp)19214b898d5cSNicolas Toromanoff static void stm32_cryp_irq_read_data(struct stm32_cryp *cryp)
19229e054ec2SFabien DESSENNE {
19234b898d5cSNicolas Toromanoff 	u32 block[AES_BLOCK_32];
19249d3b5030SFabien DESSENNE 
1925319ad16dSLinus Walleij 	readsl(cryp->regs + cryp->caps->dout, block, cryp->hw_blocksize / sizeof(u32));
19264b898d5cSNicolas Toromanoff 	scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize,
19274b898d5cSNicolas Toromanoff 							     cryp->payload_out), 1);
19284b898d5cSNicolas Toromanoff 	cryp->payload_out -= min_t(size_t, cryp->hw_blocksize,
19294b898d5cSNicolas Toromanoff 				   cryp->payload_out);
19309e054ec2SFabien DESSENNE }
19319e054ec2SFabien DESSENNE 
stm32_cryp_irq_write_block(struct stm32_cryp * cryp)19329e054ec2SFabien DESSENNE static void stm32_cryp_irq_write_block(struct stm32_cryp *cryp)
19339e054ec2SFabien DESSENNE {
19344b898d5cSNicolas Toromanoff 	u32 block[AES_BLOCK_32] = {0};
19359d3b5030SFabien DESSENNE 
19364b898d5cSNicolas Toromanoff 	scatterwalk_copychunks(block, &cryp->in_walk, min_t(size_t, cryp->hw_blocksize,
19374b898d5cSNicolas Toromanoff 							    cryp->payload_in), 0);
1938319ad16dSLinus Walleij 	writesl(cryp->regs + cryp->caps->din, block, cryp->hw_blocksize / sizeof(u32));
19394b898d5cSNicolas Toromanoff 	cryp->payload_in -= min_t(size_t, cryp->hw_blocksize, cryp->payload_in);
19409e054ec2SFabien DESSENNE }
19419e054ec2SFabien DESSENNE 
stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp * cryp)19429d3b5030SFabien DESSENNE static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp)
19439d3b5030SFabien DESSENNE {
19449d3b5030SFabien DESSENNE 	int err;
19454b898d5cSNicolas Toromanoff 	u32 cfg, block[AES_BLOCK_32] = {0};
19469d3b5030SFabien DESSENNE 	unsigned int i;
19479d3b5030SFabien DESSENNE 
19489d3b5030SFabien DESSENNE 	/* 'Special workaround' procedure described in the datasheet */
19499d3b5030SFabien DESSENNE 
19509d3b5030SFabien DESSENNE 	/* a) disable ip */
19510b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->imsc, 0);
19520b496efbSLinus Walleij 	cfg = stm32_cryp_read(cryp, cryp->caps->cr);
19539d3b5030SFabien DESSENNE 	cfg &= ~CR_CRYPEN;
19540b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
19559d3b5030SFabien DESSENNE 
19569d3b5030SFabien DESSENNE 	/* b) Update IV1R */
19570b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->iv1r, cryp->gcm_ctr - 2);
19589d3b5030SFabien DESSENNE 
19599d3b5030SFabien DESSENNE 	/* c) change mode to CTR */
19609d3b5030SFabien DESSENNE 	cfg &= ~CR_ALGO_MASK;
19619d3b5030SFabien DESSENNE 	cfg |= CR_AES_CTR;
19620b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
19639d3b5030SFabien DESSENNE 
19649d3b5030SFabien DESSENNE 	/* a) enable IP */
19659d3b5030SFabien DESSENNE 	cfg |= CR_CRYPEN;
19660b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
19679d3b5030SFabien DESSENNE 
19689d3b5030SFabien DESSENNE 	/* b) pad and write the last block */
19699d3b5030SFabien DESSENNE 	stm32_cryp_irq_write_block(cryp);
19704b898d5cSNicolas Toromanoff 	/* wait end of process */
19719d3b5030SFabien DESSENNE 	err = stm32_cryp_wait_output(cryp);
19729d3b5030SFabien DESSENNE 	if (err) {
19734b898d5cSNicolas Toromanoff 		dev_err(cryp->dev, "Timeout (write gcm last data)\n");
19749d3b5030SFabien DESSENNE 		return stm32_cryp_finish_req(cryp, err);
19759d3b5030SFabien DESSENNE 	}
19769d3b5030SFabien DESSENNE 
19779d3b5030SFabien DESSENNE 	/* c) get and store encrypted data */
19784b898d5cSNicolas Toromanoff 	/*
19794b898d5cSNicolas Toromanoff 	 * Same code as stm32_cryp_irq_read_data(), but we want to store
19804b898d5cSNicolas Toromanoff 	 * block value
19814b898d5cSNicolas Toromanoff 	 */
1982319ad16dSLinus Walleij 	readsl(cryp->regs + cryp->caps->dout, block, cryp->hw_blocksize / sizeof(u32));
19834b898d5cSNicolas Toromanoff 
19844b898d5cSNicolas Toromanoff 	scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize,
19854b898d5cSNicolas Toromanoff 							     cryp->payload_out), 1);
19864b898d5cSNicolas Toromanoff 	cryp->payload_out -= min_t(size_t, cryp->hw_blocksize,
19874b898d5cSNicolas Toromanoff 				   cryp->payload_out);
19889d3b5030SFabien DESSENNE 
19899d3b5030SFabien DESSENNE 	/* d) change mode back to AES GCM */
19909d3b5030SFabien DESSENNE 	cfg &= ~CR_ALGO_MASK;
19919d3b5030SFabien DESSENNE 	cfg |= CR_AES_GCM;
19920b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
19939d3b5030SFabien DESSENNE 
19949d3b5030SFabien DESSENNE 	/* e) change phase to Final */
19959d3b5030SFabien DESSENNE 	cfg &= ~CR_PH_MASK;
19969d3b5030SFabien DESSENNE 	cfg |= CR_PH_FINAL;
19970b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
19989d3b5030SFabien DESSENNE 
19999d3b5030SFabien DESSENNE 	/* f) write padded data */
2000319ad16dSLinus Walleij 	writesl(cryp->regs + cryp->caps->din, block, AES_BLOCK_32);
20019d3b5030SFabien DESSENNE 
20029d3b5030SFabien DESSENNE 	/* g) Empty fifo out */
20039d3b5030SFabien DESSENNE 	err = stm32_cryp_wait_output(cryp);
20049d3b5030SFabien DESSENNE 	if (err) {
20054b898d5cSNicolas Toromanoff 		dev_err(cryp->dev, "Timeout (write gcm padded data)\n");
20069d3b5030SFabien DESSENNE 		return stm32_cryp_finish_req(cryp, err);
20079d3b5030SFabien DESSENNE 	}
20089d3b5030SFabien DESSENNE 
20099d3b5030SFabien DESSENNE 	for (i = 0; i < AES_BLOCK_32; i++)
20100b496efbSLinus Walleij 		stm32_cryp_read(cryp, cryp->caps->dout);
20119d3b5030SFabien DESSENNE 
20129d3b5030SFabien DESSENNE 	/* h) run the he normal Final phase */
20139d3b5030SFabien DESSENNE 	stm32_cryp_finish_req(cryp, 0);
20149d3b5030SFabien DESSENNE }
20159d3b5030SFabien DESSENNE 
stm32_cryp_irq_set_npblb(struct stm32_cryp * cryp)20169d3b5030SFabien DESSENNE static void stm32_cryp_irq_set_npblb(struct stm32_cryp *cryp)
20179d3b5030SFabien DESSENNE {
20184b898d5cSNicolas Toromanoff 	u32 cfg;
20199d3b5030SFabien DESSENNE 
20209d3b5030SFabien DESSENNE 	/* disable ip, set NPBLB and reneable ip */
20210b496efbSLinus Walleij 	cfg = stm32_cryp_read(cryp, cryp->caps->cr);
20229d3b5030SFabien DESSENNE 	cfg &= ~CR_CRYPEN;
20230b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
20249d3b5030SFabien DESSENNE 
20254b898d5cSNicolas Toromanoff 	cfg |= (cryp->hw_blocksize - cryp->payload_in) << CR_NBPBL_SHIFT;
20269d3b5030SFabien DESSENNE 	cfg |= CR_CRYPEN;
20270b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
20289d3b5030SFabien DESSENNE }
20299d3b5030SFabien DESSENNE 
stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp * cryp)20309d3b5030SFabien DESSENNE static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp)
20319d3b5030SFabien DESSENNE {
20329d3b5030SFabien DESSENNE 	int err = 0;
20339d3b5030SFabien DESSENNE 	u32 cfg, iv1tmp;
20344b898d5cSNicolas Toromanoff 	u32 cstmp1[AES_BLOCK_32], cstmp2[AES_BLOCK_32];
20354b898d5cSNicolas Toromanoff 	u32 block[AES_BLOCK_32] = {0};
20369d3b5030SFabien DESSENNE 	unsigned int i;
20379d3b5030SFabien DESSENNE 
20389d3b5030SFabien DESSENNE 	/* 'Special workaround' procedure described in the datasheet */
20399d3b5030SFabien DESSENNE 
20409d3b5030SFabien DESSENNE 	/* a) disable ip */
20410b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->imsc, 0);
20429d3b5030SFabien DESSENNE 
20430b496efbSLinus Walleij 	cfg = stm32_cryp_read(cryp, cryp->caps->cr);
20449d3b5030SFabien DESSENNE 	cfg &= ~CR_CRYPEN;
20450b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
20469d3b5030SFabien DESSENNE 
20479d3b5030SFabien DESSENNE 	/* b) get IV1 from CRYP_CSGCMCCM7 */
20489d3b5030SFabien DESSENNE 	iv1tmp = stm32_cryp_read(cryp, CRYP_CSGCMCCM0R + 7 * 4);
20499d3b5030SFabien DESSENNE 
20509d3b5030SFabien DESSENNE 	/* c) Load CRYP_CSGCMCCMxR */
20519d3b5030SFabien DESSENNE 	for (i = 0; i < ARRAY_SIZE(cstmp1); i++)
20529d3b5030SFabien DESSENNE 		cstmp1[i] = stm32_cryp_read(cryp, CRYP_CSGCMCCM0R + i * 4);
20539d3b5030SFabien DESSENNE 
20549d3b5030SFabien DESSENNE 	/* d) Write IV1R */
20550b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->iv1r, iv1tmp);
20569d3b5030SFabien DESSENNE 
20579d3b5030SFabien DESSENNE 	/* e) change mode to CTR */
20589d3b5030SFabien DESSENNE 	cfg &= ~CR_ALGO_MASK;
20599d3b5030SFabien DESSENNE 	cfg |= CR_AES_CTR;
20600b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
20619d3b5030SFabien DESSENNE 
20629d3b5030SFabien DESSENNE 	/* a) enable IP */
20639d3b5030SFabien DESSENNE 	cfg |= CR_CRYPEN;
20640b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
20659d3b5030SFabien DESSENNE 
20669d3b5030SFabien DESSENNE 	/* b) pad and write the last block */
20679d3b5030SFabien DESSENNE 	stm32_cryp_irq_write_block(cryp);
20684b898d5cSNicolas Toromanoff 	/* wait end of process */
20699d3b5030SFabien DESSENNE 	err = stm32_cryp_wait_output(cryp);
20709d3b5030SFabien DESSENNE 	if (err) {
2071be7f5ef9SColin Ian King 		dev_err(cryp->dev, "Timeout (write ccm padded data)\n");
20729d3b5030SFabien DESSENNE 		return stm32_cryp_finish_req(cryp, err);
20739d3b5030SFabien DESSENNE 	}
20749d3b5030SFabien DESSENNE 
20759d3b5030SFabien DESSENNE 	/* c) get and store decrypted data */
20764b898d5cSNicolas Toromanoff 	/*
20774b898d5cSNicolas Toromanoff 	 * Same code as stm32_cryp_irq_read_data(), but we want to store
20784b898d5cSNicolas Toromanoff 	 * block value
20794b898d5cSNicolas Toromanoff 	 */
2080319ad16dSLinus Walleij 	readsl(cryp->regs + cryp->caps->dout, block, cryp->hw_blocksize / sizeof(u32));
20819d3b5030SFabien DESSENNE 
20824b898d5cSNicolas Toromanoff 	scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize,
20834b898d5cSNicolas Toromanoff 							     cryp->payload_out), 1);
20844b898d5cSNicolas Toromanoff 	cryp->payload_out -= min_t(size_t, cryp->hw_blocksize, cryp->payload_out);
20859d3b5030SFabien DESSENNE 
20869d3b5030SFabien DESSENNE 	/* d) Load again CRYP_CSGCMCCMxR */
20879d3b5030SFabien DESSENNE 	for (i = 0; i < ARRAY_SIZE(cstmp2); i++)
20889d3b5030SFabien DESSENNE 		cstmp2[i] = stm32_cryp_read(cryp, CRYP_CSGCMCCM0R + i * 4);
20899d3b5030SFabien DESSENNE 
20909d3b5030SFabien DESSENNE 	/* e) change mode back to AES CCM */
20919d3b5030SFabien DESSENNE 	cfg &= ~CR_ALGO_MASK;
20929d3b5030SFabien DESSENNE 	cfg |= CR_AES_CCM;
20930b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
20949d3b5030SFabien DESSENNE 
20959d3b5030SFabien DESSENNE 	/* f) change phase to header */
20969d3b5030SFabien DESSENNE 	cfg &= ~CR_PH_MASK;
20979d3b5030SFabien DESSENNE 	cfg |= CR_PH_HEADER;
20980b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->cr, cfg);
20999d3b5030SFabien DESSENNE 
21009d3b5030SFabien DESSENNE 	/* g) XOR and write padded data */
21014b898d5cSNicolas Toromanoff 	for (i = 0; i < ARRAY_SIZE(block); i++) {
21024b898d5cSNicolas Toromanoff 		block[i] ^= cstmp1[i];
21034b898d5cSNicolas Toromanoff 		block[i] ^= cstmp2[i];
21040b496efbSLinus Walleij 		stm32_cryp_write(cryp, cryp->caps->din, block[i]);
21059d3b5030SFabien DESSENNE 	}
21069d3b5030SFabien DESSENNE 
21079d3b5030SFabien DESSENNE 	/* h) wait for completion */
21089d3b5030SFabien DESSENNE 	err = stm32_cryp_wait_busy(cryp);
21099d3b5030SFabien DESSENNE 	if (err)
2110be7f5ef9SColin Ian King 		dev_err(cryp->dev, "Timeout (write ccm padded data)\n");
21119d3b5030SFabien DESSENNE 
21129d3b5030SFabien DESSENNE 	/* i) run the he normal Final phase */
21139d3b5030SFabien DESSENNE 	stm32_cryp_finish_req(cryp, err);
21149d3b5030SFabien DESSENNE }
21159d3b5030SFabien DESSENNE 
stm32_cryp_irq_write_data(struct stm32_cryp * cryp)21169e054ec2SFabien DESSENNE static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp)
21179e054ec2SFabien DESSENNE {
21184b898d5cSNicolas Toromanoff 	if (unlikely(!cryp->payload_in)) {
21199e054ec2SFabien DESSENNE 		dev_warn(cryp->dev, "No more data to process\n");
21209e054ec2SFabien DESSENNE 		return;
21219e054ec2SFabien DESSENNE 	}
21229e054ec2SFabien DESSENNE 
21234b898d5cSNicolas Toromanoff 	if (unlikely(cryp->payload_in < AES_BLOCK_SIZE &&
21249d3b5030SFabien DESSENNE 		     (stm32_cryp_get_hw_mode(cryp) == CR_AES_GCM) &&
21259d3b5030SFabien DESSENNE 		     is_encrypt(cryp))) {
21269d3b5030SFabien DESSENNE 		/* Padding for AES GCM encryption */
21274b898d5cSNicolas Toromanoff 		if (cryp->caps->padding_wa) {
21289d3b5030SFabien DESSENNE 			/* Special case 1 */
21294b898d5cSNicolas Toromanoff 			stm32_cryp_irq_write_gcm_padded_data(cryp);
21304b898d5cSNicolas Toromanoff 			return;
21314b898d5cSNicolas Toromanoff 		}
21329d3b5030SFabien DESSENNE 
21339d3b5030SFabien DESSENNE 		/* Setting padding bytes (NBBLB) */
21349d3b5030SFabien DESSENNE 		stm32_cryp_irq_set_npblb(cryp);
21359d3b5030SFabien DESSENNE 	}
21369d3b5030SFabien DESSENNE 
21374b898d5cSNicolas Toromanoff 	if (unlikely((cryp->payload_in < AES_BLOCK_SIZE) &&
21389d3b5030SFabien DESSENNE 		     (stm32_cryp_get_hw_mode(cryp) == CR_AES_CCM) &&
21399d3b5030SFabien DESSENNE 		     is_decrypt(cryp))) {
21409d3b5030SFabien DESSENNE 		/* Padding for AES CCM decryption */
21414b898d5cSNicolas Toromanoff 		if (cryp->caps->padding_wa) {
21429d3b5030SFabien DESSENNE 			/* Special case 2 */
21434b898d5cSNicolas Toromanoff 			stm32_cryp_irq_write_ccm_padded_data(cryp);
21444b898d5cSNicolas Toromanoff 			return;
21454b898d5cSNicolas Toromanoff 		}
21469d3b5030SFabien DESSENNE 
21479d3b5030SFabien DESSENNE 		/* Setting padding bytes (NBBLB) */
21489d3b5030SFabien DESSENNE 		stm32_cryp_irq_set_npblb(cryp);
21499d3b5030SFabien DESSENNE 	}
21509d3b5030SFabien DESSENNE 
21519e054ec2SFabien DESSENNE 	if (is_aes(cryp) && is_ctr(cryp))
21529e054ec2SFabien DESSENNE 		stm32_cryp_check_ctr_counter(cryp);
21539e054ec2SFabien DESSENNE 
21549e054ec2SFabien DESSENNE 	stm32_cryp_irq_write_block(cryp);
21559e054ec2SFabien DESSENNE }
21569e054ec2SFabien DESSENNE 
stm32_cryp_irq_write_gcmccm_header(struct stm32_cryp * cryp)21574b898d5cSNicolas Toromanoff static void stm32_cryp_irq_write_gcmccm_header(struct stm32_cryp *cryp)
21589d3b5030SFabien DESSENNE {
21594b898d5cSNicolas Toromanoff 	u32 block[AES_BLOCK_32] = {0};
21604b898d5cSNicolas Toromanoff 	size_t written;
21619d3b5030SFabien DESSENNE 
21624b898d5cSNicolas Toromanoff 	written = min_t(size_t, AES_BLOCK_SIZE, cryp->header_in);
21639d3b5030SFabien DESSENNE 
21644b898d5cSNicolas Toromanoff 	scatterwalk_copychunks(block, &cryp->in_walk, written, 0);
2165319ad16dSLinus Walleij 
2166319ad16dSLinus Walleij 	writesl(cryp->regs + cryp->caps->din, block, AES_BLOCK_32);
21679d3b5030SFabien DESSENNE 
21684b898d5cSNicolas Toromanoff 	cryp->header_in -= written;
21699d3b5030SFabien DESSENNE 
21704b898d5cSNicolas Toromanoff 	stm32_crypt_gcmccm_end_header(cryp);
21719d3b5030SFabien DESSENNE }
21729d3b5030SFabien DESSENNE 
stm32_cryp_irq_thread(int irq,void * arg)21739e054ec2SFabien DESSENNE static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg)
21749e054ec2SFabien DESSENNE {
21759e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = arg;
21769d3b5030SFabien DESSENNE 	u32 ph;
21770b496efbSLinus Walleij 	u32 it_mask = stm32_cryp_read(cryp, cryp->caps->imsc);
21789e054ec2SFabien DESSENNE 
21799e054ec2SFabien DESSENNE 	if (cryp->irq_status & MISR_OUT)
21809e054ec2SFabien DESSENNE 		/* Output FIFO IRQ: read data */
21814b898d5cSNicolas Toromanoff 		stm32_cryp_irq_read_data(cryp);
21829e054ec2SFabien DESSENNE 
21839e054ec2SFabien DESSENNE 	if (cryp->irq_status & MISR_IN) {
21844b898d5cSNicolas Toromanoff 		if (is_gcm(cryp) || is_ccm(cryp)) {
21850b496efbSLinus Walleij 			ph = stm32_cryp_read(cryp, cryp->caps->cr) & CR_PH_MASK;
21869d3b5030SFabien DESSENNE 			if (unlikely(ph == CR_PH_HEADER))
21879d3b5030SFabien DESSENNE 				/* Write Header */
21884b898d5cSNicolas Toromanoff 				stm32_cryp_irq_write_gcmccm_header(cryp);
21899d3b5030SFabien DESSENNE 			else
21909e054ec2SFabien DESSENNE 				/* Input FIFO IRQ: write data */
21919e054ec2SFabien DESSENNE 				stm32_cryp_irq_write_data(cryp);
21924b898d5cSNicolas Toromanoff 			if (is_gcm(cryp))
21939d3b5030SFabien DESSENNE 				cryp->gcm_ctr++;
21949d3b5030SFabien DESSENNE 		} else {
21959d3b5030SFabien DESSENNE 			/* Input FIFO IRQ: write data */
21969d3b5030SFabien DESSENNE 			stm32_cryp_irq_write_data(cryp);
21979d3b5030SFabien DESSENNE 		}
21989e054ec2SFabien DESSENNE 	}
21999e054ec2SFabien DESSENNE 
22004b898d5cSNicolas Toromanoff 	/* Mask useless interrupts */
22014b898d5cSNicolas Toromanoff 	if (!cryp->payload_in && !cryp->header_in)
22024b898d5cSNicolas Toromanoff 		it_mask &= ~IMSCR_IN;
22034b898d5cSNicolas Toromanoff 	if (!cryp->payload_out)
22044b898d5cSNicolas Toromanoff 		it_mask &= ~IMSCR_OUT;
22050b496efbSLinus Walleij 	stm32_cryp_write(cryp, cryp->caps->imsc, it_mask);
22064b898d5cSNicolas Toromanoff 
2207*56ddb9aaSMaxime Méré 	if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) {
2208*56ddb9aaSMaxime Méré 		local_bh_disable();
22094b898d5cSNicolas Toromanoff 		stm32_cryp_finish_req(cryp, 0);
2210*56ddb9aaSMaxime Méré 		local_bh_enable();
2211*56ddb9aaSMaxime Méré 	}
22124b898d5cSNicolas Toromanoff 
22139e054ec2SFabien DESSENNE 	return IRQ_HANDLED;
22149e054ec2SFabien DESSENNE }
22159e054ec2SFabien DESSENNE 
stm32_cryp_irq(int irq,void * arg)22169e054ec2SFabien DESSENNE static irqreturn_t stm32_cryp_irq(int irq, void *arg)
22179e054ec2SFabien DESSENNE {
22189e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = arg;
22199e054ec2SFabien DESSENNE 
22200b496efbSLinus Walleij 	cryp->irq_status = stm32_cryp_read(cryp, cryp->caps->mis);
22219e054ec2SFabien DESSENNE 
22229e054ec2SFabien DESSENNE 	return IRQ_WAKE_THREAD;
22239e054ec2SFabien DESSENNE }
22249e054ec2SFabien DESSENNE 
stm32_cryp_dma_init(struct stm32_cryp * cryp)2225fb11a4f6SMaxime Méré static int stm32_cryp_dma_init(struct stm32_cryp *cryp)
2226fb11a4f6SMaxime Méré {
2227fb11a4f6SMaxime Méré 	struct dma_slave_config dma_conf;
2228fb11a4f6SMaxime Méré 	struct dma_chan *chan;
2229fb11a4f6SMaxime Méré 	int ret;
2230fb11a4f6SMaxime Méré 
2231fb11a4f6SMaxime Méré 	memset(&dma_conf, 0, sizeof(dma_conf));
2232fb11a4f6SMaxime Méré 
2233fb11a4f6SMaxime Méré 	dma_conf.direction = DMA_MEM_TO_DEV;
2234fb11a4f6SMaxime Méré 	dma_conf.dst_addr = cryp->phys_base + cryp->caps->din;
2235fb11a4f6SMaxime Méré 	dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
2236fb11a4f6SMaxime Méré 	dma_conf.dst_maxburst = CRYP_DMA_BURST_REG;
2237fb11a4f6SMaxime Méré 	dma_conf.device_fc = false;
2238fb11a4f6SMaxime Méré 
2239fb11a4f6SMaxime Méré 	chan = dma_request_chan(cryp->dev, "in");
2240fb11a4f6SMaxime Méré 	if (IS_ERR(chan))
2241fb11a4f6SMaxime Méré 		return PTR_ERR(chan);
2242fb11a4f6SMaxime Méré 
2243fb11a4f6SMaxime Méré 	cryp->dma_lch_in = chan;
2244fb11a4f6SMaxime Méré 	ret = dmaengine_slave_config(cryp->dma_lch_in, &dma_conf);
2245fb11a4f6SMaxime Méré 	if (ret) {
2246fb11a4f6SMaxime Méré 		dma_release_channel(cryp->dma_lch_in);
2247fb11a4f6SMaxime Méré 		cryp->dma_lch_in = NULL;
2248fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "Couldn't configure DMA in slave.\n");
2249fb11a4f6SMaxime Méré 		return ret;
2250fb11a4f6SMaxime Méré 	}
2251fb11a4f6SMaxime Méré 
2252fb11a4f6SMaxime Méré 	memset(&dma_conf, 0, sizeof(dma_conf));
2253fb11a4f6SMaxime Méré 
2254fb11a4f6SMaxime Méré 	dma_conf.direction = DMA_DEV_TO_MEM;
2255fb11a4f6SMaxime Méré 	dma_conf.src_addr = cryp->phys_base + cryp->caps->dout;
2256fb11a4f6SMaxime Méré 	dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
2257fb11a4f6SMaxime Méré 	dma_conf.src_maxburst = CRYP_DMA_BURST_REG;
2258fb11a4f6SMaxime Méré 	dma_conf.device_fc = false;
2259fb11a4f6SMaxime Méré 
2260fb11a4f6SMaxime Méré 	chan = dma_request_chan(cryp->dev, "out");
2261fb11a4f6SMaxime Méré 	if (IS_ERR(chan)) {
2262fb11a4f6SMaxime Méré 		dma_release_channel(cryp->dma_lch_in);
2263fb11a4f6SMaxime Méré 		cryp->dma_lch_in = NULL;
2264fb11a4f6SMaxime Méré 		return PTR_ERR(chan);
2265fb11a4f6SMaxime Méré 	}
2266fb11a4f6SMaxime Méré 
2267fb11a4f6SMaxime Méré 	cryp->dma_lch_out = chan;
2268fb11a4f6SMaxime Méré 
2269fb11a4f6SMaxime Méré 	ret = dmaengine_slave_config(cryp->dma_lch_out, &dma_conf);
2270fb11a4f6SMaxime Méré 	if (ret) {
2271fb11a4f6SMaxime Méré 		dma_release_channel(cryp->dma_lch_out);
2272fb11a4f6SMaxime Méré 		cryp->dma_lch_out = NULL;
2273fb11a4f6SMaxime Méré 		dev_err(cryp->dev, "Couldn't configure DMA out slave.\n");
2274fb11a4f6SMaxime Méré 		dma_release_channel(cryp->dma_lch_in);
2275fb11a4f6SMaxime Méré 		cryp->dma_lch_in = NULL;
2276fb11a4f6SMaxime Méré 		return ret;
2277fb11a4f6SMaxime Méré 	}
2278fb11a4f6SMaxime Méré 
2279fb11a4f6SMaxime Méré 	init_completion(&cryp->dma_completion);
2280fb11a4f6SMaxime Méré 
2281fb11a4f6SMaxime Méré 	return 0;
2282fb11a4f6SMaxime Méré }
2283fb11a4f6SMaxime Méré 
2284d5e6b48fSHerbert Xu static struct skcipher_engine_alg crypto_algs[] = {
22859e054ec2SFabien DESSENNE {
2286d5e6b48fSHerbert Xu 	.base = {
228747ece481SArd Biesheuvel 		.base.cra_name		= "ecb(aes)",
228847ece481SArd Biesheuvel 		.base.cra_driver_name	= "stm32-ecb-aes",
22896364352eSMaxime Méré 		.base.cra_priority	= 300,
229040277252SMaxime Méré 		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
229147ece481SArd Biesheuvel 		.base.cra_blocksize	= AES_BLOCK_SIZE,
229247ece481SArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct stm32_cryp_ctx),
22934b898d5cSNicolas Toromanoff 		.base.cra_alignmask	= 0,
229447ece481SArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
229547ece481SArd Biesheuvel 
229647ece481SArd Biesheuvel 		.init			= stm32_cryp_init_tfm,
22979e054ec2SFabien DESSENNE 		.min_keysize		= AES_MIN_KEY_SIZE,
22989e054ec2SFabien DESSENNE 		.max_keysize		= AES_MAX_KEY_SIZE,
22999e054ec2SFabien DESSENNE 		.setkey			= stm32_cryp_aes_setkey,
23009e054ec2SFabien DESSENNE 		.encrypt		= stm32_cryp_aes_ecb_encrypt,
23019e054ec2SFabien DESSENNE 		.decrypt		= stm32_cryp_aes_ecb_decrypt,
23029e054ec2SFabien DESSENNE 	},
2303d5e6b48fSHerbert Xu 	.op = {
2304d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_cipher_one_req,
2305d5e6b48fSHerbert Xu 	},
2306d5e6b48fSHerbert Xu },
23079e054ec2SFabien DESSENNE {
2308d5e6b48fSHerbert Xu 	.base = {
230947ece481SArd Biesheuvel 		.base.cra_name		= "cbc(aes)",
231047ece481SArd Biesheuvel 		.base.cra_driver_name	= "stm32-cbc-aes",
23116364352eSMaxime Méré 		.base.cra_priority	= 300,
231240277252SMaxime Méré 		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
231347ece481SArd Biesheuvel 		.base.cra_blocksize	= AES_BLOCK_SIZE,
231447ece481SArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct stm32_cryp_ctx),
23154b898d5cSNicolas Toromanoff 		.base.cra_alignmask	= 0,
231647ece481SArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
231747ece481SArd Biesheuvel 
231847ece481SArd Biesheuvel 		.init			= stm32_cryp_init_tfm,
23199e054ec2SFabien DESSENNE 		.min_keysize		= AES_MIN_KEY_SIZE,
23209e054ec2SFabien DESSENNE 		.max_keysize		= AES_MAX_KEY_SIZE,
23219e054ec2SFabien DESSENNE 		.ivsize			= AES_BLOCK_SIZE,
23229e054ec2SFabien DESSENNE 		.setkey			= stm32_cryp_aes_setkey,
23239e054ec2SFabien DESSENNE 		.encrypt		= stm32_cryp_aes_cbc_encrypt,
23249e054ec2SFabien DESSENNE 		.decrypt		= stm32_cryp_aes_cbc_decrypt,
23259e054ec2SFabien DESSENNE 	},
2326d5e6b48fSHerbert Xu 	.op = {
2327d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_cipher_one_req,
2328d5e6b48fSHerbert Xu 	},
2329d5e6b48fSHerbert Xu },
23309e054ec2SFabien DESSENNE {
2331d5e6b48fSHerbert Xu 	.base = {
233247ece481SArd Biesheuvel 		.base.cra_name		= "ctr(aes)",
233347ece481SArd Biesheuvel 		.base.cra_driver_name	= "stm32-ctr-aes",
23346364352eSMaxime Méré 		.base.cra_priority	= 300,
233540277252SMaxime Méré 		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
233647ece481SArd Biesheuvel 		.base.cra_blocksize	= 1,
233747ece481SArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct stm32_cryp_ctx),
23384b898d5cSNicolas Toromanoff 		.base.cra_alignmask	= 0,
233947ece481SArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
234047ece481SArd Biesheuvel 
234147ece481SArd Biesheuvel 		.init			= stm32_cryp_init_tfm,
23429e054ec2SFabien DESSENNE 		.min_keysize		= AES_MIN_KEY_SIZE,
23439e054ec2SFabien DESSENNE 		.max_keysize		= AES_MAX_KEY_SIZE,
23449e054ec2SFabien DESSENNE 		.ivsize			= AES_BLOCK_SIZE,
23459e054ec2SFabien DESSENNE 		.setkey			= stm32_cryp_aes_setkey,
23469e054ec2SFabien DESSENNE 		.encrypt		= stm32_cryp_aes_ctr_encrypt,
23479e054ec2SFabien DESSENNE 		.decrypt		= stm32_cryp_aes_ctr_decrypt,
23489e054ec2SFabien DESSENNE 	},
2349d5e6b48fSHerbert Xu 	.op = {
2350d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_cipher_one_req,
2351d5e6b48fSHerbert Xu 	},
2352d5e6b48fSHerbert Xu },
23539e054ec2SFabien DESSENNE {
2354d5e6b48fSHerbert Xu 	.base = {
235547ece481SArd Biesheuvel 		.base.cra_name		= "ecb(des)",
235647ece481SArd Biesheuvel 		.base.cra_driver_name	= "stm32-ecb-des",
23576364352eSMaxime Méré 		.base.cra_priority	= 300,
235840277252SMaxime Méré 		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
235947ece481SArd Biesheuvel 		.base.cra_blocksize	= DES_BLOCK_SIZE,
236047ece481SArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct stm32_cryp_ctx),
23614b898d5cSNicolas Toromanoff 		.base.cra_alignmask	= 0,
236247ece481SArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
236347ece481SArd Biesheuvel 
236447ece481SArd Biesheuvel 		.init			= stm32_cryp_init_tfm,
23659e054ec2SFabien DESSENNE 		.min_keysize		= DES_BLOCK_SIZE,
23669e054ec2SFabien DESSENNE 		.max_keysize		= DES_BLOCK_SIZE,
23679e054ec2SFabien DESSENNE 		.setkey			= stm32_cryp_des_setkey,
23689e054ec2SFabien DESSENNE 		.encrypt		= stm32_cryp_des_ecb_encrypt,
23699e054ec2SFabien DESSENNE 		.decrypt		= stm32_cryp_des_ecb_decrypt,
23709e054ec2SFabien DESSENNE 	},
2371d5e6b48fSHerbert Xu 	.op = {
2372d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_cipher_one_req,
2373d5e6b48fSHerbert Xu 	},
2374d5e6b48fSHerbert Xu },
23759e054ec2SFabien DESSENNE {
2376d5e6b48fSHerbert Xu 	.base = {
237747ece481SArd Biesheuvel 		.base.cra_name		= "cbc(des)",
237847ece481SArd Biesheuvel 		.base.cra_driver_name	= "stm32-cbc-des",
23796364352eSMaxime Méré 		.base.cra_priority	= 300,
238040277252SMaxime Méré 		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
238147ece481SArd Biesheuvel 		.base.cra_blocksize	= DES_BLOCK_SIZE,
238247ece481SArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct stm32_cryp_ctx),
23834b898d5cSNicolas Toromanoff 		.base.cra_alignmask	= 0,
238447ece481SArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
238547ece481SArd Biesheuvel 
238647ece481SArd Biesheuvel 		.init			= stm32_cryp_init_tfm,
23879e054ec2SFabien DESSENNE 		.min_keysize		= DES_BLOCK_SIZE,
23889e054ec2SFabien DESSENNE 		.max_keysize		= DES_BLOCK_SIZE,
23899e054ec2SFabien DESSENNE 		.ivsize			= DES_BLOCK_SIZE,
23909e054ec2SFabien DESSENNE 		.setkey			= stm32_cryp_des_setkey,
23919e054ec2SFabien DESSENNE 		.encrypt		= stm32_cryp_des_cbc_encrypt,
23929e054ec2SFabien DESSENNE 		.decrypt		= stm32_cryp_des_cbc_decrypt,
23939e054ec2SFabien DESSENNE 	},
2394d5e6b48fSHerbert Xu 	.op = {
2395d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_cipher_one_req,
2396d5e6b48fSHerbert Xu 	},
2397d5e6b48fSHerbert Xu },
23989e054ec2SFabien DESSENNE {
2399d5e6b48fSHerbert Xu 	.base = {
240047ece481SArd Biesheuvel 		.base.cra_name		= "ecb(des3_ede)",
240147ece481SArd Biesheuvel 		.base.cra_driver_name	= "stm32-ecb-des3",
24026364352eSMaxime Méré 		.base.cra_priority	= 300,
240340277252SMaxime Méré 		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
240447ece481SArd Biesheuvel 		.base.cra_blocksize	= DES_BLOCK_SIZE,
240547ece481SArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct stm32_cryp_ctx),
24064b898d5cSNicolas Toromanoff 		.base.cra_alignmask	= 0,
240747ece481SArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
240847ece481SArd Biesheuvel 
240947ece481SArd Biesheuvel 		.init			= stm32_cryp_init_tfm,
24109e054ec2SFabien DESSENNE 		.min_keysize		= 3 * DES_BLOCK_SIZE,
24119e054ec2SFabien DESSENNE 		.max_keysize		= 3 * DES_BLOCK_SIZE,
24129e054ec2SFabien DESSENNE 		.setkey			= stm32_cryp_tdes_setkey,
24139e054ec2SFabien DESSENNE 		.encrypt		= stm32_cryp_tdes_ecb_encrypt,
24149e054ec2SFabien DESSENNE 		.decrypt		= stm32_cryp_tdes_ecb_decrypt,
24159e054ec2SFabien DESSENNE 	},
2416d5e6b48fSHerbert Xu 	.op = {
2417d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_cipher_one_req,
2418d5e6b48fSHerbert Xu 	},
2419d5e6b48fSHerbert Xu },
24209e054ec2SFabien DESSENNE {
2421d5e6b48fSHerbert Xu 	.base = {
242247ece481SArd Biesheuvel 		.base.cra_name		= "cbc(des3_ede)",
242347ece481SArd Biesheuvel 		.base.cra_driver_name	= "stm32-cbc-des3",
24246364352eSMaxime Méré 		.base.cra_priority	= 300,
242540277252SMaxime Méré 		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
242647ece481SArd Biesheuvel 		.base.cra_blocksize	= DES_BLOCK_SIZE,
242747ece481SArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct stm32_cryp_ctx),
24284b898d5cSNicolas Toromanoff 		.base.cra_alignmask	= 0,
242947ece481SArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
243047ece481SArd Biesheuvel 
243147ece481SArd Biesheuvel 		.init			= stm32_cryp_init_tfm,
24329e054ec2SFabien DESSENNE 		.min_keysize		= 3 * DES_BLOCK_SIZE,
24339e054ec2SFabien DESSENNE 		.max_keysize		= 3 * DES_BLOCK_SIZE,
24349e054ec2SFabien DESSENNE 		.ivsize			= DES_BLOCK_SIZE,
24359e054ec2SFabien DESSENNE 		.setkey			= stm32_cryp_tdes_setkey,
24369e054ec2SFabien DESSENNE 		.encrypt		= stm32_cryp_tdes_cbc_encrypt,
24379e054ec2SFabien DESSENNE 		.decrypt		= stm32_cryp_tdes_cbc_decrypt,
24389e054ec2SFabien DESSENNE 	},
2439d5e6b48fSHerbert Xu 	.op = {
2440d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_cipher_one_req,
2441d5e6b48fSHerbert Xu 	},
2442d5e6b48fSHerbert Xu },
24439e054ec2SFabien DESSENNE };
24449e054ec2SFabien DESSENNE 
2445d5e6b48fSHerbert Xu static struct aead_engine_alg aead_algs[] = {
24469d3b5030SFabien DESSENNE {
2447d5e6b48fSHerbert Xu 	.base.setkey		= stm32_cryp_aes_aead_setkey,
2448d5e6b48fSHerbert Xu 	.base.setauthsize	= stm32_cryp_aes_gcm_setauthsize,
2449d5e6b48fSHerbert Xu 	.base.encrypt		= stm32_cryp_aes_gcm_encrypt,
2450d5e6b48fSHerbert Xu 	.base.decrypt		= stm32_cryp_aes_gcm_decrypt,
2451d5e6b48fSHerbert Xu 	.base.init		= stm32_cryp_aes_aead_init,
2452d5e6b48fSHerbert Xu 	.base.ivsize		= 12,
2453d5e6b48fSHerbert Xu 	.base.maxauthsize	= AES_BLOCK_SIZE,
24549d3b5030SFabien DESSENNE 
2455d5e6b48fSHerbert Xu 	.base.base = {
24569d3b5030SFabien DESSENNE 		.cra_name		= "gcm(aes)",
24579d3b5030SFabien DESSENNE 		.cra_driver_name	= "stm32-gcm-aes",
24586364352eSMaxime Méré 		.cra_priority		= 300,
245940277252SMaxime Méré 		.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
24609d3b5030SFabien DESSENNE 		.cra_blocksize		= 1,
24619d3b5030SFabien DESSENNE 		.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
24624b898d5cSNicolas Toromanoff 		.cra_alignmask		= 0,
24639d3b5030SFabien DESSENNE 		.cra_module		= THIS_MODULE,
24649d3b5030SFabien DESSENNE 	},
2465d5e6b48fSHerbert Xu 	.op = {
2466d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_aead_one_req,
2467d5e6b48fSHerbert Xu 	},
24689d3b5030SFabien DESSENNE },
24699d3b5030SFabien DESSENNE {
2470d5e6b48fSHerbert Xu 	.base.setkey		= stm32_cryp_aes_aead_setkey,
2471d5e6b48fSHerbert Xu 	.base.setauthsize	= stm32_cryp_aes_ccm_setauthsize,
2472d5e6b48fSHerbert Xu 	.base.encrypt		= stm32_cryp_aes_ccm_encrypt,
2473d5e6b48fSHerbert Xu 	.base.decrypt		= stm32_cryp_aes_ccm_decrypt,
2474d5e6b48fSHerbert Xu 	.base.init		= stm32_cryp_aes_aead_init,
2475d5e6b48fSHerbert Xu 	.base.ivsize		= AES_BLOCK_SIZE,
2476d5e6b48fSHerbert Xu 	.base.maxauthsize	= AES_BLOCK_SIZE,
24779d3b5030SFabien DESSENNE 
2478d5e6b48fSHerbert Xu 	.base.base = {
24799d3b5030SFabien DESSENNE 		.cra_name		= "ccm(aes)",
24809d3b5030SFabien DESSENNE 		.cra_driver_name	= "stm32-ccm-aes",
24816364352eSMaxime Méré 		.cra_priority		= 300,
248240277252SMaxime Méré 		.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY,
24839d3b5030SFabien DESSENNE 		.cra_blocksize		= 1,
24849d3b5030SFabien DESSENNE 		.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
24854b898d5cSNicolas Toromanoff 		.cra_alignmask		= 0,
24869d3b5030SFabien DESSENNE 		.cra_module		= THIS_MODULE,
24879d3b5030SFabien DESSENNE 	},
2488d5e6b48fSHerbert Xu 	.op = {
2489d5e6b48fSHerbert Xu 		.do_one_request = stm32_cryp_aead_one_req,
2490d5e6b48fSHerbert Xu 	},
24919d3b5030SFabien DESSENNE },
24929d3b5030SFabien DESSENNE };
24939d3b5030SFabien DESSENNE 
24940b496efbSLinus Walleij static const struct stm32_cryp_caps ux500_data = {
24950b496efbSLinus Walleij 	.aeads_support = false,
24960b496efbSLinus Walleij 	.linear_aes_key = true,
24970b496efbSLinus Walleij 	.kp_mode = false,
24980b496efbSLinus Walleij 	.iv_protection = true,
24999d3b5030SFabien DESSENNE 	.swap_final = true,
25009d3b5030SFabien DESSENNE 	.padding_wa = true,
25010b496efbSLinus Walleij 	.cr = UX500_CRYP_CR,
25020b496efbSLinus Walleij 	.sr = UX500_CRYP_SR,
25030b496efbSLinus Walleij 	.din = UX500_CRYP_DIN,
25040b496efbSLinus Walleij 	.dout = UX500_CRYP_DOUT,
2505fb11a4f6SMaxime Méré 	.dmacr = UX500_CRYP_DMACR,
25060b496efbSLinus Walleij 	.imsc = UX500_CRYP_IMSC,
25070b496efbSLinus Walleij 	.mis = UX500_CRYP_MIS,
25080b496efbSLinus Walleij 	.k1l = UX500_CRYP_K1L,
25090b496efbSLinus Walleij 	.k1r = UX500_CRYP_K1R,
25100b496efbSLinus Walleij 	.k3r = UX500_CRYP_K3R,
25110b496efbSLinus Walleij 	.iv0l = UX500_CRYP_IV0L,
25120b496efbSLinus Walleij 	.iv0r = UX500_CRYP_IV0R,
25130b496efbSLinus Walleij 	.iv1l = UX500_CRYP_IV1L,
25140b496efbSLinus Walleij 	.iv1r = UX500_CRYP_IV1R,
25150b496efbSLinus Walleij };
25160b496efbSLinus Walleij 
25170b496efbSLinus Walleij static const struct stm32_cryp_caps f7_data = {
25180b496efbSLinus Walleij 	.aeads_support = true,
25190b496efbSLinus Walleij 	.linear_aes_key = false,
25200b496efbSLinus Walleij 	.kp_mode = true,
25210b496efbSLinus Walleij 	.iv_protection = false,
25220b496efbSLinus Walleij 	.swap_final = true,
25230b496efbSLinus Walleij 	.padding_wa = true,
25240b496efbSLinus Walleij 	.cr = CRYP_CR,
25250b496efbSLinus Walleij 	.sr = CRYP_SR,
25260b496efbSLinus Walleij 	.din = CRYP_DIN,
25270b496efbSLinus Walleij 	.dout = CRYP_DOUT,
2528fb11a4f6SMaxime Méré 	.dmacr = CRYP_DMACR,
25290b496efbSLinus Walleij 	.imsc = CRYP_IMSCR,
25300b496efbSLinus Walleij 	.mis = CRYP_MISR,
25310b496efbSLinus Walleij 	.k1l = CRYP_K1LR,
25320b496efbSLinus Walleij 	.k1r = CRYP_K1RR,
25330b496efbSLinus Walleij 	.k3r = CRYP_K3RR,
25340b496efbSLinus Walleij 	.iv0l = CRYP_IV0LR,
25350b496efbSLinus Walleij 	.iv0r = CRYP_IV0RR,
25360b496efbSLinus Walleij 	.iv1l = CRYP_IV1LR,
25370b496efbSLinus Walleij 	.iv1r = CRYP_IV1RR,
25389d3b5030SFabien DESSENNE };
25399d3b5030SFabien DESSENNE 
2540a43a3484SFabien DESSENNE static const struct stm32_cryp_caps mp1_data = {
25410b496efbSLinus Walleij 	.aeads_support = true,
25420b496efbSLinus Walleij 	.linear_aes_key = false,
25430b496efbSLinus Walleij 	.kp_mode = true,
25440b496efbSLinus Walleij 	.iv_protection = false,
2545a43a3484SFabien DESSENNE 	.swap_final = false,
2546a43a3484SFabien DESSENNE 	.padding_wa = false,
25470b496efbSLinus Walleij 	.cr = CRYP_CR,
25480b496efbSLinus Walleij 	.sr = CRYP_SR,
25490b496efbSLinus Walleij 	.din = CRYP_DIN,
25500b496efbSLinus Walleij 	.dout = CRYP_DOUT,
2551fb11a4f6SMaxime Méré 	.dmacr = CRYP_DMACR,
25520b496efbSLinus Walleij 	.imsc = CRYP_IMSCR,
25530b496efbSLinus Walleij 	.mis = CRYP_MISR,
25540b496efbSLinus Walleij 	.k1l = CRYP_K1LR,
25550b496efbSLinus Walleij 	.k1r = CRYP_K1RR,
25560b496efbSLinus Walleij 	.k3r = CRYP_K3RR,
25570b496efbSLinus Walleij 	.iv0l = CRYP_IV0LR,
25580b496efbSLinus Walleij 	.iv0r = CRYP_IV0RR,
25590b496efbSLinus Walleij 	.iv1l = CRYP_IV1LR,
25600b496efbSLinus Walleij 	.iv1r = CRYP_IV1RR,
2561a43a3484SFabien DESSENNE };
2562a43a3484SFabien DESSENNE 
25639e054ec2SFabien DESSENNE static const struct of_device_id stm32_dt_ids[] = {
25640b496efbSLinus Walleij 	{ .compatible = "stericsson,ux500-cryp", .data = &ux500_data},
25659d3b5030SFabien DESSENNE 	{ .compatible = "st,stm32f756-cryp", .data = &f7_data},
2566a43a3484SFabien DESSENNE 	{ .compatible = "st,stm32mp1-cryp", .data = &mp1_data},
25679e054ec2SFabien DESSENNE 	{},
25689e054ec2SFabien DESSENNE };
2569761a6982SCorentin LABBE MODULE_DEVICE_TABLE(of, stm32_dt_ids);
25709e054ec2SFabien DESSENNE 
stm32_cryp_probe(struct platform_device * pdev)25719e054ec2SFabien DESSENNE static int stm32_cryp_probe(struct platform_device *pdev)
25729e054ec2SFabien DESSENNE {
25739e054ec2SFabien DESSENNE 	struct device *dev = &pdev->dev;
25749e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp;
25759e054ec2SFabien DESSENNE 	struct reset_control *rst;
25769e054ec2SFabien DESSENNE 	int irq, ret;
25779e054ec2SFabien DESSENNE 
25789e054ec2SFabien DESSENNE 	cryp = devm_kzalloc(dev, sizeof(*cryp), GFP_KERNEL);
25799e054ec2SFabien DESSENNE 	if (!cryp)
25809e054ec2SFabien DESSENNE 		return -ENOMEM;
25819e054ec2SFabien DESSENNE 
25829d3b5030SFabien DESSENNE 	cryp->caps = of_device_get_match_data(dev);
25839d3b5030SFabien DESSENNE 	if (!cryp->caps)
25849d3b5030SFabien DESSENNE 		return -ENODEV;
25859d3b5030SFabien DESSENNE 
25869e054ec2SFabien DESSENNE 	cryp->dev = dev;
25879e054ec2SFabien DESSENNE 
2588473b4d99SYueHaibing 	cryp->regs = devm_platform_ioremap_resource(pdev, 0);
258960bcf265Sweiyongjun \(A\) 	if (IS_ERR(cryp->regs))
25909e054ec2SFabien DESSENNE 		return PTR_ERR(cryp->regs);
25919e054ec2SFabien DESSENNE 
2592fb11a4f6SMaxime Méré 	cryp->phys_base = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start;
2593fb11a4f6SMaxime Méré 
25949e054ec2SFabien DESSENNE 	irq = platform_get_irq(pdev, 0);
2595514838e9SStephen Boyd 	if (irq < 0)
25969e054ec2SFabien DESSENNE 		return irq;
25979e054ec2SFabien DESSENNE 
25989e054ec2SFabien DESSENNE 	ret = devm_request_threaded_irq(dev, irq, stm32_cryp_irq,
25999e054ec2SFabien DESSENNE 					stm32_cryp_irq_thread, IRQF_ONESHOT,
26009e054ec2SFabien DESSENNE 					dev_name(dev), cryp);
26019e054ec2SFabien DESSENNE 	if (ret) {
26029e054ec2SFabien DESSENNE 		dev_err(dev, "Cannot grab IRQ\n");
26039e054ec2SFabien DESSENNE 		return ret;
26049e054ec2SFabien DESSENNE 	}
26059e054ec2SFabien DESSENNE 
26069e054ec2SFabien DESSENNE 	cryp->clk = devm_clk_get(dev, NULL);
26079e054ec2SFabien DESSENNE 	if (IS_ERR(cryp->clk)) {
2608029812aeSEtienne Carriere 		dev_err_probe(dev, PTR_ERR(cryp->clk), "Could not get clock\n");
2609029812aeSEtienne Carriere 
26109e054ec2SFabien DESSENNE 		return PTR_ERR(cryp->clk);
26119e054ec2SFabien DESSENNE 	}
26129e054ec2SFabien DESSENNE 
26139e054ec2SFabien DESSENNE 	ret = clk_prepare_enable(cryp->clk);
26149e054ec2SFabien DESSENNE 	if (ret) {
26159e054ec2SFabien DESSENNE 		dev_err(cryp->dev, "Failed to enable clock\n");
26169e054ec2SFabien DESSENNE 		return ret;
26179e054ec2SFabien DESSENNE 	}
26189e054ec2SFabien DESSENNE 
261965f9aa36Slionel.debieve@st.com 	pm_runtime_set_autosuspend_delay(dev, CRYP_AUTOSUSPEND_DELAY);
262065f9aa36Slionel.debieve@st.com 	pm_runtime_use_autosuspend(dev);
262165f9aa36Slionel.debieve@st.com 
262265f9aa36Slionel.debieve@st.com 	pm_runtime_get_noresume(dev);
262365f9aa36Slionel.debieve@st.com 	pm_runtime_set_active(dev);
262465f9aa36Slionel.debieve@st.com 	pm_runtime_enable(dev);
262565f9aa36Slionel.debieve@st.com 
26269e054ec2SFabien DESSENNE 	rst = devm_reset_control_get(dev, NULL);
26270a2f9f57SEtienne Carriere 	if (IS_ERR(rst)) {
26280a2f9f57SEtienne Carriere 		ret = PTR_ERR(rst);
26290a2f9f57SEtienne Carriere 		if (ret == -EPROBE_DEFER)
26300a2f9f57SEtienne Carriere 			goto err_rst;
26310a2f9f57SEtienne Carriere 	} else {
26329e054ec2SFabien DESSENNE 		reset_control_assert(rst);
26339e054ec2SFabien DESSENNE 		udelay(2);
26349e054ec2SFabien DESSENNE 		reset_control_deassert(rst);
26359e054ec2SFabien DESSENNE 	}
26369e054ec2SFabien DESSENNE 
26379e054ec2SFabien DESSENNE 	platform_set_drvdata(pdev, cryp);
26389e054ec2SFabien DESSENNE 
2639fb11a4f6SMaxime Méré 	ret = stm32_cryp_dma_init(cryp);
2640fb11a4f6SMaxime Méré 	switch (ret) {
2641fb11a4f6SMaxime Méré 	case 0:
2642fb11a4f6SMaxime Méré 		break;
2643fb11a4f6SMaxime Méré 	case -ENODEV:
2644fb11a4f6SMaxime Méré 		dev_dbg(dev, "DMA mode not available\n");
2645fb11a4f6SMaxime Méré 		break;
2646fb11a4f6SMaxime Méré 	default:
2647fb11a4f6SMaxime Méré 		goto err_dma;
2648fb11a4f6SMaxime Méré 	}
2649fb11a4f6SMaxime Méré 
26509e054ec2SFabien DESSENNE 	spin_lock(&cryp_list.lock);
26519e054ec2SFabien DESSENNE 	list_add(&cryp->list, &cryp_list.dev_list);
26529e054ec2SFabien DESSENNE 	spin_unlock(&cryp_list.lock);
26539e054ec2SFabien DESSENNE 
26549e054ec2SFabien DESSENNE 	/* Initialize crypto engine */
26559e054ec2SFabien DESSENNE 	cryp->engine = crypto_engine_alloc_init(dev, 1);
26569e054ec2SFabien DESSENNE 	if (!cryp->engine) {
26579e054ec2SFabien DESSENNE 		dev_err(dev, "Could not init crypto engine\n");
26589e054ec2SFabien DESSENNE 		ret = -ENOMEM;
26599e054ec2SFabien DESSENNE 		goto err_engine1;
26609e054ec2SFabien DESSENNE 	}
26619e054ec2SFabien DESSENNE 
26629e054ec2SFabien DESSENNE 	ret = crypto_engine_start(cryp->engine);
26639e054ec2SFabien DESSENNE 	if (ret) {
26649e054ec2SFabien DESSENNE 		dev_err(dev, "Could not start crypto engine\n");
26659e054ec2SFabien DESSENNE 		goto err_engine2;
26669e054ec2SFabien DESSENNE 	}
26679e054ec2SFabien DESSENNE 
2668d5e6b48fSHerbert Xu 	ret = crypto_engine_register_skciphers(crypto_algs, ARRAY_SIZE(crypto_algs));
26699e054ec2SFabien DESSENNE 	if (ret) {
26709e054ec2SFabien DESSENNE 		dev_err(dev, "Could not register algs\n");
26719e054ec2SFabien DESSENNE 		goto err_algs;
26729e054ec2SFabien DESSENNE 	}
26739e054ec2SFabien DESSENNE 
26740b496efbSLinus Walleij 	if (cryp->caps->aeads_support) {
2675d5e6b48fSHerbert Xu 		ret = crypto_engine_register_aeads(aead_algs, ARRAY_SIZE(aead_algs));
26769d3b5030SFabien DESSENNE 		if (ret)
26779d3b5030SFabien DESSENNE 			goto err_aead_algs;
26780b496efbSLinus Walleij 	}
26799d3b5030SFabien DESSENNE 
26809e054ec2SFabien DESSENNE 	dev_info(dev, "Initialized\n");
26819e054ec2SFabien DESSENNE 
268265f9aa36Slionel.debieve@st.com 	pm_runtime_put_sync(dev);
268365f9aa36Slionel.debieve@st.com 
26849e054ec2SFabien DESSENNE 	return 0;
26859e054ec2SFabien DESSENNE 
26869d3b5030SFabien DESSENNE err_aead_algs:
2687d5e6b48fSHerbert Xu 	crypto_engine_unregister_skciphers(crypto_algs, ARRAY_SIZE(crypto_algs));
26889e054ec2SFabien DESSENNE err_algs:
26899e054ec2SFabien DESSENNE err_engine2:
26909e054ec2SFabien DESSENNE 	crypto_engine_exit(cryp->engine);
26919e054ec2SFabien DESSENNE err_engine1:
26929e054ec2SFabien DESSENNE 	spin_lock(&cryp_list.lock);
26939e054ec2SFabien DESSENNE 	list_del(&cryp->list);
26949e054ec2SFabien DESSENNE 	spin_unlock(&cryp_list.lock);
2695fb11a4f6SMaxime Méré 
2696fb11a4f6SMaxime Méré 	if (cryp->dma_lch_in)
2697fb11a4f6SMaxime Méré 		dma_release_channel(cryp->dma_lch_in);
2698fb11a4f6SMaxime Méré 	if (cryp->dma_lch_out)
2699fb11a4f6SMaxime Méré 		dma_release_channel(cryp->dma_lch_out);
2700fb11a4f6SMaxime Méré err_dma:
27010a2f9f57SEtienne Carriere err_rst:
270265f9aa36Slionel.debieve@st.com 	pm_runtime_disable(dev);
270365f9aa36Slionel.debieve@st.com 	pm_runtime_put_noidle(dev);
270465f9aa36Slionel.debieve@st.com 
27059e054ec2SFabien DESSENNE 	clk_disable_unprepare(cryp->clk);
27069e054ec2SFabien DESSENNE 
27079e054ec2SFabien DESSENNE 	return ret;
27089e054ec2SFabien DESSENNE }
27099e054ec2SFabien DESSENNE 
stm32_cryp_remove(struct platform_device * pdev)271088b01c8aSUwe Kleine-König static void stm32_cryp_remove(struct platform_device *pdev)
27119e054ec2SFabien DESSENNE {
27129e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = platform_get_drvdata(pdev);
271365f9aa36Slionel.debieve@st.com 	int ret;
27149e054ec2SFabien DESSENNE 
271588b01c8aSUwe Kleine-König 	ret = pm_runtime_get_sync(cryp->dev);
271665f9aa36Slionel.debieve@st.com 
27170b496efbSLinus Walleij 	if (cryp->caps->aeads_support)
2718d5e6b48fSHerbert Xu 		crypto_engine_unregister_aeads(aead_algs, ARRAY_SIZE(aead_algs));
2719d5e6b48fSHerbert Xu 	crypto_engine_unregister_skciphers(crypto_algs, ARRAY_SIZE(crypto_algs));
27209e054ec2SFabien DESSENNE 
27219e054ec2SFabien DESSENNE 	crypto_engine_exit(cryp->engine);
27229e054ec2SFabien DESSENNE 
27239e054ec2SFabien DESSENNE 	spin_lock(&cryp_list.lock);
27249e054ec2SFabien DESSENNE 	list_del(&cryp->list);
27259e054ec2SFabien DESSENNE 	spin_unlock(&cryp_list.lock);
27269e054ec2SFabien DESSENNE 
2727fb11a4f6SMaxime Méré 	if (cryp->dma_lch_in)
2728fb11a4f6SMaxime Méré 		dma_release_channel(cryp->dma_lch_in);
2729fb11a4f6SMaxime Méré 
2730fb11a4f6SMaxime Méré 	if (cryp->dma_lch_out)
2731fb11a4f6SMaxime Méré 		dma_release_channel(cryp->dma_lch_out);
2732fb11a4f6SMaxime Méré 
273365f9aa36Slionel.debieve@st.com 	pm_runtime_disable(cryp->dev);
273465f9aa36Slionel.debieve@st.com 	pm_runtime_put_noidle(cryp->dev);
273565f9aa36Slionel.debieve@st.com 
273688b01c8aSUwe Kleine-König 	if (ret >= 0)
27379e054ec2SFabien DESSENNE 		clk_disable_unprepare(cryp->clk);
27389e054ec2SFabien DESSENNE }
27399e054ec2SFabien DESSENNE 
274065f9aa36Slionel.debieve@st.com #ifdef CONFIG_PM
stm32_cryp_runtime_suspend(struct device * dev)274165f9aa36Slionel.debieve@st.com static int stm32_cryp_runtime_suspend(struct device *dev)
274265f9aa36Slionel.debieve@st.com {
274365f9aa36Slionel.debieve@st.com 	struct stm32_cryp *cryp = dev_get_drvdata(dev);
274465f9aa36Slionel.debieve@st.com 
274565f9aa36Slionel.debieve@st.com 	clk_disable_unprepare(cryp->clk);
274665f9aa36Slionel.debieve@st.com 
274765f9aa36Slionel.debieve@st.com 	return 0;
274865f9aa36Slionel.debieve@st.com }
274965f9aa36Slionel.debieve@st.com 
stm32_cryp_runtime_resume(struct device * dev)275065f9aa36Slionel.debieve@st.com static int stm32_cryp_runtime_resume(struct device *dev)
275165f9aa36Slionel.debieve@st.com {
275265f9aa36Slionel.debieve@st.com 	struct stm32_cryp *cryp = dev_get_drvdata(dev);
275365f9aa36Slionel.debieve@st.com 	int ret;
275465f9aa36Slionel.debieve@st.com 
275565f9aa36Slionel.debieve@st.com 	ret = clk_prepare_enable(cryp->clk);
275665f9aa36Slionel.debieve@st.com 	if (ret) {
275765f9aa36Slionel.debieve@st.com 		dev_err(cryp->dev, "Failed to prepare_enable clock\n");
275865f9aa36Slionel.debieve@st.com 		return ret;
275965f9aa36Slionel.debieve@st.com 	}
276065f9aa36Slionel.debieve@st.com 
276165f9aa36Slionel.debieve@st.com 	return 0;
276265f9aa36Slionel.debieve@st.com }
276365f9aa36Slionel.debieve@st.com #endif
276465f9aa36Slionel.debieve@st.com 
276565f9aa36Slionel.debieve@st.com static const struct dev_pm_ops stm32_cryp_pm_ops = {
276665f9aa36Slionel.debieve@st.com 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
276765f9aa36Slionel.debieve@st.com 				pm_runtime_force_resume)
276865f9aa36Slionel.debieve@st.com 	SET_RUNTIME_PM_OPS(stm32_cryp_runtime_suspend,
276965f9aa36Slionel.debieve@st.com 			   stm32_cryp_runtime_resume, NULL)
277065f9aa36Slionel.debieve@st.com };
277165f9aa36Slionel.debieve@st.com 
27729e054ec2SFabien DESSENNE static struct platform_driver stm32_cryp_driver = {
27739e054ec2SFabien DESSENNE 	.probe  = stm32_cryp_probe,
277488b01c8aSUwe Kleine-König 	.remove_new = stm32_cryp_remove,
27759e054ec2SFabien DESSENNE 	.driver = {
27769e054ec2SFabien DESSENNE 		.name           = DRIVER_NAME,
277765f9aa36Slionel.debieve@st.com 		.pm		= &stm32_cryp_pm_ops,
27789e054ec2SFabien DESSENNE 		.of_match_table = stm32_dt_ids,
27799e054ec2SFabien DESSENNE 	},
27809e054ec2SFabien DESSENNE };
27819e054ec2SFabien DESSENNE 
27829e054ec2SFabien DESSENNE module_platform_driver(stm32_cryp_driver);
27839e054ec2SFabien DESSENNE 
27849e054ec2SFabien DESSENNE MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
27859e054ec2SFabien DESSENNE MODULE_DESCRIPTION("STMicrolectronics STM32 CRYP hardware driver");
27869e054ec2SFabien DESSENNE MODULE_LICENSE("GPL");
2787