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 
27049359d6SJames Hsiao #define PPC460SX_SDR0_SRST                      0x201
28049359d6SJames Hsiao #define PPC405EX_SDR0_SRST                      0x200
29049359d6SJames Hsiao #define PPC460EX_SDR0_SRST                      0x201
30049359d6SJames Hsiao #define PPC460EX_CE_RESET                       0x08000000
31049359d6SJames Hsiao #define PPC460SX_CE_RESET                       0x20000000
32049359d6SJames Hsiao #define PPC405EX_CE_RESET                       0x00000008
33049359d6SJames Hsiao 
34049359d6SJames Hsiao #define CRYPTO4XX_CRYPTO_PRIORITY		300
35049359d6SJames Hsiao #define PPC4XX_LAST_PD				63
36049359d6SJames Hsiao #define PPC4XX_NUM_PD				64
37049359d6SJames Hsiao #define PPC4XX_LAST_GD				1023
38049359d6SJames Hsiao #define PPC4XX_NUM_GD				1024
39049359d6SJames Hsiao #define PPC4XX_LAST_SD				63
40049359d6SJames Hsiao #define PPC4XX_NUM_SD				64
41049359d6SJames Hsiao #define PPC4XX_SD_BUFFER_SIZE			2048
42049359d6SJames Hsiao 
43049359d6SJames Hsiao #define PD_ENTRY_INUSE				1
44049359d6SJames Hsiao #define PD_ENTRY_FREE				0
45049359d6SJames Hsiao #define ERING_WAS_FULL				0xffffffff
46049359d6SJames Hsiao 
47049359d6SJames Hsiao struct crypto4xx_device;
48049359d6SJames Hsiao 
49049359d6SJames Hsiao struct pd_uinfo {
50049359d6SJames Hsiao 	struct crypto4xx_device *dev;
51049359d6SJames Hsiao 	u32   state;
52049359d6SJames Hsiao 	u32 using_sd;
53049359d6SJames Hsiao 	u32 first_gd;		/* first gather discriptor
54049359d6SJames Hsiao 				used by this packet */
55049359d6SJames Hsiao 	u32 num_gd;             /* number of gather discriptor
56049359d6SJames Hsiao 				used by this packet */
57049359d6SJames Hsiao 	u32 first_sd;		/* first scatter discriptor
58049359d6SJames Hsiao 				used by this packet */
59049359d6SJames Hsiao 	u32 num_sd;		/* number of scatter discriptors
60049359d6SJames Hsiao 				used by this packet */
61049359d6SJames Hsiao 	void *sa_va;		/* shadow sa, when using cp from ctx->sa */
62049359d6SJames Hsiao 	u32 sa_pa;
63049359d6SJames Hsiao 	void *sr_va;		/* state record for shadow sa */
64049359d6SJames Hsiao 	u32 sr_pa;
65049359d6SJames Hsiao 	struct scatterlist *dest_va;
66049359d6SJames Hsiao 	struct crypto_async_request *async_req; 	/* base crypto request
67049359d6SJames Hsiao 							for this packet */
68049359d6SJames Hsiao };
69049359d6SJames Hsiao 
70049359d6SJames Hsiao struct crypto4xx_device {
71049359d6SJames Hsiao 	struct crypto4xx_core_device *core_dev;
72049359d6SJames Hsiao 	char *name;
73049359d6SJames Hsiao 	u64  ce_phy_address;
74049359d6SJames Hsiao 	void __iomem *ce_base;
75049359d6SJames Hsiao 
76049359d6SJames Hsiao 	void *pdr;			/* base address of packet
77049359d6SJames Hsiao 					descriptor ring */
78049359d6SJames Hsiao 	dma_addr_t pdr_pa;		/* physical address used to
79049359d6SJames Hsiao 					program ce pdr_base_register */
80049359d6SJames Hsiao 	void *gdr;                      /* gather descriptor ring */
81049359d6SJames Hsiao 	dma_addr_t gdr_pa;		/* physical address used to
82049359d6SJames Hsiao 					program ce gdr_base_register */
83049359d6SJames Hsiao 	void *sdr;			/* scatter descriptor ring */
84049359d6SJames Hsiao 	dma_addr_t sdr_pa;		/* physical address used to
85049359d6SJames Hsiao 					program ce sdr_base_register */
86049359d6SJames Hsiao 	void *scatter_buffer_va;
87049359d6SJames Hsiao 	dma_addr_t scatter_buffer_pa;
88049359d6SJames Hsiao 	u32 scatter_buffer_size;
89049359d6SJames Hsiao 
90049359d6SJames Hsiao 	void *shadow_sa_pool;		/* pool of memory for sa in pd_uinfo */
91049359d6SJames Hsiao 	dma_addr_t shadow_sa_pool_pa;
92049359d6SJames Hsiao 	void *shadow_sr_pool;		/* pool of memory for sr in pd_uinfo */
93049359d6SJames Hsiao 	dma_addr_t shadow_sr_pool_pa;
94049359d6SJames Hsiao 	u32 pdr_tail;
95049359d6SJames Hsiao 	u32 pdr_head;
96049359d6SJames Hsiao 	u32 gdr_tail;
97049359d6SJames Hsiao 	u32 gdr_head;
98049359d6SJames Hsiao 	u32 sdr_tail;
99049359d6SJames Hsiao 	u32 sdr_head;
100049359d6SJames Hsiao 	void *pdr_uinfo;
101049359d6SJames Hsiao 	struct list_head alg_list;	/* List of algorithm supported
102049359d6SJames Hsiao 					by this device */
103049359d6SJames Hsiao };
104049359d6SJames Hsiao 
105049359d6SJames Hsiao struct crypto4xx_core_device {
106049359d6SJames Hsiao 	struct device *device;
107049359d6SJames Hsiao 	struct of_device *ofdev;
108049359d6SJames Hsiao 	struct crypto4xx_device *dev;
109049359d6SJames Hsiao 	u32 int_status;
110049359d6SJames Hsiao 	u32 irq;
111049359d6SJames Hsiao 	struct tasklet_struct tasklet;
112049359d6SJames Hsiao 	spinlock_t lock;
113049359d6SJames Hsiao };
114049359d6SJames Hsiao 
115049359d6SJames Hsiao struct crypto4xx_ctx {
116049359d6SJames Hsiao 	struct crypto4xx_device *dev;
117049359d6SJames Hsiao 	void *sa_in;
118049359d6SJames Hsiao 	dma_addr_t sa_in_dma_addr;
119049359d6SJames Hsiao 	void *sa_out;
120049359d6SJames Hsiao 	dma_addr_t sa_out_dma_addr;
121049359d6SJames Hsiao 	void *state_record;
122049359d6SJames Hsiao 	dma_addr_t state_record_dma_addr;
123049359d6SJames Hsiao 	u32 sa_len;
124049359d6SJames Hsiao 	u32 offset_to_sr_ptr;           /* offset to state ptr, in dynamic sa */
125049359d6SJames Hsiao 	u32 direction;
126049359d6SJames Hsiao 	u32 next_hdr;
127049359d6SJames Hsiao 	u32 save_iv;
128049359d6SJames Hsiao 	u32 pd_ctl_len;
129049359d6SJames Hsiao 	u32 pd_ctl;
130049359d6SJames Hsiao 	u32 bypass;
131049359d6SJames Hsiao 	u32 is_hash;
132049359d6SJames Hsiao 	u32 hash_final;
133049359d6SJames Hsiao };
134049359d6SJames Hsiao 
135049359d6SJames Hsiao struct crypto4xx_req_ctx {
136049359d6SJames Hsiao 	struct crypto4xx_device *dev;	/* Device in which
137049359d6SJames Hsiao 					operation to send to */
138049359d6SJames Hsiao 	void *sa;
139049359d6SJames Hsiao 	u32 sa_dma_addr;
140049359d6SJames Hsiao 	u16 sa_len;
141049359d6SJames Hsiao };
142049359d6SJames Hsiao 
1434dc10c01SHerbert Xu struct crypto4xx_alg_common {
1444dc10c01SHerbert Xu 	u32 type;
1454dc10c01SHerbert Xu 	union {
1464dc10c01SHerbert Xu 		struct crypto_alg cipher;
1474dc10c01SHerbert Xu 		struct ahash_alg hash;
1484dc10c01SHerbert Xu 	} u;
1494dc10c01SHerbert Xu };
1504dc10c01SHerbert Xu 
151049359d6SJames Hsiao struct crypto4xx_alg {
152049359d6SJames Hsiao 	struct list_head  entry;
1534dc10c01SHerbert Xu 	struct crypto4xx_alg_common alg;
154049359d6SJames Hsiao 	struct crypto4xx_device *dev;
155049359d6SJames Hsiao };
156049359d6SJames Hsiao 
1574dc10c01SHerbert Xu static inline struct crypto4xx_alg *crypto_alg_to_crypto4xx_alg(
1584dc10c01SHerbert Xu 	struct crypto_alg *x)
1594dc10c01SHerbert Xu {
1604dc10c01SHerbert Xu 	switch (x->cra_flags & CRYPTO_ALG_TYPE_MASK) {
1614dc10c01SHerbert Xu 	case CRYPTO_ALG_TYPE_AHASH:
1624dc10c01SHerbert Xu 		return container_of(__crypto_ahash_alg(x),
1634dc10c01SHerbert Xu 				    struct crypto4xx_alg, alg.u.hash);
1644dc10c01SHerbert Xu 	}
1654dc10c01SHerbert Xu 
1664dc10c01SHerbert Xu 	return container_of(x, struct crypto4xx_alg, alg.u.cipher);
1674dc10c01SHerbert Xu }
168049359d6SJames Hsiao 
169049359d6SJames Hsiao extern int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size);
170049359d6SJames Hsiao extern void crypto4xx_free_sa(struct crypto4xx_ctx *ctx);
171049359d6SJames Hsiao extern u32 crypto4xx_alloc_sa_rctx(struct crypto4xx_ctx *ctx,
172049359d6SJames Hsiao 				   struct crypto4xx_ctx *rctx);
173049359d6SJames Hsiao extern void crypto4xx_free_sa_rctx(struct crypto4xx_ctx *rctx);
174049359d6SJames Hsiao extern void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx);
175049359d6SJames Hsiao extern u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx);
176049359d6SJames Hsiao extern u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx);
177049359d6SJames Hsiao extern u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx);
178049359d6SJames Hsiao extern u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx);
179049359d6SJames Hsiao extern void crypto4xx_memcpy_le(unsigned int *dst,
180049359d6SJames Hsiao 				const unsigned char *buf, int len);
181049359d6SJames Hsiao extern u32 crypto4xx_build_pd(struct crypto_async_request *req,
182049359d6SJames Hsiao 			      struct crypto4xx_ctx *ctx,
183049359d6SJames Hsiao 			      struct scatterlist *src,
184049359d6SJames Hsiao 			      struct scatterlist *dst,
185049359d6SJames Hsiao 			      unsigned int datalen,
186049359d6SJames Hsiao 			      void *iv, u32 iv_len);
187049359d6SJames Hsiao extern int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher,
188049359d6SJames Hsiao 				    const u8 *key, unsigned int keylen);
189049359d6SJames Hsiao extern int crypto4xx_encrypt(struct ablkcipher_request *req);
190049359d6SJames Hsiao extern int crypto4xx_decrypt(struct ablkcipher_request *req);
191049359d6SJames Hsiao extern int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm);
192049359d6SJames Hsiao extern int crypto4xx_hash_digest(struct ahash_request *req);
193049359d6SJames Hsiao extern int crypto4xx_hash_final(struct ahash_request *req);
194049359d6SJames Hsiao extern int crypto4xx_hash_update(struct ahash_request *req);
195049359d6SJames Hsiao extern int crypto4xx_hash_init(struct ahash_request *req);
196049359d6SJames Hsiao #endif
197