1049359d6SJames Hsiao /**
2049359d6SJames Hsiao  * AMCC SoC PPC4xx Crypto Driver
3049359d6SJames Hsiao  *
4049359d6SJames Hsiao  * Copyright (c) 2008 Applied Micro Circuits Corporation.
5049359d6SJames Hsiao  * All rights reserved. James Hsiao <jhsiao@amcc.com>
6049359d6SJames Hsiao  *
7049359d6SJames Hsiao  * This program is free software; you can redistribute it and/or modify
8049359d6SJames Hsiao  * it under the terms of the GNU General Public License as published by
9049359d6SJames Hsiao  * the Free Software Foundation; either version 2 of the License, or
10049359d6SJames Hsiao  * (at your option) any later version.
11049359d6SJames Hsiao  *
12049359d6SJames Hsiao  * This program is distributed in the hope that it will be useful,
13049359d6SJames Hsiao  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14049359d6SJames Hsiao  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15049359d6SJames Hsiao  * GNU General Public License for more details.
16049359d6SJames Hsiao  *
17049359d6SJames Hsiao  * This is the header file for AMCC Crypto offload Linux device driver for
18049359d6SJames Hsiao  * use with Linux CryptoAPI.
19049359d6SJames Hsiao 
20049359d6SJames Hsiao  */
21049359d6SJames Hsiao 
22049359d6SJames Hsiao #ifndef __CRYPTO4XX_CORE_H__
23049359d6SJames Hsiao #define __CRYPTO4XX_CORE_H__
24049359d6SJames Hsiao 
254dc10c01SHerbert Xu #include <crypto/internal/hash.h>
264dc10c01SHerbert Xu 
275343e674SChristian Lamparter #define MODULE_NAME "crypto4xx"
285343e674SChristian Lamparter 
29049359d6SJames Hsiao #define PPC460SX_SDR0_SRST                      0x201
30049359d6SJames Hsiao #define PPC405EX_SDR0_SRST                      0x200
31049359d6SJames Hsiao #define PPC460EX_SDR0_SRST                      0x201
32049359d6SJames Hsiao #define PPC460EX_CE_RESET                       0x08000000
33049359d6SJames Hsiao #define PPC460SX_CE_RESET                       0x20000000
34049359d6SJames Hsiao #define PPC405EX_CE_RESET                       0x00000008
35049359d6SJames Hsiao 
36049359d6SJames Hsiao #define CRYPTO4XX_CRYPTO_PRIORITY		300
37049359d6SJames Hsiao #define PPC4XX_LAST_PD				63
38049359d6SJames Hsiao #define PPC4XX_NUM_PD				64
39049359d6SJames Hsiao #define PPC4XX_LAST_GD				1023
40049359d6SJames Hsiao #define PPC4XX_NUM_GD				1024
41049359d6SJames Hsiao #define PPC4XX_LAST_SD				63
42049359d6SJames Hsiao #define PPC4XX_NUM_SD				64
43049359d6SJames Hsiao #define PPC4XX_SD_BUFFER_SIZE			2048
44049359d6SJames Hsiao 
45049359d6SJames Hsiao #define PD_ENTRY_INUSE				1
46049359d6SJames Hsiao #define PD_ENTRY_FREE				0
47049359d6SJames Hsiao #define ERING_WAS_FULL				0xffffffff
48049359d6SJames Hsiao 
49049359d6SJames Hsiao struct crypto4xx_device;
50049359d6SJames Hsiao 
51049359d6SJames Hsiao struct pd_uinfo {
52049359d6SJames Hsiao 	struct crypto4xx_device *dev;
53049359d6SJames Hsiao 	u32   state;
54049359d6SJames Hsiao 	u32 using_sd;
55049359d6SJames Hsiao 	u32 first_gd;		/* first gather discriptor
56049359d6SJames Hsiao 				used by this packet */
57049359d6SJames Hsiao 	u32 num_gd;             /* number of gather discriptor
58049359d6SJames Hsiao 				used by this packet */
59049359d6SJames Hsiao 	u32 first_sd;		/* first scatter discriptor
60049359d6SJames Hsiao 				used by this packet */
61049359d6SJames Hsiao 	u32 num_sd;		/* number of scatter discriptors
62049359d6SJames Hsiao 				used by this packet */
63049359d6SJames Hsiao 	void *sa_va;		/* shadow sa, when using cp from ctx->sa */
64049359d6SJames Hsiao 	u32 sa_pa;
65049359d6SJames Hsiao 	void *sr_va;		/* state record for shadow sa */
66049359d6SJames Hsiao 	u32 sr_pa;
67049359d6SJames Hsiao 	struct scatterlist *dest_va;
68049359d6SJames Hsiao 	struct crypto_async_request *async_req; 	/* base crypto request
69049359d6SJames Hsiao 							for this packet */
70049359d6SJames Hsiao };
71049359d6SJames Hsiao 
72049359d6SJames Hsiao struct crypto4xx_device {
73049359d6SJames Hsiao 	struct crypto4xx_core_device *core_dev;
74049359d6SJames Hsiao 	char *name;
75049359d6SJames Hsiao 	void __iomem *ce_base;
765343e674SChristian Lamparter 	void __iomem *trng_base;
77049359d6SJames Hsiao 
78049359d6SJames Hsiao 	void *pdr;			/* base address of packet
79049359d6SJames Hsiao 					descriptor ring */
80049359d6SJames Hsiao 	dma_addr_t pdr_pa;		/* physical address used to
81049359d6SJames Hsiao 					program ce pdr_base_register */
82049359d6SJames Hsiao 	void *gdr;                      /* gather descriptor ring */
83049359d6SJames Hsiao 	dma_addr_t gdr_pa;		/* physical address used to
84049359d6SJames Hsiao 					program ce gdr_base_register */
85049359d6SJames Hsiao 	void *sdr;			/* scatter descriptor ring */
86049359d6SJames Hsiao 	dma_addr_t sdr_pa;		/* physical address used to
87049359d6SJames Hsiao 					program ce sdr_base_register */
88049359d6SJames Hsiao 	void *scatter_buffer_va;
89049359d6SJames Hsiao 	dma_addr_t scatter_buffer_pa;
90049359d6SJames Hsiao 	u32 scatter_buffer_size;
91049359d6SJames Hsiao 
92049359d6SJames Hsiao 	void *shadow_sa_pool;		/* pool of memory for sa in pd_uinfo */
93049359d6SJames Hsiao 	dma_addr_t shadow_sa_pool_pa;
94049359d6SJames Hsiao 	void *shadow_sr_pool;		/* pool of memory for sr in pd_uinfo */
95049359d6SJames Hsiao 	dma_addr_t shadow_sr_pool_pa;
96049359d6SJames Hsiao 	u32 pdr_tail;
97049359d6SJames Hsiao 	u32 pdr_head;
98049359d6SJames Hsiao 	u32 gdr_tail;
99049359d6SJames Hsiao 	u32 gdr_head;
100049359d6SJames Hsiao 	u32 sdr_tail;
101049359d6SJames Hsiao 	u32 sdr_head;
102049359d6SJames Hsiao 	void *pdr_uinfo;
103049359d6SJames Hsiao 	struct list_head alg_list;	/* List of algorithm supported
104049359d6SJames Hsiao 					by this device */
105049359d6SJames Hsiao };
106049359d6SJames Hsiao 
107049359d6SJames Hsiao struct crypto4xx_core_device {
108049359d6SJames Hsiao 	struct device *device;
1092dc11581SGrant Likely 	struct platform_device *ofdev;
110049359d6SJames Hsiao 	struct crypto4xx_device *dev;
1115343e674SChristian Lamparter 	struct hwrng *trng;
112049359d6SJames Hsiao 	u32 int_status;
113049359d6SJames Hsiao 	u32 irq;
114049359d6SJames Hsiao 	struct tasklet_struct tasklet;
115049359d6SJames Hsiao 	spinlock_t lock;
116049359d6SJames Hsiao };
117049359d6SJames Hsiao 
118049359d6SJames Hsiao struct crypto4xx_ctx {
119049359d6SJames Hsiao 	struct crypto4xx_device *dev;
120049359d6SJames Hsiao 	void *sa_in;
121049359d6SJames Hsiao 	dma_addr_t sa_in_dma_addr;
122049359d6SJames Hsiao 	void *sa_out;
123049359d6SJames Hsiao 	dma_addr_t sa_out_dma_addr;
124049359d6SJames Hsiao 	void *state_record;
125049359d6SJames Hsiao 	dma_addr_t state_record_dma_addr;
126049359d6SJames Hsiao 	u32 sa_len;
127049359d6SJames Hsiao 	u32 offset_to_sr_ptr;           /* offset to state ptr, in dynamic sa */
128049359d6SJames Hsiao 	u32 direction;
129049359d6SJames Hsiao 	u32 save_iv;
130049359d6SJames Hsiao 	u32 pd_ctl;
131049359d6SJames Hsiao 	u32 is_hash;
132049359d6SJames Hsiao };
133049359d6SJames Hsiao 
1344dc10c01SHerbert Xu struct crypto4xx_alg_common {
1354dc10c01SHerbert Xu 	u32 type;
1364dc10c01SHerbert Xu 	union {
1374dc10c01SHerbert Xu 		struct crypto_alg cipher;
1384dc10c01SHerbert Xu 		struct ahash_alg hash;
1394dc10c01SHerbert Xu 	} u;
1404dc10c01SHerbert Xu };
1414dc10c01SHerbert Xu 
142049359d6SJames Hsiao struct crypto4xx_alg {
143049359d6SJames Hsiao 	struct list_head  entry;
1444dc10c01SHerbert Xu 	struct crypto4xx_alg_common alg;
145049359d6SJames Hsiao 	struct crypto4xx_device *dev;
146049359d6SJames Hsiao };
147049359d6SJames Hsiao 
1484dc10c01SHerbert Xu static inline struct crypto4xx_alg *crypto_alg_to_crypto4xx_alg(
1494dc10c01SHerbert Xu 	struct crypto_alg *x)
1504dc10c01SHerbert Xu {
1514dc10c01SHerbert Xu 	switch (x->cra_flags & CRYPTO_ALG_TYPE_MASK) {
1524dc10c01SHerbert Xu 	case CRYPTO_ALG_TYPE_AHASH:
1534dc10c01SHerbert Xu 		return container_of(__crypto_ahash_alg(x),
1544dc10c01SHerbert Xu 				    struct crypto4xx_alg, alg.u.hash);
1554dc10c01SHerbert Xu 	}
1564dc10c01SHerbert Xu 
1574dc10c01SHerbert Xu 	return container_of(x, struct crypto4xx_alg, alg.u.cipher);
1584dc10c01SHerbert Xu }
159049359d6SJames Hsiao 
160886c251fSChristian Lamparter int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size);
161886c251fSChristian Lamparter void crypto4xx_free_sa(struct crypto4xx_ctx *ctx);
162886c251fSChristian Lamparter void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx);
163886c251fSChristian Lamparter u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx);
164886c251fSChristian Lamparter void crypto4xx_memcpy_le(unsigned int *dst,
165049359d6SJames Hsiao 			 const unsigned char *buf, int len);
166886c251fSChristian Lamparter u32 crypto4xx_build_pd(struct crypto_async_request *req,
167049359d6SJames Hsiao 		       struct crypto4xx_ctx *ctx,
168049359d6SJames Hsiao 		       struct scatterlist *src,
169049359d6SJames Hsiao 		       struct scatterlist *dst,
170049359d6SJames Hsiao 		       unsigned int datalen,
171049359d6SJames Hsiao 		       void *iv, u32 iv_len);
172886c251fSChristian Lamparter int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher,
173049359d6SJames Hsiao 			     const u8 *key, unsigned int keylen);
174f2a13e7cSChristian Lamparter int crypto4xx_setkey_aes_cfb(struct crypto_ablkcipher *cipher,
175f2a13e7cSChristian Lamparter 			     const u8 *key, unsigned int keylen);
176f2a13e7cSChristian Lamparter int crypto4xx_setkey_aes_ecb(struct crypto_ablkcipher *cipher,
177f2a13e7cSChristian Lamparter 			     const u8 *key, unsigned int keylen);
178f2a13e7cSChristian Lamparter int crypto4xx_setkey_aes_ofb(struct crypto_ablkcipher *cipher,
179f2a13e7cSChristian Lamparter 			     const u8 *key, unsigned int keylen);
180f2a13e7cSChristian Lamparter int crypto4xx_setkey_rfc3686(struct crypto_ablkcipher *cipher,
181f2a13e7cSChristian Lamparter 			     const u8 *key, unsigned int keylen);
182886c251fSChristian Lamparter int crypto4xx_encrypt(struct ablkcipher_request *req);
183886c251fSChristian Lamparter int crypto4xx_decrypt(struct ablkcipher_request *req);
184f2a13e7cSChristian Lamparter int crypto4xx_rfc3686_encrypt(struct ablkcipher_request *req);
185f2a13e7cSChristian Lamparter int crypto4xx_rfc3686_decrypt(struct ablkcipher_request *req);
186886c251fSChristian Lamparter int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm);
187886c251fSChristian Lamparter int crypto4xx_hash_digest(struct ahash_request *req);
188886c251fSChristian Lamparter int crypto4xx_hash_final(struct ahash_request *req);
189886c251fSChristian Lamparter int crypto4xx_hash_update(struct ahash_request *req);
190886c251fSChristian Lamparter int crypto4xx_hash_init(struct ahash_request *req);
191049359d6SJames Hsiao #endif
192