summaryrefslogtreecommitdiffstats
path: root/drivers/crypto/amlogic/amlogic-gxl.h
blob: fd9192b4050bffd8504f82df7a8d6434a245d9c6 (plain)
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
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * amlogic.h - hardware cryptographic offloader for Amlogic SoC
 *
 * Copyright (C) 2018-2019 Corentin LABBE <clabbe@baylibre.com>
 */
#include <crypto/aes.h>
#include <crypto/engine.h>
#include <crypto/skcipher.h>
#include <linux/debugfs.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>

#define MODE_KEY 1
#define MODE_AES_128 0x8
#define MODE_AES_192 0x9
#define MODE_AES_256 0xa

#define MESON_DECRYPT 0
#define MESON_ENCRYPT 1

#define MESON_OPMODE_ECB 0
#define MESON_OPMODE_CBC 1

#define MAXFLOW 2

#define MAXDESC 64

/*
 * struct meson_desc - Descriptor for DMA operations
 * Note that without datasheet, some are unknown
 * @len:	length of data to operate
 * @irq:	Ignored by hardware
 * @eoc:	End of descriptor
 * @loop:	Unknown
 * @mode:	Type of algorithm (AES, SHA)
 * @begin:	Unknown
 * @end:	Unknown
 * @op_mode:	Blockmode (CBC, ECB)
 * @block:	Unknown
 * @error:	Unknown
 * @owner:	owner of the descriptor, 1 own by HW
 * @t_src:	Physical address of data to read
 * @t_dst:	Physical address of data to write
 */
struct meson_desc {
	union {
		u32 t_status;
		struct {
			u32 len:17;
			u32 irq:1;
			u32 eoc:1;
			u32 loop:1;
			u32 mode:4;
			u32 begin:1;
			u32 end:1;
			u32 op_mode:2;
			u32 enc:1;
			u32 block:1;
			u32 error:1;
			u32 owner:1;
		};
	};
	u32 t_src;
	u32 t_dst;
};

/*
 * struct meson_flow - Information used by each flow
 * @engine:	ptr to the crypto_engine for this flow
 * @keylen:	keylen for this flow operation
 * @complete:	completion for the current task on this flow
 * @status:	set to 1 by interrupt if task is done
 * @t_phy:	Physical address of task
 * @tl:		pointer to the current ce_task for this flow
 * @stat_req:	number of request done by this flow
 */
struct meson_flow {
	struct crypto_engine *engine;
	struct completion complete;
	int status;
	unsigned int keylen;
	dma_addr_t t_phy;
	struct meson_desc *tl;
#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
	unsigned long stat_req;
#endif
};

/*
 * struct meson_dev - main container for all this driver information
 * @base:	base address of amlogic-crypto
 * @busclk:	bus clock for amlogic-crypto
 * @dev:	the platform device
 * @chanlist:	array of all flow
 * @flow:	flow to use in next request
 * @irqs:	IRQ numbers for amlogic-crypto
 * @dbgfs_dir:	Debugfs dentry for statistic directory
 * @dbgfs_stats: Debugfs dentry for statistic counters
 */
struct meson_dev {
	void __iomem *base;
	struct clk *busclk;
	struct device *dev;
	struct meson_flow *chanlist;
	atomic_t flow;
	int *irqs;
#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
	struct dentry *dbgfs_dir;
#endif
};

/*
 * struct meson_cipher_req_ctx - context for a skcipher request
 * @op_dir:	direction (encrypt vs decrypt) for this request
 * @flow:	the flow to use for this request
 */
struct meson_cipher_req_ctx {
	u32 op_dir;
	int flow;
};

/*
 * struct meson_cipher_tfm_ctx - context for a skcipher TFM
 * @enginectx:		crypto_engine used by this TFM
 * @key:		pointer to key data
 * @keylen:		len of the key
 * @keymode:		The keymode(type and size of key) associated with this TFM
 * @mc:			pointer to the private data of driver handling this TFM
 * @fallback_tfm:	pointer to the fallback TFM
 */
struct meson_cipher_tfm_ctx {
	struct crypto_engine_ctx enginectx;
	u32 *key;
	u32 keylen;
	u32 keymode;
	struct meson_dev *mc;
	struct crypto_sync_skcipher *fallback_tfm;
};

/*
 * struct meson_alg_template - crypto_alg template
 * @type:		the CRYPTO_ALG_TYPE for this template
 * @blockmode:		the type of block operation
 * @mc:			pointer to the meson_dev structure associated with this template
 * @alg:		one of sub struct must be used
 * @stat_req:		number of request done on this template
 * @stat_fb:		total of all data len done on this template
 */
struct meson_alg_template {
	u32 type;
	u32 blockmode;
	union {
		struct skcipher_alg skcipher;
	} alg;
	struct meson_dev *mc;
#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
	unsigned long stat_req;
	unsigned long stat_fb;
#endif
};

int meson_enqueue(struct crypto_async_request *areq, u32 type);

int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
		     unsigned int keylen);
int meson_cipher_init(struct crypto_tfm *tfm);
void meson_cipher_exit(struct crypto_tfm *tfm);
int meson_skdecrypt(struct skcipher_request *areq);
int meson_skencrypt(struct skcipher_request *areq);