summaryrefslogtreecommitdiff
path: root/drivers/crypto/mediatek/mtk-platform.h
blob: f0831f1742abe44d0a9823393d1f255851d995bc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
 * Driver for EIP97 cryptographic accelerator.
 *
 * Copyright (c) 2016 Ryder Lee <ryder.lee@mediatek.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#ifndef __MTK_PLATFORM_H_
#define __MTK_PLATFORM_H_

#include <crypto/algapi.h>
#include <crypto/internal/aead.h>
#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include <crypto/skcipher.h>
#include <linux/crypto.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include "mtk-regs.h"

#define MTK_RDR_PROC_THRESH	BIT(0)
#define MTK_RDR_PROC_MODE	BIT(23)
#define MTK_CNT_RST		BIT(31)
#define MTK_IRQ_RDR0		BIT(1)
#define MTK_IRQ_RDR1		BIT(3)
#define MTK_IRQ_RDR2		BIT(5)
#define MTK_IRQ_RDR3		BIT(7)

#define SIZE_IN_WORDS(x)	((x) >> 2)

/**
 * Ring 0/1 are used by AES encrypt and decrypt.
 * Ring 2/3 are used by SHA.
 */
enum {
	MTK_RING0,
	MTK_RING1,
	MTK_RING2,
	MTK_RING3,
	MTK_RING_MAX
};

#define MTK_REC_NUM		(MTK_RING_MAX / 2)
#define MTK_IRQ_NUM		5

/**
 * struct mtk_desc - DMA descriptor
 * @hdr:	the descriptor control header
 * @buf:	DMA address of input buffer segment
 * @ct:		DMA address of command token that control operation flow
 * @ct_hdr:	the command token control header
 * @tag:	the user-defined field
 * @tfm:	DMA address of transform state
 * @bound:	align descriptors offset boundary
 *
 * Structure passed to the crypto engine to describe where source
 * data needs to be fetched and how it needs to be processed.
 */
struct mtk_desc {
	__le32 hdr;
	__le32 buf;
	__le32 ct;
	__le32 ct_hdr;
	__le32 tag;
	__le32 tfm;
	__le32 bound[2];
};

#define MTK_DESC_NUM		512
#define MTK_DESC_OFF		SIZE_IN_WORDS(sizeof(struct mtk_desc))
#define MTK_DESC_SZ		(MTK_DESC_OFF - 2)
#define MTK_DESC_RING_SZ	((sizeof(struct mtk_desc) * MTK_DESC_NUM))
#define MTK_DESC_CNT(x)		((MTK_DESC_OFF * (x)) << 2)
#define MTK_DESC_LAST		cpu_to_le32(BIT(22))
#define MTK_DESC_FIRST		cpu_to_le32(BIT(23))
#define MTK_DESC_BUF_LEN(x)	cpu_to_le32(x)
#define MTK_DESC_CT_LEN(x)	cpu_to_le32((x) << 24)

/**
 * struct mtk_ring - Descriptor ring
 * @cmd_base:	pointer to command descriptor ring base
 * @cmd_next:	pointer to the next command descriptor
 * @cmd_dma:	DMA address of command descriptor ring
 * @res_base:	pointer to result descriptor ring base
 * @res_next:	pointer to the next result descriptor
 * @res_prev:	pointer to the previous result descriptor
 * @res_dma:	DMA address of result descriptor ring
 *
 * A descriptor ring is a circular buffer that is used to manage
 * one or more descriptors. There are two type of descriptor rings;
 * the command descriptor ring and result descriptor ring.
 */
struct mtk_ring {
	struct mtk_desc *cmd_base;
	struct mtk_desc *cmd_next;
	dma_addr_t cmd_dma;
	struct mtk_desc *res_base;
	struct mtk_desc *res_next;
	struct mtk_desc *res_prev;
	dma_addr_t res_dma;
};

/**
 * struct mtk_aes_dma - Structure that holds sg list info
 * @sg:		pointer to scatter-gather list
 * @nents:	number of entries in the sg list
 * @remainder:	remainder of sg list
 * @sg_len:	number of entries in the sg mapped list
 */
struct mtk_aes_dma {
	struct scatterlist *sg;
	int nents;
	u32 remainder;
	u32 sg_len;
};

struct mtk_aes_base_ctx;
struct mtk_aes_rec;
struct mtk_cryp;

typedef int (*mtk_aes_fn)(struct mtk_cryp *cryp, struct mtk_aes_rec *aes);

/**
 * struct mtk_aes_rec - AES operation record
 * @cryp:	pointer to Cryptographic device
 * @queue:	crypto request queue
 * @areq:	pointer to async request
 * @done_task:	the tasklet is use in AES interrupt
 * @queue_task:	the tasklet is used to dequeue request
 * @ctx:	pointer to current context
 * @src:	the structure that holds source sg list info
 * @dst:	the structure that holds destination sg list info
 * @aligned_sg:	the scatter list is use to alignment
 * @real_dst:	pointer to the destination sg list
 * @resume:	pointer to resume function
 * @total:	request buffer length
 * @buf:	pointer to page buffer
 * @id:		the current use of ring
 * @flags:	it's describing AES operation state
 * @lock:	the async queue lock
 *
 * Structure used to record AES execution state.
 */
struct mtk_aes_rec {
	struct mtk_cryp *cryp;
	struct crypto_queue queue;
	struct crypto_async_request *areq;
	struct tasklet_struct done_task;
	struct tasklet_struct queue_task;
	struct mtk_aes_base_ctx *ctx;
	struct mtk_aes_dma src;
	struct mtk_aes_dma dst;

	struct scatterlist aligned_sg;
	struct scatterlist *real_dst;

	mtk_aes_fn resume;

	size_t total;
	void *buf;

	u8 id;
	unsigned long flags;
	/* queue lock */
	spinlock_t lock;
};

/**
 * struct mtk_sha_rec - SHA operation record
 * @cryp:	pointer to Cryptographic device
 * @queue:	crypto request queue
 * @req:	pointer to ahash request
 * @done_task:	the tasklet is use in SHA interrupt
 * @queue_task:	the tasklet is used to dequeue request
 * @id:		the current use of ring
 * @flags:	it's describing SHA operation state
 * @lock:	the async queue lock
 *
 * Structure used to record SHA execution state.
 */
struct mtk_sha_rec {
	struct mtk_cryp *cryp;
	struct crypto_queue queue;
	struct ahash_request *req;
	struct tasklet_struct done_task;
	struct tasklet_struct queue_task;

	u8 id;
	unsigned long flags;
	/* queue lock */
	spinlock_t lock;
};

/**
 * struct mtk_cryp - Cryptographic device
 * @base:	pointer to mapped register I/O base
 * @dev:	pointer to device
 * @clk_cryp:	pointer to crypto clock
 * @irq:	global system and rings IRQ
 * @ring:	pointer to descriptor rings
 * @aes:	pointer to operation record of AES
 * @sha:	pointer to operation record of SHA
 * @aes_list:	device list of AES
 * @sha_list:	device list of SHA
 * @rec:	it's used to select SHA record for tfm
 *
 * Structure storing cryptographic device information.
 */
struct mtk_cryp {
	void __iomem *base;
	struct device *dev;
	struct clk *clk_cryp;
	int irq[MTK_IRQ_NUM];

	struct mtk_ring *ring[MTK_RING_MAX];
	struct mtk_aes_rec *aes[MTK_REC_NUM];
	struct mtk_sha_rec *sha[MTK_REC_NUM];

	struct list_head aes_list;
	struct list_head sha_list;

	bool rec;
};

int mtk_cipher_alg_register(struct mtk_cryp *cryp);
void mtk_cipher_alg_release(struct mtk_cryp *cryp);
int mtk_hash_alg_register(struct mtk_cryp *cryp);
void mtk_hash_alg_release(struct mtk_cryp *cryp);

#endif /* __MTK_PLATFORM_H_ */