Blame view

drivers/crypto/omap-aes.c 30.9 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
2
3
4
5
6
7
8
  /*
   * Cryptographic API.
   *
   * Support for OMAP AES HW acceleration.
   *
   * Copyright (c) 2010 Nokia Corporation
   * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
0d35583a1   Mark A. Greer   crypto: omap-aes ...
9
   * Copyright (c) 2011 Texas Instruments Incorporated
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
10
   */
016af9b5c   Joel Fernandes   crypto: omap-aes ...
11
12
13
14
15
  #define pr_fmt(fmt) "%20s: " fmt, __func__
  #define prn(num) pr_debug(#num "=%d
  ", num)
  #define prx(num) pr_debug(#num "=%x
  ", num)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
16
17
18
19
20
21
  
  #include <linux/err.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/errno.h>
  #include <linux/kernel.h>
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
22
23
24
  #include <linux/platform_device.h>
  #include <linux/scatterlist.h>
  #include <linux/dma-mapping.h>
ebedbf790   Mark A. Greer   crypto: omap-aes ...
25
  #include <linux/dmaengine.h>
5946c4a5e   Mark A. Greer   crypto: omap-aes ...
26
  #include <linux/pm_runtime.h>
bc69d124d   Mark A. Greer   crypto: omap-aes ...
27
28
29
  #include <linux/of.h>
  #include <linux/of_device.h>
  #include <linux/of_address.h>
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
30
31
32
33
34
  #include <linux/io.h>
  #include <linux/crypto.h>
  #include <linux/interrupt.h>
  #include <crypto/scatterwalk.h>
  #include <crypto/aes.h>
cb3f38175   Corentin LABBE   crypto: omap - Us...
35
  #include <crypto/gcm.h>
2589ad840   Corentin LABBE   crypto: engine - ...
36
  #include <crypto/engine.h>
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
37
  #include <crypto/internal/skcipher.h>
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
38
  #include <crypto/internal/aead.h>
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
39

afc2dc133   Tero Kristo   crypto: omap-aes ...
40
  #include "omap-crypto.h"
5b3d4d2e6   Tero Kristo   crypto: omap-aes ...
41
  #include "omap-aes.h"
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
42
43
44
45
  
  /* keep registered devices data here */
  static LIST_HEAD(dev_list);
  static DEFINE_SPINLOCK(list_lock);
537c62ca1   Tero Kristo   crypto: omap-aes ...
46
  static int aes_fallback_sz = 200;
016af9b5c   Joel Fernandes   crypto: omap-aes ...
47
48
49
50
51
52
53
54
55
56
57
  #ifdef DEBUG
  #define omap_aes_read(dd, offset)				\
  ({								\
  	int _read_ret;						\
  	_read_ret = __raw_readl(dd->io_base + offset);		\
  	pr_debug("omap_aes_read(" #offset "=%#x)= %#x
  ",	\
  		 offset, _read_ret);				\
  	_read_ret;						\
  })
  #else
d695bfd6f   Tero Kristo   crypto: omap-aes ...
58
  inline u32 omap_aes_read(struct omap_aes_dev *dd, u32 offset)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
59
60
61
  {
  	return __raw_readl(dd->io_base + offset);
  }
016af9b5c   Joel Fernandes   crypto: omap-aes ...
62
63
64
65
66
67
68
69
70
71
72
  #endif
  
  #ifdef DEBUG
  #define omap_aes_write(dd, offset, value)				\
  	do {								\
  		pr_debug("omap_aes_write(" #offset "=%#x) value=%#x
  ",	\
  			 offset, value);				\
  		__raw_writel(value, dd->io_base + offset);		\
  	} while (0)
  #else
d695bfd6f   Tero Kristo   crypto: omap-aes ...
73
  inline void omap_aes_write(struct omap_aes_dev *dd, u32 offset,
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
74
75
76
77
  				  u32 value)
  {
  	__raw_writel(value, dd->io_base + offset);
  }
016af9b5c   Joel Fernandes   crypto: omap-aes ...
78
  #endif
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  
  static inline void omap_aes_write_mask(struct omap_aes_dev *dd, u32 offset,
  					u32 value, u32 mask)
  {
  	u32 val;
  
  	val = omap_aes_read(dd, offset);
  	val &= ~mask;
  	val |= value;
  	omap_aes_write(dd, offset, val);
  }
  
  static void omap_aes_write_n(struct omap_aes_dev *dd, u32 offset,
  					u32 *value, int count)
  {
  	for (; count--; value++, offset += 4)
  		omap_aes_write(dd, offset, *value);
  }
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
97
98
  static int omap_aes_hw_init(struct omap_aes_dev *dd)
  {
f303b455b   Tero Kristo   crypto: omap-aes ...
99
  	int err;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
100
  	if (!(dd->flags & FLAGS_INIT)) {
eeb2b202c   Dmitry Kasatkin   crypto: omap-aes ...
101
  		dd->flags |= FLAGS_INIT;
21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
102
  		dd->err = 0;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
103
  	}
f303b455b   Tero Kristo   crypto: omap-aes ...
104
105
106
107
108
109
  	err = pm_runtime_get_sync(dd->dev);
  	if (err < 0) {
  		dev_err(dd->dev, "failed to get sync: %d
  ", err);
  		return err;
  	}
eeb2b202c   Dmitry Kasatkin   crypto: omap-aes ...
110
  	return 0;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
111
  }
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
112
113
114
115
116
117
  void omap_aes_clear_copy_flags(struct omap_aes_dev *dd)
  {
  	dd->flags &= ~(OMAP_CRYPTO_COPY_MASK << FLAGS_IN_DATA_ST_SHIFT);
  	dd->flags &= ~(OMAP_CRYPTO_COPY_MASK << FLAGS_OUT_DATA_ST_SHIFT);
  	dd->flags &= ~(OMAP_CRYPTO_COPY_MASK << FLAGS_ASSOC_DATA_ST_SHIFT);
  }
d695bfd6f   Tero Kristo   crypto: omap-aes ...
118
  int omap_aes_write_ctrl(struct omap_aes_dev *dd)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
119
  {
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
120
  	struct omap_aes_reqctx *rctx;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
121
  	unsigned int key32;
67a730ce4   Dmitry Kasatkin   crypto: omap-aes ...
122
  	int i, err;
5396c6c07   Vutla, Lokesh   crypto: omap-aes ...
123
  	u32 val;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
124

21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
125
126
127
  	err = omap_aes_hw_init(dd);
  	if (err)
  		return err;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
128
  	key32 = dd->ctx->keylen / sizeof(u32);
67a730ce4   Dmitry Kasatkin   crypto: omap-aes ...
129

ad18cc9d0   Tero Kristo   crypto: omap-aes ...
130
131
132
133
  	/* RESET the key as previous HASH keys should not get affected*/
  	if (dd->flags & FLAGS_GCM)
  		for (i = 0; i < 0x40; i = i + 4)
  			omap_aes_write(dd, i, 0x0);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
134
  	for (i = 0; i < key32; i++) {
0d35583a1   Mark A. Greer   crypto: omap-aes ...
135
  		omap_aes_write(dd, AES_REG_KEY(dd, i),
ac855b3c1   Herbert Xu   crypto: omap-aes ...
136
  			       (__force u32)cpu_to_le32(dd->ctx->key[i]));
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
137
  	}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
138

b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
139
140
  	if ((dd->flags & (FLAGS_CBC | FLAGS_CTR)) && dd->req->iv)
  		omap_aes_write_n(dd, AES_REG_IV(dd, 0), (void *)dd->req->iv, 4);
67a730ce4   Dmitry Kasatkin   crypto: omap-aes ...
141

ad18cc9d0   Tero Kristo   crypto: omap-aes ...
142
143
144
145
  	if ((dd->flags & (FLAGS_GCM)) && dd->aead_req->iv) {
  		rctx = aead_request_ctx(dd->aead_req);
  		omap_aes_write_n(dd, AES_REG_IV(dd, 0), (u32 *)rctx->iv, 4);
  	}
67a730ce4   Dmitry Kasatkin   crypto: omap-aes ...
146
147
148
  	val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
  	if (dd->flags & FLAGS_CBC)
  		val |= AES_REG_CTRL_CBC;
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
149
150
  
  	if (dd->flags & (FLAGS_CTR | FLAGS_GCM))
8ed49c767   Joel Fernandes   crypto: omap-aes ...
151
  		val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_128;
5396c6c07   Vutla, Lokesh   crypto: omap-aes ...
152

ad18cc9d0   Tero Kristo   crypto: omap-aes ...
153
154
  	if (dd->flags & FLAGS_GCM)
  		val |= AES_REG_CTRL_GCM;
67a730ce4   Dmitry Kasatkin   crypto: omap-aes ...
155
156
  	if (dd->flags & FLAGS_ENCRYPT)
  		val |= AES_REG_CTRL_DIRECTION;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
157

5396c6c07   Vutla, Lokesh   crypto: omap-aes ...
158
  	omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, AES_REG_CTRL_MASK);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
159

21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
160
  	return 0;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
161
  }
0d35583a1   Mark A. Greer   crypto: omap-aes ...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
  static void omap_aes_dma_trigger_omap2(struct omap_aes_dev *dd, int length)
  {
  	u32 mask, val;
  
  	val = dd->pdata->dma_start;
  
  	if (dd->dma_lch_out != NULL)
  		val |= dd->pdata->dma_enable_out;
  	if (dd->dma_lch_in != NULL)
  		val |= dd->pdata->dma_enable_in;
  
  	mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
  	       dd->pdata->dma_start;
  
  	omap_aes_write_mask(dd, AES_REG_MASK(dd), val, mask);
  
  }
  
  static void omap_aes_dma_trigger_omap4(struct omap_aes_dev *dd, int length)
  {
  	omap_aes_write(dd, AES_REG_LENGTH_N(0), length);
  	omap_aes_write(dd, AES_REG_LENGTH_N(1), 0);
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
184
185
  	if (dd->flags & FLAGS_GCM)
  		omap_aes_write(dd, AES_REG_A_LEN, dd->assoc_len);
0d35583a1   Mark A. Greer   crypto: omap-aes ...
186
187
188
189
190
191
192
193
194
195
196
197
198
  
  	omap_aes_dma_trigger_omap2(dd, length);
  }
  
  static void omap_aes_dma_stop(struct omap_aes_dev *dd)
  {
  	u32 mask;
  
  	mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
  	       dd->pdata->dma_start;
  
  	omap_aes_write_mask(dd, AES_REG_MASK(dd), 0, mask);
  }
d695bfd6f   Tero Kristo   crypto: omap-aes ...
199
  struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_reqctx *rctx)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
200
  {
164f3ef30   Lokesh Vutla   crypto: omap-aes ...
201
  	struct omap_aes_dev *dd;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
202
203
  
  	spin_lock_bh(&list_lock);
164f3ef30   Lokesh Vutla   crypto: omap-aes ...
204
205
  	dd = list_first_entry(&dev_list, struct omap_aes_dev, list);
  	list_move_tail(&dd->list, &dev_list);
619ce7005   Tero Kristo   crypto: omap-aes ...
206
  	rctx->dd = dd;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
207
208
209
210
  	spin_unlock_bh(&list_lock);
  
  	return dd;
  }
ebedbf790   Mark A. Greer   crypto: omap-aes ...
211
212
213
214
215
216
217
  static void omap_aes_dma_out_callback(void *data)
  {
  	struct omap_aes_dev *dd = data;
  
  	/* dma_lch_out - completed */
  	tasklet_schedule(&dd->done_task);
  }
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
218
219
220
  
  static int omap_aes_dma_init(struct omap_aes_dev *dd)
  {
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
221
  	int err;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
222

ebedbf790   Mark A. Greer   crypto: omap-aes ...
223
224
  	dd->dma_lch_out = NULL;
  	dd->dma_lch_in = NULL;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
225

da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
226
227
  	dd->dma_lch_in = dma_request_chan(dd->dev, "rx");
  	if (IS_ERR(dd->dma_lch_in)) {
ebedbf790   Mark A. Greer   crypto: omap-aes ...
228
229
  		dev_err(dd->dev, "Unable to request in DMA channel
  ");
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
230
  		return PTR_ERR(dd->dma_lch_in);
ebedbf790   Mark A. Greer   crypto: omap-aes ...
231
  	}
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
232
233
  	dd->dma_lch_out = dma_request_chan(dd->dev, "tx");
  	if (IS_ERR(dd->dma_lch_out)) {
ebedbf790   Mark A. Greer   crypto: omap-aes ...
234
235
  		dev_err(dd->dev, "Unable to request out DMA channel
  ");
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
236
  		err = PTR_ERR(dd->dma_lch_out);
ebedbf790   Mark A. Greer   crypto: omap-aes ...
237
238
  		goto err_dma_out;
  	}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
239

537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
240
241
242
  	return 0;
  
  err_dma_out:
ebedbf790   Mark A. Greer   crypto: omap-aes ...
243
  	dma_release_channel(dd->dma_lch_in);
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
244

537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
245
246
247
248
249
  	return err;
  }
  
  static void omap_aes_dma_cleanup(struct omap_aes_dev *dd)
  {
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
250
251
  	if (dd->pio_only)
  		return;
ebedbf790   Mark A. Greer   crypto: omap-aes ...
252
253
  	dma_release_channel(dd->dma_lch_out);
  	dma_release_channel(dd->dma_lch_in);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
254
  }
619ce7005   Tero Kristo   crypto: omap-aes ...
255
256
257
258
  static int omap_aes_crypt_dma(struct omap_aes_dev *dd,
  			      struct scatterlist *in_sg,
  			      struct scatterlist *out_sg,
  			      int in_sg_len, int out_sg_len)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
259
  {
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
260
  	struct dma_async_tx_descriptor *tx_in, *tx_out = NULL, *cb_desc;
ebedbf790   Mark A. Greer   crypto: omap-aes ...
261
  	struct dma_slave_config cfg;
4b645c946   Joel Fernandes   crypto: omap-aes ...
262
  	int ret;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
263

98837abc8   Joel Fernandes   crypto: omap-aes ...
264
265
  	if (dd->pio_only) {
  		scatterwalk_start(&dd->in_walk, dd->in_sg);
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
266
267
  		if (out_sg_len)
  			scatterwalk_start(&dd->out_walk, dd->out_sg);
98837abc8   Joel Fernandes   crypto: omap-aes ...
268
269
270
271
272
273
  
  		/* Enable DATAIN interrupt and let it take
  		   care of the rest */
  		omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x2);
  		return 0;
  	}
0a641712e   Joel Fernandes   crypto: omap-aes ...
274
  	dma_sync_sg_for_device(dd->dev, dd->in_sg, in_sg_len, DMA_TO_DEVICE);
ebedbf790   Mark A. Greer   crypto: omap-aes ...
275
  	memset(&cfg, 0, sizeof(cfg));
0d35583a1   Mark A. Greer   crypto: omap-aes ...
276
277
  	cfg.src_addr = dd->phys_base + AES_REG_DATA_N(dd, 0);
  	cfg.dst_addr = dd->phys_base + AES_REG_DATA_N(dd, 0);
ebedbf790   Mark A. Greer   crypto: omap-aes ...
278
279
280
281
282
283
284
285
286
287
288
289
290
  	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  	cfg.src_maxburst = DST_MAXBURST;
  	cfg.dst_maxburst = DST_MAXBURST;
  
  	/* IN */
  	ret = dmaengine_slave_config(dd->dma_lch_in, &cfg);
  	if (ret) {
  		dev_err(dd->dev, "can't configure IN dmaengine slave: %d
  ",
  			ret);
  		return ret;
  	}
4b645c946   Joel Fernandes   crypto: omap-aes ...
291
  	tx_in = dmaengine_prep_slave_sg(dd->dma_lch_in, in_sg, in_sg_len,
ebedbf790   Mark A. Greer   crypto: omap-aes ...
292
293
294
295
296
297
298
299
300
301
  					DMA_MEM_TO_DEV,
  					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
  	if (!tx_in) {
  		dev_err(dd->dev, "IN prep_slave_sg() failed
  ");
  		return -EINVAL;
  	}
  
  	/* No callback necessary */
  	tx_in->callback_param = dd;
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
302
  	tx_in->callback = NULL;
ebedbf790   Mark A. Greer   crypto: omap-aes ...
303
304
  
  	/* OUT */
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
305
306
307
308
309
310
311
312
  	if (out_sg_len) {
  		ret = dmaengine_slave_config(dd->dma_lch_out, &cfg);
  		if (ret) {
  			dev_err(dd->dev, "can't configure OUT dmaengine slave: %d
  ",
  				ret);
  			return ret;
  		}
ebedbf790   Mark A. Greer   crypto: omap-aes ...
313

5d5f3eed2   Tero Kristo   crypto: omap-aes-...
314
315
316
317
318
319
320
321
322
323
324
325
326
  		tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg,
  						 out_sg_len,
  						 DMA_DEV_TO_MEM,
  						 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
  		if (!tx_out) {
  			dev_err(dd->dev, "OUT prep_slave_sg() failed
  ");
  			return -EINVAL;
  		}
  
  		cb_desc = tx_out;
  	} else {
  		cb_desc = tx_in;
ebedbf790   Mark A. Greer   crypto: omap-aes ...
327
  	}
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
328
  	if (dd->flags & FLAGS_GCM)
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
329
  		cb_desc->callback = omap_aes_gcm_dma_out_callback;
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
330
  	else
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
331
332
  		cb_desc->callback = omap_aes_dma_out_callback;
  	cb_desc->callback_param = dd;
ebedbf790   Mark A. Greer   crypto: omap-aes ...
333
334
  
  	dmaengine_submit(tx_in);
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
335
336
  	if (tx_out)
  		dmaengine_submit(tx_out);
ebedbf790   Mark A. Greer   crypto: omap-aes ...
337
338
  
  	dma_async_issue_pending(dd->dma_lch_in);
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
339
340
  	if (out_sg_len)
  		dma_async_issue_pending(dd->dma_lch_out);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
341

0d35583a1   Mark A. Greer   crypto: omap-aes ...
342
  	/* start DMA */
4b645c946   Joel Fernandes   crypto: omap-aes ...
343
  	dd->pdata->trigger(dd, dd->total);
83ea7e0fe   Dmitry Kasatkin   crypto: omap-aes ...
344

537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
345
346
  	return 0;
  }
d695bfd6f   Tero Kristo   crypto: omap-aes ...
347
  int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
348
  {
4b645c946   Joel Fernandes   crypto: omap-aes ...
349
  	int err;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
350

ac855b3c1   Herbert Xu   crypto: omap-aes ...
351
352
  	pr_debug("total: %zu
  ", dd->total);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
353

98837abc8   Joel Fernandes   crypto: omap-aes ...
354
355
356
357
358
359
360
361
  	if (!dd->pio_only) {
  		err = dma_map_sg(dd->dev, dd->in_sg, dd->in_sg_len,
  				 DMA_TO_DEVICE);
  		if (!err) {
  			dev_err(dd->dev, "dma_map_sg() error
  ");
  			return -EINVAL;
  		}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
362

5d5f3eed2   Tero Kristo   crypto: omap-aes-...
363
364
365
366
367
368
369
370
  		if (dd->out_sg_len) {
  			err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len,
  					 DMA_FROM_DEVICE);
  			if (!err) {
  				dev_err(dd->dev, "dma_map_sg() error
  ");
  				return -EINVAL;
  			}
98837abc8   Joel Fernandes   crypto: omap-aes ...
371
  		}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
372
  	}
619ce7005   Tero Kristo   crypto: omap-aes ...
373
  	err = omap_aes_crypt_dma(dd, dd->in_sg, dd->out_sg, dd->in_sg_len,
4b645c946   Joel Fernandes   crypto: omap-aes ...
374
  				 dd->out_sg_len);
98837abc8   Joel Fernandes   crypto: omap-aes ...
375
  	if (err && !dd->pio_only) {
4b645c946   Joel Fernandes   crypto: omap-aes ...
376
  		dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
5d5f3eed2   Tero Kristo   crypto: omap-aes-...
377
378
379
  		if (dd->out_sg_len)
  			dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
  				     DMA_FROM_DEVICE);
21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
380
  	}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
381
382
383
384
385
386
  
  	return err;
  }
  
  static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
387
  	struct skcipher_request *req = dd->req;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
388
389
390
  
  	pr_debug("err: %d
  ", err);
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
391
  	crypto_finalize_skcipher_request(dd->engine, req, err);
f303b455b   Tero Kristo   crypto: omap-aes ...
392
393
394
  
  	pm_runtime_mark_last_busy(dd->dev);
  	pm_runtime_put_autosuspend(dd->dev);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
395
  }
d695bfd6f   Tero Kristo   crypto: omap-aes ...
396
  int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
397
  {
ac855b3c1   Herbert Xu   crypto: omap-aes ...
398
399
  	pr_debug("total: %zu
  ", dd->total);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
400

0d35583a1   Mark A. Greer   crypto: omap-aes ...
401
  	omap_aes_dma_stop(dd);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
402

537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
403

16f080aaa   Rahul Pathak   crypto: omap - Re...
404
  	return 0;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
405
  }
21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
406
  static int omap_aes_handle_queue(struct omap_aes_dev *dd,
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
407
  				 struct skcipher_request *req)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
408
  {
eeb2b202c   Dmitry Kasatkin   crypto: omap-aes ...
409
  	if (req)
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
410
  		return crypto_transfer_skcipher_request_to_engine(dd->engine, req);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
411

0529900a0   Baolin Wang   crypto: omap-aes ...
412
413
  	return 0;
  }
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
414

0529900a0   Baolin Wang   crypto: omap-aes ...
415
  static int omap_aes_prepare_req(struct crypto_engine *engine,
c21c8b898   Corentin LABBE   crypto: omap - co...
416
  				void *areq)
0529900a0   Baolin Wang   crypto: omap-aes ...
417
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
418
419
420
421
  	struct skcipher_request *req = container_of(areq, struct skcipher_request, base);
  	struct omap_aes_ctx *ctx = crypto_skcipher_ctx(
  			crypto_skcipher_reqtfm(req));
  	struct omap_aes_reqctx *rctx = skcipher_request_ctx(req);
619ce7005   Tero Kristo   crypto: omap-aes ...
422
  	struct omap_aes_dev *dd = rctx->dd;
afc2dc133   Tero Kristo   crypto: omap-aes ...
423
424
  	int ret;
  	u16 flags;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
425

0529900a0   Baolin Wang   crypto: omap-aes ...
426
427
  	if (!dd)
  		return -ENODEV;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
428

537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
429
430
  	/* assign new request to device */
  	dd->req = req;
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
431
432
  	dd->total = req->cryptlen;
  	dd->total_save = req->cryptlen;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
433
  	dd->in_sg = req->src;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
434
  	dd->out_sg = req->dst;
afc2dc133   Tero Kristo   crypto: omap-aes ...
435
436
437
438
439
440
441
  	dd->orig_out = req->dst;
  
  	flags = OMAP_CRYPTO_COPY_DATA;
  	if (req->src == req->dst)
  		flags |= OMAP_CRYPTO_FORCE_COPY;
  
  	ret = omap_crypto_align_sg(&dd->in_sg, dd->total, AES_BLOCK_SIZE,
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
442
  				   dd->in_sgl, flags,
afc2dc133   Tero Kristo   crypto: omap-aes ...
443
444
445
446
447
448
449
450
451
  				   FLAGS_IN_DATA_ST_SHIFT, &dd->flags);
  	if (ret)
  		return ret;
  
  	ret = omap_crypto_align_sg(&dd->out_sg, dd->total, AES_BLOCK_SIZE,
  				   &dd->out_sgl, 0,
  				   FLAGS_OUT_DATA_ST_SHIFT, &dd->flags);
  	if (ret)
  		return ret;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
452

7c001a865   Herbert Xu   crypto: omap - St...
453
454
455
456
457
458
459
  	dd->in_sg_len = sg_nents_for_len(dd->in_sg, dd->total);
  	if (dd->in_sg_len < 0)
  		return dd->in_sg_len;
  
  	dd->out_sg_len = sg_nents_for_len(dd->out_sg, dd->total);
  	if (dd->out_sg_len < 0)
  		return dd->out_sg_len;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
460
461
  	rctx->mode &= FLAGS_MODE_MASK;
  	dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;
67a730ce4   Dmitry Kasatkin   crypto: omap-aes ...
462
  	dd->ctx = ctx;
619ce7005   Tero Kristo   crypto: omap-aes ...
463
  	rctx->dd = dd;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
464

0529900a0   Baolin Wang   crypto: omap-aes ...
465
466
  	return omap_aes_write_ctrl(dd);
  }
eeb2b202c   Dmitry Kasatkin   crypto: omap-aes ...
467

0529900a0   Baolin Wang   crypto: omap-aes ...
468
  static int omap_aes_crypt_req(struct crypto_engine *engine,
c21c8b898   Corentin LABBE   crypto: omap - co...
469
  			      void *areq)
0529900a0   Baolin Wang   crypto: omap-aes ...
470
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
471
472
  	struct skcipher_request *req = container_of(areq, struct skcipher_request, base);
  	struct omap_aes_reqctx *rctx = skcipher_request_ctx(req);
619ce7005   Tero Kristo   crypto: omap-aes ...
473
  	struct omap_aes_dev *dd = rctx->dd;
0529900a0   Baolin Wang   crypto: omap-aes ...
474
475
476
477
478
  
  	if (!dd)
  		return -ENODEV;
  
  	return omap_aes_crypt_dma_start(dd);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
479
  }
891dcbbb0   Tero Kristo   crypto: omap-aes ...
480
481
482
483
484
485
486
  static void omap_aes_copy_ivout(struct omap_aes_dev *dd, u8 *ivbuf)
  {
  	int i;
  
  	for (i = 0; i < 4; i++)
  		((u32 *)ivbuf)[i] = omap_aes_read(dd, AES_REG_IV(dd, i));
  }
21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
487
  static void omap_aes_done_task(unsigned long data)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
488
489
  {
  	struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
490

4b645c946   Joel Fernandes   crypto: omap-aes ...
491
492
  	pr_debug("enter done_task
  ");
21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
493

98837abc8   Joel Fernandes   crypto: omap-aes ...
494
495
496
  	if (!dd->pio_only) {
  		dma_sync_sg_for_device(dd->dev, dd->out_sg, dd->out_sg_len,
  				       DMA_FROM_DEVICE);
6242332ff   Joel Fernandes   crypto: omap-aes ...
497
498
499
  		dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
  		dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
  			     DMA_FROM_DEVICE);
98837abc8   Joel Fernandes   crypto: omap-aes ...
500
501
  		omap_aes_crypt_dma_stop(dd);
  	}
6242332ff   Joel Fernandes   crypto: omap-aes ...
502

6585cd368   Tero Kristo   crypto: omap-aes ...
503
  	omap_crypto_cleanup(dd->in_sg, NULL, 0, dd->total_save,
afc2dc133   Tero Kristo   crypto: omap-aes ...
504
  			    FLAGS_IN_DATA_ST_SHIFT, dd->flags);
6242332ff   Joel Fernandes   crypto: omap-aes ...
505

6585cd368   Tero Kristo   crypto: omap-aes ...
506
  	omap_crypto_cleanup(dd->out_sg, dd->orig_out, 0, dd->total_save,
afc2dc133   Tero Kristo   crypto: omap-aes ...
507
  			    FLAGS_OUT_DATA_ST_SHIFT, dd->flags);
6242332ff   Joel Fernandes   crypto: omap-aes ...
508

891dcbbb0   Tero Kristo   crypto: omap-aes ...
509
510
511
  	/* Update IV output */
  	if (dd->flags & (FLAGS_CBC | FLAGS_CTR))
  		omap_aes_copy_ivout(dd, dd->req->iv);
4b645c946   Joel Fernandes   crypto: omap-aes ...
512
  	omap_aes_finish_req(dd, 0);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
513
514
515
516
  
  	pr_debug("exit
  ");
  }
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
517
  static int omap_aes_crypt(struct skcipher_request *req, unsigned long mode)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
518
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
519
520
521
  	struct omap_aes_ctx *ctx = crypto_skcipher_ctx(
  			crypto_skcipher_reqtfm(req));
  	struct omap_aes_reqctx *rctx = skcipher_request_ctx(req);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
522
  	struct omap_aes_dev *dd;
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
523
  	int ret;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
524

dbb326fd0   Ard Biesheuvel   crypto: omap-aes ...
525
526
  	if ((req->cryptlen % AES_BLOCK_SIZE) && !(mode & FLAGS_CTR))
  		return -EINVAL;
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
527
528
  	pr_debug("nbytes: %d, enc: %d, cbc: %d
  ", req->cryptlen,
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
529
530
  		  !!(mode & FLAGS_ENCRYPT),
  		  !!(mode & FLAGS_CBC));
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
531
  	if (req->cryptlen < aes_fallback_sz) {
6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
532
533
534
535
536
537
538
  		skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
  		skcipher_request_set_callback(&rctx->fallback_req,
  					      req->base.flags,
  					      req->base.complete,
  					      req->base.data);
  		skcipher_request_set_crypt(&rctx->fallback_req, req->src,
  					   req->dst, req->cryptlen, req->iv);
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
539
540
  
  		if (mode & FLAGS_ENCRYPT)
6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
541
  			ret = crypto_skcipher_encrypt(&rctx->fallback_req);
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
542
  		else
6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
543
  			ret = crypto_skcipher_decrypt(&rctx->fallback_req);
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
544
545
  		return ret;
  	}
619ce7005   Tero Kristo   crypto: omap-aes ...
546
  	dd = omap_aes_find_dev(rctx);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
547
548
549
550
  	if (!dd)
  		return -ENODEV;
  
  	rctx->mode = mode;
21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
551
  	return omap_aes_handle_queue(dd, req);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
552
553
554
  }
  
  /* ********************** ALG API ************************************ */
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
555
  static int omap_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
556
557
  			   unsigned int keylen)
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
558
  	struct omap_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
559
  	int ret;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
560
561
562
563
564
565
566
567
568
569
  
  	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
  		   keylen != AES_KEYSIZE_256)
  		return -EINVAL;
  
  	pr_debug("enter, keylen: %d
  ", keylen);
  
  	memcpy(ctx->key, key, keylen);
  	ctx->keylen = keylen;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
570

6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
571
572
  	crypto_skcipher_clear_flags(ctx->fallback, CRYPTO_TFM_REQ_MASK);
  	crypto_skcipher_set_flags(ctx->fallback, tfm->base.crt_flags &
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
573
  						 CRYPTO_TFM_REQ_MASK);
6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
574
  	ret = crypto_skcipher_setkey(ctx->fallback, key, keylen);
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
575
576
  	if (!ret)
  		return 0;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
577
578
  	return 0;
  }
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
579
  static int omap_aes_ecb_encrypt(struct skcipher_request *req)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
580
581
582
  {
  	return omap_aes_crypt(req, FLAGS_ENCRYPT);
  }
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
583
  static int omap_aes_ecb_decrypt(struct skcipher_request *req)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
584
585
586
  {
  	return omap_aes_crypt(req, 0);
  }
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
587
  static int omap_aes_cbc_encrypt(struct skcipher_request *req)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
588
589
590
  {
  	return omap_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC);
  }
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
591
  static int omap_aes_cbc_decrypt(struct skcipher_request *req)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
592
593
594
  {
  	return omap_aes_crypt(req, FLAGS_CBC);
  }
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
595
  static int omap_aes_ctr_encrypt(struct skcipher_request *req)
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
596
597
598
  {
  	return omap_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CTR);
  }
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
599
  static int omap_aes_ctr_decrypt(struct skcipher_request *req)
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
600
601
602
  {
  	return omap_aes_crypt(req, FLAGS_CTR);
  }
c21c8b898   Corentin LABBE   crypto: omap - co...
603
604
605
606
  static int omap_aes_prepare_req(struct crypto_engine *engine,
  				void *req);
  static int omap_aes_crypt_req(struct crypto_engine *engine,
  			      void *req);
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
607
  static int omap_aes_init_tfm(struct crypto_skcipher *tfm)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
608
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
609
610
  	const char *name = crypto_tfm_alg_name(&tfm->base);
  	struct omap_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
611
  	struct crypto_skcipher *blk;
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
612

6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
613
  	blk = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
614
615
616
617
  	if (IS_ERR(blk))
  		return PTR_ERR(blk);
  
  	ctx->fallback = blk;
6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
618
619
  	crypto_skcipher_set_reqsize(tfm, sizeof(struct omap_aes_reqctx) +
  					 crypto_skcipher_reqsize(blk));
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
620

c21c8b898   Corentin LABBE   crypto: omap - co...
621
622
623
  	ctx->enginectx.op.prepare_request = omap_aes_prepare_req;
  	ctx->enginectx.op.unprepare_request = NULL;
  	ctx->enginectx.op.do_one_request = omap_aes_crypt_req;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
624
625
  	return 0;
  }
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
626
  static void omap_aes_exit_tfm(struct crypto_skcipher *tfm)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
627
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
628
  	struct omap_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
629
630
  
  	if (ctx->fallback)
6a99d7a2d   Ard Biesheuvel   crypto: omap-aes ...
631
  		crypto_free_skcipher(ctx->fallback);
9fcb191a8   Lokesh Vutla   crypto: omap-aes ...
632
633
  
  	ctx->fallback = NULL;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
634
635
636
  }
  
  /* ********************** ALGS ************************************ */
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
637
  static struct skcipher_alg algs_ecb_cbc[] = {
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
638
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
  	.base.cra_name		= "ecb(aes)",
  	.base.cra_driver_name	= "ecb-aes-omap",
  	.base.cra_priority	= 300,
  	.base.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
  				  CRYPTO_ALG_ASYNC |
  				  CRYPTO_ALG_NEED_FALLBACK,
  	.base.cra_blocksize	= AES_BLOCK_SIZE,
  	.base.cra_ctxsize	= sizeof(struct omap_aes_ctx),
  	.base.cra_module	= THIS_MODULE,
  
  	.min_keysize		= AES_MIN_KEY_SIZE,
  	.max_keysize		= AES_MAX_KEY_SIZE,
  	.setkey			= omap_aes_setkey,
  	.encrypt		= omap_aes_ecb_encrypt,
  	.decrypt		= omap_aes_ecb_decrypt,
  	.init			= omap_aes_init_tfm,
  	.exit			= omap_aes_exit_tfm,
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
656
657
  },
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
  	.base.cra_name		= "cbc(aes)",
  	.base.cra_driver_name	= "cbc-aes-omap",
  	.base.cra_priority	= 300,
  	.base.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
  				  CRYPTO_ALG_ASYNC |
  				  CRYPTO_ALG_NEED_FALLBACK,
  	.base.cra_blocksize	= AES_BLOCK_SIZE,
  	.base.cra_ctxsize	= sizeof(struct omap_aes_ctx),
  	.base.cra_module	= THIS_MODULE,
  
  	.min_keysize		= AES_MIN_KEY_SIZE,
  	.max_keysize		= AES_MAX_KEY_SIZE,
  	.ivsize			= AES_BLOCK_SIZE,
  	.setkey			= omap_aes_setkey,
  	.encrypt		= omap_aes_cbc_encrypt,
  	.decrypt		= omap_aes_cbc_decrypt,
  	.init			= omap_aes_init_tfm,
  	.exit			= omap_aes_exit_tfm,
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
676
677
  }
  };
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
678
  static struct skcipher_alg algs_ctr[] = {
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
679
  {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
680
681
682
683
684
685
  	.base.cra_name		= "ctr(aes)",
  	.base.cra_driver_name	= "ctr-aes-omap",
  	.base.cra_priority	= 300,
  	.base.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
  				  CRYPTO_ALG_ASYNC |
  				  CRYPTO_ALG_NEED_FALLBACK,
a9459bdcb   Ard Biesheuvel   crypto: omap-aes-...
686
  	.base.cra_blocksize	= 1,
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
687
688
689
690
691
692
693
694
695
696
697
698
  	.base.cra_ctxsize	= sizeof(struct omap_aes_ctx),
  	.base.cra_module	= THIS_MODULE,
  
  	.min_keysize		= AES_MIN_KEY_SIZE,
  	.max_keysize		= AES_MAX_KEY_SIZE,
  	.ivsize			= AES_BLOCK_SIZE,
  	.setkey			= omap_aes_setkey,
  	.encrypt		= omap_aes_ctr_encrypt,
  	.decrypt		= omap_aes_ctr_decrypt,
  	.init			= omap_aes_init_tfm,
  	.exit			= omap_aes_exit_tfm,
  }
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
699
700
701
702
703
704
705
706
  };
  
  static struct omap_aes_algs_info omap_aes_algs_info_ecb_cbc[] = {
  	{
  		.algs_list	= algs_ecb_cbc,
  		.size		= ARRAY_SIZE(algs_ecb_cbc),
  	},
  };
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
707
708
709
710
711
712
713
714
715
  static struct aead_alg algs_aead_gcm[] = {
  {
  	.base = {
  		.cra_name		= "gcm(aes)",
  		.cra_driver_name	= "gcm-aes-omap",
  		.cra_priority		= 300,
  		.cra_flags		= CRYPTO_ALG_ASYNC |
  					  CRYPTO_ALG_KERN_DRIVER_ONLY,
  		.cra_blocksize		= 1,
f0956d42c   Ard Biesheuvel   crypto: omap-aes-...
716
  		.cra_ctxsize		= sizeof(struct omap_aes_gcm_ctx),
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
717
718
719
720
  		.cra_alignmask		= 0xf,
  		.cra_module		= THIS_MODULE,
  	},
  	.init		= omap_aes_gcm_cra_init,
cb3f38175   Corentin LABBE   crypto: omap - Us...
721
  	.ivsize		= GCM_AES_IV_SIZE,
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
722
723
  	.maxauthsize	= AES_BLOCK_SIZE,
  	.setkey		= omap_aes_gcm_setkey,
12adf9d63   Ard Biesheuvel   crypto: omap-aes-...
724
  	.setauthsize	= omap_aes_gcm_setauthsize,
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
725
726
727
728
729
730
731
732
733
734
735
  	.encrypt	= omap_aes_gcm_encrypt,
  	.decrypt	= omap_aes_gcm_decrypt,
  },
  {
  	.base = {
  		.cra_name		= "rfc4106(gcm(aes))",
  		.cra_driver_name	= "rfc4106-gcm-aes-omap",
  		.cra_priority		= 300,
  		.cra_flags		= CRYPTO_ALG_ASYNC |
  					  CRYPTO_ALG_KERN_DRIVER_ONLY,
  		.cra_blocksize		= 1,
f0956d42c   Ard Biesheuvel   crypto: omap-aes-...
736
  		.cra_ctxsize		= sizeof(struct omap_aes_gcm_ctx),
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
737
738
739
740
  		.cra_alignmask		= 0xf,
  		.cra_module		= THIS_MODULE,
  	},
  	.init		= omap_aes_gcm_cra_init,
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
741
  	.maxauthsize	= AES_BLOCK_SIZE,
cb3f38175   Corentin LABBE   crypto: omap - Us...
742
  	.ivsize		= GCM_RFC4106_IV_SIZE,
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
743
  	.setkey		= omap_aes_4106gcm_setkey,
12adf9d63   Ard Biesheuvel   crypto: omap-aes-...
744
  	.setauthsize	= omap_aes_4106gcm_setauthsize,
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
745
746
747
748
749
750
751
752
753
  	.encrypt	= omap_aes_4106gcm_encrypt,
  	.decrypt	= omap_aes_4106gcm_decrypt,
  },
  };
  
  static struct omap_aes_aead_algs omap_aes_aead_info = {
  	.algs_list	=	algs_aead_gcm,
  	.size		=	ARRAY_SIZE(algs_aead_gcm),
  };
0d35583a1   Mark A. Greer   crypto: omap-aes ...
754
  static const struct omap_aes_pdata omap_aes_pdata_omap2 = {
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
755
756
  	.algs_info	= omap_aes_algs_info_ecb_cbc,
  	.algs_info_size	= ARRAY_SIZE(omap_aes_algs_info_ecb_cbc),
0d35583a1   Mark A. Greer   crypto: omap-aes ...
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
  	.trigger	= omap_aes_dma_trigger_omap2,
  	.key_ofs	= 0x1c,
  	.iv_ofs		= 0x20,
  	.ctrl_ofs	= 0x30,
  	.data_ofs	= 0x34,
  	.rev_ofs	= 0x44,
  	.mask_ofs	= 0x48,
  	.dma_enable_in	= BIT(2),
  	.dma_enable_out	= BIT(3),
  	.dma_start	= BIT(5),
  	.major_mask	= 0xf0,
  	.major_shift	= 4,
  	.minor_mask	= 0x0f,
  	.minor_shift	= 0,
  };
bc69d124d   Mark A. Greer   crypto: omap-aes ...
772
  #ifdef CONFIG_OF
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
  static struct omap_aes_algs_info omap_aes_algs_info_ecb_cbc_ctr[] = {
  	{
  		.algs_list	= algs_ecb_cbc,
  		.size		= ARRAY_SIZE(algs_ecb_cbc),
  	},
  	{
  		.algs_list	= algs_ctr,
  		.size		= ARRAY_SIZE(algs_ctr),
  	},
  };
  
  static const struct omap_aes_pdata omap_aes_pdata_omap3 = {
  	.algs_info	= omap_aes_algs_info_ecb_cbc_ctr,
  	.algs_info_size	= ARRAY_SIZE(omap_aes_algs_info_ecb_cbc_ctr),
  	.trigger	= omap_aes_dma_trigger_omap2,
  	.key_ofs	= 0x1c,
  	.iv_ofs		= 0x20,
  	.ctrl_ofs	= 0x30,
  	.data_ofs	= 0x34,
  	.rev_ofs	= 0x44,
  	.mask_ofs	= 0x48,
  	.dma_enable_in	= BIT(2),
  	.dma_enable_out	= BIT(3),
  	.dma_start	= BIT(5),
  	.major_mask	= 0xf0,
  	.major_shift	= 4,
  	.minor_mask	= 0x0f,
  	.minor_shift	= 0,
  };
0d35583a1   Mark A. Greer   crypto: omap-aes ...
802
  static const struct omap_aes_pdata omap_aes_pdata_omap4 = {
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
803
804
  	.algs_info	= omap_aes_algs_info_ecb_cbc_ctr,
  	.algs_info_size	= ARRAY_SIZE(omap_aes_algs_info_ecb_cbc_ctr),
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
805
  	.aead_algs_info	= &omap_aes_aead_info,
0d35583a1   Mark A. Greer   crypto: omap-aes ...
806
807
808
809
810
811
812
  	.trigger	= omap_aes_dma_trigger_omap4,
  	.key_ofs	= 0x3c,
  	.iv_ofs		= 0x40,
  	.ctrl_ofs	= 0x50,
  	.data_ofs	= 0x60,
  	.rev_ofs	= 0x80,
  	.mask_ofs	= 0x84,
67216756e   Joel Fernandes   crypto: omap-aes ...
813
814
  	.irq_status_ofs = 0x8c,
  	.irq_enable_ofs = 0x90,
0d35583a1   Mark A. Greer   crypto: omap-aes ...
815
816
817
818
819
820
821
  	.dma_enable_in	= BIT(5),
  	.dma_enable_out	= BIT(6),
  	.major_mask	= 0x0700,
  	.major_shift	= 8,
  	.minor_mask	= 0x003f,
  	.minor_shift	= 0,
  };
1bf95cca8   Joel Fernandes   crypto: omap-aes ...
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
  static irqreturn_t omap_aes_irq(int irq, void *dev_id)
  {
  	struct omap_aes_dev *dd = dev_id;
  	u32 status, i;
  	u32 *src, *dst;
  
  	status = omap_aes_read(dd, AES_REG_IRQ_STATUS(dd));
  	if (status & AES_REG_IRQ_DATA_IN) {
  		omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x0);
  
  		BUG_ON(!dd->in_sg);
  
  		BUG_ON(_calc_walked(in) > dd->in_sg->length);
  
  		src = sg_virt(dd->in_sg) + _calc_walked(in);
  
  		for (i = 0; i < AES_BLOCK_WORDS; i++) {
  			omap_aes_write(dd, AES_REG_DATA_N(dd, i), *src);
  
  			scatterwalk_advance(&dd->in_walk, 4);
  			if (dd->in_sg->length == _calc_walked(in)) {
5be4d4c94   Cristian Stoica   crypto: replace s...
843
  				dd->in_sg = sg_next(dd->in_sg);
1bf95cca8   Joel Fernandes   crypto: omap-aes ...
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
  				if (dd->in_sg) {
  					scatterwalk_start(&dd->in_walk,
  							  dd->in_sg);
  					src = sg_virt(dd->in_sg) +
  					      _calc_walked(in);
  				}
  			} else {
  				src++;
  			}
  		}
  
  		/* Clear IRQ status */
  		status &= ~AES_REG_IRQ_DATA_IN;
  		omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status);
  
  		/* Enable DATA_OUT interrupt */
  		omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x4);
  
  	} else if (status & AES_REG_IRQ_DATA_OUT) {
  		omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x0);
  
  		BUG_ON(!dd->out_sg);
  
  		BUG_ON(_calc_walked(out) > dd->out_sg->length);
  
  		dst = sg_virt(dd->out_sg) + _calc_walked(out);
  
  		for (i = 0; i < AES_BLOCK_WORDS; i++) {
  			*dst = omap_aes_read(dd, AES_REG_DATA_N(dd, i));
  			scatterwalk_advance(&dd->out_walk, 4);
  			if (dd->out_sg->length == _calc_walked(out)) {
5be4d4c94   Cristian Stoica   crypto: replace s...
875
  				dd->out_sg = sg_next(dd->out_sg);
1bf95cca8   Joel Fernandes   crypto: omap-aes ...
876
877
878
879
880
881
882
883
884
885
  				if (dd->out_sg) {
  					scatterwalk_start(&dd->out_walk,
  							  dd->out_sg);
  					dst = sg_virt(dd->out_sg) +
  					      _calc_walked(out);
  				}
  			} else {
  				dst++;
  			}
  		}
310b0d55f   Vutla, Lokesh   crypto: omap-aes ...
886
  		dd->total -= min_t(size_t, AES_BLOCK_SIZE, dd->total);
1bf95cca8   Joel Fernandes   crypto: omap-aes ...
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
  
  		/* Clear IRQ status */
  		status &= ~AES_REG_IRQ_DATA_OUT;
  		omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status);
  
  		if (!dd->total)
  			/* All bytes read! */
  			tasklet_schedule(&dd->done_task);
  		else
  			/* Enable DATA_IN interrupt for next block */
  			omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x2);
  	}
  
  	return IRQ_HANDLED;
  }
bc69d124d   Mark A. Greer   crypto: omap-aes ...
902
903
904
  static const struct of_device_id omap_aes_of_match[] = {
  	{
  		.compatible	= "ti,omap2-aes",
0d35583a1   Mark A. Greer   crypto: omap-aes ...
905
906
907
  		.data		= &omap_aes_pdata_omap2,
  	},
  	{
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
908
909
910
911
  		.compatible	= "ti,omap3-aes",
  		.data		= &omap_aes_pdata_omap3,
  	},
  	{
0d35583a1   Mark A. Greer   crypto: omap-aes ...
912
913
  		.compatible	= "ti,omap4-aes",
  		.data		= &omap_aes_pdata_omap4,
bc69d124d   Mark A. Greer   crypto: omap-aes ...
914
915
916
917
918
919
920
921
922
  	},
  	{},
  };
  MODULE_DEVICE_TABLE(of, omap_aes_of_match);
  
  static int omap_aes_get_res_of(struct omap_aes_dev *dd,
  		struct device *dev, struct resource *res)
  {
  	struct device_node *node = dev->of_node;
bc69d124d   Mark A. Greer   crypto: omap-aes ...
923
  	int err = 0;
7d5569315   Corentin LABBE   crypto: omap - us...
924
925
  	dd->pdata = of_device_get_match_data(dev);
  	if (!dd->pdata) {
bc69d124d   Mark A. Greer   crypto: omap-aes ...
926
927
928
929
930
931
932
933
934
935
936
937
938
  		dev_err(dev, "no compatible OF match
  ");
  		err = -EINVAL;
  		goto err;
  	}
  
  	err = of_address_to_resource(node, 0, res);
  	if (err < 0) {
  		dev_err(dev, "can't translate OF node address
  ");
  		err = -EINVAL;
  		goto err;
  	}
bc69d124d   Mark A. Greer   crypto: omap-aes ...
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
  err:
  	return err;
  }
  #else
  static const struct of_device_id omap_aes_of_match[] = {
  	{},
  };
  
  static int omap_aes_get_res_of(struct omap_aes_dev *dd,
  		struct device *dev, struct resource *res)
  {
  	return -EINVAL;
  }
  #endif
  
  static int omap_aes_get_res_pdev(struct omap_aes_dev *dd,
  		struct platform_device *pdev, struct resource *res)
  {
  	struct device *dev = &pdev->dev;
  	struct resource *r;
  	int err = 0;
  
  	/* Get the base address */
  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	if (!r) {
  		dev_err(dev, "no MEM resource info
  ");
  		err = -ENODEV;
  		goto err;
  	}
  	memcpy(res, r, sizeof(*res));
0d35583a1   Mark A. Greer   crypto: omap-aes ...
970
971
  	/* Only OMAP2/3 can be non-DT */
  	dd->pdata = &omap_aes_pdata_omap2;
bc69d124d   Mark A. Greer   crypto: omap-aes ...
972
973
974
  err:
  	return err;
  }
537c62ca1   Tero Kristo   crypto: omap-aes ...
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
  static ssize_t fallback_show(struct device *dev, struct device_attribute *attr,
  			     char *buf)
  {
  	return sprintf(buf, "%d
  ", aes_fallback_sz);
  }
  
  static ssize_t fallback_store(struct device *dev, struct device_attribute *attr,
  			      const char *buf, size_t size)
  {
  	ssize_t status;
  	long value;
  
  	status = kstrtol(buf, 0, &value);
  	if (status)
  		return status;
  
  	/* HW accelerator only works with buffers > 9 */
  	if (value < 9) {
  		dev_err(dev, "minimum fallback size 9
  ");
  		return -EINVAL;
  	}
  
  	aes_fallback_sz = value;
  
  	return size;
  }
5007387fc   Tero Kristo   crypto: omap-aes ...
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
  static ssize_t queue_len_show(struct device *dev, struct device_attribute *attr,
  			      char *buf)
  {
  	struct omap_aes_dev *dd = dev_get_drvdata(dev);
  
  	return sprintf(buf, "%d
  ", dd->engine->queue.max_qlen);
  }
  
  static ssize_t queue_len_store(struct device *dev,
  			       struct device_attribute *attr, const char *buf,
  			       size_t size)
  {
  	struct omap_aes_dev *dd;
  	ssize_t status;
  	long value;
  	unsigned long flags;
  
  	status = kstrtol(buf, 0, &value);
  	if (status)
  		return status;
  
  	if (value < 1)
  		return -EINVAL;
  
  	/*
  	 * Changing the queue size in fly is safe, if size becomes smaller
  	 * than current size, it will just not accept new entries until
  	 * it has shrank enough.
  	 */
  	spin_lock_bh(&list_lock);
  	list_for_each_entry(dd, &dev_list, list) {
  		spin_lock_irqsave(&dd->lock, flags);
  		dd->engine->queue.max_qlen = value;
  		dd->aead_queue.base.max_qlen = value;
  		spin_unlock_irqrestore(&dd->lock, flags);
  	}
  	spin_unlock_bh(&list_lock);
  
  	return size;
  }
  
  static DEVICE_ATTR_RW(queue_len);
537c62ca1   Tero Kristo   crypto: omap-aes ...
1046
1047
1048
  static DEVICE_ATTR_RW(fallback);
  
  static struct attribute *omap_aes_attrs[] = {
5007387fc   Tero Kristo   crypto: omap-aes ...
1049
  	&dev_attr_queue_len.attr,
537c62ca1   Tero Kristo   crypto: omap-aes ...
1050
1051
1052
1053
1054
1055
1056
  	&dev_attr_fallback.attr,
  	NULL,
  };
  
  static struct attribute_group omap_aes_attr_group = {
  	.attrs = omap_aes_attrs,
  };
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1057
1058
1059
1060
  static int omap_aes_probe(struct platform_device *pdev)
  {
  	struct device *dev = &pdev->dev;
  	struct omap_aes_dev *dd;
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
1061
  	struct skcipher_alg *algp;
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1062
  	struct aead_alg *aalg;
bc69d124d   Mark A. Greer   crypto: omap-aes ...
1063
  	struct resource res;
1801ad948   Joel Fernandes   crypto: omap-aes ...
1064
  	int err = -ENOMEM, i, j, irq = -1;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1065
  	u32 reg;
05007c10f   Joel Fernandes   crypto: omap-aes ...
1066
  	dd = devm_kzalloc(dev, sizeof(struct omap_aes_dev), GFP_KERNEL);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1067
1068
1069
1070
1071
1072
1073
  	if (dd == NULL) {
  		dev_err(dev, "unable to alloc data struct.
  ");
  		goto err_data;
  	}
  	dd->dev = dev;
  	platform_set_drvdata(pdev, dd);
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1074
  	aead_init_queue(&dd->aead_queue, OMAP_AES_QUEUE_LENGTH);
bc69d124d   Mark A. Greer   crypto: omap-aes ...
1075
1076
1077
  	err = (dev->of_node) ? omap_aes_get_res_of(dd, dev, &res) :
  			       omap_aes_get_res_pdev(dd, pdev, &res);
  	if (err)
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1078
  		goto err_res;
bc69d124d   Mark A. Greer   crypto: omap-aes ...
1079

30862281f   Laurent Navet   drivers: crypto: ...
1080
1081
1082
  	dd->io_base = devm_ioremap_resource(dev, &res);
  	if (IS_ERR(dd->io_base)) {
  		err = PTR_ERR(dd->io_base);
5946c4a5e   Mark A. Greer   crypto: omap-aes ...
1083
  		goto err_res;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1084
  	}
bc69d124d   Mark A. Greer   crypto: omap-aes ...
1085
  	dd->phys_base = res.start;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1086

f303b455b   Tero Kristo   crypto: omap-aes ...
1087
1088
  	pm_runtime_use_autosuspend(dev);
  	pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY);
5946c4a5e   Mark A. Greer   crypto: omap-aes ...
1089
  	pm_runtime_enable(dev);
f7b2b5dd6   Nishanth Menon   crypto: omap-aes ...
1090
1091
1092
1093
1094
  	err = pm_runtime_get_sync(dev);
  	if (err < 0) {
  		dev_err(dev, "%s: failed to get_sync(%d)
  ",
  			__func__, err);
3cf33a468   Zhang Qilong   crypto: omap-aes ...
1095
  		goto err_pm_disable;
f7b2b5dd6   Nishanth Menon   crypto: omap-aes ...
1096
  	}
5946c4a5e   Mark A. Greer   crypto: omap-aes ...
1097

0d35583a1   Mark A. Greer   crypto: omap-aes ...
1098
1099
1100
  	omap_aes_dma_stop(dd);
  
  	reg = omap_aes_read(dd, AES_REG_REV(dd));
5946c4a5e   Mark A. Greer   crypto: omap-aes ...
1101
1102
  
  	pm_runtime_put_sync(dev);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1103

0d35583a1   Mark A. Greer   crypto: omap-aes ...
1104
1105
1106
1107
  	dev_info(dev, "OMAP AES hw accel rev: %u.%u
  ",
  		 (reg & dd->pdata->major_mask) >> dd->pdata->major_shift,
  		 (reg & dd->pdata->minor_mask) >> dd->pdata->minor_shift);
21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
1108
  	tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1109
1110
  
  	err = omap_aes_dma_init(dd);
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
1111
1112
1113
  	if (err == -EPROBE_DEFER) {
  		goto err_irq;
  	} else if (err && AES_REG_IRQ_STATUS(dd) && AES_REG_IRQ_ENABLE(dd)) {
1801ad948   Joel Fernandes   crypto: omap-aes ...
1114
1115
1116
1117
  		dd->pio_only = 1;
  
  		irq = platform_get_irq(pdev, 0);
  		if (irq < 0) {
62c58f8d6   Gustavo A. R. Silva   crypto: omap-aes ...
1118
  			err = irq;
1801ad948   Joel Fernandes   crypto: omap-aes ...
1119
1120
  			goto err_irq;
  		}
bce2a2288   Joel Fernandes   crypto: omap-aes ...
1121
  		err = devm_request_irq(dev, irq, omap_aes_irq, 0,
1801ad948   Joel Fernandes   crypto: omap-aes ...
1122
1123
1124
1125
1126
1127
1128
  				dev_name(dev), dd);
  		if (err) {
  			dev_err(dev, "Unable to grab omap-aes IRQ
  ");
  			goto err_irq;
  		}
  	}
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1129
  	spin_lock_init(&dd->lock);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1130
1131
1132
1133
1134
  
  	INIT_LIST_HEAD(&dd->list);
  	spin_lock(&list_lock);
  	list_add_tail(&dd->list, &dev_list);
  	spin_unlock(&list_lock);
0d0cda93d   Tero Kristo   crypto: omap-aes ...
1135
1136
  	/* Initialize crypto engine */
  	dd->engine = crypto_engine_alloc_init(dev, 1);
c98ef8dbc   Wei Yongjun   crypto: omap-aes ...
1137
1138
  	if (!dd->engine) {
  		err = -ENOMEM;
0d0cda93d   Tero Kristo   crypto: omap-aes ...
1139
  		goto err_engine;
c98ef8dbc   Wei Yongjun   crypto: omap-aes ...
1140
  	}
0d0cda93d   Tero Kristo   crypto: omap-aes ...
1141

0d0cda93d   Tero Kristo   crypto: omap-aes ...
1142
1143
1144
  	err = crypto_engine_start(dd->engine);
  	if (err)
  		goto err_engine;
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1145
  	for (i = 0; i < dd->pdata->algs_info_size; i++) {
3741bbb20   Lokesh Vutla   crypto: omap-aes ...
1146
1147
1148
  		if (!dd->pdata->algs_info[i].registered) {
  			for (j = 0; j < dd->pdata->algs_info[i].size; j++) {
  				algp = &dd->pdata->algs_info[i].algs_list[j];
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1149

b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
1150
1151
  				pr_debug("reg alg: %s
  ", algp->base.cra_name);
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1152

b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
1153
  				err = crypto_register_skcipher(algp);
3741bbb20   Lokesh Vutla   crypto: omap-aes ...
1154
1155
  				if (err)
  					goto err_algs;
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1156

3741bbb20   Lokesh Vutla   crypto: omap-aes ...
1157
1158
  				dd->pdata->algs_info[i].registered++;
  			}
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1159
  		}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1160
  	}
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1161
1162
1163
1164
  	if (dd->pdata->aead_algs_info &&
  	    !dd->pdata->aead_algs_info->registered) {
  		for (i = 0; i < dd->pdata->aead_algs_info->size; i++) {
  			aalg = &dd->pdata->aead_algs_info->algs_list[i];
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1165

b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
1166
1167
  			pr_debug("reg alg: %s
  ", aalg->base.cra_name);
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1168
1169
1170
1171
1172
1173
1174
1175
  
  			err = crypto_register_aead(aalg);
  			if (err)
  				goto err_aead_algs;
  
  			dd->pdata->aead_algs_info->registered++;
  		}
  	}
537c62ca1   Tero Kristo   crypto: omap-aes ...
1176
1177
1178
1179
1180
1181
  	err = sysfs_create_group(&dev->kobj, &omap_aes_attr_group);
  	if (err) {
  		dev_err(dev, "could not create sysfs device attrs
  ");
  		goto err_aead_algs;
  	}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1182
  	return 0;
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1183
1184
1185
1186
1187
  err_aead_algs:
  	for (i = dd->pdata->aead_algs_info->registered - 1; i >= 0; i--) {
  		aalg = &dd->pdata->aead_algs_info->algs_list[i];
  		crypto_unregister_aead(aalg);
  	}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1188
  err_algs:
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1189
1190
  	for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
  		for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
1191
  			crypto_unregister_skcipher(
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1192
  					&dd->pdata->algs_info[i].algs_list[j]);
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
1193

0d0cda93d   Tero Kristo   crypto: omap-aes ...
1194
1195
1196
  err_engine:
  	if (dd->engine)
  		crypto_engine_exit(dd->engine);
da8b29a6c   Peter Ujfalusi   crypto: omap-aes ...
1197
  	omap_aes_dma_cleanup(dd);
1801ad948   Joel Fernandes   crypto: omap-aes ...
1198
  err_irq:
21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
1199
  	tasklet_kill(&dd->done_task);
3cf33a468   Zhang Qilong   crypto: omap-aes ...
1200
  err_pm_disable:
5946c4a5e   Mark A. Greer   crypto: omap-aes ...
1201
  	pm_runtime_disable(dev);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1202
  err_res:
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
  	dd = NULL;
  err_data:
  	dev_err(dev, "initialization failed.
  ");
  	return err;
  }
  
  static int omap_aes_remove(struct platform_device *pdev)
  {
  	struct omap_aes_dev *dd = platform_get_drvdata(pdev);
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1213
  	struct aead_alg *aalg;
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1214
  	int i, j;
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1215
1216
1217
1218
1219
1220
1221
  
  	if (!dd)
  		return -ENODEV;
  
  	spin_lock(&list_lock);
  	list_del(&dd->list);
  	spin_unlock(&list_lock);
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1222
  	for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
9ef4e6e5e   Tero Kristo   crypto: omap-aes ...
1223
  		for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) {
b3e3f0fe4   Ard Biesheuvel   crypto: omap - sw...
1224
  			crypto_unregister_skcipher(
f9fb69e73   Mark A. Greer   crypto: omap-aes ...
1225
  					&dd->pdata->algs_info[i].algs_list[j]);
9ef4e6e5e   Tero Kristo   crypto: omap-aes ...
1226
1227
  			dd->pdata->algs_info[i].registered--;
  		}
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1228

9ef4e6e5e   Tero Kristo   crypto: omap-aes ...
1229
  	for (i = dd->pdata->aead_algs_info->registered - 1; i >= 0; i--) {
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1230
1231
  		aalg = &dd->pdata->aead_algs_info->algs_list[i];
  		crypto_unregister_aead(aalg);
9ef4e6e5e   Tero Kristo   crypto: omap-aes ...
1232
  		dd->pdata->aead_algs_info->registered--;
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1233
  	}
0529900a0   Baolin Wang   crypto: omap-aes ...
1234
  	crypto_engine_exit(dd->engine);
ad18cc9d0   Tero Kristo   crypto: omap-aes ...
1235

21fe9767f   Dmitry Kasatkin   crypto: omap-aes ...
1236
  	tasklet_kill(&dd->done_task);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1237
  	omap_aes_dma_cleanup(dd);
5946c4a5e   Mark A. Greer   crypto: omap-aes ...
1238
  	pm_runtime_disable(dd->dev);
e7508ef2a   Tero Kristo   crypto: omap-aes ...
1239
1240
  
  	sysfs_remove_group(&dd->dev->kobj, &omap_aes_attr_group);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1241
1242
1243
  
  	return 0;
  }
0635fb3a3   Mark A. Greer   crypto: omap-aes ...
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
  #ifdef CONFIG_PM_SLEEP
  static int omap_aes_suspend(struct device *dev)
  {
  	pm_runtime_put_sync(dev);
  	return 0;
  }
  
  static int omap_aes_resume(struct device *dev)
  {
  	pm_runtime_get_sync(dev);
  	return 0;
  }
  #endif
ea7b28439   Jingoo Han   crypto: omap-aes ...
1257
  static SIMPLE_DEV_PM_OPS(omap_aes_pm_ops, omap_aes_suspend, omap_aes_resume);
0635fb3a3   Mark A. Greer   crypto: omap-aes ...
1258

537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1259
1260
1261
1262
1263
  static struct platform_driver omap_aes_driver = {
  	.probe	= omap_aes_probe,
  	.remove	= omap_aes_remove,
  	.driver	= {
  		.name	= "omap-aes",
0635fb3a3   Mark A. Greer   crypto: omap-aes ...
1264
  		.pm	= &omap_aes_pm_ops,
bc69d124d   Mark A. Greer   crypto: omap-aes ...
1265
  		.of_match_table	= omap_aes_of_match,
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1266
1267
  	},
  };
94e51df9d   Sachin Kamat   crypto: omap-aes ...
1268
  module_platform_driver(omap_aes_driver);
537559a5b   Dmitry Kasatkin   crypto: omap-aes ...
1269
1270
1271
1272
  
  MODULE_DESCRIPTION("OMAP AES hw acceleration support.");
  MODULE_LICENSE("GPL v2");
  MODULE_AUTHOR("Dmitry Kasatkin");